COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
protocol_layers_access.h
1//
2// Copyright 2017 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#pragma once
11
12#include "comms/details/macro_common.h"
13#include "comms/details/reverse_macro_args.h"
14
15#define COMMS_LAYER_TYPE_1 COMMS_EXPAND(::ThisLayer)
16#define COMMS_LAYER_TYPE_2 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_1
17#define COMMS_LAYER_TYPE_3 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_2
18#define COMMS_LAYER_TYPE_4 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_3
19#define COMMS_LAYER_TYPE_5 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_4
20#define COMMS_LAYER_TYPE_6 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_5
21#define COMMS_LAYER_TYPE_7 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_6
22#define COMMS_LAYER_TYPE_8 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_7
23#define COMMS_LAYER_TYPE_9 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_8
24#define COMMS_LAYER_TYPE_10 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_9
25#define COMMS_LAYER_TYPE_11 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_10
26#define COMMS_LAYER_TYPE_12 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_11
27#define COMMS_LAYER_TYPE_13 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_12
28#define COMMS_LAYER_TYPE_14 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_13
29#define COMMS_LAYER_TYPE_15 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_14
30#define COMMS_LAYER_TYPE_16 COMMS_EXPAND(::NextLayer) COMMS_LAYER_TYPE_15
31
32#define COMMS_DO_LAYER_TYPE_INTERNAL_(N, B_) typename B_ COMMS_EXPAND(COMMS_LAYER_TYPE_ ## N)
33#define COMMS_DO_LAYER_TYPE_INTERNAL(N, B_) COMMS_EXPAND(COMMS_DO_LAYER_TYPE_INTERNAL_(N, B_))
34#define COMMS_DO_LAYER_TYPE(B_, ...) \
35 COMMS_EXPAND(COMMS_DO_LAYER_TYPE_INTERNAL(COMMS_NUM_ARGS(__VA_ARGS__), B_))
36
37#define COMMS_LAYER_TYPE_ALIAS(c_, B_, n_) \
38 using COMMS_CONCATENATE(Layer_, n_) = COMMS_DO_LAYER_TYPE_INTERNAL(c_, B_);
39
40#define COMMS_LAYER_TYPE_ALIAS_1(B_, n_) COMMS_LAYER_TYPE_ALIAS(1, B_, n_)
41#define COMMS_LAYER_TYPE_ALIAS_2(B_, n_, ...) \
42 COMMS_LAYER_TYPE_ALIAS(2, B_, n_) \
43 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_1(B_, __VA_ARGS__))
44#define COMMS_LAYER_TYPE_ALIAS_3(B_, n_, ...) \
45 COMMS_LAYER_TYPE_ALIAS(3, B_, n_) \
46 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_2(B_, __VA_ARGS__))
47#define COMMS_LAYER_TYPE_ALIAS_4(B_, n_, ...) \
48 COMMS_LAYER_TYPE_ALIAS(4, B_, n_) \
49 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_3(B_, __VA_ARGS__))
50#define COMMS_LAYER_TYPE_ALIAS_5(B_, n_, ...) \
51 COMMS_LAYER_TYPE_ALIAS(5, B_, n_) \
52 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_4(B_, __VA_ARGS__))
53#define COMMS_LAYER_TYPE_ALIAS_6(B_, n_, ...) \
54 COMMS_LAYER_TYPE_ALIAS(6, B_, n_) \
55 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_5(B_, __VA_ARGS__))
56#define COMMS_LAYER_TYPE_ALIAS_7(B_, n_, ...) \
57 COMMS_LAYER_TYPE_ALIAS(7, B_, n_) \
58 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_6(B_, __VA_ARGS__))
59#define COMMS_LAYER_TYPE_ALIAS_8(B_, n_, ...) \
60 COMMS_LAYER_TYPE_ALIAS(8, B_, n_) \
61 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_7(B_, __VA_ARGS__))
62#define COMMS_LAYER_TYPE_ALIAS_9(B_, n_, ...) \
63 COMMS_LAYER_TYPE_ALIAS(9, B_, n_) \
64 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_8(B_, __VA_ARGS__))
65#define COMMS_LAYER_TYPE_ALIAS_10(B_, n_, ...) \
66 COMMS_LAYER_TYPE_ALIAS(10, B_, n_) \
67 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_9(B_, __VA_ARGS__))
68#define COMMS_LAYER_TYPE_ALIAS_11(B_, n_, ...) \
69 COMMS_LAYER_TYPE_ALIAS(11, B_, n_) \
70 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_10(B_, __VA_ARGS__))
71#define COMMS_LAYER_TYPE_ALIAS_12(B_, n_, ...) \
72 COMMS_LAYER_TYPE_ALIAS(12, B_, n_) \
73 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_11(B_, __VA_ARGS__))
74#define COMMS_LAYER_TYPE_ALIAS_13(B_, n_, ...) \
75 COMMS_LAYER_TYPE_ALIAS(13, B_, n_) \
76 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_12(B_, __VA_ARGS__))
77#define COMMS_LAYER_TYPE_ALIAS_14(B_, n_, ...) \
78 COMMS_LAYER_TYPE_ALIAS(14, B_, n_) \
79 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_13(B_, __VA_ARGS__))
80#define COMMS_LAYER_TYPE_ALIAS_15(B_, n_, ...) \
81 COMMS_LAYER_TYPE_ALIAS(15, B_, n_) \
82 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_14(B_, __VA_ARGS__))
83#define COMMS_LAYER_TYPE_ALIAS_16(B_, n_, ...) \
84 COMMS_LAYER_TYPE_ALIAS(16, B_, n_) \
85 COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_15(B_, __VA_ARGS__))
86
87#define COMMS_DO_LAYER_TYPE_ALIAS_INTERNAL_(N, B_, ...) COMMS_EXPAND(COMMS_LAYER_TYPE_ALIAS_ ## N(B_, __VA_ARGS__))
88#define COMMS_DO_LAYER_TYPE_ALIAS_INTERNAL(N, B_, ...) COMMS_EXPAND(COMMS_DO_LAYER_TYPE_ALIAS_INTERNAL_(N, B_, __VA_ARGS__))
89#define COMMS_DO_LAYER_TYPE_ALIAS(B_, ...) \
90 COMMS_EXPAND(COMMS_DO_LAYER_TYPE_ALIAS_INTERNAL(COMMS_NUM_ARGS(__VA_ARGS__), B_, __VA_ARGS__))
91
92#define COMMS_LAYER_CALL_1 COMMS_EXPAND(.thisLayer())
93#define COMMS_LAYER_CALL_2 COMMS_EXPAND(.nextLayer())
94#define COMMS_LAYER_CALL_3 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_2
95#define COMMS_LAYER_CALL_4 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_3
96#define COMMS_LAYER_CALL_5 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_4
97#define COMMS_LAYER_CALL_6 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_5
98#define COMMS_LAYER_CALL_7 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_6
99#define COMMS_LAYER_CALL_8 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_7
100#define COMMS_LAYER_CALL_9 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_8
101#define COMMS_LAYER_CALL_10 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_9
102#define COMMS_LAYER_CALL_11 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_10
103#define COMMS_LAYER_CALL_12 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_11
104#define COMMS_LAYER_CALL_13 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_12
105#define COMMS_LAYER_CALL_14 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_13
106#define COMMS_LAYER_CALL_15 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_14
107#define COMMS_LAYER_CALL_16 COMMS_EXPAND(.nextLayer()) COMMS_LAYER_CALL_15
108
109#define COMMS_DO_LAYER_CALL_INTERNAL_(N, B_) COMMS_EXPAND(B_) COMMS_EXPAND(COMMS_LAYER_CALL_ ## N)
110#define COMMS_DO_LAYER_CALL_INTERNAL(N, B_) COMMS_EXPAND(COMMS_DO_LAYER_CALL_INTERNAL_(N, B_))
111#define COMMS_DO_LAYER_CALL(B_, ...) \
112 COMMS_EXPAND(COMMS_DO_LAYER_CALL_INTERNAL(COMMS_NUM_ARGS(__VA_ARGS__), B_))
113
114#ifdef COMMS_MUST_DEFINE_BASE
115
116#define COMMS_ACCESS_LAYER_FUNC(c_, n_) \
117 COMMS_DO_LAYER_TYPE_INTERNAL(c_, Base)& COMMS_CONCATENATE(layer_, n_)()
118#define COMMS_ACCESS_LAYER_CONST_FUNC(c_, n_) \
119 const COMMS_DO_LAYER_TYPE_INTERNAL(c_, Base)& COMMS_CONCATENATE(layer_, n_)() const
120
121#else // #ifdef COMMS_MUST_DEFINE_BASE
122#define COMMS_ACCESS_LAYER_FUNC(c_, n_) FUNC_AUTO_REF_RETURN(COMMS_CONCATENATE(layer_, n_), decltype(COMMS_DO_LAYER_CALL_INTERNAL(c_, COMMS_EXPAND(comms::frame::toFrameLayerBase(*this)))))
123#define COMMS_ACCESS_LAYER_CONST_FUNC(c_, n_) FUNC_AUTO_REF_RETURN_CONST(COMMS_CONCATENATE(layer_, n_), decltype(COMMS_DO_LAYER_CALL_INTERNAL(c_, COMMS_EXPAND(comms::frame::toFrameLayerBase(*this)))))
124
125#endif // #ifdef COMMS_MUST_DEFINE_BASE
126
127#define COMMS_ACCESS_LAYER_ACC_FUNC(c_, n_) \
128 COMMS_ACCESS_LAYER_FUNC(c_, n_) {\
129 return COMMS_DO_LAYER_CALL_INTERNAL(c_, comms::frame::toFrameLayerBase(*this)); \
130 } \
131 COMMS_ACCESS_LAYER_CONST_FUNC(c_, n_) {\
132 return COMMS_DO_LAYER_CALL_INTERNAL(c_, comms::frame::toFrameLayerBase(*this)); \
133 }
134
135#define COMMS_ACCESS_LAYER_ACC_FUNC_1(n_) COMMS_ACCESS_LAYER_ACC_FUNC(1, n_)
136#define COMMS_ACCESS_LAYER_ACC_FUNC_2(n_, ...) \
137 COMMS_ACCESS_LAYER_ACC_FUNC(2, n_) \
138 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_1(__VA_ARGS__))
139#define COMMS_ACCESS_LAYER_ACC_FUNC_3(n_, ...) \
140 COMMS_ACCESS_LAYER_ACC_FUNC(3, n_) \
141 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_2(__VA_ARGS__))
142#define COMMS_ACCESS_LAYER_ACC_FUNC_4(n_, ...) \
143 COMMS_ACCESS_LAYER_ACC_FUNC(4, n_) \
144 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_3(__VA_ARGS__))
145#define COMMS_ACCESS_LAYER_ACC_FUNC_5(n_, ...) \
146 COMMS_ACCESS_LAYER_ACC_FUNC(5, n_) \
147 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_4(__VA_ARGS__))
148#define COMMS_ACCESS_LAYER_ACC_FUNC_6(n_, ...) \
149 COMMS_ACCESS_LAYER_ACC_FUNC(6, n_) \
150 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_5(__VA_ARGS__))
151#define COMMS_ACCESS_LAYER_ACC_FUNC_7(n_, ...) \
152 COMMS_ACCESS_LAYER_ACC_FUNC(7, n_) \
153 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_6(__VA_ARGS__))
154#define COMMS_ACCESS_LAYER_ACC_FUNC_8(n_, ...) \
155 COMMS_ACCESS_LAYER_ACC_FUNC(8, n_) \
156 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_7(__VA_ARGS__))
157#define COMMS_ACCESS_LAYER_ACC_FUNC_9(n_, ...) \
158 COMMS_ACCESS_LAYER_ACC_FUNC(9, n_) \
159 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_8(__VA_ARGS__))
160#define COMMS_ACCESS_LAYER_ACC_FUNC_10(n_, ...) \
161 COMMS_ACCESS_LAYER_ACC_FUNC(10, n_) \
162 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_9(__VA_ARGS__))
163#define COMMS_ACCESS_LAYER_ACC_FUNC_11(n_, ...) \
164 COMMS_ACCESS_LAYER_ACC_FUNC(11, n_) \
165 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_10(__VA_ARGS__))
166#define COMMS_ACCESS_LAYER_ACC_FUNC_12(n_, ...) \
167 COMMS_ACCESS_LAYER_ACC_FUNC(12, n_) \
168 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_11(__VA_ARGS__))
169#define COMMS_ACCESS_LAYER_ACC_FUNC_13(n_, ...) \
170 COMMS_ACCESS_LAYER_ACC_FUNC(13, n_) \
171 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_12(__VA_ARGS__))
172#define COMMS_ACCESS_LAYER_ACC_FUNC_14(n_, ...) \
173 COMMS_ACCESS_LAYER_ACC_FUNC(14, n_) \
174 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_13(__VA_ARGS__))
175#define COMMS_ACCESS_LAYER_ACC_FUNC_15(n_, ...) \
176 COMMS_ACCESS_LAYER_ACC_FUNC(15, n_) \
177 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_14(__VA_ARGS__))
178#define COMMS_ACCESS_LAYER_ACC_FUNC_16(n_, ...) \
179 COMMS_ACCESS_LAYER_ACC_FUNC(16, n_) \
180 COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_15(c_, __VA_ARGS__))
181
182#define COMMS_CHOOSE_ACCESS_LAYER_ACC_FUNC_(N, ...) COMMS_EXPAND(COMMS_ACCESS_LAYER_ACC_FUNC_ ## N(__VA_ARGS__))
183#define COMMS_CHOOSE_ACCESS_LAYER_ACC_FUNC(N, ...) COMMS_EXPAND(COMMS_CHOOSE_ACCESS_LAYER_ACC_FUNC_(N, __VA_ARGS__))
184#define COMMS_DO_ACCESS_LAYER_ACC_FUNC(...) \
185 COMMS_EXPAND(COMMS_CHOOSE_ACCESS_LAYER_ACC_FUNC(COMMS_NUM_ARGS(__VA_ARGS__), __VA_ARGS__))
186