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