Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:02

0001 
0002 #ifndef BOOST_CONTRACT_BASE_TYPES_HPP_
0003 #define BOOST_CONTRACT_BASE_TYPES_HPP_
0004 
0005 // Copyright (C) 2008-2018 Lorenzo Caminiti
0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying
0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
0009 
0010 /** @file
0011 Specify inheritance form base classes (for subcontracting).
0012 */
0013 
0014 // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
0015 #include <boost/contract/core/config.hpp>
0016 #include <boost/preprocessor/config/config.hpp>
0017 
0018 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0019 
0020 /**
0021 Used to program the @c typedef that lists the bases of a derived class.
0022 
0023 In order to support subcontracting, a derived class that specifies contracts for
0024 one or more overriding public functions must declare a @c typedef named
0025 @c base_types (or @RefMacro{BOOST_CONTRACT_BASES_TYPEDEF}) using this macro:
0026 
0027     @code
0028         class u
0029             #define BASES public b, protected virtual w1, private w2
0030             : BASES
0031         {
0032             friend class boost::contract:access;
0033 
0034             typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
0035             #undef BASES
0036 
0037             ...
0038         };
0039     @endcode
0040 
0041 This @c typedef must be @c public unless @RefClass{boost::contract::access} is
0042 used.
0043 
0044 @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes}
0045 
0046 @param ...  Comma separated list of base classes.
0047             Each base must explicitly specify its access specifier @c public,
0048             @c protected, or @c private, and also @c virtual when present
0049             (this not always required in C++ instead).
0050             There is a limit of about 20 maximum bases that can be listed
0051             (because of similar limits in Boost.MPL internally used by this
0052             library).
0053             This is a variadic macro parameter, on compilers that do not support
0054             variadic macros, the @c typedef for base classes can be programmed
0055             manually without using this macro (see
0056             @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}).
0057             
0058 */
0059 #define BOOST_CONTRACT_BASE_TYPES(...)
0060 
0061 #elif !BOOST_PP_VARIADICS
0062     
0063 #define BOOST_CONTRACT_BASE_TYPES \
0064 BOOST_CONTRACT_ERROR_macro_BASE_TYPES_requires_variadic_macros_otherwise_manually_program_base_types
0065 
0066 #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
0067 
0068 #include <boost/mpl/vector.hpp>
0069 #include <boost/contract/detail/preprocessor/keyword/virtual.hpp>
0070 #include <boost/contract/detail/preprocessor/keyword/public.hpp>
0071 #include <boost/contract/detail/preprocessor/keyword/protected.hpp>
0072 #include <boost/contract/detail/preprocessor/keyword/private.hpp>
0073 #include <boost/preprocessor/variadic/to_seq.hpp>
0074 #include <boost/preprocessor/seq/fold_left.hpp>
0075 #include <boost/preprocessor/seq/enum.hpp>
0076 #include <boost/preprocessor/seq/push_back.hpp>
0077 #include <boost/preprocessor/seq/size.hpp>
0078 #include <boost/preprocessor/seq/seq.hpp> // For HEAD, TAIL, etc.
0079 #include <boost/preprocessor/tuple/elem.hpp>
0080 #include <boost/preprocessor/tuple/rem.hpp>
0081 #include <boost/preprocessor/tuple/eat.hpp>
0082 #include <boost/preprocessor/comparison/equal.hpp>
0083 #include <boost/preprocessor/control/iif.hpp>
0084 #include <boost/preprocessor/facilities/expand.hpp>
0085 
0086 /* PRIVATE */
0087 
0088 #define BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
0089     BOOST_PP_EXPAND( \
0090         BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_VIRTUAL(base), \
0091             BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_VIRTUAL \
0092         , \
0093             BOOST_PP_TUPLE_REM(1) \
0094         )(base) \
0095     )
0096 
0097 #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_(is_public, types_nilseq, base) \
0098     ( \
0099         is_public, \
0100         BOOST_PP_IIF(is_public, \
0101             BOOST_PP_SEQ_PUSH_BACK \
0102         , \
0103             types_nilseq BOOST_PP_TUPLE_EAT(2) \
0104         )(types_nilseq, base) \
0105     )
0106 
0107 #define BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_(is_public, types_nilseq, \
0108         base) \
0109     (0, types_nilseq)
0110 
0111 // Precondition: base = `public [virtual] ...`.
0112 #define BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_(is_public, types_nilseq, \
0113         base) \
0114     ( \
0115         1, \
0116         BOOST_PP_SEQ_PUSH_BACK(types_nilseq, \
0117             BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_( \
0118                     BOOST_CONTRACT_DETAIL_PP_KEYWORD_REMOVE_PUBLIC(base)) \
0119         ) \
0120     )
0121 
0122 #define BOOST_CONTRACT_BASE_TYPES_ACCESS_(is_public, types_nilseq, base) \
0123     BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
0124         BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_PUBLIC_ \
0125     , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
0126         BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
0127     , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
0128         BOOST_CONTRACT_BASE_TYPES_SKIP_NOT_PUBLIC_ \
0129     , \
0130         BOOST_CONTRACT_BASE_TYPES_PUSH_BACK_IF_ \
0131     )))(is_public, types_nilseq, base)
0132 
0133 #define BOOST_CONTRACT_BASE_TYPES_(s, public_types, base) \
0134     BOOST_CONTRACT_BASE_TYPES_ACCESS_( \
0135         BOOST_PP_TUPLE_ELEM(2, 0, public_types), \
0136         BOOST_PP_TUPLE_ELEM(2, 1, public_types), \
0137         BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(base) \
0138     )
0139 
0140 #define BOOST_CONTRACT_BASE_TYPES_RETURN_YES_(types_nilseq) \
0141     BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(types_nilseq))
0142 
0143 #define BOOST_CONTRACT_BASE_TYPES_RETURN_(types_nilseq) \
0144     BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(types_nilseq), 1), \
0145         BOOST_PP_TUPLE_EAT(1) \
0146     , \
0147         BOOST_CONTRACT_BASE_TYPES_RETURN_YES_ \
0148     )(types_nilseq)
0149 
0150 #define BOOST_CONTRACT_BASE_TYPES_OK_(base_tuple, bases_seq) \
0151     boost::mpl::vector< \
0152         BOOST_CONTRACT_BASE_TYPES_RETURN_(BOOST_PP_TUPLE_ELEM(2, 1, \
0153             BOOST_PP_SEQ_FOLD_LEFT( \
0154                 BOOST_CONTRACT_BASE_TYPES_, \
0155                 (0, (BOOST_PP_NIL)), \
0156                 bases_seq \
0157             ) \
0158         )) \
0159     >
0160 
0161 #define BOOST_CONTRACT_BASE_TYPES_ERR_(bases_tuple, bases_seq) \
0162     BOOST_CONTRACT_ERROR_all_bases_must_explicitly_specify_public_protected_or_private base_tuple
0163 
0164 #define BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_(base) \
0165     BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PUBLIC(base), \
0166         1 \
0167     , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PROTECTED(base), \
0168         1 \
0169     , BOOST_PP_IIF(BOOST_CONTRACT_DETAIL_PP_KEYWORD_IS_PRIVATE(base), \
0170         1 \
0171     , \
0172         0 \
0173     )))
0174 
0175 // Cannot check that all base types have access specifiers (unless users have to
0176 // specify bases using pp-seq, because user specified base list can have
0177 // unwrapped commas between bases but also within a given base type, when base
0178 // types are templates), but at least check the very first base type explicitly
0179 // specifies access `[virtual] public | protected | private [virtual] ...`.
0180 #define BOOST_CONTRACT_BASE_TYPES_CHECK_(bases_tuple, bases_seq) \
0181     BOOST_PP_IIF(BOOST_CONTRACT_BASE_TYPES_IS_ACCESS_( \
0182             BOOST_CONTRACT_BASE_TYPES_REMOVE_VIRTUAL_(BOOST_PP_SEQ_HEAD( \
0183                     bases_seq))), \
0184         BOOST_CONTRACT_BASE_TYPES_OK_ \
0185     , \
0186         BOOST_CONTRACT_BASE_TYPES_ERR_ \
0187     )(bases_tuple, bases_seq)
0188 
0189 /* PUBLIC */
0190 
0191 #define BOOST_CONTRACT_BASE_TYPES(...) \
0192     BOOST_CONTRACT_BASE_TYPES_CHECK_((__VA_ARGS__), \
0193             BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
0194 
0195 #else
0196 
0197 #define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */
0198 
0199 #endif
0200 
0201 #endif // #include guard
0202