mirror of
https://github.com/boostorg/variant.git
synced 2026-07-24 14:07:52 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65dae1db5a | |||
| 4ad95f185b | |||
| 0367512bc7 | |||
| e1a611c000 | |||
| 134dfbf46e | |||
| 92a530a2b9 | |||
| 9bc9c1c143 | |||
| 5398f31ea2 | |||
| e30800b534 | |||
| 9b04ff9221 | |||
| 7a5b0f2538 | |||
| 01a9630c37 | |||
| 0396d6c73d | |||
| 63fb3ff427 | |||
| 0d226eb597 | |||
| 464799f446 | |||
| f59cdef172 | |||
| e20324e2c4 | |||
| 592e1b5339 | |||
| a2523c620d | |||
| e70b03583f | |||
| e05edc0248 | |||
| 76f2c0fc19 | |||
| 8507087c59 | |||
| f17d91a8b4 | |||
| 3e02b4963d | |||
| a4eaf348ea | |||
| 54ea9c42a1 | |||
| eb17a6afd8 | |||
| 3891cde7ed | |||
| 591ae9bf26 | |||
| 5b34fe155f | |||
| 2a6c6f3948 | |||
| c13372a092 | |||
| 64d68fc379 | |||
| 19ba44bb3f | |||
| 4d02fbcd84 | |||
| 4f4555fa93 | |||
| e0151cc209 | |||
| 3bc66e9264 | |||
| aa1eeb3b0f | |||
| a400952c16 | |||
| dcc25e1a1d | |||
| c7d1cccc13 | |||
| 5edc863174 | |||
| d465155ccc | |||
| ddf192fc53 | |||
| de56bdaa0a | |||
| 2d1dea19ba | |||
| 39469616d2 |
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE header PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<header name="boost/variant/polymorphic_get.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
<class name="bad_polymorphic_get">
|
||||
<inherit access="public">
|
||||
<classname>boost::bad_get</classname>
|
||||
</inherit>
|
||||
|
||||
<purpose>
|
||||
<simpara>The exception thrown in the event of a failed application of
|
||||
<code><functionname>boost::polymorphic_get</functionname></code> on the given
|
||||
operand value.</simpara>
|
||||
</purpose>
|
||||
|
||||
<method name="what" specifiers="virtual" cv="const">
|
||||
<type>const char *</type>
|
||||
</method>
|
||||
</class>
|
||||
|
||||
<overloaded-function name="polymorphic_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>The <code>polymorphic_get</code> function allows run-time checked,
|
||||
type-safe retrieval of the content of the given
|
||||
<code><classname>variant</classname></code>. The function succeeds
|
||||
only if the content is of the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>, with
|
||||
failure indicated as described below.</simpara>
|
||||
<simpara><emphasis role="bold">Warning</emphasis>: After either
|
||||
<code>operand</code> or its content is destroyed (e.g., when the
|
||||
given <code><classname>variant</classname></code> is assigned a
|
||||
value of different type), the returned reference is invalidated.
|
||||
Thus, significant care and caution must be extended when handling
|
||||
the returned reference.</simpara>
|
||||
</description>
|
||||
|
||||
<notes>
|
||||
<simpara>As part of its guarantee of type-safety, <code>polymorphic_get</code>
|
||||
enforces <code>const</code>-correctness. Thus, the specified type
|
||||
<code>U</code> must be <code>const</code>-qualified whenever
|
||||
<code>operand</code> or its content is likewise
|
||||
<code>const</code>-qualified. The converse, however, is not required:
|
||||
that is, the specified type <code>U</code> may be
|
||||
<code>const</code>-qualified even when <code>operand</code> and its
|
||||
content are not.</simpara>
|
||||
</notes>
|
||||
|
||||
<returns>
|
||||
<simpara>If passed a pointer, <code>polymorphic_get</code> returns a pointer to
|
||||
the value content if it is of the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>;
|
||||
otherwise, a null pointer is returned. If passed a reference,
|
||||
<code>polymorphic_get</code> returns a reference to the value content if it is of
|
||||
the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>; otherwise, an exception is thrown
|
||||
(see below).</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>Overloads taking a
|
||||
<code><classname>variant</classname></code> pointer will not
|
||||
throw; the overloads taking a
|
||||
<code><classname>variant</classname></code> reference throw
|
||||
<code><classname>bad_polymorphic_get</classname></code> if the content is not of
|
||||
the specified type <code>U</code>or of type
|
||||
derived from type <code>U</code>.</simpara>
|
||||
</throws>
|
||||
|
||||
<rationale>
|
||||
<simpara>While visitation via
|
||||
<code><functionname>apply_visitor</functionname></code>
|
||||
is generally preferred due to its greater safety, <code>polymorphic_get</code> may
|
||||
may be more convenient in some cases due to its straightforward
|
||||
usage.</simpara>
|
||||
</rationale>
|
||||
</overloaded-function>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
@@ -19,6 +19,7 @@
|
||||
<xi:include href="apply_visitor.xml"/>
|
||||
<xi:include href="multivisitor.xml"/>
|
||||
<xi:include href="get.xml"/>
|
||||
<xi:include href="polymorphic_get.xml"/>
|
||||
<xi:include href="bad_visit.xml"/>
|
||||
<xi:include href="static_visitor.xml"/>
|
||||
<xi:include href="visitor_ptr.xml"/>
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
<purpose>
|
||||
<simpara>Expands to the length of the
|
||||
template parameter list for
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
<code><classname>variant</classname></code>. Not used if
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined.
|
||||
</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
@@ -25,6 +28,17 @@
|
||||
</description>
|
||||
</macro>
|
||||
|
||||
<macro name="BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES">
|
||||
<purpose>
|
||||
<simpara>If this macro is defined, then library won't use C++11 variadic templates.
|
||||
Users may define this macro to make
|
||||
<code><macroname>BOOST_VARIANT_ENUM_PARAMS</macroname></code>
|
||||
and <code><macroname>BOOST_VARIANT_ENUM_SHIFTED_PARAMS</macroname></code> expand
|
||||
to a comma-separated sequence instead of variadic templates.
|
||||
</simpara>
|
||||
</purpose>
|
||||
</macro>
|
||||
|
||||
<macro name="BOOST_VARIANT_ENUM_PARAMS" kind="functionlike">
|
||||
<macro-parameter name="param"/>
|
||||
|
||||
@@ -34,7 +48,21 @@
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<para>Expands to a comma-separated sequence of length
|
||||
<para> When variadic templates are available and
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined, expands to variadic template list in the following manner:
|
||||
<code><programlisting>
|
||||
BOOST_VARIANT_ENUM_PARAMS(T) => T0, TN...
|
||||
BOOST_VARIANT_ENUM_PARAMS(class T) => class T0, class... TN
|
||||
BOOST_VARIANT_ENUM_PARAMS(class Something) => class Something0, class... SomethingN
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename Something) => typename Something0, typename... SomethingN
|
||||
BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
|
||||
BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
|
||||
</programlisting></code>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Otherwise expands to a comma-separated sequence of length
|
||||
<code><macroname>BOOST_VARIANT_LIMIT_TYPES</macroname></code>, where
|
||||
each element in the sequence consists of the concatenation of
|
||||
<emphasis>param</emphasis> with its zero-based index into the
|
||||
@@ -59,7 +87,21 @@
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<para>Expands to a comma-separated sequence of length
|
||||
<para> When variadic templates are available and
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined, expands to variadic template list in the following manner:
|
||||
<code><programlisting>
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) => TN...
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class T) => class... TN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something) => class... SomethingN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something) => typename... SomethingN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
|
||||
</programlisting></code>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Otherwise expands to a comma-separated sequence of length
|
||||
<code><macroname>BOOST_VARIANT_LIMIT_TYPES</macroname> - 1</code>,
|
||||
where each element in the sequence consists of the concatenation of
|
||||
<emphasis>param</emphasis> with its one-based index into the sequence.
|
||||
@@ -121,4 +163,4 @@
|
||||
full lambda support either.)</para>
|
||||
</description>
|
||||
</macro>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
#include "boost/assert.hpp"
|
||||
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include "boost/type_traits/remove_reference.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
@@ -42,9 +38,8 @@ inline T forced_return()
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
|
||||
typedef typename boost::remove_reference<T>::type basic_type;
|
||||
basic_type* dummy = 0;
|
||||
return *static_cast< basic_type* >(dummy);
|
||||
T (*dummy_function_ptr)() = 0;
|
||||
return dummy_function_ptr();
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -76,6 +71,8 @@ forced_return()
|
||||
|
||||
#else // defined(BOOST_MSVC)
|
||||
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4702 ) // unreachable code
|
||||
// msvc-specific implementation
|
||||
//
|
||||
// Leverages __declspec(noreturn) for optimized implementation.
|
||||
@@ -95,6 +92,8 @@ forced_return()
|
||||
forced_return_no_return();
|
||||
}
|
||||
|
||||
# pragma warning( pop )
|
||||
|
||||
#endif // BOOST_MSVC optimization
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace detail { namespace variant {
|
||||
// declaration workaround (below).
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
template < typename... T >
|
||||
struct make_variant_list
|
||||
@@ -40,7 +40,7 @@ struct make_variant_list
|
||||
typedef typename mpl::list< T... >::type type;
|
||||
};
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
struct make_variant_list
|
||||
@@ -65,7 +65,7 @@ public: // metafunction result
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
@@ -125,6 +125,27 @@ struct substitute<
|
||||
// template expression (i.e., F<...>) specializations
|
||||
//
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <
|
||||
template <typename...> class F
|
||||
, typename... Ts
|
||||
, typename Dest
|
||||
, typename Source
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
F<Ts...>
|
||||
, Dest
|
||||
, Source
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
typedef F<typename substitute<
|
||||
Ts, Dest, Source
|
||||
>::type...> type;
|
||||
};
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
|
||||
typedef typename substitute< \
|
||||
BOOST_PP_CAT(U,N), Dest, Source \
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "boost/variant/detail/forced_return.hpp"
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
|
||||
#include "boost/assert.hpp"
|
||||
#include "boost/mpl/eval_if.hpp"
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/identity.hpp"
|
||||
@@ -47,10 +46,18 @@
|
||||
// and potentially increase runtime performance. (TODO: Investigate further.)
|
||||
//
|
||||
#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
|
||||
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
# include "boost/mpl/limits/list.hpp"
|
||||
# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
|
||||
BOOST_MPL_LIMIT_LIST_SIZE
|
||||
#else
|
||||
# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
@@ -154,8 +161,7 @@ inline
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
|
||||
visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
|
||||
{
|
||||
// should never be here at runtime:
|
||||
BOOST_ASSERT(false);
|
||||
// should never be here at runtime!
|
||||
typedef typename Visitor::result_type result_type;
|
||||
return ::boost::detail::variant::forced_return< result_type >();
|
||||
}
|
||||
@@ -179,8 +185,7 @@ visitation_impl(
|
||||
, NBF, W* = 0, S* = 0
|
||||
)
|
||||
{
|
||||
// should never be here at runtime:
|
||||
BOOST_ASSERT(false);
|
||||
// should never be here at runtime!
|
||||
typedef typename Visitor::result_type result_type;
|
||||
return ::boost::detail::variant::forced_return< result_type >();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace boost {
|
||||
//
|
||||
// The exception thrown in the event of a failed get of a value.
|
||||
//
|
||||
class bad_get
|
||||
class BOOST_SYMBOL_VISIBLE bad_get
|
||||
: public std::exception
|
||||
{
|
||||
public: // std::exception implementation
|
||||
@@ -86,11 +86,13 @@ public: // visitor interfaces
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
#else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/polymorphic_get.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2013 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
#define BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/throw_exception.hpp"
|
||||
#include "boost/utility/addressof.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
#include "boost/variant/get.hpp"
|
||||
|
||||
#include "boost/type_traits/add_reference.hpp"
|
||||
#include "boost/type_traits/add_pointer.hpp"
|
||||
#include "boost/type_traits/is_base_of.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// class bad_polymorphic_get
|
||||
//
|
||||
// The exception thrown in the event of a failed get of a value.
|
||||
//
|
||||
class BOOST_SYMBOL_VISIBLE bad_polymorphic_get
|
||||
: public bad_get
|
||||
{
|
||||
public: // std::exception implementation
|
||||
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "boost::bad_polymorphic_get: "
|
||||
"failed value get using boost::polymorphic_get";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// function template get<T>
|
||||
//
|
||||
// Retrieves content of given variant object if content is of type T.
|
||||
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
|
||||
//
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
// (detail) class template get_polymorphic_visitor
|
||||
//
|
||||
// Generic static visitor that: if the value is of the specified
|
||||
// type or of a type derived from specified, returns a pointer
|
||||
// to the value it visits; else a null pointer.
|
||||
//
|
||||
template <typename Base>
|
||||
struct get_polymorphic_visitor
|
||||
{
|
||||
private: // private typedefs
|
||||
typedef typename add_pointer<Base>::type pointer;
|
||||
typedef typename add_reference<Base>::type reference;
|
||||
|
||||
pointer get(reference operand, boost::true_type) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::addressof(operand);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
pointer get(T&, boost::false_type) const BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<pointer>(0);
|
||||
}
|
||||
|
||||
public: // visitor interfaces
|
||||
typedef pointer result_type;
|
||||
|
||||
template <typename U>
|
||||
pointer operator()(U& operand) const BOOST_NOEXCEPT
|
||||
{
|
||||
typedef boost::integral_constant<
|
||||
bool,
|
||||
boost::is_base_of<Base, U>::value || boost::is_same<Base, U>::value
|
||||
> tag_t;
|
||||
return get(operand, tag_t());
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
polymorphic_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_polymorphic_visitor<U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
polymorphic_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_polymorphic_visitor<const U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
polymorphic_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
U_ptr result = polymorphic_get<U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_polymorphic_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
polymorphic_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
U_ptr result = polymorphic_get<const U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_polymorphic_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
@@ -116,7 +116,7 @@ struct substitute<
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
typedef ::boost::variant<
|
||||
typename enable_recursive<
|
||||
@@ -131,7 +131,7 @@ struct substitute<
|
||||
>::type...
|
||||
> type;
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
@@ -154,7 +154,7 @@ private: // helpers, for metafunction result (below)
|
||||
public: // metafunction result
|
||||
|
||||
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
|
||||
#endif
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
|
||||
|
||||
@@ -346,20 +346,12 @@ public: // visitor interface
|
||||
return operand;
|
||||
}
|
||||
|
||||
#if defined BOOST_MSVC
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4702 ) // unreachable code
|
||||
#endif
|
||||
template <typename U>
|
||||
T& operator()(U&) const
|
||||
{
|
||||
// logical error to be here: see precondition above
|
||||
BOOST_ASSERT(false);
|
||||
return ::boost::detail::variant::forced_return< T& >();
|
||||
}
|
||||
#if defined BOOST_MSVC
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,16 +25,6 @@
|
||||
#include "boost/preprocessor/enum_shifted_params.hpp"
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_NO_REFERENCE_SUPPORT
|
||||
//
|
||||
@@ -67,11 +57,34 @@
|
||||
#include "boost/variant/detail/substitute_fwd.hpp"
|
||||
|
||||
#if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
//
|
||||
|
||||
/*
|
||||
GCC before 4.0 had no variadic tempaltes;
|
||||
GCC 4.6 has incomplete implementation of variadic templates.
|
||||
|
||||
MSVC2013 has variadic templates, but they have issues.
|
||||
*/
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
|
||||
|| (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) \
|
||||
|| (defined(_MSC_VER) && (_MSC_VER <= 1800)) \
|
||||
|| defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) \
|
||||
|| defined (BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
# define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
|
||||
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
|
||||
@@ -104,7 +117,7 @@
|
||||
// Rationale: Cleaner, simpler code for clients of variant library. Minimal
|
||||
// code modifications to move from C++03 to C++11.
|
||||
//
|
||||
// Without !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
// With BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES defined
|
||||
// will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else`
|
||||
//
|
||||
|
||||
@@ -117,7 +130,17 @@
|
||||
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
|
||||
/**/
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
|
||||
@@ -148,7 +171,8 @@
|
||||
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -188,7 +212,6 @@ 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)
|
||||
//
|
||||
// Defines void types that are each unique and specializations of
|
||||
@@ -217,11 +240,10 @@ BOOST_PP_REPEAT(
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
# define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
|
||||
//
|
||||
@@ -250,7 +272,7 @@ BOOST_PP_REPEAT(
|
||||
) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class template variant (concept inspired by Andrei Alexandrescu)
|
||||
|
||||
+13
-6
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Antony Polukhin 2012.
|
||||
// (C) Copyright Antony Polukhin 2012-2014.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -75,7 +75,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant(variant&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to.push_back(std::move(data_from[i]));
|
||||
data_to.push_back(boost::move(data_from[i]));
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -108,7 +108,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on same types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -142,7 +142,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -176,7 +176,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types II");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -210,7 +210,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(T&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(s2[i]);
|
||||
data_to[i] = boost::move(s2[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -222,6 +222,13 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
|
||||
|
||||
int main () {
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
std::cout << "# Running tests in C++11 mode (with rvalues).\n";
|
||||
#else
|
||||
std::cout << "# Running tests in C++03 mode (without rvalues).\n";
|
||||
#endif
|
||||
|
||||
do_test(false);
|
||||
do_test(true);
|
||||
}
|
||||
|
||||
+1
-7
@@ -16,13 +16,6 @@ project
|
||||
: requirements
|
||||
#<dependency>/boost/test//minimal
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
<toolset>gcc-4.8:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>gcc-4.9:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>clang-3.0:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>clang-3.1:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>clang-3.2:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>clang-3.3:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
<toolset>clang-3.4:<cxxflags>-DBOOST_VARIANT_USE_VARIADIC_TEMPLATES
|
||||
;
|
||||
|
||||
test-suite variant
|
||||
@@ -40,6 +33,7 @@ test-suite variant
|
||||
[ run variant_reference_test.cpp ]
|
||||
[ run variant_comparison_test.cpp ]
|
||||
[ run variant_visit_test.cpp ]
|
||||
[ run variant_polymorphic_get_test.cpp ]
|
||||
[ run variant_multivisit_test.cpp ]
|
||||
[ run hash_variant_test.cpp ]
|
||||
[ run rvalue_test.cpp ]
|
||||
|
||||
+15
-11
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011
|
||||
// Copyright (c) 2011-2014
|
||||
// Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
@@ -6,25 +6,28 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant/detail/hash_variant.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/functional/hash/hash.hpp"
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef boost::variant<bool, int, unsigned int, double> variant_type;
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
variant_type bool_variant1 = true;
|
||||
variant_type bool_variant2 = false;
|
||||
variant_type int_variant = 1;
|
||||
variant_type float_variant = 1.0;
|
||||
variant_type uint_variant = static_cast<unsigned int>(1);
|
||||
typedef boost::variant<bool, int, unsigned int, char> variant_type;
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
variant_type bool_variant1 = true;
|
||||
variant_type bool_variant2 = false;
|
||||
variant_type int_variant = 1;
|
||||
variant_type char_variant1 = '\1';
|
||||
variant_type char_variant2 = '\2';
|
||||
variant_type uint_variant = static_cast<unsigned int>(1);
|
||||
|
||||
BOOST_CHECK(hasher(bool_variant1) != hasher(bool_variant2));
|
||||
BOOST_CHECK(hasher(bool_variant1) == hasher(bool_variant1));
|
||||
BOOST_CHECK(hasher(int_variant) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(float_variant) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(char_variant1) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(char_variant1) != hasher(char_variant2));
|
||||
BOOST_CHECK(hasher(char_variant1) == hasher(char_variant1));
|
||||
BOOST_CHECK(hasher(char_variant2) == hasher(char_variant2));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
@@ -32,3 +35,4 @@ int test_main(int , char* [])
|
||||
run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,20 @@ int main( int argc, char* argv[] )
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#include <tuple>
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
struct vector_printer
|
||||
struct printer
|
||||
: boost::static_visitor<std::string>
|
||||
{
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
std::string operator()(
|
||||
const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &var) const
|
||||
{
|
||||
return boost::apply_visitor( printer(), var );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string operator()(const std::vector<T>& vec) const
|
||||
{
|
||||
@@ -61,13 +71,36 @@ struct vector_printer
|
||||
|
||||
typename std::vector<T>::const_iterator it = vec.begin();
|
||||
for (; it != vec.end(); ++it)
|
||||
ost << boost::apply_visitor( vector_printer(), *it );
|
||||
ost << printer()( *it );
|
||||
|
||||
ost << ") ";
|
||||
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
template <int...> struct indices {};
|
||||
template <typename... Ts, int... Is>
|
||||
std::string operator()(const std::tuple<Ts...>& tup, indices<Is...>)
|
||||
{
|
||||
std::ostringstream ost;
|
||||
ost << "( ";
|
||||
(void) (int []){0, (ost << printer()( std::get<Is>(tup) ), 0)... };
|
||||
ost << ") ";
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
template <int N, int... Is>
|
||||
struct make_indices : make_indices<N-1, N-1, Is...> {};
|
||||
template <int... Is>
|
||||
struct make_indices<0, Is...> : indices<Is...> {};
|
||||
template <typename... Ts>
|
||||
std::string operator()(const std::tuple<Ts...>& tup) const
|
||||
{
|
||||
return printer()(tup, make_indices<sizeof...(Ts)>());
|
||||
}
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
template <typename T>
|
||||
std::string operator()(const T& operand) const
|
||||
{
|
||||
@@ -91,7 +124,7 @@ void test_recursive_variant()
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
std::string result1( printer()(var1) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
@@ -108,7 +141,7 @@ void test_recursive_variant()
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
std::string result2( printer()(var2) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
@@ -135,7 +168,7 @@ void test_recursive_variant()
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var4(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
|
||||
std::string result3( printer()(var4) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
@@ -150,7 +183,7 @@ void test_recursive_variant()
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
std::string result5( printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
@@ -160,6 +193,21 @@ void test_recursive_variant()
|
||||
std::map<int, boost::recursive_variant_>
|
||||
>::type var6_t;
|
||||
var6_t var6;
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
typedef boost::make_recursive_variant<
|
||||
int,
|
||||
std::tuple<int, boost::recursive_variant_>
|
||||
>::type var7_t;
|
||||
var7_t var7 = 0;
|
||||
var7 = std::tuple<int, var7_t>(1, var7);
|
||||
var7 = std::tuple<int, var7_t>(2, var7);
|
||||
|
||||
std::string result7( printer()(var7) );
|
||||
|
||||
std::cout << "result7: " << result7 << '\n';
|
||||
BOOST_CHECK(result7 == "( 2 ( 1 0 ) ) ");
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
}
|
||||
|
||||
void test_recursive_variant_over()
|
||||
@@ -178,7 +226,7 @@ void test_recursive_variant_over()
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
std::string result1( printer()(var1) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
@@ -197,7 +245,7 @@ void test_recursive_variant_over()
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
std::string result2( printer()(var2) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
@@ -235,7 +283,7 @@ void test_recursive_variant_over()
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var3(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
|
||||
std::string result3( printer()(var3) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
@@ -252,7 +300,7 @@ void test_recursive_variant_over()
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
std::string result5( printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
|
||||
+41
-1
@@ -3,7 +3,7 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2012-2013 Antony Polukhin
|
||||
// Copyright (c) 2012-2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/type_traits/is_nothrow_move_assignable.hpp"
|
||||
#include "boost/mpl/bool.hpp"
|
||||
|
||||
// Most part of tests from this file require rvalue references support
|
||||
|
||||
@@ -189,6 +190,13 @@ private:
|
||||
move_only_structure& operator=(const move_only_structure&);
|
||||
};
|
||||
|
||||
struct visitor_returning_move_only_type: boost::static_visitor<move_only_structure> {
|
||||
template <class T>
|
||||
move_only_structure operator()(const T&) const {
|
||||
return move_only_structure();
|
||||
}
|
||||
};
|
||||
|
||||
void run_move_only()
|
||||
{
|
||||
move_only_structure mo;
|
||||
@@ -204,6 +212,9 @@ void run_move_only()
|
||||
vi = static_cast<move_only_structure&&>(mo);
|
||||
vi2 = static_cast<move_only_structure&&>(mo);
|
||||
BOOST_CHECK(vi.which() == 1);
|
||||
|
||||
move_only_structure from_visitor = boost::apply_visitor(visitor_returning_move_only_type(), vi);
|
||||
(void)from_visitor;
|
||||
}
|
||||
|
||||
void run_moves_are_noexcept() {
|
||||
@@ -256,6 +267,25 @@ void run_tricky_compilation_test()
|
||||
v = nothrow_copyable_throw_movable();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_container : boost::mpl::false_ {};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<boost::variant<T> > : is_container<T> {};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct is_container<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
: boost::mpl::bool_<is_container<T0>::value
|
||||
|| is_container<boost::variant<BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)> >::value>
|
||||
{};
|
||||
|
||||
void run_is_container_compilation_test()
|
||||
{
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int> >::value));
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int, char> >::value));
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int, char, float> >::value));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
run();
|
||||
@@ -264,5 +294,15 @@ int test_main(int , char* [])
|
||||
run_moves_are_noexcept();
|
||||
run_tricky_compilation_test();
|
||||
run_const_rvalues();
|
||||
run_is_container_compilation_test();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 6)
|
||||
# ifdef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
BOOST_CHECK(false &&
|
||||
"Something wrong with macro definitions. GCC-4.7+ is known to work with variadic templates"
|
||||
);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/variant_visit_test.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/variant/variant.hpp"
|
||||
#include "boost/variant/apply_visitor.hpp"
|
||||
#include "boost/variant/static_visitor.hpp"
|
||||
#include "boost/variant/polymorphic_get.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
struct base {int trash;};
|
||||
struct derived1 : base{};
|
||||
struct derived2 : base{};
|
||||
|
||||
struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
|
||||
struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
|
||||
struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
|
||||
struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
typedef boost::variant<int, base, derived1, derived2> var_t;
|
||||
|
||||
var_t var1;
|
||||
BOOST_CHECK(!boost::polymorphic_get<base>(&var1));
|
||||
|
||||
var1 = derived1();
|
||||
BOOST_CHECK(boost::polymorphic_get<base>(&var1));
|
||||
|
||||
derived2 d;
|
||||
d.trash = 777;
|
||||
var_t var2 = d;
|
||||
BOOST_CHECK(boost::polymorphic_get<base>(var2).trash == 777);
|
||||
|
||||
var2 = 777;
|
||||
BOOST_CHECK(!boost::polymorphic_get<base>(&var2));
|
||||
BOOST_CHECK(boost::polymorphic_get<int>(var2) == 777);
|
||||
|
||||
typedef boost::variant<int, vbase, vderived1, vderived2, vderived3> vvar_t;
|
||||
|
||||
vvar_t v = vderived3();
|
||||
boost::polymorphic_get<vderived3>(v).trash = 777;
|
||||
const vvar_t& cv = v;
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(cv).trash == 777);
|
||||
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(cv).foo() == 3);
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(v).foo() == 3);
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
Reference in New Issue
Block a user