]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/contract/base_types.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / contract / base_types.hpp
1
2 #ifndef BOOST_CONTRACT_BASE_TYPES_HPP_
3 #define BOOST_CONTRACT_BASE_TYPES_HPP_
4
5 // Copyright (C) 2008-2018 Lorenzo Caminiti
6 // Distributed under the Boost Software License, Version 1.0 (see accompanying
7 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
8 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
9
10 /** @file
11 Specify inheritance form base classes (for subcontracting).
12 */
13
14 // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
15 #include <boost/contract/core/config.hpp>
16 #include <boost/preprocessor/config/config.hpp>
17
18 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
19
20 /**
21 Used to program the @c typedef that lists the bases of a derived class.
22
23 In order to support subcontracting, a derived class that specifies contracts for
24 one or more overriding public functions must declare a @c typedef named
25 @c base_types (or @RefMacro{BOOST_CONTRACT_BASES_TYPEDEF}) using this macro:
26
27 @code
28 class u
29 #define BASES public b, protected virtual w1, private w2
30 : BASES
31 {
32 friend class boost::contract:access;
33
34 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
35 #undef BASES
36
37 ...
38 };
39 @endcode
40
41 This @c typedef must be @c public unless @RefClass{boost::contract::access} is
42 used.
43
44 @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes}
45
46 @param ... Comma separated list of base classes.
47 Each base must explicitly specify its access specifier @c public,
48 @c protected, or @c private, and also @c virtual when present
49 (this not always required in C++ instead).
50 There is a limit of about 20 maximum bases that can be listed
51 (because of similar limits in Boost.MPL internally used by this
52 library).
53 This is a variadic macro parameter, on compilers that do not support
54 variadic macros, the @c typedef for base classes can be programmed
55 manually without using this macro (see
56 @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}).
57
58 */
59 #define BOOST_CONTRACT_BASE_TYPES(...)
60
61 #elif !BOOST_PP_VARIADICS
62
63 #define BOOST_CONTRACT_BASE_TYPES \
64 BOOST_CONTRACT_ERROR_macro_BASE_TYPES_requires_variadic_macros_otherwise_manually_program_base_types
65
66 #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
67
68 #include <boost/mpl/vector.hpp>
69 #include <boost/contract/detail/preprocessor/keyword/virtual.hpp>
70 #include <boost/contract/detail/preprocessor/keyword/public.hpp>
71 #include <boost/contract/detail/preprocessor/keyword/protected.hpp>
72 #include <boost/contract/detail/preprocessor/keyword/private.hpp>
73 #include <boost/preprocessor/variadic/to_seq.hpp>
74 #include <boost/preprocessor/seq/fold_left.hpp>
75 #include <boost/preprocessor/seq/enum.hpp>
76 #include <boost/preprocessor/seq/push_back.hpp>
77 #include <boost/preprocessor/seq/size.hpp>
78 #include <boost/preprocessor/seq/seq.hpp> // For HEAD, TAIL, etc.
79 #include <boost/preprocessor/tuple/elem.hpp>
80 #include <boost/preprocessor/tuple/rem.hpp>
81 #include <boost/preprocessor/tuple/eat.hpp>
82 #include <boost/preprocessor/comparison/equal.hpp>
83 #include <boost/preprocessor/control/iif.hpp>
84 #include <boost/preprocessor/facilities/expand.hpp>
85
86 /* PRIVATE */
87
88 #define BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
89 BOOST_PP_EXPAND( \
90 BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(base), \
91 BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL \
92 , \
93 BOOST_PP_TUPLE_REM(1) \
94 )(base) \
95 )
96
97 #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_(is_public, types_nilseq, base) \
98 ( \
99 is_public, \
100 BOOST_PP_IIF(is_public, \
101 BOOST_PP_SEQ_PUSH_BACK \
102 , \
103 types_nilseq BOOST_PP_TUPLE_EAT(2) \
104 )(types_nilseq, base) \
105 )
106
107 #define BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_(is_public, types_nilseq, \
108 base) \
109 (0, types_nilseq)
110
111 // Precondition: base = `public [virtual] ...`.
112 #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_(is_public, types_nilseq, \
113 base) \
114 ( \
115 1, \
116 BOOST_PP_SEQ_PUSH_BACK(types_nilseq, \
117 BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_( \
118 BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(base)) \
119 ) \
120 )
121
122 #define BOOST_CONTRACT_BASE_TYPES_ACCESS_(is_public, types_nilseq, base) \
123 BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
124 BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_ \
125 , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
126 BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
127 , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
128 BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
129 , \
130 BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_ \
131 )))(is_public, types_nilseq, base)
132
133 #define BOOST_CONTRACT_BASE_TYPES_(s, public_types, base) \
134 BOOST_CONTRACT_BASE_TYPES_ACCESS_( \
135 BOOST_PP_TUPLE_ELEM(2, 0, public_types), \
136 BOOST_PP_TUPLE_ELEM(2, 1, public_types), \
137 BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
138 )
139
140 #define BOOST_CONTRACT_BASE_TYPES_RETURN_YES_(types_nilseq) \
141 BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(types_nilseq))
142
143 #define BOOST_CONTRACT_BASE_TYPES_RETURN_(types_nilseq) \
144 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(types_nilseq), 1), \
145 BOOST_PP_TUPLE_EAT(1) \
146 , \
147 BOOST_CONTRACT_BASE_TYPES_RETURN_YES_ \
148 )(types_nilseq)
149
150 #define BOOST_CONTRACT_BASE_TYPES_OK_(base_tuple, bases_seq) \
151 boost::mpl::vector< \
152 BOOST_CONTRACT_BASE_TYPES_RETURN_(BOOST_PP_TUPLE_ELEM(2, 1, \
153 BOOST_PP_SEQ_FOLD_LEFT( \
154 BOOST_CONTRACT_BASE_TYPES_, \
155 (0, (BOOST_PP_NIL)), \
156 bases_seq \
157 ) \
158 )) \
159 >
160
161 #define BOOST_CONTRACT_BASE_TYPES_ERR_(bases_tuple, bases_seq) \
162 BOOST_CONTRACT_ERROR_all_bases_must_explicitly_specify_public_protected_or_private base_tuple
163
164 #define BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_(base) \
165 BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
166 1 \
167 , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
168 1 \
169 , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
170 1 \
171 , \
172 0 \
173 )))
174
175 // Cannot check that all base types have access specifiers (unless users have to
176 // specify bases using pp-seq, because user specified base list can have
177 // unwrapped commas between bases but also within a given base type, when base
178 // types are templates), but at least check the very first base type explicitly
179 // specifies access `[virtual] public | protected | private [virtual] ...`.
180 #define BOOST_CONTRACT_BASE_TYPES_CHECK_(bases_tuple, bases_seq) \
181 BOOST_PP_IIF(BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_( \
182 BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(BOOST_PP_SEQ_HEAD( \
183 bases_seq))), \
184 BOOST_CONTRACT_BASE_TYPES_OK_ \
185 , \
186 BOOST_CONTRACT_BASE_TYPES_ERR_ \
187 )(bases_tuple, bases_seq)
188
189 /* PUBLIC */
190
191 #define BOOST_CONTRACT_BASE_TYPES(...) \
192 BOOST_CONTRACT_BASE_TYPES_CHECK_((__VA_ARGS__), \
193 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
194
195 #else
196
197 #define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */
198
199 #endif
200
201 #endif // #include guard
202