Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / contract / override.hpp
1
2 #ifndef BOOST_CONTRACT_OVERRIDE_HPP_
3 #define BOOST_CONTRACT_OVERRIDE_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 Handle public function overrides (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/cat.hpp>
17 #include <boost/preprocessor/config/config.hpp>
18
19 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
20     /**
21     Declare an override type trait with an arbitrary name.
22
23     Declare the override type trait named @c type_name to pass as an explicit
24     template parameter to @RefFunc{boost::contract::public_function} for public
25     function overrides.
26     
27     @see @RefSect{advanced.named_overrides, Named Overrides}
28
29     @param type_name    Name of the override type trait this macro will declare.
30                         (This is not a variadic macro parameter but it should
31                         never contain commas because it is an identifier.)
32     @param func_name    Function name of the public function override.
33                         This macro is called just once even if the function name
34                         is overloaded (the same override type trait is used for
35                         all overloaded functions with the same name, see
36                         @RefSect{advanced.function_overloads,
37                         Function Overloads}).
38                         (This is not a variadic macro parameter but it should
39                         never contain commas because it is an identifier.)
40     */
41     #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name)
42 #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
43     #include <boost/contract/core/virtual.hpp>
44     #include <boost/contract/detail/type_traits/mirror.hpp>
45     #include <boost/contract/detail/tvariadic.hpp>
46     #include <boost/contract/detail/none.hpp>
47     #include <boost/contract/detail/name.hpp>
48
49     /* PRIVATE */
50
51     #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, arity_compl, \
52             func_name) \
53         template< \
54             class BOOST_CONTRACT_DETAIL_NAME1(B), \
55             class BOOST_CONTRACT_DETAIL_NAME1(C) \
56             BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
57             BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, \
58                     BOOST_CONTRACT_DETAIL_NAME1(Args)) \
59         > \
60         static void BOOST_CONTRACT_DETAIL_NAME1(call_base)( \
61             boost::contract::virtual_* BOOST_CONTRACT_DETAIL_NAME1(v), \
62             BOOST_CONTRACT_DETAIL_NAME1(C)* BOOST_CONTRACT_DETAIL_NAME1(obj) \
63             BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
64             BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, \
65                 BOOST_CONTRACT_DETAIL_NAME1(Args), \
66                 &, \
67                 BOOST_CONTRACT_DETAIL_NAME1(args) \
68             ) \
69             BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
70             BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
71                     boost::contract::detail::none&) \
72         ) { \
73             BOOST_CONTRACT_DETAIL_NAME1(obj)-> \
74             BOOST_CONTRACT_DETAIL_NAME1(B)::func_name( \
75                 BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, \
76                         BOOST_CONTRACT_DETAIL_NAME1(args)) \
77                 BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
78                 BOOST_CONTRACT_DETAIL_NAME1(v) \
79             ); \
80         }
81
82     #if BOOST_CONTRACT_DETAIL_TVARIADIC
83         #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
84             BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, func_name)
85     #else
86         #include <boost/preprocessor/repetition/repeat.hpp>
87         #include <boost/preprocessor/arithmetic/inc.hpp>
88         #include <boost/preprocessor/arithmetic/sub.hpp>
89
90         #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
91             BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
92                     BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, func_name) \
93         
94         #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, func_name) \
95             BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, \
96                     BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), func_name)
97     #endif
98
99     /* PUBLIC */
100
101     #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
102         struct type_name { \
103             BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \
104                 BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \
105                 func_name \
106             ) \
107             BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
108         };
109 #else
110     #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
111             struct type_name {}; /* empty (not used), just to compile */
112 #endif
113     
114 /* PUBLIC */
115
116 /**
117 Declare an override type trait named <c>override_<i>func_name</i></c>.
118
119 Declare the override type trait named <c>override_<i>func_name</i></c> to pass
120 as an explicit template parameter to @RefFunc{boost::contract::public_function}
121 for public function overrides.
122 Use @RefMacro{BOOST_CONTRACT_NAMED_OVERRIDE} to generate an override type trait
123 with a name different than <c>override_<i>func_name</i></c> (usually not
124 needed).
125
126 @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
127         Public Function Overrides}
128
129 @param func_name    Function name of the public function override.
130                     This macro is called just once even if the function name is
131                     overloaded (the same override type trait is used for all
132                     overloaded functions with the same name, see
133                     @RefSect{advanced.function_overloads, Function Overloads}).
134                     (This is not a variadic macro parameter but it should never
135                     contain any comma because it is an identifier.)
136 */
137 #define BOOST_CONTRACT_OVERRIDE(func_name) \
138     BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, func_name), func_name)
139     
140 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
141     /**
142     Declare multiple override type traits at once naming them
143     <c>override_...</c> (for convenience).
144
145     This variadic macro is provided for convenience as
146     <c>BOOST_CONTRACT_OVERRIDES(f_1, f_2, ..., f_n)</c> expands to code
147     equivalent to:
148
149     @code
150     BOOST_CONTRACT_OVERRIDE(f_1)
151     BOOST_CONTRACT_OVERRIDE(f_2)
152     ...
153     BOOST_CONTRACT_OVERRIDE(f_n)
154     @endcode
155
156     On compilers that do not support variadic macros,
157     the override type traits can be equivalently programmed one-by-one calling
158     @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name as shown above.
159     
160     @see    @RefSect{tutorial.public_function_overrides__subcontracting_,
161             Public Function Overrides}
162     
163     @param ...  A comma separated list of one or more function names of public
164                 function overrides.
165                 (Each function name should never contain commas because it is an
166                 identifier.)
167     */
168     #define BOOST_CONTRACT_OVERRIDES(...)
169 #elif BOOST_PP_VARIADICS
170     #include <boost/preprocessor/seq/for_each.hpp>
171     #include <boost/preprocessor/variadic/to_seq.hpp>
172     
173     /* PRIVATE */
174
175     #define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, func_name) \
176         BOOST_CONTRACT_OVERRIDE(func_name)
177     
178     /* PUBLIC */
179
180     #define BOOST_CONTRACT_OVERRIDES(...) \
181         BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \
182                 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
183 #else
184     #define BOOST_CONTRACT_OVERRIDES \
185 BOOST_CONTRACT_ERROR_macro_OVERRIDES_requires_variadic_macros_otherwise_manually_repeat_OVERRIDE_macro
186 #endif
187
188 #endif // #include guard
189