mirror of
https://github.com/boostorg/variant.git
synced 2026-07-24 14:07:52 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3de4fd2fb1 | |||
| eb17a6afd8 | |||
| 3891cde7ed | |||
| 591ae9bf26 | |||
| 5b34fe155f | |||
| 2a6c6f3948 | |||
| c13372a092 | |||
| 64d68fc379 | |||
| 19ba44bb3f | |||
| 4d02fbcd84 | |||
| 4f4555fa93 | |||
| e0151cc209 | |||
| 3bc66e9264 | |||
| aa1eeb3b0f | |||
| a400952c16 | |||
| dcc25e1a1d | |||
| c7d1cccc13 | |||
| 5edc863174 | |||
| d465155ccc | |||
| ddf192fc53 | |||
| de56bdaa0a | |||
| 2d1dea19ba | |||
| 39469616d2 |
+7
-1
@@ -1,5 +1,11 @@
|
||||
project boost/doc ;
|
||||
import boostbook : boostbook ;
|
||||
|
||||
boostbook variant-doc : variant.xml ;
|
||||
boostbook variant-doc
|
||||
:
|
||||
variant.xml
|
||||
:
|
||||
<xsl:param>boost.root=../../../..
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
<rationale>
|
||||
<simpara>While visitation via
|
||||
<code><functionname>apply_visitor</functionname></code>
|
||||
is generally prefered due to its greater safety, <code>get</code> may
|
||||
is generally preferred due to its greater safety, <code>get</code> may
|
||||
may be more convenient in some cases due to its straightforward
|
||||
usage.</simpara>
|
||||
</rationale>
|
||||
|
||||
@@ -364,6 +364,11 @@
|
||||
</returns>
|
||||
|
||||
<throws>Will not throw.</throws>
|
||||
|
||||
<notes>
|
||||
<simpara>Not available when <code>BOOST_NO_TYPEID</code> is
|
||||
defined.</simpara>
|
||||
</notes>
|
||||
</method>
|
||||
|
||||
</method-group>
|
||||
@@ -536,6 +541,12 @@
|
||||
<simpara>Calls <code>out << x</code>, where <code>x</code> is
|
||||
the content of <code>rhs</code>.</simpara>
|
||||
</effects>
|
||||
|
||||
<notes>
|
||||
<simpara>Not available when <code>BOOST_NO_IOSTREAM</code> is
|
||||
defined.</simpara>
|
||||
</notes>
|
||||
|
||||
</function>
|
||||
|
||||
<class name="make_variant_over">
|
||||
|
||||
@@ -343,7 +343,7 @@ seq2.push_back(3.14);
|
||||
|
||||
are_strict_equals visitor;
|
||||
assert( std::equal(
|
||||
v1.begin(), v1.end(), v2.begin()
|
||||
seq1.begin(), seq1.end(), seq2.begin()
|
||||
, <functionname>boost::apply_visitor</functionname>( visitor )
|
||||
) );</programlisting>
|
||||
|
||||
|
||||
@@ -83,9 +83,9 @@ str += " world! ";</programlisting>
|
||||
|
||||
<programlisting>void times_two( boost::variant< int, std::string > & operand )
|
||||
{
|
||||
if ( int* pi = <functionname>boost::get</functionname><int>( &v ) )
|
||||
if ( int* pi = <functionname>boost::get</functionname><int>( &operand ) )
|
||||
*pi *= 2;
|
||||
else if ( std::string* pstr = <functionname>boost::get</functionname><std::string>( &v ) )
|
||||
else if ( std::string* pstr = <functionname>boost::get</functionname><std::string>( &operand ) )
|
||||
*pstr += *pstr;
|
||||
}</programlisting>
|
||||
|
||||
|
||||
+5
-10
@@ -21,16 +21,11 @@
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>Permission to copy, use, sell and distribute this software
|
||||
is granted provided this copyright notice appears in all copies.
|
||||
Permission to modify the code and to distribute modified code is
|
||||
granted provided this copyright notice appears in all copies, and
|
||||
a notice that the code was modified is included with the copyright
|
||||
notice.</para>
|
||||
|
||||
<para> This software is provided "as is" without express or
|
||||
implied warranty, and with no claim as to its suitability for any
|
||||
purpose.</para>
|
||||
<para>Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at
|
||||
<ulink
|
||||
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<librarypurpose>Safe, generic, stack-based discriminated union container</librarypurpose>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
// See http://www.boost.org/libs/variant for documentation.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
|
||||
#include "boost/variant/detail/apply_visitor_unary.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
||||
#include "boost/utility/enable_if.hpp"
|
||||
#include "boost/mpl/not.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -63,6 +67,9 @@ public: // visitor interfaces
|
||||
return visitor_(value1_, value2);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor, typename Visitable2>
|
||||
@@ -100,6 +107,9 @@ public: // visitor interfaces
|
||||
return boost::apply_visitor(invoker, visitable2_);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
@@ -58,7 +58,7 @@ public: // unary visitor interface
|
||||
|
||||
template <typename Visitable>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
||||
operator()(Visitable& visitable)
|
||||
operator()(Visitable& visitable) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitable);
|
||||
}
|
||||
@@ -67,11 +67,14 @@ public: // binary visitor interface
|
||||
|
||||
template <typename Visitable1, typename Visitable2>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
||||
operator()(Visitable1& visitable1, Visitable2& visitable2)
|
||||
operator()(Visitable1& visitable1, Visitable2& visitable2) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitable1, visitable2);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor>
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
||||
#include "boost/utility/enable_if.hpp"
|
||||
#include "boost/mpl/not.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
|
||||
#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/assert.hpp"
|
||||
|
||||
namespace boost {
|
||||
@@ -32,7 +33,7 @@ public: // structors
|
||||
delete backup_;
|
||||
}
|
||||
|
||||
explicit backup_holder(T* backup)
|
||||
explicit backup_holder(T* backup) BOOST_NOEXCEPT
|
||||
: backup_(backup)
|
||||
{
|
||||
}
|
||||
@@ -53,7 +54,7 @@ public: // modifiers
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(backup_holder& rhs)
|
||||
void swap(backup_holder& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
T* tmp = rhs.backup_;
|
||||
rhs.backup_ = this->backup_;
|
||||
@@ -83,7 +84,7 @@ backup_holder<T>::backup_holder(const backup_holder&)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs)
|
||||
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/hash_variant.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2011
|
||||
// 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_HASH_VARIANT_FUNCTION_HPP
|
||||
#define BOOST_HASH_VARIANT_FUNCTION_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail { namespace variant {
|
||||
struct variant_hasher: public boost::static_visitor<std::size_t> {
|
||||
template <class T>
|
||||
std::size_t operator()(T const& val) const {
|
||||
using namespace boost;
|
||||
hash<T> hasher;
|
||||
return hasher(val);
|
||||
}
|
||||
};
|
||||
}}
|
||||
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
std::size_t hash_value(variant< BOOST_VARIANT_ENUM_PARAMS(T) > const& val) {
|
||||
std::size_t seed = boost::apply_visitor(detail::variant::variant_hasher(), val);
|
||||
hash_combine(seed, val.which());
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "boost/call_traits.hpp"
|
||||
#include "boost/detail/reference_content.hpp"
|
||||
#include "boost/variant/recursive_wrapper_fwd.hpp"
|
||||
#include "boost/variant/detail/move.hpp"
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
# include "boost/mpl/aux_/value_wknd.hpp"
|
||||
@@ -79,8 +80,22 @@ struct make_initializer_node
|
||||
recursive_enabled_T;
|
||||
typedef typename unwrap_recursive<recursive_enabled_T>::type
|
||||
public_T;
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef boost::is_reference<public_T>
|
||||
is_reference_content_t;
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, public_T, const public_T& >::type
|
||||
param_T;
|
||||
|
||||
template <class T> struct disable_overload{};
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, disable_overload<public_T>, public_T&& >::type
|
||||
param2_T;
|
||||
#else
|
||||
typedef typename call_traits<public_T>::param_type
|
||||
param_T;
|
||||
#endif
|
||||
|
||||
public: // static functions
|
||||
|
||||
@@ -96,6 +111,18 @@ struct make_initializer_node
|
||||
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
static int initialize(void* dest, param2_T operand)
|
||||
{
|
||||
// This assert must newer trigger, because all the reference contents are
|
||||
// handled by the initilize(void* dest, param_T operand) function above
|
||||
BOOST_ASSERT(!is_reference_content_t::value);
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, param2_T, recursive_enabled_T>::type value_T;
|
||||
new(dest) value_T( boost::detail::variant::move(operand) );
|
||||
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
friend class initializer_node;
|
||||
|
||||
@@ -82,6 +82,8 @@ public: // metafunction result
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
typename detail::move_type<T>::type
|
||||
@@ -93,6 +95,12 @@ move(T& source)
|
||||
return move_t(source);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using std::move;
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// class template return_t
|
||||
//
|
||||
|
||||
@@ -64,6 +64,9 @@ public: // visitor interface
|
||||
out_ << operand;
|
||||
}
|
||||
|
||||
private:
|
||||
printer& operator=(const printer&);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
#include "boost/type_traits/has_nothrow_copy.hpp"
|
||||
#include "boost/variant/detail/has_nothrow_move.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable : 4702) //unreachable code
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
|
||||
@@ -163,7 +167,7 @@ visitation_impl_invoke(
|
||||
, has_nothrow_copy<T>
|
||||
>::type never_uses_backup;
|
||||
|
||||
return visitation_impl_invoke_impl(
|
||||
return (visitation_impl_invoke_impl)(
|
||||
internal_which, visitor, storage, t
|
||||
, never_uses_backup()
|
||||
);
|
||||
@@ -242,7 +246,7 @@ visitation_impl(
|
||||
// ...applying the appropriate case:
|
||||
# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
|
||||
case (Which::value + (N)): \
|
||||
return visitation_impl_invoke( \
|
||||
return (visitation_impl_invoke)( \
|
||||
internal_which, visitor, storage \
|
||||
, static_cast<BOOST_PP_CAT(T,N)*>(0) \
|
||||
, no_backup_flag, 1L \
|
||||
@@ -257,6 +261,7 @@ visitation_impl(
|
||||
|
||||
# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
// If not handled in this iteration, continue unrolling:
|
||||
@@ -283,4 +288,8 @@ visitation_impl(
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
|
||||
#include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
# include "boost/mpl/eval_if.hpp"
|
||||
# include "boost/mpl/identity.hpp"
|
||||
# include "boost/mpl/protect.hpp"
|
||||
# include "boost/mpl/transform.hpp"
|
||||
#else
|
||||
# include "boost/preprocessor/cat.hpp"
|
||||
# include "boost/preprocessor/repeat.hpp"
|
||||
#endif
|
||||
#include "boost/mpl/equal.hpp"
|
||||
#include "boost/mpl/eval_if.hpp"
|
||||
#include "boost/mpl/identity.hpp"
|
||||
#include "boost/mpl/if.hpp"
|
||||
#include "boost/mpl/protect.hpp"
|
||||
#include "boost/mpl/transform.hpp"
|
||||
#include "boost/type_traits/is_same.hpp"
|
||||
#include "boost/preprocessor/cat.hpp"
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/is_sequence.hpp"
|
||||
@@ -74,34 +74,48 @@ template <
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
::boost::variant<
|
||||
::boost::detail::variant::over_sequence< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
>
|
||||
, RecursiveVariant
|
||||
, ::boost::recursive_variant_
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
::boost::detail::variant::is_over_sequence<T0>
|
||||
, mpl::identity< T0 >
|
||||
, make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
>::type initial_types;
|
||||
typedef T0 initial_types;
|
||||
|
||||
typedef typename mpl::transform<
|
||||
initial_types
|
||||
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
|
||||
>::type types;
|
||||
|
||||
public: // metafunction result
|
||||
public:
|
||||
|
||||
typedef ::boost::variant< types > type;
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
typedef typename mpl::if_<
|
||||
mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
|
||||
, ::boost::variant<
|
||||
::boost::detail::variant::over_sequence< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
>
|
||||
, ::boost::variant< over_sequence<types> >
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
, typename RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
, RecursiveVariant
|
||||
, ::boost::recursive_variant_
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
|
||||
@@ -123,9 +137,6 @@ private: // helpers, for metafunction result (below)
|
||||
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_DETAIL_NO_SUBSTITUTE)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define BOOST_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
|
||||
#include "boost/variant/recursive_wrapper_fwd.hpp"
|
||||
#include "boost/variant/detail/move.hpp"
|
||||
#include "boost/checked_delete.hpp"
|
||||
|
||||
namespace boost {
|
||||
@@ -43,6 +44,11 @@ public: // structors
|
||||
recursive_wrapper(const recursive_wrapper& operand);
|
||||
recursive_wrapper(const T& operand);
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
recursive_wrapper(recursive_wrapper&& operand);
|
||||
recursive_wrapper(T&& operand);
|
||||
#endif
|
||||
|
||||
private: // helpers, for modifiers (below)
|
||||
|
||||
void assign(const T& rhs);
|
||||
@@ -61,13 +67,28 @@ public: // modifiers
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(recursive_wrapper& operand)
|
||||
void swap(recursive_wrapper& operand) BOOST_NOEXCEPT
|
||||
{
|
||||
T* temp = operand.p_;
|
||||
operand.p_ = p_;
|
||||
p_ = temp;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
recursive_wrapper& operator=(recursive_wrapper&& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
recursive_wrapper& operator=(T&& rhs)
|
||||
{
|
||||
get() = detail::variant::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
public: // queries
|
||||
|
||||
T& get() { return *get_pointer(); }
|
||||
@@ -102,6 +123,20 @@ recursive_wrapper<T>::recursive_wrapper(const T& operand)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
|
||||
: p_(new T( detail::variant::move(operand.get()) ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T&& operand)
|
||||
: p_(new T( detail::variant::move(operand) ))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void recursive_wrapper<T>::assign(const T& rhs)
|
||||
{
|
||||
@@ -113,7 +148,7 @@ void recursive_wrapper<T>::assign(const T& rhs)
|
||||
// Swaps two recursive_wrapper<T> objects of the same type T.
|
||||
//
|
||||
template <typename T>
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs)
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -229,7 +229,7 @@ template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant;
|
||||
// Tag type indicates where recursive variant substitution should occur.
|
||||
//
|
||||
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
struct recursive_variant_;
|
||||
struct recursive_variant_ {};
|
||||
#else
|
||||
typedef mpl::arg<1> recursive_variant_;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#==============================================================================
|
||||
# Copyright (c) 2012 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)
|
||||
#==============================================================================
|
||||
|
||||
# performance tests
|
||||
import testing ;
|
||||
import path ;
|
||||
|
||||
path-constant TEST_DIR : . ;
|
||||
|
||||
project performance/test
|
||||
: source-location ./
|
||||
: requirements
|
||||
# <library>/boost/chrono//boost_chrono
|
||||
# <library>/boost/system//boost_system
|
||||
<link>static
|
||||
<target-os>freebsd:<linkflags>"-lrt"
|
||||
<target-os>linux:<linkflags>"-lrt"
|
||||
<toolset>gcc:<cxxflags>-fvisibility=hidden
|
||||
<toolset>intel-linux:<cxxflags>-fvisibility=hidden
|
||||
<toolset>sun:<cxxflags>-xldscope=hidden
|
||||
: default-build release
|
||||
;
|
||||
|
||||
run move_perf.cpp : $(TEST_DIR) ;
|
||||
|
||||
Executable
+229
@@ -0,0 +1,229 @@
|
||||
// (C) Copyright Antony Polukhin 2012.
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org/libs/config for most recent version.
|
||||
|
||||
//
|
||||
// Testing variant performance rvalue copy/assign performance
|
||||
//
|
||||
|
||||
#define BOOST_ERROR_CODE_HEADER_ONLY
|
||||
#define BOOST_CHRONO_HEADER_ONLY
|
||||
#include <boost/chrono.hpp>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct scope {
|
||||
typedef boost::chrono::steady_clock test_clock;
|
||||
typedef boost::chrono::milliseconds duration_t;
|
||||
test_clock::time_point start_;
|
||||
const char* const message_;
|
||||
|
||||
explicit scope(const char* const message)
|
||||
: start_(test_clock::now())
|
||||
, message_(message)
|
||||
{}
|
||||
|
||||
~scope() {
|
||||
std::cout << message_ << " " << boost::chrono::duration_cast<duration_t>(test_clock::now() - start_) << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void do_test(bool do_count_cleanup_time = false) {
|
||||
BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
|
||||
typedef std::vector<char> str_t;
|
||||
typedef boost::variant<int, str_t, float> var_t;
|
||||
|
||||
const char hello1_c[] = "hello long word";
|
||||
const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));
|
||||
|
||||
const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
|
||||
const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
std::cout << "#############################################\n";
|
||||
std::cout << "#############################################\n";
|
||||
std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
|
||||
std::cout << "#############################################\n";
|
||||
}
|
||||
|
||||
std::vector<var_t> data_from, data_to;
|
||||
data_from.resize(c_run_count, hello1);
|
||||
data_to.reserve(c_run_count);
|
||||
{
|
||||
scope sc("boost::variant(const variant&) copying speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to.push_back(data_from[i]);
|
||||
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello1);
|
||||
data_to.clear();
|
||||
data_to.reserve(c_run_count);
|
||||
{
|
||||
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]));
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on same types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, hello2);
|
||||
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on different types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, var_t(0));
|
||||
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on different types II");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, var_t(0));
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
std::vector<str_t> s1(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
|
||||
{
|
||||
scope sc("boost::variant=(const T&) copying speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = s1[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
s1.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<str_t> s2(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
s2.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
do_test(false);
|
||||
do_test(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Boost.Variant Library test Jamfile
|
||||
#
|
||||
# Copyright (C) 2003, Eric Friedman, Itay Maman.
|
||||
#
|
||||
# This material is provided "as is", with absolutely no warranty expressed
|
||||
# or implied. Any use is at your own risk.
|
||||
#
|
||||
# Permission to use or copy this software for any purpose is hereby granted
|
||||
# without fee, provided the above notices are retained on all copies.
|
||||
# Permission to modify the code and to distribute modified code is granted,
|
||||
# provided the above notices are retained, and a notice that the code was
|
||||
# modified is included with the above copyright notice.
|
||||
#
|
||||
|
||||
subproject libs/variant/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
# Make tests run by default.
|
||||
DEPENDS all : test ;
|
||||
|
||||
{
|
||||
# look in BOOST_ROOT for sources first, just in this Jamfile
|
||||
local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
|
||||
|
||||
test-suite variant
|
||||
:
|
||||
[ run libs/variant/test/test1.cpp libs/variant/test/class_a.cpp
|
||||
: : : : variant_test1 ]
|
||||
[ run libs/variant/test/test2.cpp
|
||||
: : : : variant_test2 ]
|
||||
[ run libs/variant/test/test3.cpp
|
||||
: : : : variant_test3 ]
|
||||
[ run libs/variant/test/test4.cpp libs/variant/test/class_a.cpp
|
||||
: : : : variant_test4 ]
|
||||
[ run libs/variant/test/test5.cpp
|
||||
: : : : variant_test5 ]
|
||||
[ run libs/variant/test/test6.cpp
|
||||
: : : : variant_test6 ]
|
||||
[ run libs/variant/test/test7.cpp
|
||||
: : : : variant_test7 ]
|
||||
[ run libs/variant/test/test8.cpp
|
||||
: : : : variant_test8 ]
|
||||
[ run libs/variant/test/recursive_variant_test.cpp ]
|
||||
[ run libs/variant/test/variant_reference_test.cpp ]
|
||||
[ run libs/variant/test/variant_comparison_test.cpp ]
|
||||
[ run libs/variant/test/variant_visit_test.cpp ]
|
||||
;
|
||||
}
|
||||
@@ -11,6 +11,11 @@
|
||||
# provided the above notices are retained, and a notice that the code was
|
||||
# modified is included with the above copyright notice.
|
||||
#
|
||||
project
|
||||
: requirements
|
||||
#<dependency>/boost/test//minimal
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
;
|
||||
|
||||
test-suite variant
|
||||
:
|
||||
@@ -27,4 +32,8 @@ test-suite variant
|
||||
[ run variant_reference_test.cpp ]
|
||||
[ run variant_comparison_test.cpp ]
|
||||
[ run variant_visit_test.cpp ]
|
||||
[ run hash_variant_test.cpp ]
|
||||
[ run rvalue_test.cpp ]
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2011
|
||||
// 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)
|
||||
|
||||
#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);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
run();
|
||||
return 0;
|
||||
}
|
||||
+4
-23
@@ -232,29 +232,6 @@ struct int_adder : boost::static_visitor<>
|
||||
|
||||
|
||||
|
||||
|
||||
struct held_type_name : boost::static_visitor<std::string>
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
std::string operator()(const T& ) const
|
||||
{
|
||||
ost_ << '[' << typeid(T).name() << ']';
|
||||
return result();
|
||||
}
|
||||
|
||||
std::string result() const
|
||||
{
|
||||
return ost_.str();
|
||||
}
|
||||
|
||||
mutable std::ostringstream ost_;
|
||||
|
||||
}; //held_type_name
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct spec
|
||||
{
|
||||
@@ -267,7 +244,9 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
|
||||
const VariantType& cvar = var;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() == typeid(S));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
@@ -316,7 +295,9 @@ inline void verify_not(VariantType& var, spec<S>)
|
||||
{
|
||||
const VariantType& cvar = var;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() != typeid(S));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
|
||||
+181
-11
@@ -12,10 +12,13 @@
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/mpl/vector.hpp"
|
||||
#include "boost/mpl/copy.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
struct vector_printer
|
||||
: boost::static_visitor<std::string>
|
||||
@@ -45,24 +48,191 @@ struct vector_printer
|
||||
}
|
||||
};
|
||||
|
||||
int test_main(int , char* [])
|
||||
void test_recursive_variant()
|
||||
{
|
||||
typedef boost::make_recursive_variant<
|
||||
int
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>::type var_t;
|
||||
>::type var1_t;
|
||||
|
||||
std::vector<var_t> vec;
|
||||
vec.push_back(3);
|
||||
vec.push_back(5);
|
||||
vec.push_back(vec);
|
||||
vec.push_back(7);
|
||||
std::vector<var1_t> vec1;
|
||||
vec1.push_back(3);
|
||||
vec1.push_back(5);
|
||||
vec1.push_back(vec1);
|
||||
vec1.push_back(7);
|
||||
|
||||
var_t var(vec);
|
||||
std::string result( boost::apply_visitor( vector_printer(), var ) );
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
|
||||
std::cout << "result: " << result << '\n';
|
||||
BOOST_CHECK(result == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
boost::variant<int, double>
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>::type var2_t;
|
||||
|
||||
std::vector<var2_t> vec2;
|
||||
vec2.push_back(boost::variant<int, double>(3));
|
||||
vec2.push_back(boost::variant<int, double>(3.5));
|
||||
vec2.push_back(vec2);
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
int
|
||||
, std::vector<
|
||||
boost::variant<
|
||||
double
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>
|
||||
>::type var3_t;
|
||||
|
||||
typedef boost::variant<double, std::vector<var3_t> > var4_t;
|
||||
|
||||
std::vector<var3_t> vec3;
|
||||
vec3.push_back(3);
|
||||
vec3.push_back(5);
|
||||
std::vector<var4_t> vec4;
|
||||
vec4.push_back(3.5);
|
||||
vec4.push_back(vec3);
|
||||
vec3.push_back(vec4);
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var4(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
double,
|
||||
std::vector<var1_t>
|
||||
>::type var5_t;
|
||||
|
||||
std::vector<var5_t> vec5;
|
||||
vec5.push_back(3.5);
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
int,
|
||||
std::map<int, boost::recursive_variant_>
|
||||
>::type var6_t;
|
||||
var6_t var6;
|
||||
}
|
||||
|
||||
void test_recursive_variant_over()
|
||||
{
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
int
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type var1_t;
|
||||
|
||||
std::vector<var1_t> vec1;
|
||||
vec1.push_back(3);
|
||||
vec1.push_back(5);
|
||||
vec1.push_back(vec1);
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
boost::make_variant_over<boost::mpl::vector<int, double> >::type
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type var2_t;
|
||||
|
||||
std::vector<var2_t> vec2;
|
||||
vec2.push_back(boost::variant<int, double>(3));
|
||||
vec2.push_back(boost::variant<int, double>(3.5));
|
||||
vec2.push_back(vec2);
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
int
|
||||
, std::vector<
|
||||
boost::make_variant_over<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type
|
||||
>
|
||||
>
|
||||
>::type var3_t;
|
||||
|
||||
typedef boost::make_variant_over<
|
||||
boost::mpl::copy<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<var3_t>
|
||||
>
|
||||
>::type
|
||||
>::type var4_t;
|
||||
|
||||
std::vector<var3_t> vec3;
|
||||
vec3.push_back(3);
|
||||
vec3.push_back(5);
|
||||
std::vector<var4_t> vec4;
|
||||
vec4.push_back(3.5);
|
||||
vec4.push_back(vec3);
|
||||
vec3.push_back(vec4);
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var3(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<var1_t>
|
||||
>
|
||||
>::type var5_t;
|
||||
|
||||
std::vector<var5_t> vec5;
|
||||
vec5.push_back(3.5);
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
test_recursive_variant();
|
||||
test_recursive_variant_over();
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/rvalue_test.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2012
|
||||
// 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)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
// This test requires rvalue references support
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
void run()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
void run1()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
void run_move_only()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
class move_copy_conting_class {
|
||||
public:
|
||||
static unsigned int moves_count;
|
||||
static unsigned int copy_count;
|
||||
|
||||
move_copy_conting_class(){}
|
||||
move_copy_conting_class(move_copy_conting_class&&) {
|
||||
++ moves_count;
|
||||
}
|
||||
|
||||
move_copy_conting_class& operator=(move_copy_conting_class&&) {
|
||||
++ moves_count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
move_copy_conting_class(const move_copy_conting_class&) {
|
||||
++ copy_count;
|
||||
}
|
||||
move_copy_conting_class& operator=(const move_copy_conting_class&) {
|
||||
++ copy_count;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int move_copy_conting_class::moves_count = 0;
|
||||
unsigned int move_copy_conting_class::copy_count = 0;
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef boost::variant<int, move_copy_conting_class> variant_I_type;
|
||||
variant_I_type v1, v2;
|
||||
|
||||
// Assuring that `move_copy_conting_class` was not created
|
||||
BOOST_CHECK(move_copy_conting_class::copy_count == 0);
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count == 0);
|
||||
|
||||
v1 = move_copy_conting_class();
|
||||
// Assuring that `move_copy_conting_class` was moved at least once
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
|
||||
unsigned int total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
|
||||
move_copy_conting_class var;
|
||||
v1 = 0;
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v1 = var;
|
||||
// Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
|
||||
BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
|
||||
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v2 = static_cast<variant_I_type&&>(v1);
|
||||
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
BOOST_CHECK(move_copy_conting_class::copy_count == 0);
|
||||
|
||||
v1 = move_copy_conting_class();
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v2 = static_cast<variant_I_type&&>(v1);
|
||||
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
BOOST_CHECK(move_copy_conting_class::copy_count == 0);
|
||||
total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v1 = v2;
|
||||
// Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
|
||||
BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
|
||||
|
||||
|
||||
typedef boost::variant<move_copy_conting_class, int> variant_II_type;
|
||||
variant_II_type v3;
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v1 = static_cast<variant_II_type&&>(v3);
|
||||
// Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
v2 = static_cast<variant_I_type&&>(v1);
|
||||
// Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
variant_I_type v5(static_cast<variant_I_type&&>(v1));
|
||||
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count != 0);
|
||||
BOOST_CHECK(move_copy_conting_class::copy_count == 0);
|
||||
|
||||
total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
variant_I_type v6(v1);
|
||||
// Assuring that move constructor moves/copyes value not more times than copy constructor
|
||||
BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
|
||||
}
|
||||
|
||||
void run1()
|
||||
{
|
||||
move_copy_conting_class::moves_count = 0;
|
||||
move_copy_conting_class::copy_count = 0;
|
||||
|
||||
move_copy_conting_class c1;
|
||||
typedef boost::variant<int, move_copy_conting_class> variant_I_type;
|
||||
variant_I_type v1(static_cast<move_copy_conting_class&&>(c1));
|
||||
|
||||
// Assuring that `move_copy_conting_class` was not copyied
|
||||
BOOST_CHECK(move_copy_conting_class::copy_count == 0);
|
||||
BOOST_CHECK(move_copy_conting_class::moves_count > 0);
|
||||
}
|
||||
|
||||
struct move_only_structure {
|
||||
move_only_structure(){}
|
||||
move_only_structure(move_only_structure&&){}
|
||||
move_only_structure& operator=(move_only_structure&&) { return *this; }
|
||||
|
||||
private:
|
||||
move_only_structure(const move_only_structure&);
|
||||
move_only_structure& operator=(const move_only_structure&);
|
||||
};
|
||||
|
||||
void run_move_only()
|
||||
{
|
||||
move_only_structure mo;
|
||||
boost::variant<int, move_only_structure > vi, vi2(static_cast<move_only_structure&&>(mo));
|
||||
BOOST_CHECK(vi.which() == 0);
|
||||
BOOST_CHECK(vi2.which() == 1);
|
||||
|
||||
vi = 10;
|
||||
vi2 = 10;
|
||||
BOOST_CHECK(vi.which() == 0);
|
||||
BOOST_CHECK(vi2.which() == 0);
|
||||
|
||||
vi = static_cast<move_only_structure&&>(mo);
|
||||
vi2 = static_cast<move_only_structure&&>(mo);
|
||||
BOOST_CHECK(vi.which() == 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
run();
|
||||
run1();
|
||||
run_move_only();
|
||||
return 0;
|
||||
}
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from const int to const short
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
|
||||
+7
-2
@@ -11,6 +11,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
@@ -38,10 +43,10 @@ struct short_string
|
||||
using std::strlen;
|
||||
#endif // BOOST_NO_STDC_NAMESPACE
|
||||
|
||||
size_t e_limit = this->e_limit; // avoid warnings on some compilers
|
||||
size_t limit = this->e_limit; // avoid warnings on some compilers
|
||||
size_t src_len = strlen(src);
|
||||
|
||||
len_ = (std::min)(src_len, e_limit-1);
|
||||
len_ = (std::min)(src_len, limit-1);
|
||||
std::copy(src, src + len_, buffer_);
|
||||
buffer_[len_] = '\0';
|
||||
}
|
||||
|
||||
@@ -122,7 +122,9 @@ int test_main(int, char* [])
|
||||
std::ostringstream e1_str;
|
||||
e1_str << e1;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(e1.type() == typeid(Add));
|
||||
#endif
|
||||
BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))");
|
||||
|
||||
//Evaluate expression
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
@@ -197,6 +203,9 @@ public:
|
||||
|
||||
ValueType& expected_;
|
||||
|
||||
private:
|
||||
compare_helper& operator=(const compare_helper&);
|
||||
|
||||
};
|
||||
|
||||
template<typename VariantType, typename ExpectedType>
|
||||
|
||||
@@ -63,6 +63,7 @@ void check_fail(Variant& v)
|
||||
try
|
||||
{
|
||||
T& r = get<T>(v);
|
||||
(void)r; // suppress warning about r not being used
|
||||
BOOST_CHECK(false && &r); // should never reach
|
||||
}
|
||||
catch(boost::bad_get&)
|
||||
@@ -110,3 +111,4 @@ int test_main(int , char* [])
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user