| 1 | //----------------------------------------------------------------------------- | 
|---|
| 2 | // boost variant/detail/initializer.hpp header file | 
|---|
| 3 | // See http://www.boost.org for updates, documentation, and revision history. | 
|---|
| 4 | //----------------------------------------------------------------------------- | 
|---|
| 5 | // | 
|---|
| 6 | // Copyright (c) 2002-2003 | 
|---|
| 7 | // Eric Friedman, Itay Maman | 
|---|
| 8 | // | 
|---|
| 9 | // Distributed under the Boost Software License, Version 1.0. (See | 
|---|
| 10 | // accompanying file LICENSE_1_0.txt or copy at | 
|---|
| 11 | // http://www.boost.org/LICENSE_1_0.txt) | 
|---|
| 12 |  | 
|---|
| 13 | #ifndef BOOST_VARIANT_DETAIL_INITIALIZER_HPP | 
|---|
| 14 | #define BOOST_VARIANT_DETAIL_INITIALIZER_HPP | 
|---|
| 15 |  | 
|---|
| 16 | #include <new> // for placement new | 
|---|
| 17 |  | 
|---|
| 18 | #include "boost/config.hpp" | 
|---|
| 19 |  | 
|---|
| 20 | #include "boost/call_traits.hpp" | 
|---|
| 21 | #include "boost/detail/reference_content.hpp" | 
|---|
| 22 | #include "boost/variant/recursive_wrapper_fwd.hpp" | 
|---|
| 23 |  | 
|---|
| 24 | #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) | 
|---|
| 25 | #   include "boost/mpl/aux_/value_wknd.hpp" | 
|---|
| 26 | #   include "boost/mpl/int.hpp" | 
|---|
| 27 | #   include "boost/mpl/iter_fold.hpp" | 
|---|
| 28 | #   include "boost/mpl/next.hpp" | 
|---|
| 29 | #   include "boost/mpl/deref.hpp" | 
|---|
| 30 | #   include "boost/mpl/pair.hpp" | 
|---|
| 31 | #   include "boost/mpl/protect.hpp" | 
|---|
| 32 | #else | 
|---|
| 33 | #   include "boost/variant/variant_fwd.hpp" | 
|---|
| 34 | #   include "boost/preprocessor/cat.hpp" | 
|---|
| 35 | #   include "boost/preprocessor/enum.hpp" | 
|---|
| 36 | #   include "boost/preprocessor/repeat.hpp" | 
|---|
| 37 | #endif | 
|---|
| 38 |  | 
|---|
| 39 | namespace boost { | 
|---|
| 40 | namespace detail { namespace variant { | 
|---|
| 41 |  | 
|---|
| 42 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 43 | // (detail) support to simulate standard overload resolution rules | 
|---|
| 44 | // | 
|---|
| 45 | // The below initializers allows variant to follow standard overload | 
|---|
| 46 | // resolution rules over the specified set of bounded types. | 
|---|
| 47 | // | 
|---|
| 48 | // On compilers where using declarations in class templates can correctly | 
|---|
| 49 | // avoid name hiding, use an optimal solution based on the variant's typelist. | 
|---|
| 50 | // | 
|---|
| 51 | // Otherwise, use a preprocessor workaround based on knowledge of the fixed | 
|---|
| 52 | // size of the variant's psuedo-variadic template parameter list. | 
|---|
| 53 | // | 
|---|
| 54 |  | 
|---|
| 55 | #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) | 
|---|
| 56 |  | 
|---|
| 57 | // (detail) quoted metafunction make_initializer_node | 
|---|
| 58 | // | 
|---|
| 59 | // Exposes a pair whose first type is a node in the initializer hierarchy. | 
|---|
| 60 | // | 
|---|
| 61 | struct make_initializer_node | 
|---|
| 62 | { | 
|---|
| 63 |     template <typename BaseIndexPair, typename Iterator> | 
|---|
| 64 |     struct apply | 
|---|
| 65 |     { | 
|---|
| 66 |     private: // helpers, for metafunction result (below) | 
|---|
| 67 |  | 
|---|
| 68 |         typedef typename BaseIndexPair::first | 
|---|
| 69 |             base; | 
|---|
| 70 |         typedef typename BaseIndexPair::second | 
|---|
| 71 |             index; | 
|---|
| 72 |  | 
|---|
| 73 |         class initializer_node | 
|---|
| 74 |             : public base | 
|---|
| 75 |         { | 
|---|
| 76 |         private: // helpers, for static functions (below) | 
|---|
| 77 |  | 
|---|
| 78 |             typedef typename mpl::deref<Iterator>::type | 
|---|
| 79 |                 recursive_enabled_T; | 
|---|
| 80 |             typedef typename unwrap_recursive<recursive_enabled_T>::type | 
|---|
| 81 |                 public_T; | 
|---|
| 82 |             typedef typename call_traits<public_T>::param_type | 
|---|
| 83 |                 param_T; | 
|---|
| 84 |  | 
|---|
| 85 |         public: // static functions | 
|---|
| 86 |  | 
|---|
| 87 |             using base::initialize; | 
|---|
| 88 |  | 
|---|
| 89 |             static int initialize(void* dest, param_T operand) | 
|---|
| 90 |             { | 
|---|
| 91 |                 typedef typename boost::detail::make_reference_content< | 
|---|
| 92 |                       recursive_enabled_T | 
|---|
| 93 |                     >::type internal_T; | 
|---|
| 94 |  | 
|---|
| 95 |                 new(dest) internal_T(operand); | 
|---|
| 96 |                 return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which | 
|---|
| 97 |             } | 
|---|
| 98 |  | 
|---|
| 99 |         }; | 
|---|
| 100 |  | 
|---|
| 101 |         friend class initializer_node; | 
|---|
| 102 |  | 
|---|
| 103 |     public: // metafunction result | 
|---|
| 104 |  | 
|---|
| 105 |         typedef mpl::pair< | 
|---|
| 106 |               initializer_node | 
|---|
| 107 |             , typename mpl::next< index >::type | 
|---|
| 108 |             > type; | 
|---|
| 109 |  | 
|---|
| 110 |     }; | 
|---|
| 111 | }; | 
|---|
| 112 |  | 
|---|
| 113 | // (detail) class initializer_root | 
|---|
| 114 | // | 
|---|
| 115 | // Every level of the initializer hierarchy must expose the name | 
|---|
| 116 | // "initialize," so initializer_root provides a dummy function: | 
|---|
| 117 | // | 
|---|
| 118 | class initializer_root | 
|---|
| 119 | { | 
|---|
| 120 | public: // static functions | 
|---|
| 121 |  | 
|---|
| 122 |     static void initialize(); | 
|---|
| 123 |  | 
|---|
| 124 | }; | 
|---|
| 125 |  | 
|---|
| 126 | #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) | 
|---|
| 127 |  | 
|---|
| 128 | #   if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)  | 
|---|
| 129 |  | 
|---|
| 130 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \ | 
|---|
| 131 |           BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \ | 
|---|
| 132 |     /**/ | 
|---|
| 133 |  | 
|---|
| 134 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \ | 
|---|
| 135 |         typedef typename unwrap_recursive< \ | 
|---|
| 136 |               BOOST_PP_CAT(recursive_enabled_T,N) \ | 
|---|
| 137 |             >::type BOOST_PP_CAT(public_T,N); \ | 
|---|
| 138 |         typedef typename call_traits< \ | 
|---|
| 139 |               BOOST_PP_CAT(public_T,N) \ | 
|---|
| 140 |             >::param_type BOOST_PP_CAT(param_T,N); \ | 
|---|
| 141 |     /**/ | 
|---|
| 142 |  | 
|---|
| 143 | #   else // MSVC7 and below | 
|---|
| 144 |  | 
|---|
| 145 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \ | 
|---|
| 146 |           BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \ | 
|---|
| 147 |         , BOOST_VARIANT_ENUM_PARAMS(typename param_T) \ | 
|---|
| 148 |     /**/ | 
|---|
| 149 |  | 
|---|
| 150 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \ | 
|---|
| 151 |     /**/ | 
|---|
| 152 |  | 
|---|
| 153 | #   endif // MSVC7 and below workaround | 
|---|
| 154 |  | 
|---|
| 155 | template < BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS > | 
|---|
| 156 | struct preprocessor_list_initializer | 
|---|
| 157 | { | 
|---|
| 158 | public: // static functions | 
|---|
| 159 |  | 
|---|
| 160 |     #define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \ | 
|---|
| 161 |         BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \ | 
|---|
| 162 |         static int initialize( \ | 
|---|
| 163 |               void* dest \ | 
|---|
| 164 |             , BOOST_PP_CAT(param_T,N) operand \ | 
|---|
| 165 |             ) \ | 
|---|
| 166 |         { \ | 
|---|
| 167 |             typedef typename boost::detail::make_reference_content< \ | 
|---|
| 168 |                   BOOST_PP_CAT(recursive_enabled_T,N) \ | 
|---|
| 169 |                 >::type internal_T; \ | 
|---|
| 170 |             \ | 
|---|
| 171 |             new(dest) internal_T(operand); \ | 
|---|
| 172 |             return (N); /*which*/ \ | 
|---|
| 173 |         } \ | 
|---|
| 174 |         /**/ | 
|---|
| 175 |  | 
|---|
| 176 |     BOOST_PP_REPEAT( | 
|---|
| 177 |           BOOST_VARIANT_LIMIT_TYPES | 
|---|
| 178 |         , BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION | 
|---|
| 179 |         , _ | 
|---|
| 180 |         ) | 
|---|
| 181 |  | 
|---|
| 182 |     #undef BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION | 
|---|
| 183 |  | 
|---|
| 184 | }; | 
|---|
| 185 |  | 
|---|
| 186 | #   if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) | 
|---|
| 187 |  | 
|---|
| 188 | #if !defined(BOOST_VARIANT_AUX_ECHO) | 
|---|
| 189 | #   define BOOST_VARIANT_AUX_ECHO(z,N,token) token | 
|---|
| 190 | #endif | 
|---|
| 191 |  | 
|---|
| 192 | template <> | 
|---|
| 193 | struct preprocessor_list_initializer< | 
|---|
| 194 |       BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, int) | 
|---|
| 195 |     , BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, const int) | 
|---|
| 196 |     > | 
|---|
| 197 | { | 
|---|
| 198 | }; | 
|---|
| 199 |  | 
|---|
| 200 | #   endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround | 
|---|
| 201 |  | 
|---|
| 202 | #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround | 
|---|
| 203 |  | 
|---|
| 204 | }} // namespace detail::variant | 
|---|
| 205 | } // namespace boost | 
|---|
| 206 |  | 
|---|
| 207 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 208 | // macro BOOST_VARIANT_AUX_INITIALIZER_T | 
|---|
| 209 | // | 
|---|
| 210 | // Given both the variant's typelist and a basename for forming the list of | 
|---|
| 211 | // bounded types (i.e., T becomes T1, T2, etc.), exposes the initializer | 
|---|
| 212 | // most appropriate to the current compiler. | 
|---|
| 213 | // | 
|---|
| 214 |  | 
|---|
| 215 | #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) | 
|---|
| 216 |  | 
|---|
| 217 | #define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ | 
|---|
| 218 |     ::boost::mpl::iter_fold< \ | 
|---|
| 219 |           mpl_seq \ | 
|---|
| 220 |         , ::boost::mpl::pair< \ | 
|---|
| 221 |               ::boost::detail::variant::initializer_root \ | 
|---|
| 222 |             , ::boost::mpl::int_<0> \ | 
|---|
| 223 |             > \ | 
|---|
| 224 |         , ::boost::mpl::protect< \ | 
|---|
| 225 |               ::boost::detail::variant::make_initializer_node \ | 
|---|
| 226 |             > \ | 
|---|
| 227 |         >::type::first \ | 
|---|
| 228 |     /**/ | 
|---|
| 229 |  | 
|---|
| 230 | #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) | 
|---|
| 231 |  | 
|---|
| 232 | #   if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | 
|---|
| 233 |  | 
|---|
| 234 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \ | 
|---|
| 235 |           BOOST_VARIANT_ENUM_PARAMS(typename_base) \ | 
|---|
| 236 |         /**/ | 
|---|
| 237 |  | 
|---|
| 238 | #   else // MSVC7 and below | 
|---|
| 239 |  | 
|---|
| 240 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE(z,N,T) \ | 
|---|
| 241 |         ::boost::call_traits< \ | 
|---|
| 242 |               ::boost::unwrap_recursive<BOOST_PP_CAT(T,N)>::type \ | 
|---|
| 243 |             >::param_type \ | 
|---|
| 244 |         /**/ | 
|---|
| 245 |  | 
|---|
| 246 |     #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \ | 
|---|
| 247 |           BOOST_VARIANT_ENUM_PARAMS(typename_base) \ | 
|---|
| 248 |         , BOOST_PP_ENUM( \ | 
|---|
| 249 |               BOOST_VARIANT_LIMIT_TYPES \ | 
|---|
| 250 |             , BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE \ | 
|---|
| 251 |             , typename_base \ | 
|---|
| 252 |             ) \ | 
|---|
| 253 |         /**/ | 
|---|
| 254 |  | 
|---|
| 255 | #   endif // MSVC7 workaround | 
|---|
| 256 |  | 
|---|
| 257 | #define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ | 
|---|
| 258 |     ::boost::detail::variant::preprocessor_list_initializer< \ | 
|---|
| 259 |           BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \ | 
|---|
| 260 |         > \ | 
|---|
| 261 |     /**/ | 
|---|
| 262 |  | 
|---|
| 263 | #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround | 
|---|
| 264 |  | 
|---|
| 265 | #endif // BOOST_VARIANT_DETAIL_INITIALIZER_HPP | 
|---|