COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
bits_access.h
1//
2// Copyright 2016 - 2025 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8#pragma once
9
10#include "comms/details/base_detection.h"
11#include "comms/details/gen_enum.h"
12#include "comms/details/macro_common.h"
13
14#include <tuple>
15#include <type_traits>
16
17#ifdef COMMS_MUST_DEFINE_BASE
18#define COMMS_AS_BITMASK_FUNC Base& asBitmask()
19#define COMMS_AS_BITMASK_CONST_FUNC const Base& asBitmask() const
20#else // #ifdef COMMS_MUST_DEFINE_BASE
21#define COMMS_AS_BITMASK_FUNC FUNC_AUTO_REF_RETURN(asBitmask, decltype(comms::field::toFieldBase(*this)))
22#define COMMS_AS_BITMASK_CONST_FUNC FUNC_AUTO_REF_RETURN_CONST(asBitmask, decltype(comms::field::toFieldBase(*this)))
23#endif // #ifdef COMMS_MUST_DEFINE_BASE
24
25#define COMMS_BIT_ACC_FUNC(f_, n_) \
26 bool COMMS_CONCATENATE(getBitValue_, n_)() const {\
27 return f_.getBitValue(COMMS_CONCATENATE(BitIdx_, n_)); \
28 } \
29 void COMMS_CONCATENATE(setBitValue_, n_)(bool val) {\
30 f_.setBitValue(COMMS_CONCATENATE(BitIdx_, n_), val); \
31 }
32
33#define COMMS_BIT_ACC_FUNC_1(f_, n_) COMMS_BIT_ACC_FUNC(f_, n_)
34#define COMMS_BIT_ACC_FUNC_2(f_, n_, ...) \
35 COMMS_BIT_ACC_FUNC(f_, n_) \
36 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_1(f_, __VA_ARGS__))
37#define COMMS_BIT_ACC_FUNC_3(f_, n_, ...) \
38 COMMS_BIT_ACC_FUNC(f_, n_) \
39 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_2(f_, __VA_ARGS__))
40#define COMMS_BIT_ACC_FUNC_4(f_, n_, ...) \
41 COMMS_BIT_ACC_FUNC(f_, n_) \
42 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_3(f_, __VA_ARGS__))
43#define COMMS_BIT_ACC_FUNC_5(f_, n_, ...) \
44 COMMS_BIT_ACC_FUNC(f_, n_) \
45 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_4(f_, __VA_ARGS__))
46#define COMMS_BIT_ACC_FUNC_6(f_, n_, ...) \
47 COMMS_BIT_ACC_FUNC(f_, n_) \
48 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_5(f_, __VA_ARGS__))
49#define COMMS_BIT_ACC_FUNC_7(f_, n_, ...) \
50 COMMS_BIT_ACC_FUNC(f_, n_) \
51 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_6(f_, __VA_ARGS__))
52#define COMMS_BIT_ACC_FUNC_8(f_, n_, ...) \
53 COMMS_BIT_ACC_FUNC(f_, n_) \
54 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_7(f_, __VA_ARGS__))
55#define COMMS_BIT_ACC_FUNC_9(f_, n_, ...) \
56 COMMS_BIT_ACC_FUNC(f_, n_) \
57 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_8(f_, __VA_ARGS__))
58#define COMMS_BIT_ACC_FUNC_10(f_, n_, ...) \
59 COMMS_BIT_ACC_FUNC(f_, n_) \
60 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_9(f_, __VA_ARGS__))
61#define COMMS_BIT_ACC_FUNC_11(f_, n_, ...) \
62 COMMS_BIT_ACC_FUNC(f_, n_) \
63 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_10(f_, __VA_ARGS__))
64#define COMMS_BIT_ACC_FUNC_12(f_, n_, ...) \
65 COMMS_BIT_ACC_FUNC(f_, n_) \
66 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_11(f_, __VA_ARGS__))
67#define COMMS_BIT_ACC_FUNC_13(f_, n_, ...) \
68 COMMS_BIT_ACC_FUNC(f_, n_) \
69 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_12(f_, __VA_ARGS__))
70#define COMMS_BIT_ACC_FUNC_14(f_, n_, ...) \
71 COMMS_BIT_ACC_FUNC(f_, n_) \
72 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_13(f_, __VA_ARGS__))
73#define COMMS_BIT_ACC_FUNC_15(f_, n_, ...) \
74 COMMS_BIT_ACC_FUNC(f_, n_) \
75 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_14(f_, __VA_ARGS__))
76#define COMMS_BIT_ACC_FUNC_16(f_, n_, ...) \
77 COMMS_BIT_ACC_FUNC(f_, n_) \
78 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_15(f_, __VA_ARGS__))
79#define COMMS_BIT_ACC_FUNC_17(f_, n_, ...) \
80 COMMS_BIT_ACC_FUNC(f_, n_) \
81 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_16(f_, __VA_ARGS__))
82#define COMMS_BIT_ACC_FUNC_18(f_, n_, ...) \
83 COMMS_BIT_ACC_FUNC(f_, n_) \
84 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_17(f_, __VA_ARGS__))
85#define COMMS_BIT_ACC_FUNC_19(f_, n_, ...) \
86 COMMS_BIT_ACC_FUNC(f_, n_) \
87 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_18(f_, __VA_ARGS__))
88#define COMMS_BIT_ACC_FUNC_20(f_, n_, ...) \
89 COMMS_BIT_ACC_FUNC(f_, n_) \
90 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_19(f_, __VA_ARGS__))
91#define COMMS_BIT_ACC_FUNC_21(f_, n_, ...) \
92 COMMS_BIT_ACC_FUNC(f_, n_) \
93 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_20(f_, __VA_ARGS__))
94#define COMMS_BIT_ACC_FUNC_22(f_, n_, ...) \
95 COMMS_BIT_ACC_FUNC(f_, n_) \
96 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_21(f_, __VA_ARGS__))
97#define COMMS_BIT_ACC_FUNC_23(f_, n_, ...) \
98 COMMS_BIT_ACC_FUNC(f_, n_) \
99 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_22(f_, __VA_ARGS__))
100#define COMMS_BIT_ACC_FUNC_24(f_, n_, ...) \
101 COMMS_BIT_ACC_FUNC(f_, n_) \
102 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_23(f_, __VA_ARGS__))
103#define COMMS_BIT_ACC_FUNC_25(f_, n_, ...) \
104 COMMS_BIT_ACC_FUNC(f_, n_) \
105 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_24(f_, __VA_ARGS__))
106#define COMMS_BIT_ACC_FUNC_26(f_, n_, ...) \
107 COMMS_BIT_ACC_FUNC(f_, n_) \
108 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_25(f_, __VA_ARGS__))
109#define COMMS_BIT_ACC_FUNC_27(f_, n_, ...) \
110 COMMS_BIT_ACC_FUNC(f_, n_) \
111 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_26(f_, __VA_ARGS__))
112#define COMMS_BIT_ACC_FUNC_28(f_, n_, ...) \
113 COMMS_BIT_ACC_FUNC(f_, n_) \
114 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_27(f_, __VA_ARGS__))
115#define COMMS_BIT_ACC_FUNC_29(f_, n_, ...) \
116 COMMS_BIT_ACC_FUNC(f_, n_) \
117 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_28(f_, __VA_ARGS__))
118#define COMMS_BIT_ACC_FUNC_30(f_, n_, ...) \
119 COMMS_BIT_ACC_FUNC(f_, n_) \
120 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_29(f_, __VA_ARGS__))
121#define COMMS_BIT_ACC_FUNC_31(f_, n_, ...) \
122 COMMS_BIT_ACC_FUNC(f_, n_) \
123 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_30(f_, __VA_ARGS__))
124#define COMMS_BIT_ACC_FUNC_32(f_, n_, ...) \
125 COMMS_BIT_ACC_FUNC(f_, n_) \
126 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_31(f_, __VA_ARGS__))
127#define COMMS_BIT_ACC_FUNC_33(f_, n_, ...) \
128 COMMS_BIT_ACC_FUNC(f_, n_) \
129 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_32(f_, __VA_ARGS__))
130#define COMMS_BIT_ACC_FUNC_34(f_, n_, ...) \
131 COMMS_BIT_ACC_FUNC(f_, n_) \
132 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_33(f_, __VA_ARGS__))
133#define COMMS_BIT_ACC_FUNC_35(f_, n_, ...) \
134 COMMS_BIT_ACC_FUNC(f_, n_) \
135 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_34(f_, __VA_ARGS__))
136#define COMMS_BIT_ACC_FUNC_36(f_, n_, ...) \
137 COMMS_BIT_ACC_FUNC(f_, n_) \
138 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_35(f_, __VA_ARGS__))
139#define COMMS_BIT_ACC_FUNC_37(f_, n_, ...) \
140 COMMS_BIT_ACC_FUNC(f_, n_) \
141 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_36(f_, __VA_ARGS__))
142#define COMMS_BIT_ACC_FUNC_38(f_, n_, ...) \
143 COMMS_BIT_ACC_FUNC(f_, n_) \
144 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_37(f_, __VA_ARGS__))
145#define COMMS_BIT_ACC_FUNC_39(f_, n_, ...) \
146 COMMS_BIT_ACC_FUNC(f_, n_) \
147 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_38(f_, __VA_ARGS__))
148#define COMMS_BIT_ACC_FUNC_40(f_, n_, ...) \
149 COMMS_BIT_ACC_FUNC(f_, n_) \
150 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_39(f_, __VA_ARGS__))
151#define COMMS_BIT_ACC_FUNC_41(f_, n_, ...) \
152 COMMS_BIT_ACC_FUNC(f_, n_) \
153 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_40(f_, __VA_ARGS__))
154#define COMMS_BIT_ACC_FUNC_42(f_, n_, ...) \
155 COMMS_BIT_ACC_FUNC(f_, n_) \
156 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_41(f_, __VA_ARGS__))
157#define COMMS_BIT_ACC_FUNC_43(f_, n_, ...) \
158 COMMS_BIT_ACC_FUNC(f_, n_) \
159 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_42(f_, __VA_ARGS__))
160#define COMMS_BIT_ACC_FUNC_44(f_, n_, ...) \
161 COMMS_BIT_ACC_FUNC(f_, n_) \
162 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_43(f_, __VA_ARGS__))
163#define COMMS_BIT_ACC_FUNC_45(f_, n_, ...) \
164 COMMS_BIT_ACC_FUNC(f_, n_) \
165 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_44(f_, __VA_ARGS__))
166#define COMMS_BIT_ACC_FUNC_46(f_, n_, ...) \
167 COMMS_BIT_ACC_FUNC(f_, n_) \
168 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_45(f_, __VA_ARGS__))
169#define COMMS_BIT_ACC_FUNC_47(f_, n_, ...) \
170 COMMS_BIT_ACC_FUNC(f_, n_) \
171 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_46(f_, __VA_ARGS__))
172#define COMMS_BIT_ACC_FUNC_48(f_, n_, ...) \
173 COMMS_BIT_ACC_FUNC(f_, n_) \
174 COMMS_EXPAND(COMMS_BIT_ACC_FUNC_47(f_, __VA_ARGS__))
175
176#define COMMS_CHOOSE_BIT_ACC_FUNC_(N, f_, ...) COMMS_EXPAND(COMMS_BIT_ACC_FUNC_ ## N(f_, __VA_ARGS__))
177#define COMMS_CHOOSE_BIT_ACC_FUNC(N, f_, ...) COMMS_EXPAND(COMMS_CHOOSE_BIT_ACC_FUNC_(N, f_, __VA_ARGS__))
178#define COMMS_DO_BIT_ACC_FUNC(f_, ...) \
179 COMMS_EXPAND(COMMS_CHOOSE_BIT_ACC_FUNC(COMMS_NUM_ARGS(__VA_ARGS__), f_, __VA_ARGS__))
180