Chris@16: //----------------------------------------------------------------------------- Chris@16: // boost variant/detail/initializer.hpp header file Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: //----------------------------------------------------------------------------- Chris@16: // Chris@16: // Copyright (c) 2002-2003 Chris@16: // Eric Friedman, Itay Maman Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_VARIANT_DETAIL_INITIALIZER_HPP Chris@16: #define BOOST_VARIANT_DETAIL_INITIALIZER_HPP Chris@16: Chris@16: #include // for placement new Chris@16: Chris@16: #include "boost/config.hpp" Chris@16: Chris@16: #include "boost/call_traits.hpp" Chris@16: #include "boost/detail/reference_content.hpp" Chris@16: #include "boost/variant/recursive_wrapper_fwd.hpp" Chris@16: #include "boost/variant/detail/move.hpp" Chris@16: Chris@16: #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) Chris@16: # include "boost/mpl/aux_/value_wknd.hpp" Chris@16: # include "boost/mpl/int.hpp" Chris@16: # include "boost/mpl/iter_fold.hpp" Chris@16: # include "boost/mpl/next.hpp" Chris@16: # include "boost/mpl/deref.hpp" Chris@16: # include "boost/mpl/pair.hpp" Chris@16: # include "boost/mpl/protect.hpp" Chris@16: #else Chris@16: # include "boost/variant/variant_fwd.hpp" Chris@16: # include "boost/preprocessor/cat.hpp" Chris@16: # include "boost/preprocessor/enum.hpp" Chris@16: # include "boost/preprocessor/repeat.hpp" Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: namespace detail { namespace variant { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // (detail) support to simulate standard overload resolution rules Chris@16: // Chris@16: // The below initializers allows variant to follow standard overload Chris@16: // resolution rules over the specified set of bounded types. Chris@16: // Chris@16: // On compilers where using declarations in class templates can correctly Chris@16: // avoid name hiding, use an optimal solution based on the variant's typelist. Chris@16: // Chris@16: // Otherwise, use a preprocessor workaround based on knowledge of the fixed Chris@16: // size of the variant's psuedo-variadic template parameter list. Chris@16: // Chris@16: Chris@16: #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) Chris@16: Chris@16: // (detail) quoted metafunction make_initializer_node Chris@16: // Chris@16: // Exposes a pair whose first type is a node in the initializer hierarchy. Chris@16: // Chris@16: struct make_initializer_node Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: private: // helpers, for metafunction result (below) Chris@16: Chris@16: typedef typename BaseIndexPair::first Chris@16: base; Chris@16: typedef typename BaseIndexPair::second Chris@16: index; Chris@16: Chris@16: class initializer_node Chris@16: : public base Chris@16: { Chris@16: private: // helpers, for static functions (below) Chris@16: Chris@16: typedef typename mpl::deref::type Chris@16: recursive_enabled_T; Chris@16: typedef typename unwrap_recursive::type Chris@16: public_T; Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: typedef boost::is_reference Chris@16: is_reference_content_t; Chris@16: Chris@16: typedef typename boost::mpl::if_::type Chris@16: param_T; Chris@16: Chris@16: template struct disable_overload{}; Chris@16: Chris@16: typedef typename boost::mpl::if_, public_T&& >::type Chris@16: param2_T; Chris@16: #else Chris@16: typedef typename call_traits::param_type Chris@16: param_T; Chris@16: #endif Chris@16: Chris@16: public: // static functions Chris@16: Chris@16: using base::initialize; Chris@16: Chris@16: static int initialize(void* dest, param_T operand) Chris@16: { Chris@16: typedef typename boost::detail::make_reference_content< Chris@16: recursive_enabled_T Chris@16: >::type internal_T; Chris@16: Chris@16: new(dest) internal_T(operand); Chris@16: return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: static int initialize(void* dest, param2_T operand) Chris@16: { Chris@16: // This assert must newer trigger, because all the reference contents are Chris@16: // handled by the initilize(void* dest, param_T operand) function above Chris@16: BOOST_ASSERT(!is_reference_content_t::value); Chris@16: Chris@16: typedef typename boost::mpl::if_::type value_T; Chris@16: new(dest) value_T( boost::detail::variant::move(operand) ); Chris@16: return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: friend class initializer_node; Chris@16: Chris@16: public: // metafunction result Chris@16: Chris@16: typedef mpl::pair< Chris@16: initializer_node Chris@16: , typename mpl::next< index >::type Chris@16: > type; Chris@16: Chris@16: }; Chris@16: }; Chris@16: Chris@16: // (detail) class initializer_root Chris@16: // Chris@16: // Every level of the initializer hierarchy must expose the name Chris@16: // "initialize," so initializer_root provides a dummy function: Chris@16: // Chris@16: class initializer_root Chris@16: { Chris@16: public: // static functions Chris@16: Chris@16: static void initialize(); Chris@16: Chris@16: }; Chris@16: Chris@16: #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) Chris@16: Chris@101: // Obsolete. Remove. Chris@16: #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \ Chris@16: BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \ Chris@16: /**/ Chris@16: Chris@101: // Obsolete. Remove. Chris@16: #define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \ Chris@16: typedef typename unwrap_recursive< \ Chris@16: BOOST_PP_CAT(recursive_enabled_T,N) \ Chris@16: >::type BOOST_PP_CAT(public_T,N); \ Chris@16: typedef typename call_traits< \ Chris@16: BOOST_PP_CAT(public_T,N) \ Chris@16: >::param_type BOOST_PP_CAT(param_T,N); \ Chris@16: /**/ Chris@16: Chris@101: template < BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) > Chris@16: struct preprocessor_list_initializer Chris@16: { Chris@16: public: // static functions Chris@16: Chris@16: #define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \ Chris@101: typedef typename unwrap_recursive< \ Chris@101: BOOST_PP_CAT(recursive_enabled_T,N) \ Chris@101: >::type BOOST_PP_CAT(public_T,N); \ Chris@101: typedef typename call_traits< \ Chris@101: BOOST_PP_CAT(public_T,N) \ Chris@101: >::param_type BOOST_PP_CAT(param_T,N); \ Chris@16: static int initialize( \ Chris@16: void* dest \ Chris@16: , BOOST_PP_CAT(param_T,N) operand \ Chris@16: ) \ Chris@16: { \ Chris@16: typedef typename boost::detail::make_reference_content< \ Chris@16: BOOST_PP_CAT(recursive_enabled_T,N) \ Chris@16: >::type internal_T; \ Chris@16: \ Chris@16: new(dest) internal_T(operand); \ Chris@16: return (N); /*which*/ \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: BOOST_PP_REPEAT( Chris@16: BOOST_VARIANT_LIMIT_TYPES Chris@16: , BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION Chris@16: , _ Chris@16: ) Chris@16: Chris@16: #undef BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION Chris@16: Chris@16: }; Chris@16: Chris@16: #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround Chris@16: Chris@16: }} // namespace detail::variant Chris@16: } // namespace boost Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // macro BOOST_VARIANT_AUX_INITIALIZER_T Chris@16: // Chris@16: // Given both the variant's typelist and a basename for forming the list of Chris@16: // bounded types (i.e., T becomes T1, T2, etc.), exposes the initializer Chris@16: // most appropriate to the current compiler. Chris@16: // Chris@16: Chris@16: #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) Chris@16: Chris@16: #define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ Chris@16: ::boost::mpl::iter_fold< \ Chris@16: mpl_seq \ Chris@16: , ::boost::mpl::pair< \ Chris@16: ::boost::detail::variant::initializer_root \ Chris@16: , ::boost::mpl::int_<0> \ Chris@16: > \ Chris@16: , ::boost::mpl::protect< \ Chris@16: ::boost::detail::variant::make_initializer_node \ Chris@16: > \ Chris@16: >::type::first \ Chris@16: /**/ Chris@16: Chris@16: #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) Chris@16: Chris@101: // Obsolete. Remove. Chris@16: #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \ Chris@16: BOOST_VARIANT_ENUM_PARAMS(typename_base) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \ Chris@16: ::boost::detail::variant::preprocessor_list_initializer< \ Chris@101: BOOST_VARIANT_ENUM_PARAMS(typename_base) \ Chris@16: > \ Chris@16: /**/ Chris@16: Chris@16: #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround Chris@16: Chris@16: #endif // BOOST_VARIANT_DETAIL_INITIALIZER_HPP