PageRenderTime 37ms CodeModel.GetById 15ms app.highlight 13ms RepoModel.GetById 5ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/variant/detail/initializer.hpp

http://hadesmem.googlecode.com/
C++ Header | 265 lines | 160 code | 56 blank | 49 comment | 5 complexity | 7db2fb4752c543b3d9b35840367c9f68 MD5 | raw file
  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
 39namespace boost {
 40namespace 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//
 61struct 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//
118class initializer_root
119{
120public: // 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
155template < BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS >
156struct preprocessor_list_initializer
157{
158public: // 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
192template <>
193struct 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