mirror of
https://github.com/boostorg/variant.git
synced 2026-02-17 14:12:12 +00:00
Dramatically reduced overhead caused by recursive_variant implementation for non-recursive variants.
[SVN r19720]
This commit is contained in:
222
include/boost/variant/detail/enable_recursive.hpp
Normal file
222
include/boost/variant/detail/enable_recursive.hpp
Normal file
@@ -0,0 +1,222 @@
|
||||
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
///// header body
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/enable_recursive.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both the copyright notice and this permission notice appear in
|
||||
// supporting documentation. No representations are made about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
|
||||
#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
|
||||
#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
|
||||
|
||||
#include "boost/mpl/aux_/config/ctps.hpp"
|
||||
|
||||
#include "boost/variant/detail/enable_recursive_fwd.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
# include "boost/mpl/aux_/template_arity.hpp"
|
||||
# include "boost/mpl/aux_/preprocessor/params.hpp"
|
||||
# include "boost/mpl/aux_/preprocessor/repeat.hpp"
|
||||
# include "boost/mpl/int_fwd.hpp"
|
||||
# include "boost/preprocessor/cat.hpp"
|
||||
# include "boost/preprocessor/arithmetic/inc.hpp"
|
||||
# include "boost/preprocessor/iterate.hpp"
|
||||
#else
|
||||
# include "boost/mpl/apply.hpp"
|
||||
# include "boost/mpl/apply_if.hpp"
|
||||
# include "boost/mpl/lambda.hpp"
|
||||
#endif
|
||||
|
||||
#include "boost/mpl/bool_fwd.hpp"
|
||||
#include "boost/mpl/if.hpp"
|
||||
#include "boost/mpl/or.hpp"
|
||||
#include "boost/type_traits/is_same.hpp"
|
||||
|
||||
#include "boost/incomplete.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) class specialization template enable_recursive_impl
|
||||
//
|
||||
// Performs recursive variant substitution.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
template <
|
||||
typename T, typename RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
|
||||
typename Arity = mpl::int_< mpl::aux::template_arity<T>::value >
|
||||
)
|
||||
>
|
||||
struct enable_recursive_impl
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename RecursiveVariant>
|
||||
struct enable_recursive_impl< recursive_variant_, RecursiveVariant >
|
||||
{
|
||||
typedef RecursiveVariant type;
|
||||
};
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL(N) \
|
||||
typedef typename enable_recursive_impl< \
|
||||
BOOST_PP_CAT(U,N), RecursiveVariant \
|
||||
>::type BOOST_PP_CAT(u,N); \
|
||||
/**/
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF(z, N, _) \
|
||||
BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PP_ITERATION_LIMITS (1,BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY)
|
||||
#define BOOST_PP_FILENAME_1 "boost/variant/detail/enable_recursive.hpp"
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL
|
||||
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
template <typename T, typename U1>
|
||||
struct rebind1
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::lambda<
|
||||
mpl::identity<T>
|
||||
>::type le_;
|
||||
|
||||
public:
|
||||
typedef typename mpl::apply_if<
|
||||
is_same< le_, mpl::identity<T> >
|
||||
, le_ // identity<T>
|
||||
, mpl::apply1<le_, U1>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename RecursiveVariant>
|
||||
struct enable_recursive_impl
|
||||
: rebind1< T,RecursiveVariant >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction enable_recursive
|
||||
//
|
||||
// Attempts recursive variant substitution and wraps with boost::incomplete
|
||||
// if substituion occurs *and* NoWrapper is false_.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T, typename RecursiveVariant, typename NoWrapper>
|
||||
struct enable_recursive
|
||||
: enable_recursive_impl<T,RecursiveVariant>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, typename RecursiveVariant>
|
||||
struct enable_recursive< T,RecursiveVariant,mpl::false_ >
|
||||
{
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
typedef typename enable_recursive_impl<T,RecursiveVariant>::type t_;
|
||||
|
||||
public: // metafunction result
|
||||
|
||||
// [Wrap with incomplete only if rebind really changed something:]
|
||||
typedef typename mpl::if_<
|
||||
is_same< t_,T >
|
||||
, t_
|
||||
, boost::incomplete<t_>
|
||||
>::type type;
|
||||
|
||||
};
|
||||
|
||||
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T, typename RecursiveVariant, typename NoWrapper>
|
||||
struct enable_recursive
|
||||
{
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
typedef typename enable_recursive_impl<T,RecursiveVariant>::type t_;
|
||||
|
||||
public: // metafunction result
|
||||
|
||||
// [Wrap with incomplete only if rebind really changed something:]
|
||||
typedef typename mpl::if_<
|
||||
mpl::or_< NoWrapper, is_same< t_,T > >
|
||||
, t_
|
||||
, boost::incomplete<t_>
|
||||
>::type type;
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction class quoted_enable_recursive
|
||||
//
|
||||
// Same behavior as enable_recursive metafunction (see above).
|
||||
//
|
||||
template <typename RecursiveVariant, typename NoWrapper>
|
||||
struct quoted_enable_recursive
|
||||
{
|
||||
template <typename T>
|
||||
struct apply
|
||||
: enable_recursive<T, RecursiveVariant, NoWrapper>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
|
||||
|
||||
///// iteration, depth == 1
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#define i BOOST_PP_FRAME_ITERATION(1)
|
||||
|
||||
template <
|
||||
template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
|
||||
, BOOST_MPL_PP_PARAMS(i,typename U)
|
||||
, typename RecursiveVariant
|
||||
>
|
||||
struct enable_recursive_impl<
|
||||
T< BOOST_MPL_PP_PARAMS(i,U) >
|
||||
, RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
|
||||
>
|
||||
{
|
||||
private:
|
||||
BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF, _)
|
||||
|
||||
public:
|
||||
typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
|
||||
};
|
||||
|
||||
#undef i
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
119
include/boost/variant/detail/enable_recursive_fwd.hpp
Normal file
119
include/boost/variant/detail/enable_recursive_fwd.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/enable_recursive_fwd.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both the copyright notice and this permission notice appear in
|
||||
// supporting documentation. No representations are made about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
|
||||
#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
|
||||
#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
|
||||
|
||||
#include "boost/mpl/aux_/config/ctps.hpp"
|
||||
|
||||
#include "boost/mpl/bool_fwd.hpp"
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
# include "boost/mpl/bool.hpp"
|
||||
#else
|
||||
# include "boost/type_traits/is_base_and_derived.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) tag recursive_flag
|
||||
//
|
||||
// Signifies that the variant should perform recursive substituion.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct recursive_flag
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
struct recursive_flag_tag
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct recursive_flag
|
||||
: recursive_flag_tag
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction is_recursive_flag
|
||||
//
|
||||
// Signifies that the variant should perform recursive substituion.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct is_recursive_flag
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_recursive_flag< recursive_flag<T> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct is_recursive_flag
|
||||
: is_base_and_derived< recursive_flag_tag,T >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction enable_recursive
|
||||
//
|
||||
// Attempts recursive variant substitution and wraps with boost::incomplete
|
||||
// if substituion occurs *and* NoWrapper is false_.
|
||||
//
|
||||
template <
|
||||
typename T
|
||||
, typename RecursiveVariant
|
||||
, typename NoWrapper = mpl::false_
|
||||
>
|
||||
struct enable_recursive;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction class quoted_enable_recursive
|
||||
//
|
||||
// Same behavior as enable_recursive metafunction (see above).
|
||||
//
|
||||
template <
|
||||
typename RecursiveVariant
|
||||
, typename NoWrapper = mpl::false_
|
||||
>
|
||||
struct quoted_enable_recursive;
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
|
||||
@@ -1,130 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/enable_recursive_stub.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both the copyright notice and this permission notice appear in
|
||||
// supporting documentation. No representations are made about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
|
||||
#ifndef BOOST_MPL_VARIANT_DETAIL_ENABLE_RECURSIVE_STUB_HPP
|
||||
#define BOOST_MPL_VARIANT_DETAIL_ENABLE_RECURSIVE_STUB_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/mpl/aux_/config/ttp.hpp"
|
||||
|
||||
#include "boost/incomplete_fwd.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
//
|
||||
// Defined if MPL lambda facility should be used as workaround for broken
|
||||
// compilers.
|
||||
//
|
||||
#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
|
||||
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# include "boost/mpl/aux_/template_arity.hpp"
|
||||
# include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
# include "boost/mpl/int_fwd.hpp"
|
||||
#else
|
||||
# include "boost/mpl/apply.hpp"
|
||||
# include "boost/mpl/apply_if.hpp"
|
||||
# include "boost/mpl/identity.hpp"
|
||||
# include "boost/mpl/if.hpp"
|
||||
# include "boost/mpl/lambda.hpp"
|
||||
# include "boost/type_traits/is_same.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction enable_recursive
|
||||
//
|
||||
// Enables the boost::variant<..., boost::recursive_variant, ...> syntax.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
// primary template (specialized in recursive_variant.hpp)
|
||||
template <
|
||||
typename T, typename Variant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
|
||||
typename Arity = mpl::int_< mpl::aux::template_arity<T>::value >
|
||||
)
|
||||
>
|
||||
struct enable_recursive_impl
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
template <typename T, typename U1>
|
||||
struct rebind1
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::lambda<
|
||||
mpl::identity<T>
|
||||
>::type le_;
|
||||
|
||||
public:
|
||||
typedef typename mpl::apply_if<
|
||||
is_same< le_, mpl::identity<T> >
|
||||
, le_ // identity<T>
|
||||
, mpl::apply1<le_, U1>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename Variant>
|
||||
struct enable_recursive_impl
|
||||
: rebind1< T,Variant >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT workaround
|
||||
|
||||
template <typename T, typename Variant>
|
||||
struct enable_recursive
|
||||
{
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
typedef typename enable_recursive_impl<T,Variant>::type t_;
|
||||
|
||||
public: // metafunction result
|
||||
|
||||
// [Wrap with incomplete only if rebind really changed something:]
|
||||
typedef typename mpl::if_<
|
||||
is_same< t_,T >
|
||||
, t_
|
||||
, boost::incomplete<t_>
|
||||
>::type type;
|
||||
|
||||
};
|
||||
|
||||
template <typename Variant>
|
||||
struct quoted_enable_recursive
|
||||
{
|
||||
template <typename T>
|
||||
struct apply
|
||||
: enable_recursive<T, Variant>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MPL_VARIANT_DETAIL_ENABLE_RECURSIVE_STUB_HPP
|
||||
64
include/boost/variant/detail/make_variant_list.hpp
Normal file
64
include/boost/variant/detail/make_variant_list.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/make_variant_list.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2002-2003
|
||||
// Eric Friedman, Itay Maman
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appears in all copies and
|
||||
// that both the copyright notice and this permission notice appear in
|
||||
// supporting documentation. No representations are made about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
|
||||
#ifndef BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
|
||||
#define BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
|
||||
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
|
||||
#include "boost/mpl/list.hpp"
|
||||
#include "boost/preprocessor/cat.hpp"
|
||||
#include "boost/preprocessor/enum.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction make_variant_list
|
||||
//
|
||||
// Provides a MPL-compatible sequence with the specified non-void types
|
||||
// as arguments.
|
||||
//
|
||||
// Rationale: see class template convert_void (variant_fwd.hpp) and using-
|
||||
// declaration workaround (below).
|
||||
//
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
struct make_variant_list
|
||||
{
|
||||
public: // metafunction result
|
||||
|
||||
// [Define a macro to convert any void(NN) tags to mpl::void...]
|
||||
# define BOOST_VARIANT_AUX_CONVERT_VOID(z, N,_) \
|
||||
typename convert_void< BOOST_PP_CAT(T,N) >::type
|
||||
|
||||
// [...so that the specified types can be passed to mpl::list...]
|
||||
typedef typename mpl::list<
|
||||
BOOST_PP_ENUM(
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_VARIANT_AUX_CONVERT_VOID
|
||||
, _
|
||||
)
|
||||
>::type type;
|
||||
|
||||
// [...and, finally, the conversion macro can be undefined:]
|
||||
# undef BOOST_VARIANT_AUX_CONVERT_VOID
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
|
||||
@@ -1,8 +1,3 @@
|
||||
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
///// header body
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/recursive_variant.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
@@ -22,110 +17,144 @@
|
||||
#ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
|
||||
#define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
|
||||
|
||||
#include "boost/variant/detail/enable_recursive_stub.hpp"
|
||||
#include "boost/incomplete.hpp" // only forward-declared in stub header
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
#include "boost/variant/detail/enable_recursive.hpp"
|
||||
#include "boost/variant/detail/make_variant_list.hpp"
|
||||
|
||||
#include "boost/mpl/limits/arity.hpp"
|
||||
#include "boost/mpl/arg.hpp"
|
||||
#include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
# include "boost/mpl/int_fwd.hpp"
|
||||
# include "boost/mpl/aux_/preprocessor/params.hpp"
|
||||
# include "boost/mpl/aux_/preprocessor/repeat.hpp"
|
||||
# include "boost/preprocessor/arithmetic/inc.hpp"
|
||||
# include "boost/preprocessor/iterate.hpp"
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
# include "boost/mpl/apply_if.hpp"
|
||||
# include "boost/mpl/identity.hpp"
|
||||
# include "boost/mpl/is_sequence.hpp"
|
||||
# include "boost/mpl/protect.hpp"
|
||||
# include "boost/mpl/transform.hpp"
|
||||
#else
|
||||
# include "boost/preprocessor/cat.hpp"
|
||||
# include "boost/preprocessor/repeat.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
|
||||
//
|
||||
// Exposes maximum allowed arity of class templates with recursive_variant
|
||||
// arguments. (That is, variant< ..., T<[1], recursive_variant, ... [N]> >.)
|
||||
//
|
||||
#define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \
|
||||
BOOST_MPL_METAFUNCTION_MAX_ARITY
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/variant/variant.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// type recursive_variant
|
||||
//
|
||||
// Tag type indicates where recursive variant substitution should occur.
|
||||
//
|
||||
typedef mpl::arg<1>
|
||||
recursive_variant;
|
||||
namespace detail { namespace variant {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) class specialization template enable_recursive_impl
|
||||
// (detail) metafunction specialization enable_recursive_impl
|
||||
//
|
||||
// Enables recursive variant substitution.
|
||||
// Handles embedded variant types.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
template <typename Variant>
|
||||
struct enable_recursive_impl< recursive_variant, Variant >
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
, typename RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct enable_recursive_impl<
|
||||
::boost::variant<
|
||||
recursive_flag< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
>
|
||||
, RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
typedef Variant type;
|
||||
typedef ::boost::variant<
|
||||
recursive_flag< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
> type;
|
||||
};
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL(N) \
|
||||
typedef typename enable_recursive_impl< \
|
||||
BOOST_PP_CAT(U,N), Variant \
|
||||
>::type BOOST_PP_CAT(u,N); \
|
||||
/**/
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
, typename RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct enable_recursive_impl<
|
||||
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
, RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF(z, N, _) \
|
||||
BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
|
||||
/**/
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
#define BOOST_PP_ITERATION_LIMITS (1,BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY)
|
||||
#define BOOST_PP_FILENAME_1 "boost/variant/recursive_variant.hpp"
|
||||
#include BOOST_PP_ITERATE()
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF_IMPL
|
||||
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::is_sequence<T0>
|
||||
, mpl::identity< T0 >
|
||||
, make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
>::type initial_types;
|
||||
|
||||
}} // namespace detail::variant
|
||||
typedef typename mpl::transform<
|
||||
initial_types
|
||||
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
|
||||
>::type types;
|
||||
|
||||
public: // metafunction result
|
||||
|
||||
typedef ::boost::variant< types > type;
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
|
||||
typedef typename enable_recursive< \
|
||||
BOOST_PP_CAT(T,N) \
|
||||
, RecursiveVariant \
|
||||
, mpl::true_ \
|
||||
>::type BOOST_PP_CAT(wknd_T,N); \
|
||||
/**/
|
||||
|
||||
BOOST_PP_REPEAT(
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
|
||||
, _
|
||||
)
|
||||
|
||||
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
|
||||
|
||||
public: // metafunction result
|
||||
|
||||
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
|
||||
|
||||
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
|
||||
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
//
|
||||
// see detail/enable_recursive_stub.hpp for workaround.
|
||||
// no specializations: embedded variants unsupported on these compilers!
|
||||
//
|
||||
|
||||
#endif // !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// metafunction recursive_variant
|
||||
//
|
||||
// See docs and boost/variant/variant_fwd.hpp for more information.
|
||||
//
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
struct recursive_variant
|
||||
{
|
||||
public: // metafunction result
|
||||
|
||||
typedef boost::variant<
|
||||
detail::variant::recursive_flag< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
> type;
|
||||
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP
|
||||
|
||||
///// iteration, depth == 1
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#define i BOOST_PP_FRAME_ITERATION(1)
|
||||
|
||||
template <
|
||||
template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
|
||||
, BOOST_MPL_PP_PARAMS(i,typename U)
|
||||
, typename Variant
|
||||
>
|
||||
struct enable_recursive_impl<
|
||||
T< BOOST_MPL_PP_PARAMS(i,U) >
|
||||
, Variant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
|
||||
>
|
||||
{
|
||||
private:
|
||||
BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEF, _)
|
||||
|
||||
public:
|
||||
typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
|
||||
};
|
||||
|
||||
#undef i
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
#include <typeinfo> // for typeid, std::type_info
|
||||
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
#include "boost/variant/detail/enable_recursive_fwd.hpp"
|
||||
#include "boost/variant/detail/make_variant_list.hpp"
|
||||
#include "boost/variant/detail/visitation_impl.hpp"
|
||||
#include "boost/variant/detail/enable_recursive_stub.hpp"
|
||||
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
#include "boost/variant/detail/has_nothrow_move.hpp"
|
||||
@@ -60,12 +61,11 @@
|
||||
#include "boost/mpl/int.hpp"
|
||||
#include "boost/mpl/is_sequence.hpp"
|
||||
#include "boost/mpl/iter_fold.hpp"
|
||||
#include "boost/mpl/front.hpp"
|
||||
#include "boost/mpl/list.hpp"
|
||||
#include "boost/mpl/logical.hpp"
|
||||
#include "boost/mpl/max_element.hpp"
|
||||
#include "boost/mpl/next.hpp"
|
||||
#include "boost/mpl/pair.hpp"
|
||||
#include "boost/mpl/protect.hpp"
|
||||
#include "boost/mpl/remove_if.hpp"
|
||||
#include "boost/mpl/sizeof.hpp"
|
||||
#include "boost/mpl/size_t.hpp"
|
||||
@@ -93,6 +93,7 @@
|
||||
# include "boost/mpl/O1_size.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail { namespace variant {
|
||||
@@ -491,40 +492,6 @@ public: // visitor interfaces
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) metafunction make_variant_list
|
||||
//
|
||||
// Provides a MPL-compatible sequence with the specified non-void types
|
||||
// as arguments.
|
||||
//
|
||||
// Rationale: see class template convert_void (variant_fwd.hpp) and using-
|
||||
// declaration workaround (below).
|
||||
//
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
struct make_variant_list
|
||||
{
|
||||
public: // metafunction result
|
||||
|
||||
// [Define a macro to convert any void(NN) tags to mpl::void...]
|
||||
# define BOOST_VARIANT_AUX_CONVERT_VOID(z, N,_) \
|
||||
typename convert_void<BOOST_PP_CAT(T,N)>::type
|
||||
|
||||
// [...so that the specified types can be passed to mpl::list...]
|
||||
typedef typename mpl::list<
|
||||
BOOST_PP_ENUM(
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_VARIANT_AUX_CONVERT_VOID
|
||||
, _
|
||||
)
|
||||
>::type type;
|
||||
|
||||
// [...and, finally, the conversion macro can be undefined:]
|
||||
# undef BOOST_VARIANT_AUX_CONVERT_VOID
|
||||
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) support for MPL-Sequence initializer
|
||||
//
|
||||
@@ -532,6 +499,8 @@ public: // metafunction result
|
||||
// overload resolution rules on any specified set of bounded types.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
// (detail) quoted metafunction make_initializer_node
|
||||
//
|
||||
// Exposes a pair whose first type is a node in the initializer hierarchy.
|
||||
@@ -593,6 +562,13 @@ public: // static functions
|
||||
|
||||
};
|
||||
|
||||
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
//
|
||||
// MPL-sequence initializer cannot be supported on these compilers.
|
||||
// See preprocessor_list_initializer workaround below.
|
||||
//
|
||||
|
||||
#endif // !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
}} // namespace detail::variant
|
||||
@@ -603,57 +579,76 @@ public: // static functions
|
||||
// See docs and boost/variant/variant_fwd.hpp for more information.
|
||||
//
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T_)
|
||||
>
|
||||
typename T0_
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
|
||||
#elif !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename wknd_T)
|
||||
#else // MSVC6
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
|
||||
#endif
|
||||
>
|
||||
class variant
|
||||
{
|
||||
private: // private typedefs
|
||||
|
||||
struct is_recursive
|
||||
: detail::variant::is_recursive_flag<T0_>
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
private: // helpers, for typedefs (below)
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::is_sequence<T_0>
|
||||
, mpl::identity<T_0>
|
||||
is_recursive
|
||||
, T0_
|
||||
, mpl::identity< T0_ >
|
||||
>::type T0;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::is_sequence<T0>
|
||||
, mpl::identity<T0>
|
||||
, detail::variant::make_variant_list<
|
||||
BOOST_VARIANT_ENUM_PARAMS(T_)
|
||||
BOOST_VARIANT_ENUM_PARAMS(T)
|
||||
>
|
||||
>::type plain_nonrecursive_types;
|
||||
>::type initial_types;
|
||||
|
||||
public: // typedefs
|
||||
|
||||
typedef typename mpl::transform<
|
||||
plain_nonrecursive_types
|
||||
, mpl::protect< detail::variant::quoted_enable_recursive<variant> >
|
||||
typedef typename mpl::apply_if<
|
||||
is_recursive
|
||||
, mpl::transform<
|
||||
initial_types
|
||||
, mpl::protect<
|
||||
detail::variant::quoted_enable_recursive<variant>
|
||||
>
|
||||
>
|
||||
, mpl::identity< initial_types >
|
||||
>::type types;
|
||||
|
||||
private: // private typedefs
|
||||
|
||||
typedef typename mpl::front<types>::type T0;
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
#elif !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
|
||||
private: // helpers, for typedefs (below)
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
typedef typename mpl::apply_if<
|
||||
is_recursive
|
||||
, T0_
|
||||
, mpl::identity< T0_ >
|
||||
>::type wknd_T0;
|
||||
|
||||
typedef variant wknd_self_t;
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
|
||||
typedef typename detail::variant::enable_recursive< \
|
||||
BOOST_PP_CAT(T_,N) \
|
||||
, wknd_self_t \
|
||||
>::type BOOST_PP_CAT(T,N); \
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
|
||||
typedef typename mpl::apply_if< \
|
||||
is_recursive \
|
||||
, detail::variant::enable_recursive< \
|
||||
BOOST_PP_CAT(wknd_T,N) \
|
||||
, variant \
|
||||
> \
|
||||
, mpl::identity< BOOST_PP_CAT(wknd_T,N) > \
|
||||
>::type BOOST_PP_CAT(T,N); \
|
||||
/**/
|
||||
|
||||
# else // MSVC7 and below
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
|
||||
typedef BOOST_PP_CAT(T_,N) BOOST_PP_CAT(T,N); \
|
||||
/**/
|
||||
|
||||
# endif // MSVC7 and below workaround
|
||||
|
||||
BOOST_PP_REPEAT(
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
|
||||
@@ -670,24 +665,40 @@ public: // typedefs
|
||||
|
||||
private: // static precondition assertions
|
||||
|
||||
// Sequences are not supported for compilers that do not support
|
||||
// using declarations in templates (see below).
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
|
||||
// NOTE TO USER :
|
||||
// variant< type-sequence > syntax is not supported on this compiler!
|
||||
//
|
||||
BOOST_STATIC_ASSERT((
|
||||
::boost::mpl::not_< mpl::is_sequence<T0> >::value
|
||||
));
|
||||
|
||||
# else // MSVC6
|
||||
#else // MSVC6
|
||||
|
||||
public: // typedefs
|
||||
|
||||
typedef T0_ T0;
|
||||
|
||||
typedef typename detail::variant::make_variant_list<
|
||||
BOOST_VARIANT_ENUM_PARAMS(T)
|
||||
>::type types;
|
||||
|
||||
private: // static precondition assertions
|
||||
|
||||
// for some reason, msvc needs following all on one line:
|
||||
BOOST_STATIC_CONSTANT(bool, msvc_not_is_sequence_T0 = mpl::not_< mpl::is_sequence<T0> >::value);
|
||||
BOOST_STATIC_CONSTANT(bool, msvc_not_is_recursive = mpl::not_< is_recursive >::value);
|
||||
BOOST_STATIC_CONSTANT(bool, msvc_not_is_sequence_T0 = mpl::not_< mpl::is_sequence<T0_> >::value);
|
||||
|
||||
// NOTE TO USER :
|
||||
// recursive_variant is not supported on MSVC6!
|
||||
//
|
||||
BOOST_STATIC_ASSERT(msvc_not_is_recursive);
|
||||
|
||||
// NOTE TO USER :
|
||||
// variant< type-sequence > syntax is not supported on MSVC6!
|
||||
//
|
||||
BOOST_STATIC_ASSERT(msvc_not_is_sequence_T0);
|
||||
|
||||
# endif // MSVC6 workaround
|
||||
|
||||
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
|
||||
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT and MSVC6 workaround
|
||||
|
||||
private: // static precondition assertions, cont.
|
||||
|
||||
|
||||
@@ -18,32 +18,27 @@
|
||||
#define BOOST_VARIANT_VARIANT_FWD_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/mpl/limits/list.hpp"
|
||||
#include "boost/empty_fwd.hpp"
|
||||
#include "boost/mpl/arg.hpp"
|
||||
#include "boost/mpl/void.hpp"
|
||||
#include "boost/preprocessor/cat.hpp"
|
||||
#include "boost/preprocessor/dec.hpp"
|
||||
#include "boost/preprocessor/enum_params.hpp"
|
||||
#include "boost/preprocessor/enum_shifted.hpp"
|
||||
#include "boost/preprocessor/enum_shifted_params.hpp"
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
|
||||
#include "boost/empty_fwd.hpp"
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
# include "boost/preprocessor/enum_params_with_a_default.hpp"
|
||||
#else
|
||||
# include "boost/preprocessor/enum_params_with_defaults.hpp"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_LIMIT_TYPES
|
||||
//
|
||||
// Implementation-defined preprocessor symbol describing the actual
|
||||
// length of variant's pseudo-variadic template parameter list.
|
||||
//
|
||||
#include "boost/mpl/limits/list.hpp"
|
||||
#define BOOST_VARIANT_LIMIT_TYPES \
|
||||
BOOST_MPL_LIMIT_LIST_SIZE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
|
||||
// macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
|
||||
//
|
||||
// Defined if variant does not support variant<Types> syntax (see below).
|
||||
//
|
||||
@@ -51,6 +46,32 @@
|
||||
# define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
//
|
||||
// Defined if MPL lambda facility should be used as workaround for broken
|
||||
// compilers. (Thus, only types w/ MPL lambda workarounds can be accepted.)
|
||||
//
|
||||
|
||||
#include "boost/mpl/aux_/config/ctps.hpp"
|
||||
#include "boost/mpl/aux_/config/ttp.hpp"
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
|
||||
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
|
||||
//
|
||||
// Exposes maximum allowed arity of class templates with recursive_variant
|
||||
// arguments. (That is, variant< ..., T<[1], recursive_variant, ... [N]> >.)
|
||||
//
|
||||
#include "boost/mpl/limits/arity.hpp"
|
||||
#define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \
|
||||
BOOST_MPL_METAFUNCTION_MAX_ARITY
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_ENUM_PARAMS
|
||||
//
|
||||
@@ -61,6 +82,14 @@
|
||||
#define BOOST_VARIANT_ENUM_PARAMS( param ) \
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS
|
||||
//
|
||||
// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params.
|
||||
//
|
||||
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -101,7 +130,7 @@ struct convert_void< void_ >
|
||||
|
||||
#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
// (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES - 1)
|
||||
// (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES)
|
||||
//
|
||||
// Defines void types that are each unique and specializations of
|
||||
// convert_void that yields mpl::void_ for each voidNN type.
|
||||
@@ -118,7 +147,7 @@ struct convert_void< void_ >
|
||||
/**/
|
||||
|
||||
BOOST_PP_REPEAT(
|
||||
BOOST_PP_DEC(BOOST_VARIANT_LIMIT_TYPES)
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_VARIANT_DETAIL_DEFINE_VOID_N
|
||||
, _
|
||||
)
|
||||
@@ -129,6 +158,35 @@ BOOST_PP_REPEAT(
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
|
||||
//
|
||||
// Template parameter list for variant and recursive_variant declarations.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
|
||||
typename BOOST_PP_CAT(T,N) = detail::variant::void_ \
|
||||
/**/
|
||||
|
||||
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
|
||||
typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
|
||||
|
||||
#define BOOST_VARIANT_AUX_DECLARE_PARAMS \
|
||||
typename T0 = boost::empty \
|
||||
, BOOST_PP_ENUM_SHIFTED( \
|
||||
BOOST_VARIANT_LIMIT_TYPES \
|
||||
, BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \
|
||||
, T \
|
||||
) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class template variant (concept inspired by Andrei Alexandrescu)
|
||||
//
|
||||
@@ -145,30 +203,29 @@ BOOST_PP_REPEAT(
|
||||
// or
|
||||
// variant<>, which is variant<boost::empty>
|
||||
//
|
||||
template <
|
||||
template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant;
|
||||
|
||||
typename First = boost::empty,
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// metafunction recursive_variant
|
||||
//
|
||||
// Exposes a boost::variant with recursive_variant_ tags (below) substituted
|
||||
// with the variant itself (wrapped as needed with boost::incomplete).
|
||||
//
|
||||
template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct recursive_variant;
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
#undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL
|
||||
#undef BOOST_VARIANT_AUX_DECLARE_PARAMS
|
||||
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
|
||||
BOOST_PP_DEC(BOOST_VARIANT_LIMIT_TYPES)
|
||||
, typename T
|
||||
, detail::variant::void_
|
||||
)
|
||||
|
||||
#else// defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS(
|
||||
BOOST_PP_DEC(BOOST_VARIANT_LIMIT_TYPES)
|
||||
, typename T
|
||||
, detail::variant::void//NN
|
||||
)
|
||||
|
||||
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
|
||||
|
||||
>
|
||||
class variant;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// type recursive_variant_
|
||||
//
|
||||
// Tag type indicates where recursive variant substitution should occur.
|
||||
//
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
struct recursive_variant_;
|
||||
#else
|
||||
typedef mpl::arg<1> recursive_variant_;
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user