Compare commits

..

4 Commits

Author SHA1 Message Date
nobody ddf192fc53 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Rene Rivera de56bdaa0a Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Gennaro Prota 2d1dea19ba manual merge from trunk: fixed typos reported in http://bugs.debian.org/378016
[SVN r34637]
2006-07-20 14:06:13 +00:00
nobody 39469616d2 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
55 changed files with 934 additions and 2693 deletions
+1 -7
View File
@@ -1,11 +1,5 @@
project boost/doc ;
import boostbook : boostbook ;
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
;
boostbook variant-doc : variant.xml ;
+1 -62
View File
@@ -146,60 +146,6 @@
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type</type>
<parameter name="visitor">
<paramtype>MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2 &amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3 &amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type</type>
<parameter name="visitor">
<paramtype>const MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2 &amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3 &amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Visitor"/>
@@ -233,13 +179,6 @@
the given <code><classname>variant</classname></code>
operands.</listitem>
<listitem>Overloads accepting three or more operands invoke the
function call operator of the given visitor on the content of
the given <code><classname>variant</classname></code>
operands. Maximum amount of parameters controlled by
<code><emphasis role="bold"><macroname>BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS</macroname></emphasis></code>
macro. Those functions are actually defined in <xref linkend="header.boost.variant.multivisitors_hpp"/>.</listitem>
<listitem>The overload accepting only a visitor returns a
<classname alt="boost::apply_visitor_delayed_t">generic function object</classname>
that accepts either one or two arguments and invokes
@@ -277,4 +216,4 @@
</throws>
</overloaded-function>
</namespace>
</header>
</header>
+1 -23
View File
@@ -11,7 +11,7 @@
are as follows:</para>
<itemizedlist>
<listitem><conceptname>CopyConstructible</conceptname> or <conceptname>MoveConstructible</conceptname>.</listitem>
<listitem><conceptname>CopyConstructible</conceptname> [20.1.3].</listitem>
<listitem>Destructor upholds the no-throw exception-safety
guarantee.</listitem>
<listitem>Complete at the point of <code>variant</code> template
@@ -34,12 +34,6 @@
concept. (Note that top-level <code>const</code>-qualified types and
reference types do <emphasis>not</emphasis> meet these
requirements.)</listitem>
<listitem><conceptname>MoveAssignable</conceptname>:
<code>variant</code> is itself <emphasis>MoveAssignable</emphasis> if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level <code>const</code>-qualified types and
reference types do <emphasis>not</emphasis> meet these
requirements.)</listitem>
<listitem><conceptname>DefaultConstructible</conceptname> [20.1.4]:
<code>variant</code> is itself
<conceptname>DefaultConstructible</conceptname> if and only if its first
@@ -57,10 +51,6 @@
<code>variant</code> is itself <emphasis>OutputStreamable</emphasis>
if and only if every one of its bounded types meets the requirements
of the concept.</listitem>
<listitem><link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>:
<code>variant</code> is itself <emphasis>Hashable</emphasis>
if and only if every one of its bounded types meets the requirements
of the concept.</listitem>
</itemizedlist>
</section>
@@ -139,16 +129,4 @@ public:
</itemizedlist>
</section>
<section id="variant.concepts.hashable">
<title><emphasis>Hashable</emphasis></title>
<para>The requirements on an <emphasis role="bold">hashable</emphasis> type <code>T</code> are as follows:</para>
<itemizedlist>
<listitem>For any object <code>t</code> of type <code>T</code>,
<code>boost::hash&lt;T&gt;()(t)</code> must be a valid
expression.</listitem>
</itemizedlist>
</section>
</section>
-88
View File
@@ -1,88 +0,0 @@
<?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/multivisitors.hpp">
<using-namespace name="boost"/>
<para>Provides declarations of <functionname>apply_visitor</functionname> for three or more
<code><classname>variant</classname></code> parameters.</para>
<macro name="BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS">
<purpose>
<simpara>Controls maximum amount of <code><classname>variant</classname></code>
parameters for multi visistors. </simpara>
</purpose>
<description>
<para><emphasis role="bold">Note</emphasis>: Default amount is 4. Define it
to bigger value before including &lt;boost/variant/multivisitors.hpp&gt; to
increase maximum amount of <code><classname>variant</classname></code>
parameters for <functionname>apply_visitor</functionname>.</para>
</description>
</macro>
<namespace name="boost">
<overloaded-function name="apply_visitor /*three or more variant parameters*/">
<description>
<simpara>Allows compile-time checked type-safe application of the
given visitor to the content of the given variant, ensuring that all
types are handled by the visitor. See <functionname>apply_visitor</functionname>
for more information.</simpara>
</description>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type</type>
<parameter name="visitor">
<paramtype>MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2 &amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3 &amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type</type>
<parameter name="visitor">
<paramtype>const MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2 &amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3 &amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
</overloaded-function>
</namespace>
</header>
+2 -3
View File
@@ -8,7 +8,7 @@
<header name="boost/variant.hpp">
<section id="variant.header.include-all">
<para>This header exists simply as a convenience to the user, including
all of the headers in the <code>boost/variant</code> directory except &lt;boost/multivisiors.hpp&gt;.</para>
all of the headers in the <code>boost/variant</code> directory.</para>
</section>
</header>
@@ -17,9 +17,8 @@
<xi:include href="recursive_variant.xml"/>
<xi:include href="recursive_wrapper.xml"/>
<xi:include href="apply_visitor.xml"/>
<xi:include href="multivisitor.xml"/>
<xi:include href="get.xml"/>
<xi:include href="bad_visit.xml"/>
<xi:include href="static_visitor.xml"/>
<xi:include href="visitor_ptr.xml"/>
</library-reference>
</library-reference>
+3 -195
View File
@@ -110,26 +110,6 @@
copy constructor of <code>other</code>'s contained type.</simpara>
</throws>
</constructor>
<constructor>
<parameter name="other">
<paramtype>variant &amp;&amp;</paramtype>
</parameter>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<postconditions>
<simpara>Content of <code>*this</code> is move constructed from the content of
<code>other</code>.</simpara>
</postconditions>
<throws>
<simpara>May fail with any exceptions arising from the
move constructor of <code>other</code>'s contained type.</simpara>
</throws>
</constructor>
<constructor>
<template>
@@ -172,25 +152,6 @@
construction from temporaries.</simpara>
</notes>
</constructor>
<constructor>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="operand">
<paramtype>T &amp;&amp;</paramtype>
</parameter>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<notes>
<simpara>Same semantics as previous constructor, but allows
move construction if <code>operand</code> is an rvalue.</simpara>
</notes>
</constructor>
<constructor>
<template>
@@ -247,28 +208,6 @@
construction from temporaries.</simpara>
</notes>
</constructor>
<constructor>
<template>
<template-type-parameter name="U1"/>
<template-type-parameter name="U2"/>
<template-varargs/>
<template-type-parameter name="UN"/>
</template>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<parameter name="operand">
<paramtype>variant&lt;U1, U2, ..., UN&gt; &amp;&amp;</paramtype>
</parameter>
<notes>
<simpara>Same semantics as previous constructor, but allows
move construction.</simpara>
</notes>
</constructor>
<method-group name="modifiers">
@@ -281,7 +220,7 @@
<requires>
<simpara>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
<conceptname>Assignable</conceptname>
concept.</simpara>
</requires>
@@ -295,7 +234,7 @@
the contained type of <code>*this</code>, then may fail with any
exceptions arising from the <code>swap</code> of the contents of
<code>*this</code> and <code>other</code>. Otherwise, may fail
with any exceptions arising from either of the move or copy constructors
with any exceptions arising from either of the copy constructors
of the contained types. Also, in the event of insufficient
memory, may fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
@@ -335,43 +274,6 @@
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
<parameter name="rhs">
<paramtype>variant &amp;&amp;</paramtype>
</parameter>
<requires>
<itemizedlist>
<listitem>C++11 compatible compiler.</listitem>
<listitem>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
concept.</listitem>
</itemizedlist>
</requires>
<effects>
<simpara>If the contained type of <code>rhs</code> is the same as
the contained type of <code>*this</code>, then move assigns the
content of <code>rhs</code> into the content of
<code>*this</code>. Otherwise, move constructs
<code>*this</code> using the content of <code>rhs</code>,
destroying the previous content of <code>*this</code>.</simpara>
</effects>
<throws>
<simpara>If the contained type of <code>rhs</code> is the same as
the contained type of <code>*this</code>, then may fail with any
exceptions arising from the move assignment of the content of
<code>rhs</code> into the content <code>*this</code>. Otherwise,
may fail with any exceptions arising from the move constructor
of the contained type of <code>rhs</code>. Also, in the event of
insufficient memory, may fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
@@ -417,52 +319,6 @@
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="rhs">
<paramtype>T &amp;&amp;</paramtype>
</parameter>
<requires>
<itemizedlist>
<listitem>C++11 compatible compiler.</listitem>
<listitem><code>rhs</code> is an rvalue. Otherwise previous operator will be used.</listitem>
<listitem><code>T</code> must be unambiguously convertible to
one of the bounded types (i.e., <code>T1</code>,
<code>T2</code>, etc.).</listitem>
<listitem>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
concept.</listitem>
</itemizedlist>
</requires>
<effects>
<simpara>If the contained type of <code>*this</code> is
<code>T</code>, then move assigns <code>rhs</code> into the content
of <code>*this</code>. Otherwise, makes the content of
<code>*this</code> the best conversion of <code>rhs</code> to
one of the bounded types, as determined by standard overload
resolution rules, destroying the previous content of
<code>*this</code>(conversion is usually done via move construction).</simpara>
</effects>
<throws>
<simpara>If the contained type of <code>*this</code> is
<code>T</code>, then may fail with any exceptions arising from
the move assignment of <code>rhs</code> into the content
<code>*this</code>. Otherwise, may fail with any exceptions
arising from the conversion of <code>rhs</code> to one of the
bounded types. Also, in the event of insufficient memory, may
fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
</method-group>
<method-group name="queries">
@@ -508,11 +364,6 @@
</returns>
<throws>Will not throw.</throws>
<notes>
<simpara>Not available when <code>BOOST_NO_TYPEID</code> is
defined.</simpara>
</notes>
</method>
</method-group>
@@ -685,49 +536,6 @@
<simpara>Calls <code>out &lt;&lt; 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>
<function name="hash_value">
<purpose>Provides hashing for <code>variant</code> types so
that <code>boost::hash</code> may compute hash.</purpose>
<template>
<template-type-parameter name="T1"/>
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
</template>
<type>std::size_t</type>
<parameter name="rhs">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</paramtype>
</parameter>
<requires>
<simpara>Every bounded type of the <code>variant</code> must
fulfill the requirements of the
<link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>
concept.</simpara>
</requires>
<effects>
<simpara>Calls <code>boost::hash&lt;T&gt;()(x)</code>, where <code>x</code> is
the content of <code>rhs</code> and <code>T</code> is its type.</simpara>
</effects>
<notes>
<simpara>Actually, this function is defined in
<code>&lt;boost/variant/detail/hash_variant.hpp&gt;</code>
header.</simpara>
</notes>
</function>
<class name="make_variant_over">
@@ -765,4 +573,4 @@
</description>
</class>
</namespace>
</header>
</header>
+1 -58
View File
@@ -222,10 +222,6 @@ public:
</para>
<para><emphasis role="bold">Performance</emphasis>: <classname>boost::recursive_wrapper</classname>
has no empty state, which makes its move constructor not very optimal. Consider using <code>std::unique_ptr</code>
or some other safe pointer for better performance on C++11 compatible compilers.</para>
</section>
<section id="variant.tutorial.recursive.recursive-variant">
@@ -347,7 +343,7 @@ seq2.push_back(3.14);
are_strict_equals visitor;
assert( std::equal(
seq1.begin(), seq1.end(), seq2.begin()
v1.begin(), v1.end(), v2.begin()
, <functionname>boost::apply_visitor</functionname>( visitor )
) );</programlisting>
@@ -355,57 +351,4 @@ assert( std::equal(
</section>
<section id="variant.tutorial.multi-visitation">
<title>Multi visitation</title>
<para>Multi visitation extends the power and flexibility of visitation by allowing simultaneous
visitation of the content of three and more different <code>variant</code>
objects. Note that header for multi visitors shall be included separately.</para>
<para>Notably this feature requires that multi visitors are incompatible
with the visitor objects discussed in the tutorial above, as they must
operate on same amout of arguments that was passed to <code>apply_visitor</code>.
The following demonstrates the implementation of a multi visitor for three parameters:
<programlisting>
#include &lt;boost/variant/multivisitors.hpp&gt;
typedef <classname>boost::variant</classname>&lt;int, double, bool&gt; bool_like_t;
typedef <classname>boost::variant</classname>&lt;int, double&gt; arithmetics_t;
struct if_visitor: public <classname>boost::static_visitor</classname>&lt;arithmetics_t&gt; {
template &lt;class T1, class T2&gt;
arithmetics_t operator()(bool b, T1 v1, T2 v2) const {
if (b) {
return v1;
} else {
return v2;
}
}
};
</programlisting>
</para>
<para>As expected, the visitor is applied to three <code>variant</code>
arguments by means of <code>apply_visitor</code>:
<programlisting>
bool_like_t v0(1), v1(true), v2(1.0);
assert(
<functionname>boost::apply_visitor</functionname>(if_visitor(), v0, v1, v2)
==
arithmetics_t(true)
);
</programlisting>
</para>
<para>Finally, we must note that multi visitation does not support
&quot;delayed&quot; form of
<code><functionname>apply_visitor</functionname></code>.
</para>
</section>
</section>
+2 -2
View File
@@ -83,9 +83,9 @@ str += " world! ";</programlisting>
<programlisting>void times_two( boost::variant&lt; int, std::string &gt; &amp; operand )
{
if ( int* pi = <functionname>boost::get</functionname>&lt;int&gt;( &amp;operand ) )
if ( int* pi = <functionname>boost::get</functionname>&lt;int&gt;( &amp;v ) )
*pi *= 2;
else if ( std::string* pstr = <functionname>boost::get</functionname>&lt;std::string&gt;( &amp;operand ) )
else if ( std::string* pstr = <functionname>boost::get</functionname>&lt;std::string&gt;( &amp;v ) )
*pstr += *pstr;
}</programlisting>
+10 -5
View File
@@ -21,11 +21,16 @@
</copyright>
<legalnotice>
<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>
<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>
</legalnotice>
<librarypurpose>Safe, generic, stack-based discriminated union container</librarypurpose>
+1 -1
View File
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// boost variant.hpp header file
// See http://www.boost.org/libs/variant for documentation.
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003
+1 -1
View File
@@ -28,7 +28,7 @@ struct bad_visit
{
public: // std::exception interface
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
virtual const char * what() const throw()
{
return "boost::bad_visit: "
"failed visitation using boost::apply_visitor";
@@ -19,11 +19,7 @@
#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 {
@@ -52,7 +48,7 @@ private: // representation
public: // structors
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
: visitor_(visitor)
, value1_(value1)
{
@@ -67,9 +63,6 @@ public: // visitor interfaces
return visitor_(value1_, value2);
}
private:
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
};
template <typename Visitor, typename Visitable2>
@@ -87,7 +80,7 @@ private: // representation
public: // structors
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
: visitor_(visitor)
, visitable2_(visitable2)
{
@@ -107,9 +100,6 @@ public: // visitor interfaces
return boost::apply_visitor(invoker, visitable2_);
}
private:
apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
};
}} // namespace detail::variant
@@ -156,6 +146,8 @@ apply_visitor(
// const-visitor version:
//
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <typename Visitor, typename Visitable1, typename Visitable2>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
@@ -173,6 +165,8 @@ apply_visitor(
return boost::apply_visitor(unwrapper, visitable1);
}
#endif // MSVC7 and below exclusion
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
@@ -49,7 +49,7 @@ private: // representation
public: // structors
explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
explicit apply_visitor_delayed_t(Visitor& visitor)
: visitor_(visitor)
{
}
@@ -58,7 +58,7 @@ public: // unary visitor interface
template <typename Visitable>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Visitable& visitable) const
operator()(Visitable& visitable)
{
return apply_visitor(visitor_, visitable);
}
@@ -67,14 +67,11 @@ public: // binary visitor interface
template <typename Visitable1, typename Visitable2>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Visitable1& visitable1, Visitable2& visitable2) const
operator()(Visitable1& visitable1, Visitable2& visitable2)
{
return apply_visitor(visitor_, visitable1, visitable2);
}
private:
apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
};
template <typename Visitor>
@@ -17,11 +17,7 @@
#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 {
@@ -66,6 +62,8 @@ apply_visitor(Visitor& visitor, Visitable& visitable)
// const-visitor version:
//
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <typename Visitor, typename Visitable>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
@@ -74,6 +72,8 @@ apply_visitor(const Visitor& visitor, Visitable& visitable)
return visitable.apply_visitor(visitor);
}
#endif // MSVC7 and below exclusion
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
@@ -13,7 +13,6 @@
#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
#include "boost/config.hpp"
#include "boost/assert.hpp"
namespace boost {
@@ -28,12 +27,12 @@ private: // representation
public: // structors
~backup_holder() BOOST_NOEXCEPT
~backup_holder()
{
delete backup_;
}
explicit backup_holder(T* backup) BOOST_NOEXCEPT
explicit backup_holder(T* backup)
: backup_(backup)
{
}
@@ -54,7 +53,7 @@ public: // modifiers
return *this;
}
void swap(backup_holder& rhs) BOOST_NOEXCEPT
void swap(backup_holder& rhs)
{
T* tmp = rhs.backup_;
rhs.backup_ = this->backup_;
@@ -63,12 +62,12 @@ public: // modifiers
public: // queries
T& get() BOOST_NOEXCEPT
T& get()
{
return *backup_;
}
const T& get() const BOOST_NOEXCEPT
const T& get() const
{
return *backup_;
}
@@ -84,7 +83,7 @@ backup_holder<T>::backup_holder(const backup_holder&)
}
template <typename T>
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs)
{
lhs.swap(rhs);
}
@@ -25,13 +25,19 @@ namespace detail { namespace variant {
//
template <typename T>
inline T& cast_storage(void* storage)
inline T& cast_storage(
void* storage
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
)
{
return *static_cast<T*>(storage);
}
template <typename T>
inline const T& cast_storage(const void* storage)
inline const T& cast_storage(
const void* storage
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
)
{
return *static_cast<const T*>(storage);
}
+1
View File
@@ -21,6 +21,7 @@
//
#if BOOST_WORKAROUND(__MWERKS__, <= 0x3201) \
|| BOOST_WORKAROUND(BOOST_INTEL, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
&& !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
# define BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING
#endif
@@ -78,6 +78,7 @@ public:
// See boost/variant/detail/enable_recursive_fwd.hpp for more information.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T, typename RecursiveVariant, typename NoWrapper>
struct enable_recursive
@@ -111,6 +112,34 @@ public: // metafunction result
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T, typename RecursiveVariant, typename NoWrapper>
struct enable_recursive
{
private: // helpers, for metafunction result (below)
typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(
T, RecursiveVariant, ::boost::recursive_variant_
)::type t_;
public: // metafunction result
// [Wrap with recursive_wrapper only if rebind really changed something:]
typedef typename mpl::if_<
mpl::or_<
NoWrapper
, is_same< t_,T >
, is_reference<t_>
, is_pointer<t_>
>
, t_
, boost::recursive_wrapper<t_>
>::type type;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction class quoted_enable_recursive
@@ -17,7 +17,11 @@
#include "boost/mpl/bool_fwd.hpp"
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/bool.hpp"
#else
# include "boost/type_traits/is_base_and_derived.hpp"
#endif
namespace boost {
namespace detail { namespace variant {
@@ -28,6 +32,7 @@ namespace detail { namespace variant {
// Signifies that the variant should perform recursive substituion.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct recursive_flag
@@ -35,6 +40,20 @@ struct recursive_flag
typedef T type;
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
struct recursive_flag_tag
{
};
template <typename T>
struct recursive_flag
: recursive_flag_tag
{
typedef T type;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction is_recursive_flag
@@ -42,6 +61,7 @@ struct recursive_flag
// Signifies that the variant should perform recursive substituion.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_flag
@@ -55,6 +75,15 @@ struct is_recursive_flag< recursive_flag<T> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_flag
: is_base_and_derived< recursive_flag_tag,T >
{
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction enable_recursive
@@ -17,7 +17,7 @@
#include "boost/variant/detail/generic_result_type.hpp"
#include "boost/assert.hpp"
#if !defined(BOOST_MSVC)
#if !defined(BOOST_MSVC) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/type_traits/remove_reference.hpp"
#endif
@@ -32,12 +32,13 @@ namespace detail { namespace variant {
//
#if !defined(BOOST_MSVC) \
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_NO_VOID_RETURNS)
// "standard" implementation:
template <typename T>
inline T forced_return()
inline T forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
@@ -48,7 +49,7 @@ inline T forced_return()
}
template <>
inline void forced_return<void>()
inline void forced_return<void>( BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(void) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
@@ -65,7 +66,7 @@ inline void forced_return<void>()
template <typename T>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
forced_return()
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
@@ -87,7 +88,7 @@ inline void forced_return_no_return() {};
template <typename T>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
forced_return()
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
@@ -0,0 +1,106 @@
// (C) Copyright Eric Friedman 2002-2003.
// 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)
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
#define BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
#include "boost/config.hpp" // for STATIC_CONSTANT
#include "boost/variant/detail/has_trivial_move.hpp"
#include "boost/type_traits/has_nothrow_copy.hpp"
#include "boost/type_traits/has_nothrow_assign.hpp"
#include "boost/mpl/and.hpp"
#include "boost/mpl/or.hpp"
// should be the last #include
#include "boost/variant/detail/bool_trait_def.hpp"
namespace boost {
namespace detail { namespace variant {
// TRAIT: has_nothrow_move
template <typename T>
struct has_nothrow_move_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, ::boost::mpl::and_<
has_nothrow_copy<T>
, has_nothrow_assign<T>
>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move
, T
, (::boost::detail::variant::has_nothrow_move_impl<T>::value)
)
// TRAIT: has_nothrow_move_constructor
template <typename T>
struct has_nothrow_move_constructor_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_nothrow_move<T>
, has_trivial_move_constructor<T>
, has_nothrow_copy<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move_constructor
, T
, (::boost::detail::variant::has_nothrow_move_constructor_impl<T>::value)
)
// TRAIT: has_nothrow_move_assign
template <typename T>
struct has_nothrow_move_assign_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_nothrow_move<T>
, has_trivial_move_assign<T>
, has_nothrow_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move_assign
, T
, (::boost::detail::variant::has_nothrow_move_assign_impl<T>::value)
)
}} // namespace detail::variant
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move_constructor)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move_assign)
} // namespace boost
#include "boost/variant/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
@@ -0,0 +1,100 @@
// (C) Copyright Eric Friedman 2002-2003.
// 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)
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
#define BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
#include "boost/config.hpp" // for STATIC_CONSTANT
#include "boost/type_traits/has_trivial_copy.hpp"
#include "boost/type_traits/has_trivial_assign.hpp"
#include "boost/mpl/and.hpp"
#include "boost/mpl/or.hpp"
// should be the last #include
#include "boost/variant/detail/bool_trait_def.hpp"
namespace boost {
namespace detail { namespace variant {
// TRAIT: has_trivial_move
template <typename T>
struct has_trivial_move_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::and_<
has_trivial_copy<T>
, has_trivial_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move
, T
, (::boost::detail::variant::has_trivial_move_impl<T>::value)
)
// TRAIT: has_trivial_move_constructor
template <typename T>
struct has_trivial_move_constructor_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, has_trivial_copy<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move_constructor
, T
, (::boost::detail::variant::has_trivial_move_constructor_impl<T>::value)
)
// TRAIT: has_trivial_move_assign
template <typename T>
struct has_trivial_move_assign_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, has_trivial_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move_assign
, T
, (::boost::detail::variant::has_trivial_move_assign_impl<T>::value)
)
}} // namespace detail::variant
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move_constructor)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move_assign)
} // namespace boost
#include "boost/variant/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
@@ -1,47 +0,0 @@
//-----------------------------------------------------------------------------
// 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)
# 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 {
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
+54 -38
View File
@@ -20,7 +20,6 @@
#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"
@@ -80,22 +79,8 @@ 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
@@ -111,18 +96,6 @@ 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;
@@ -152,12 +125,12 @@ public: // static functions
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
// Obsolete. Remove.
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \
BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \
/**/
// Obsolete. Remove.
#define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
typedef typename unwrap_recursive< \
BOOST_PP_CAT(recursive_enabled_T,N) \
@@ -167,18 +140,25 @@ public: // static functions
>::param_type BOOST_PP_CAT(param_T,N); \
/**/
template < BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) >
# else // MSVC7 and below
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \
BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \
, BOOST_VARIANT_ENUM_PARAMS(typename param_T) \
/**/
#define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
/**/
# endif // MSVC7 and below workaround
template < BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS >
struct preprocessor_list_initializer
{
public: // static functions
#define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \
typedef typename unwrap_recursive< \
BOOST_PP_CAT(recursive_enabled_T,N) \
>::type BOOST_PP_CAT(public_T,N); \
typedef typename call_traits< \
BOOST_PP_CAT(public_T,N) \
>::param_type BOOST_PP_CAT(param_T,N); \
BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
static int initialize( \
void* dest \
, BOOST_PP_CAT(param_T,N) operand \
@@ -203,6 +183,22 @@ public: // static functions
};
# if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
#if !defined(BOOST_VARIANT_AUX_ECHO)
# define BOOST_VARIANT_AUX_ECHO(z,N,token) token
#endif
template <>
struct preprocessor_list_initializer<
BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, int)
, BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, const int)
>
{
};
# endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
}} // namespace detail::variant
@@ -233,14 +229,34 @@ public: // static functions
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
// Obsolete. Remove.
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
BOOST_VARIANT_ENUM_PARAMS(typename_base) \
/**/
# else // MSVC7 and below
#define BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE(z,N,T) \
::boost::call_traits< \
::boost::unwrap_recursive<BOOST_PP_CAT(T,N)>::type \
>::param_type \
/**/
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
BOOST_VARIANT_ENUM_PARAMS(typename_base) \
, BOOST_PP_ENUM( \
BOOST_VARIANT_LIMIT_TYPES \
, BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE \
, typename_base \
) \
/**/
# endif // MSVC7 workaround
#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \
::boost::detail::variant::preprocessor_list_initializer< \
BOOST_VARIANT_ENUM_PARAMS(typename_base) \
BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
> \
/**/
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
// Copyright (c) 2013 Antony Polukhin
// Copyright (c) 2002-2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -31,17 +31,6 @@ namespace detail { namespace variant {
// Rationale: see class template convert_void (variant_fwd.hpp) and using-
// declaration workaround (below).
//
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
template < typename... T >
struct make_variant_list
{
typedef typename mpl::list< T... >::type type;
};
#else
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
struct make_variant_list
{
@@ -65,8 +54,6 @@ public: // metafunction result
};
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
}} // namespace detail::variant
} // namespace boost
+112 -15
View File
@@ -5,7 +5,6 @@
//
// Copyright (c) 2002-2003 Eric Friedman
// Copyright (c) 2002 by Andrei Alexandrescu
// Copyright (c) 2013 Antony Polukhin
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
@@ -25,11 +24,92 @@
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/move/move.hpp"
#include "boost/mpl/if.hpp"
#include "boost/type_traits/is_base_and_derived.hpp"
namespace boost { namespace detail { namespace variant {
namespace boost {
namespace detail { namespace variant {
using boost::move;
//////////////////////////////////////////////////////////////////////////
// forward declares
//
// NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
//
template <typename Deriving> class moveable;
template <typename T> class move_source;
template <typename T> class move_return;
namespace detail {
// (detail) moveable_tag
//
// Concrete type from which moveable<T> derives.
//
// TODO: Move into moveable_fwd.hpp and define has_move_constructor.
//
template <typename Deriving>
struct moveable_tag
{
};
} // namespace detail
//////////////////////////////////////////////////////////////////////////
// function template move
//
// Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
// the object; else, returns the T&.
//
namespace detail {
// (detail) class template move_type
//
// Metafunction that, given moveable T, provides move_source<T>, else T&.
//
template <typename T>
struct move_type
{
public: // metafunction result
typedef typename mpl::if_<
is_base_and_derived<detail::moveable_tag<T>, T>
, move_source<T>
, T&
>::type type;
};
} // namespace detail
template <typename T>
inline
typename detail::move_type<T>::type
move(T& source)
{
typedef typename detail::move_type<T>::type
move_t;
return move_t(source);
}
//////////////////////////////////////////////////////////////////////////
// class template return_t
//
// Metafunction that, given moveable T, provides move_return<T>, else T.
//
template <typename T>
struct return_t
{
public: // metafunction result
typedef typename mpl::if_<
is_base_and_derived<moveable<T>, T>
, move_return<T>
, T
>::type type;
};
//////////////////////////////////////////////////////////////////////////
// function template move_swap
@@ -38,30 +118,47 @@ using boost::move;
// types and on non-conforming compilers.
//
namespace move_swap_fallback {
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
|| BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
template <typename T1, typename T2>
inline void swap(T1& lhs, T2& rhs)
// [Indicate that move_swap by overload is disabled...]
#define BOOST_NO_MOVE_SWAP_BY_OVERLOAD
// [...and provide straight swap-by-move implementation:]
template <typename T>
inline void move_swap(T& lhs, T& rhs)
{
T1 tmp( boost::detail::variant::move(lhs) );
T tmp( boost::detail::variant::move(lhs) );
lhs = boost::detail::variant::move(rhs);
rhs = boost::detail::variant::move(tmp);
}
} // namespace move_swap_fallback
#else// !workaround
namespace detail { namespace move_swap {
template <typename T>
inline void swap(T& lhs, T& rhs)
{
T tmp( boost::detail::variant::move(lhs) );
lhs = boost::detail::variant::move(rhs);
rhs = boost::detail::variant::move(tmp);
}
}} // namespace detail::move_swap
template <typename T>
inline void move_swap(T& lhs, T& rhs)
{
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
move_swap_fallback::swap(lhs, rhs);
#else
using move_swap_fallback::swap;
using detail::move_swap::swap;
swap(lhs, rhs);
#endif
}
}}} // namespace boost::detail::variant
#endif // workaround
}} // namespace detail::variant
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_MOVE_HPP
@@ -16,6 +16,12 @@
#define BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
#include "boost/mpl/aux_/config/ctps.hpp"
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/bool.hpp"
# include "boost/mpl/identity.hpp"
# include "boost/type.hpp"
#endif
namespace boost {
@@ -38,6 +44,7 @@ struct over_sequence
// Indicates whether the specified type is of form over_sequence<...> or not.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_over_sequence
@@ -51,6 +58,36 @@ struct is_over_sequence< over_sequence<Types> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef char (&yes_over_sequence_t)[1];
typedef char (&no_over_sequence_t)[2];
no_over_sequence_t is_over_sequence_test(...);
template<typename T>
yes_over_sequence_t is_over_sequence_test(
type< ::boost::detail::variant::over_sequence<T> >
);
template<typename T>
struct is_over_sequence_impl
{
BOOST_STATIC_CONSTANT(bool, value = (
sizeof(is_over_sequence_test(type<T>()))
== sizeof(yes_over_sequence_t)
));
};
template <typename T>
struct is_over_sequence
: mpl::bool_<
::boost::detail::variant::is_over_sequence_impl<T>::value
>
{
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
}} // namespace detail::variant
} // namespace boost
@@ -28,6 +28,7 @@
#include "boost/mpl/aux_/config/ttp.hpp"
#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
# define BOOST_VARIANT_DETAIL_NO_SUBSTITUTE
#endif
@@ -64,9 +64,6 @@ public: // visitor interface
out_ << operand;
}
private:
printer& operator=(const printer&);
};
}} // namespace detail::variant
@@ -33,12 +33,8 @@
#include "boost/preprocessor/repeat.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/type_traits/has_nothrow_copy.hpp"
#include "boost/type_traits/is_nothrow_move_constructible.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
@@ -67,6 +63,7 @@ struct apply_visitor_unrolled {};
// "Never ending" iterator range facilitates visitation_impl unrolling.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename Iter, typename LastIter>
struct visitation_impl_step
@@ -86,6 +83,29 @@ struct visitation_impl_step< LastIter,LastIter >
typedef visitation_impl_step next;
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename Iter, typename LastIter>
struct visitation_impl_step
{
typedef typename mpl::eval_if<
is_same<Iter, LastIter>
, mpl::identity<apply_visitor_unrolled>
, Iter
>::type type;
typedef typename mpl::eval_if<
is_same<type, apply_visitor_unrolled> //is_same<Iter, LastIter>
, mpl::identity<LastIter>
, mpl::next<Iter>
>::type next_iter;
typedef visitation_impl_step<
next_iter, LastIter
> next;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) function template visitation_impl_invoke
@@ -139,11 +159,11 @@ visitation_impl_invoke(
{
typedef typename mpl::or_<
NoBackupFlag
, is_nothrow_move_constructible<T>
, has_nothrow_move_constructor<T>
, 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()
);
@@ -222,7 +242,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 \
@@ -237,7 +257,6 @@ visitation_impl(
# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
default: break;
}
// If not handled in this iteration, continue unrolling:
@@ -264,8 +283,4 @@ visitation_impl(
}} // namespace detail::variant
} // namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
+51 -9
View File
@@ -17,13 +17,18 @@
#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/type_traits/add_reference.hpp"
#include "boost/type_traits/add_pointer.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include "boost/mpl/bool.hpp"
# include "boost/mpl/or.hpp"
# include "boost/type_traits/is_same.hpp"
#endif
namespace boost {
//////////////////////////////////////////////////////////////////////////
@@ -36,7 +41,7 @@ class bad_get
{
public: // std::exception implementation
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
virtual const char * what() const throw()
{
return "boost::bad_get: "
"failed value get using boost::get";
@@ -72,22 +77,59 @@ public: // visitor typedefs
public: // visitor interfaces
pointer operator()(reference operand) const BOOST_NOEXCEPT
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
pointer operator()(reference operand) const
{
return boost::addressof(operand);
}
template <typename U>
pointer operator()(const U&) const BOOST_NOEXCEPT
pointer operator()(const U&) const
{
return static_cast<pointer>(0);
}
#else // MSVC6
private: // helpers, for visitor interfaces (below)
pointer execute_impl(reference operand, mpl::true_) const
{
return boost::addressof(operand);
}
template <typename U>
pointer execute_impl(const U& operand, mpl::false_) const
{
return static_cast<pointer>(0);
}
public: // visitor interfaces
template <typename U>
pointer operator()(U& operand) const
{
// MSVC6 finds normal implementation (above) ambiguous,
// so we must explicitly disambiguate
typedef typename mpl::or_<
is_same<U, T>
, is_same<const U, T>
>::type U_is_T;
return execute_impl(operand, U_is_T());
}
#endif // MSVC6 workaround
};
}} // namespace detail::variant
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
#else
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = 0
@@ -99,7 +141,7 @@ inline
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);
@@ -114,7 +156,7 @@ inline
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);
@@ -135,7 +177,7 @@ get(
U_ptr result = get<U>(&operand);
if (!result)
boost::throw_exception(bad_get());
throw bad_get();
return *result;
}
@@ -151,7 +193,7 @@ get(
U_ptr result = get<const U>(&operand);
if (!result)
boost::throw_exception(bad_get());
throw bad_get();
return *result;
}
-143
View File
@@ -1,143 +0,0 @@
// Boost.Varaint
// Multivisitors defined here
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013.
//
// 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_MULTIVISITORS_HPP
#define BOOST_VARIANT_MULTIVISITORS_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/variant.hpp>
#include <boost/bind.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#ifndef BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS
# define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 4
#endif
namespace boost {
namespace detail { namespace variant {
template <class VisitorT, class Visitable1T, class Visitable2T>
struct two_variables_holder {
private:
VisitorT& visitor_;
Visitable1T& visitable1_;
Visitable2T& visitable2_;
// required to supress warnings and enshure that we do not copy
// this visitor
two_variables_holder& operator=(const two_variables_holder&);
public:
typedef BOOST_DEDUCED_TYPENAME VisitorT::result_type result_type;
explicit two_variables_holder(VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2) BOOST_NOEXCEPT
: visitor_(visitor)
, visitable1_(visitable1)
, visitable2_(visitable2)
{}
#define BOOST_VARIANT_OPERATOR_BEG() \
return ::boost::apply_visitor( \
::boost::bind<result_type>(boost::ref(visitor_), _1, _2 \
/**/
#define BOOST_VARIANT_OPERATOR_END() \
), visitable1_, visitable2_); \
/**/
#define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \
BOOST_PP_COMMA() boost::ref( BOOST_PP_CAT(vis, n) ) \
/**/
#define BOOST_VARIANT_VISIT(z, n, data) \
template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 1), class VisitableUnwrapped)> \
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()( \
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 1), VisitableUnwrapped, & vis) \
) const \
{ \
BOOST_VARIANT_OPERATOR_BEG() \
BOOST_PP_REPEAT(BOOST_PP_ADD(n, 1), BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \
BOOST_VARIANT_OPERATOR_END() \
} \
/**/
BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, ~)
#undef BOOST_VARIANT_OPERATOR_BEG
#undef BOOST_VARIANT_OPERATOR_END
#undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
#undef BOOST_VARIANT_VISIT
};
template <class VisitorT, class Visitable1T, class Visitable2T>
inline two_variables_holder<VisitorT, Visitable1T, Visitable2T> make_two_variables_holder(
VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2
) BOOST_NOEXCEPT
{
return two_variables_holder<VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2);
}
template <class VisitorT, class Visitable1T, class Visitable2T>
inline two_variables_holder<const VisitorT, Visitable1T, Visitable2T> make_two_variables_holder(
const VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2
) BOOST_NOEXCEPT
{
return two_variables_holder<const VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2);
}
}} // namespace detail::variant
#define BOOST_VARIANT_APPLY_VISITOR_BEG() \
return ::boost::apply_visitor( \
boost::detail::variant::make_two_variables_holder(visitor, var0 , var1), \
var2 \
/**/
#define BOOST_VARIANT_APPLY_VISITOR_END() \
); \
/**/
#define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \
BOOST_PP_COMMA() BOOST_PP_CAT(var, BOOST_PP_ADD(n, 3)) \
/**/
#define BOOST_VARIANT_VISIT(z, n, data) \
template <class Visitor BOOST_PP_COMMA() BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 3), class T)> \
inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(BOOST_DEDUCED_TYPENAME Visitor::result_type) apply_visitor( \
data BOOST_PP_COMMA() BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 3), T, & var) \
) \
{ \
BOOST_VARIANT_APPLY_VISITOR_BEG() \
BOOST_PP_REPEAT(n, BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \
BOOST_VARIANT_APPLY_VISITOR_END() \
} \
/**/
BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, const Visitor& visitor)
BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, Visitor& visitor)
#undef BOOST_VARIANT_APPLY_VISITOR_BEG
#undef BOOST_VARIANT_APPLY_VISITOR_END
#undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER
#undef BOOST_VARIANT_VISIT
} // namespace boost
#endif // BOOST_VARIANT_MULTIVISITORS_HPP
+36 -63
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman
// Copyright (c) 2013 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -21,15 +21,15 @@
#include "boost/mpl/aux_/lambda_arity_param.hpp"
#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"
#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/bool.hpp"
#include "boost/mpl/is_sequence.hpp"
@@ -68,42 +68,6 @@ struct substitute<
> type;
};
template <
BOOST_VARIANT_ENUM_PARAMS(typename T)
, typename RecursiveVariant
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
>
struct substitute<
::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:
typedef T0 initial_types;
typedef typename mpl::transform<
initial_types
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
>::type types;
public:
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
@@ -116,22 +80,27 @@ struct substitute<
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
>
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
typedef ::boost::variant<
typename enable_recursive<
T0
, RecursiveVariant
, mpl::true_
>::type,
typename enable_recursive<
TN
, RecursiveVariant
, mpl::true_
>::type...
> type;
#else
#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 typename mpl::transform<
initial_types
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
>::type types;
public: // metafunction result
typedef ::boost::variant< types > type;
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
private: // helpers, for metafunction result (below)
@@ -154,7 +123,9 @@ private: // helpers, for metafunction result (below)
public: // metafunction result
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
#endif
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
};
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
@@ -194,7 +165,9 @@ struct make_recursive_variant_over
{
private: // precondition assertions
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
#endif
public: // metafunction result
+2 -37
View File
@@ -14,7 +14,6 @@
#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 {
@@ -44,11 +43,6 @@ 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);
@@ -67,28 +61,13 @@ public: // modifiers
return *this;
}
void swap(recursive_wrapper& operand) BOOST_NOEXCEPT
void swap(recursive_wrapper& operand)
{
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(); }
@@ -123,20 +102,6 @@ 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)
{
@@ -148,7 +113,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) BOOST_NOEXCEPT
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs)
{
lhs.swap(rhs);
}
@@ -16,6 +16,12 @@
#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
#include "boost/mpl/aux_/config/ctps.hpp"
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/bool.hpp"
# include "boost/mpl/identity.hpp"
# include "boost/type.hpp"
#endif
#include "boost/mpl/aux_/lambda_support.hpp"
@@ -50,6 +56,7 @@ template <typename T> class recursive_wrapper;
namespace detail {
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_wrapper_impl
@@ -63,6 +70,28 @@ struct is_recursive_wrapper_impl< recursive_wrapper<T> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef char (&yes_recursive_wrapper_t)[1];
typedef char (&no_recursive_wrapper_t)[2];
no_recursive_wrapper_t is_recursive_wrapper_test(...);
template<typename T>
yes_recursive_wrapper_t is_recursive_wrapper_test(
type< ::boost::recursive_wrapper<T> >
);
template<typename T>
struct is_recursive_wrapper_impl
{
BOOST_STATIC_CONSTANT(bool, value = (
sizeof(is_recursive_wrapper_test(type<T>()))
== sizeof(yes_recursive_wrapper_t)
));
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
} // namespace detail
@@ -78,6 +107,7 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1(
// If specified type T matches recursive_wrapper<U>, then U; else T.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct unwrap_recursive
@@ -95,6 +125,20 @@ struct unwrap_recursive< recursive_wrapper<T> >
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T))
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct unwrap_recursive
: mpl::eval_if<
is_recursive_wrapper<T>
, T
, mpl::identity< T >
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T))
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
} // namespace boost
+8 -7
View File
@@ -19,6 +19,10 @@
#include "boost/mpl/if.hpp"
#include "boost/type_traits/is_base_and_derived.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include "boost/type_traits/is_same.hpp"
#endif
// should be the last #include
#include "boost/type_traits/detail/bool_trait_def.hpp"
@@ -48,13 +52,10 @@ public: // typedefs
typedef R result_type;
protected: // for use as base class only
#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
static_visitor() = default;
~static_visitor() = default;
#else
static_visitor() BOOST_NOEXCEPT { }
~static_visitor() BOOST_NOEXCEPT { }
#endif
static_visitor() { }
~static_visitor() { }
};
//////////////////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
+3 -59
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2013 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -71,54 +71,6 @@
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
#endif
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
#include <boost/preprocessor/seq/size.hpp>
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)(
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class...
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename...
#define ARGS_VARIADER_1(x) x ## N...
#define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N
#define BOOST_VARIANT_MAKE_VARIADIC(sequence, x) BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x)
#define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x) BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x)
#define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig)
///////////////////////////////////////////////////////////////////////////////
// BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS
//
// Convenience macro for enumeration of variant params.
// When variadic templates are available expands:
// 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...
// 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...
//
// 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)
// will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else`
//
#define BOOST_VARIANT_ENUM_PARAMS(x) \
x ## 0, \
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
/**/
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
/**/
#else
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
//
@@ -148,7 +100,6 @@
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
namespace boost {
@@ -217,11 +168,6 @@ BOOST_PP_REPEAT(
}} // namespace detail::variant
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
#define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
#else
///////////////////////////////////////////////////////////////////////////////
// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
//
@@ -250,8 +196,6 @@ BOOST_PP_REPEAT(
) \
/**/
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
///////////////////////////////////////////////////////////////////////////////
// class template variant (concept inspired by Andrei Alexandrescu)
//
@@ -285,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
+2 -3
View File
@@ -18,7 +18,6 @@
#include "boost/mpl/eval_if.hpp"
#include "boost/mpl/identity.hpp"
#include "boost/throw_exception.hpp"
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/type_traits/is_void.hpp"
@@ -55,7 +54,7 @@ private: // private typedefs
public: // structors
explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT
explicit visitor_ptr_t(visitor_t visitor)
: visitor_(visitor)
{
}
@@ -65,7 +64,7 @@ public: // static visitor interfaces
template <typename U>
result_type operator()(const U&) const
{
boost::throw_exception(bad_visit());
throw bad_visit();
}
#if !defined(BOOST_NO_VOID_RETURNS)
-29
View File
@@ -1,29 +0,0 @@
#==============================================================================
# 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) ;
-229
View File
@@ -1,229 +0,0 @@
// (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);
}
-29
View File
@@ -1,7 +1,6 @@
# Boost.Variant Library test Jamfile
#
# Copyright (C) 2003, Eric Friedman, Itay Maman.
# Copyright (C) 2013, Antony Polukhin.
#
# This material is provided "as is", with absolutely no warranty expressed
# or implied. Any use is at your own risk.
@@ -12,18 +11,6 @@
# 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
<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,20 +27,4 @@ test-suite variant
[ run variant_reference_test.cpp ]
[ run variant_comparison_test.cpp ]
[ run variant_visit_test.cpp ]
[ run variant_multivisit_test.cpp ]
[ run hash_variant_test.cpp ]
[ run rvalue_test.cpp ]
[ run recursive_variant_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
<toolset>gcc-4.3:<cxxflags>-fno-exceptions
<toolset>gcc-4.4:<cxxflags>-fno-exceptions
<toolset>gcc-4.5:<cxxflags>-fno-exceptions
<toolset>gcc-4.6:<cxxflags>-fno-exceptions
<toolset>gcc-4.7:<cxxflags>-fno-exceptions
<toolset>gcc-4.8:<cxxflags>-fno-exceptions
<toolset>clang:<cxxflags>-fno-exceptions
: variant_noexcept_test
]
[ run variant_swap_test.cpp ]
;
-34
View File
@@ -1,34 +0,0 @@
// 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;
}
+23 -4
View File
@@ -232,6 +232,29 @@ 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
{
@@ -244,9 +267,7 @@ 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<>()
@@ -295,9 +316,7 @@ 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<>()
+19 -218
View File
@@ -3,51 +3,19 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2013 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// 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)
// This file is used in two test cases:
//
// 1) recursive_variant_test.cpp that tests recursive usage of variant
//
// 2) variant_noexcept_test that tests Boost.Variant ability to compile
// and work with disabled exceptions
#ifdef BOOST_NO_EXCEPTIONS
// `boost/test/minimal.hpp` cannot work with exceptions disabled,
// so we need the following workarounds for that case:
namespace boost {
int exit_success = 0;
}
int test_main(int , char* []);
int main( int argc, char* argv[] )
{
return test_main(argc, argv);
}
#include <stdlib.h>
#define BOOST_CHECK(exp) if (!(exp)) exit(EXIT_FAILURE)
#else // BOOST_NO_EXCEPTIONS
# include "boost/test/minimal.hpp"
#endif // BOOST_NO_EXCEPTIONS
#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>
@@ -77,191 +45,24 @@ struct vector_printer
}
};
void test_recursive_variant()
{
typedef boost::make_recursive_variant<
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<
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();
typedef boost::make_recursive_variant<
int
, std::vector<boost::recursive_variant_>
>::type var_t;
std::vector<var_t> vec;
vec.push_back(3);
vec.push_back(5);
vec.push_back(vec);
vec.push_back(7);
var_t var(vec);
std::string result( boost::apply_visitor( vector_printer(), var ) );
std::cout << "result: " << result << '\n';
BOOST_CHECK(result == "( 3 5 ( 3 5 ) 7 ) ");
return boost::exit_success;
}
-268
View File
@@ -1,268 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/rvalue_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2012-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)
#include "boost/config.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "boost/type_traits/is_nothrow_move_assignable.hpp"
// Most part of tests from this file require rvalue references support
class move_copy_conting_class {
public:
static unsigned int moves_count;
static unsigned int copy_count;
move_copy_conting_class(){}
move_copy_conting_class(BOOST_RV_REF(move_copy_conting_class) ) {
++ moves_count;
}
move_copy_conting_class& operator=(BOOST_RV_REF(move_copy_conting_class) ) {
++ moves_count;
return *this;
}
move_copy_conting_class(const move_copy_conting_class&) {
++ copy_count;
}
move_copy_conting_class& operator=(BOOST_COPY_ASSIGN_REF(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;
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
void run()
{
// Making sure that internals of Boost.Move do not interfere with
// internals of Boost.Variant and in case of C++03 or C++98 compilation
// is still possible.
typedef boost::variant<int, move_copy_conting_class> variant_I_type;
variant_I_type v1, v2;
v1 = move_copy_conting_class();
v2 = v1;
v2 = boost::move(v1);
v1.swap(v2);
move_copy_conting_class val;
v2 = boost::move(val);
v2 = 10;
variant_I_type v3(boost::move(val));
variant_I_type v4(boost::move(v1));
}
void run1()
{
BOOST_CHECK(true);
}
void run_move_only()
{
BOOST_CHECK(true);
}
void run_moves_are_noexcept()
{
BOOST_CHECK(true);
}
void run_const_rvalues()
{
BOOST_CHECK(true);
}
#else
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 = boost::move(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 = boost::move(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 = boost::move(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 = boost::move(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(boost::move(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(boost::move(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);
}
void run_moves_are_noexcept() {
#ifndef BOOST_NO_CXX11_NOEXCEPT
typedef boost::variant<int, short, double> variant_noexcept_t;
//BOOST_CHECK(boost::is_nothrow_move_assignable<variant_noexcept_t>::value);
BOOST_CHECK(boost::is_nothrow_move_constructible<variant_noexcept_t>::value);
typedef boost::variant<int, short, double, move_only_structure> variant_except_t;
//BOOST_CHECK(!boost::is_nothrow_move_assignable<variant_except_t>::value);
BOOST_CHECK(!boost::is_nothrow_move_constructible<variant_except_t>::value);
#endif
}
inline const std::string get_string() { return "test"; }
inline const boost::variant<int, std::string> get_variant() { return std::string("test"); }
inline const boost::variant<std::string, int> get_variant2() { return std::string("test"); }
void run_const_rvalues()
{
typedef boost::variant<int, std::string> variant_t;
const variant_t v1(get_string());
const variant_t v2(get_variant());
const variant_t v3(get_variant2());
variant_t v4, v5, v6, v7;
v4 = get_string();
v5 = get_variant();
v6 = get_variant2();
v7 = boost::move(v1);
}
#endif
struct nothrow_copyable_throw_movable {
nothrow_copyable_throw_movable(){}
nothrow_copyable_throw_movable(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT {}
nothrow_copyable_throw_movable& operator=(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT { return *this; }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
nothrow_copyable_throw_movable(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) {}
nothrow_copyable_throw_movable& operator=(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) { return *this; }
#endif
};
// This test is created to cover the following situation:
// https://svn.boost.org/trac/boost/ticket/8772
void run_tricky_compilation_test()
{
boost::variant<int, nothrow_copyable_throw_movable> v;
v = nothrow_copyable_throw_movable();
}
int test_main(int , char* [])
{
run();
run1();
run_move_only();
run_moves_are_noexcept();
run_tricky_compilation_test();
run_const_rvalues();
return 0;
}
-6
View File
@@ -10,12 +10,6 @@
// 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"
+2 -7
View File
@@ -11,11 +11,6 @@
// 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"
@@ -43,10 +38,10 @@ struct short_string
using std::strlen;
#endif // BOOST_NO_STDC_NAMESPACE
size_t limit = this->e_limit; // avoid warnings on some compilers
size_t e_limit = this->e_limit; // avoid warnings on some compilers
size_t src_len = strlen(src);
len_ = (std::min)(src_len, limit-1);
len_ = (std::min)(src_len, e_limit-1);
std::copy(src, src + len_, buffer_);
buffer_[len_] = '\0';
}
-2
View File
@@ -122,9 +122,7 @@ 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
-6
View File
@@ -10,12 +10,6 @@
// 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"
-9
View File
@@ -10,12 +10,6 @@
// 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"
@@ -203,9 +197,6 @@ public:
ValueType& expected_;
private:
compare_helper& operator=(const compare_helper&);
};
template<typename VariantType, typename ExpectedType>
-2
View File
@@ -63,7 +63,6 @@ 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&)
@@ -111,4 +110,3 @@ int test_main(int , char* [])
return boost::exit_success;
}
-124
View File
@@ -1,124 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/variant_multivisit_test.cpp source 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)
#include "boost/config.hpp"
#define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
#include "boost/variant/multivisitors.hpp"
#include "boost/test/minimal.hpp"
typedef boost::variant<char, unsigned char, signed char, unsigned short, int, unsigned int> variant6_t;
struct test_visitor: boost::static_visitor<> {
// operators that shall not be called
template <class T1, class T2, class T3>
void operator()(T1, T2, T3) const
{
BOOST_CHECK(false);
}
template <class T1, class T2, class T3, class T4>
void operator()(T1, T2, T3, T4) const
{
BOOST_CHECK(false);
}
template <class T1, class T2, class T3, class T4, class T5>
void operator()(T1, T2, T3, T4, T5) const
{
BOOST_CHECK(false);
}
// operators that are OK to call
void operator()(char v0, unsigned char v1, signed char v2) const
{
BOOST_CHECK(v0 == 0);
BOOST_CHECK(v1 == 1);
BOOST_CHECK(v2 == 2);
}
void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const
{
BOOST_CHECK(v0 == 0);
BOOST_CHECK(v1 == 1);
BOOST_CHECK(v2 == 2);
BOOST_CHECK(v3 == 3);
}
void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const
{
BOOST_CHECK(v0 == 0);
BOOST_CHECK(v1 == 1);
BOOST_CHECK(v2 == 2);
BOOST_CHECK(v3 == 3);
BOOST_CHECK(v4 == 4);
}
};
typedef boost::variant<int, double, bool> bool_like_t;
typedef boost::variant<int, double> arithmetics_t;
struct if_visitor: public boost::static_visitor<arithmetics_t> {
template <class T1, class T2>
arithmetics_t operator()(bool b, T1 v1, T2 v2) const {
if (b) {
return v1;
} else {
return v2;
}
}
};
int test_main(int , char* [])
{
test_visitor v;
variant6_t v_array6[6];
v_array6[0] = char(0);
v_array6[1] = static_cast<unsigned char>(1);
v_array6[2] = static_cast<signed char>(2);
v_array6[3] = static_cast<unsigned short>(3);
v_array6[4] = static_cast<int>(4);
v_array6[5] = static_cast<unsigned int>(5);
boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2]);
boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2]);
// Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
//#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
#ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
#endif
bool_like_t v0(1), v1(true), v2(1.0);
BOOST_CHECK(
boost::apply_visitor(if_visitor(), v0, v1, v2)
==
arithmetics_t(true)
);
/* Delayed multi visitation is not implemented
if_visitor if_vis;
BOOST_CHECK(
boost::apply_visitor(if_vis)(v0, v1, v2)
==
arithmetics_t(true)
);
*/
return boost::exit_success;
}
+2
View File
@@ -77,6 +77,8 @@ void test_reference_content(T& t, const T& value1, const T& value2)
template <typename Base, typename Derived>
void base_derived_test(Derived d)
{
typedef typename boost::is_pointer<Base>::type is_ptr;
Base b(d);
BOOST_CHECK((check_base_derived(
b
-90
View File
@@ -1,90 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/variant_swap_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2009 ArtVPS Ltd.
// 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)
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include <vector>
#include <algorithm>
void run1()
{
using boost::variant;
typedef variant< int, std::vector<int>* > t_var;
std::vector<int> vec;
t_var v0(23), v1(&vec);
BOOST_REQUIRE(v0.which() == 0);
BOOST_REQUIRE(v1.which() == 1);
swap(v0, v1);
BOOST_CHECK(v0.which() == 1);
BOOST_CHECK(v1.which() == 0);
}
void run2()
{
using boost::variant;
using std::swap;
typedef variant< std::vector<int>, std::vector<double> > t_var;
std::vector<int> vec1;
std::vector<double> vec2;
t_var v0(vec1), v1(vec2);
BOOST_REQUIRE(v0.which() == 0);
BOOST_REQUIRE(v1.which() == 1);
swap(v0, v1);
BOOST_CHECK(v0.which() == 1);
BOOST_CHECK(v1.which() == 0);
v0.swap(v1);
BOOST_CHECK(v0.which() == 0);
BOOST_CHECK(v1.which() == 1);
}
void run3()
{
using boost::variant;
using std::swap;
typedef variant< int, double > t_var;
t_var v0(1), v1(2.0);
BOOST_REQUIRE(v0.which() == 0);
BOOST_REQUIRE(v1.which() == 1);
swap(v0, v1);
BOOST_CHECK(v0.which() == 1);
BOOST_CHECK(v1.which() == 0);
v0.swap(v1);
BOOST_CHECK(v0.which() == 0);
BOOST_CHECK(v1.which() == 1);
}
int test_main(int , char* [])
{
run1();
run2();
run3();
return 0;
}