epoc32/include/stdapis/boost/variant/detail/initializer.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     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