mirror of
https://github.com/boostorg/variant.git
synced 2026-07-22 13:53:38 +00:00
Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 724f7fdebc | |||
| 037af28f3d | |||
| ee19ae6fb5 | |||
| 2cbea14c39 | |||
| 3ed1af5e79 | |||
| ac98e0ce4e | |||
| 57f1c98b29 | |||
| 0d43b3ec34 | |||
| b0ec38cbc4 | |||
| a283053408 | |||
| 84bdf52f3f | |||
| 0e0e0604e4 | |||
| 1bf7b791fd | |||
| 97e5305d6b | |||
| 791f267dda | |||
| d8180bc3a8 | |||
| a1b3867b3a | |||
| 4254803c98 | |||
| 6db57f7d6b | |||
| 1b57cf1ade | |||
| f9d2d9f9d9 | |||
| 86165b88e3 | |||
| e8e060416c | |||
| eebda61e78 | |||
| a3eb4ddd48 | |||
| e6014a3e21 | |||
| 3d44c5b695 | |||
| f5f3769cd4 | |||
| 64673bf9df | |||
| bc54cab94e | |||
| 6c26dd544d | |||
| efd81f5a2a | |||
| 7c2576948d | |||
| b173a982e9 | |||
| d1376d9783 | |||
| 21b9130e3a | |||
| f398fb9b2a | |||
| 78d52b15cc | |||
| 2bef470d77 | |||
| f9e03b6053 | |||
| e5547f95bc | |||
| 0aae21dc6e | |||
| 3f255f9108 | |||
| 9f5f65ab9b | |||
| 3e99de6129 | |||
| 40614b7c73 | |||
| 392fab2f89 | |||
| 7afab43f31 | |||
| 0110af77a4 | |||
| 79f5d17b43 | |||
| fad89dadec | |||
| 802f51fdc0 | |||
| 25da2b8de7 | |||
| 5d727edcff | |||
| 4d362457bb | |||
| a8b1d0f5d0 | |||
| f7be108ab5 | |||
| 0fe5e2e874 | |||
| 7df722ef6e | |||
| 25e12b7428 | |||
| 769ecfba29 | |||
| ba9d0e00d7 | |||
| deaf338bd4 | |||
| 126fb460ce |
+7
-1
@@ -1,5 +1,11 @@
|
||||
project boost/doc ;
|
||||
import boostbook : boostbook ;
|
||||
|
||||
boostbook variant-doc : variant.xml ;
|
||||
boostbook variant-doc
|
||||
:
|
||||
variant.xml
|
||||
:
|
||||
<xsl:param>boost.root=../../../..
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
|
||||
@@ -146,6 +146,60 @@
|
||||
</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 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand1">
|
||||
<paramtype>Variant1 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand2">
|
||||
<paramtype>Variant2 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand3">
|
||||
<paramtype>Variant3 &</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 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand1">
|
||||
<paramtype>Variant1 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand2">
|
||||
<paramtype>Variant2 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand3">
|
||||
<paramtype>Variant3 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="other_operands">
|
||||
<paramtype>...</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="Visitor"/>
|
||||
@@ -179,6 +233,13 @@
|
||||
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
|
||||
@@ -216,4 +277,4 @@
|
||||
</throws>
|
||||
</overloaded-function>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
are as follows:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><conceptname>CopyConstructible</conceptname> [20.1.3].</listitem>
|
||||
<listitem><conceptname>CopyConstructible</conceptname> or <conceptname>MoveConstructible</conceptname>.</listitem>
|
||||
<listitem>Destructor upholds the no-throw exception-safety
|
||||
guarantee.</listitem>
|
||||
<listitem>Complete at the point of <code>variant</code> template
|
||||
@@ -34,6 +34,12 @@
|
||||
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
|
||||
@@ -51,6 +57,10 @@
|
||||
<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>
|
||||
|
||||
@@ -129,4 +139,16 @@ 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<T>()(t)</code> must be a valid
|
||||
expression.</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
@@ -0,0 +1,88 @@
|
||||
<?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 <boost/variant/multivisitors.hpp> 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 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand1">
|
||||
<paramtype>Variant1 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand2">
|
||||
<paramtype>Variant2 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand3">
|
||||
<paramtype>Variant3 &</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 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand1">
|
||||
<paramtype>Variant1 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand2">
|
||||
<paramtype>Variant2 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="operand3">
|
||||
<paramtype>Variant3 &</paramtype>
|
||||
</parameter>
|
||||
<parameter name="other_operands">
|
||||
<paramtype>...</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
</overloaded-function>
|
||||
</namespace>
|
||||
</header>
|
||||
@@ -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.</para>
|
||||
all of the headers in the <code>boost/variant</code> directory except <boost/multivisiors.hpp>.</para>
|
||||
</section>
|
||||
</header>
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
<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>
|
||||
|
||||
+195
-3
@@ -110,6 +110,26 @@
|
||||
copy constructor of <code>other</code>'s contained type.</simpara>
|
||||
</throws>
|
||||
</constructor>
|
||||
|
||||
<constructor>
|
||||
<parameter name="other">
|
||||
<paramtype>variant &&</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>
|
||||
@@ -152,6 +172,25 @@
|
||||
construction from temporaries.</simpara>
|
||||
</notes>
|
||||
</constructor>
|
||||
|
||||
<constructor>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
</template>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>T &&</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>
|
||||
@@ -208,6 +247,28 @@
|
||||
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<U1, U2, ..., UN> &&</paramtype>
|
||||
</parameter>
|
||||
|
||||
<notes>
|
||||
<simpara>Same semantics as previous constructor, but allows
|
||||
move construction.</simpara>
|
||||
</notes>
|
||||
</constructor>
|
||||
|
||||
<method-group name="modifiers">
|
||||
|
||||
@@ -220,7 +281,7 @@
|
||||
|
||||
<requires>
|
||||
<simpara>Every bounded type must fulfill the requirements of the
|
||||
<conceptname>Assignable</conceptname>
|
||||
<conceptname>MoveAssignable</conceptname>
|
||||
concept.</simpara>
|
||||
</requires>
|
||||
|
||||
@@ -234,7 +295,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 copy constructors
|
||||
with any exceptions arising from either of the move or 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>
|
||||
@@ -274,6 +335,43 @@
|
||||
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
|
||||
</throws>
|
||||
</method>
|
||||
|
||||
<method name="operator=">
|
||||
<type>variant &</type>
|
||||
|
||||
<parameter name="rhs">
|
||||
<paramtype>variant &&</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 &</type>
|
||||
@@ -319,6 +417,52 @@
|
||||
</throws>
|
||||
</method>
|
||||
|
||||
<method name="operator=">
|
||||
<type>variant &</type>
|
||||
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
</template>
|
||||
|
||||
<parameter name="rhs">
|
||||
<paramtype>T &&</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">
|
||||
@@ -364,6 +508,11 @@
|
||||
</returns>
|
||||
|
||||
<throws>Will not throw.</throws>
|
||||
|
||||
<notes>
|
||||
<simpara>Not available when <code>BOOST_NO_TYPEID</code> is
|
||||
defined.</simpara>
|
||||
</notes>
|
||||
</method>
|
||||
|
||||
</method-group>
|
||||
@@ -536,6 +685,49 @@
|
||||
<simpara>Calls <code>out << x</code>, where <code>x</code> is
|
||||
the content of <code>rhs</code>.</simpara>
|
||||
</effects>
|
||||
|
||||
<notes>
|
||||
<simpara>Not available when <code>BOOST_NO_IOSTREAM</code> is
|
||||
defined.</simpara>
|
||||
</notes>
|
||||
|
||||
</function>
|
||||
|
||||
<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><T1, T2, ..., TN> &</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<T>()(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><boost/variant/detail/hash_variant.hpp></code>
|
||||
header.</simpara>
|
||||
</notes>
|
||||
|
||||
</function>
|
||||
|
||||
<class name="make_variant_over">
|
||||
@@ -573,4 +765,4 @@
|
||||
</description>
|
||||
</class>
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -222,6 +222,10 @@ 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">
|
||||
@@ -343,7 +347,7 @@ seq2.push_back(3.14);
|
||||
|
||||
are_strict_equals visitor;
|
||||
assert( std::equal(
|
||||
v1.begin(), v1.end(), v2.begin()
|
||||
seq1.begin(), seq1.end(), seq2.begin()
|
||||
, <functionname>boost::apply_visitor</functionname>( visitor )
|
||||
) );</programlisting>
|
||||
|
||||
@@ -351,4 +355,57 @@ 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 <boost/variant/multivisitors.hpp>
|
||||
|
||||
typedef <classname>boost::variant</classname><int, double, bool> bool_like_t;
|
||||
typedef <classname>boost::variant</classname><int, double> arithmetics_t;
|
||||
|
||||
struct if_visitor: public <classname>boost::static_visitor</classname><arithmetics_t> {
|
||||
template <class T1, class T2>
|
||||
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
|
||||
"delayed" form of
|
||||
<code><functionname>apply_visitor</functionname></code>.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
@@ -83,9 +83,9 @@ str += " world! ";</programlisting>
|
||||
|
||||
<programlisting>void times_two( boost::variant< int, std::string > & operand )
|
||||
{
|
||||
if ( int* pi = <functionname>boost::get</functionname><int>( &v ) )
|
||||
if ( int* pi = <functionname>boost::get</functionname><int>( &operand ) )
|
||||
*pi *= 2;
|
||||
else if ( std::string* pstr = <functionname>boost::get</functionname><std::string>( &v ) )
|
||||
else if ( std::string* pstr = <functionname>boost::get</functionname><std::string>( &operand ) )
|
||||
*pstr += *pstr;
|
||||
}</programlisting>
|
||||
|
||||
|
||||
+5
-10
@@ -21,16 +21,11 @@
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>Permission to copy, use, sell and distribute this software
|
||||
is granted provided this copyright notice appears in all copies.
|
||||
Permission to modify the code and to distribute modified code is
|
||||
granted provided this copyright notice appears in all copies, and
|
||||
a notice that the code was modified is included with the copyright
|
||||
notice.</para>
|
||||
|
||||
<para> This software is provided "as is" without express or
|
||||
implied warranty, and with no claim as to its suitability for any
|
||||
purpose.</para>
|
||||
<para>Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at
|
||||
<ulink
|
||||
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<librarypurpose>Safe, generic, stack-based discriminated union container</librarypurpose>
|
||||
|
||||
@@ -28,7 +28,7 @@ struct bad_visit
|
||||
{
|
||||
public: // std::exception interface
|
||||
|
||||
virtual const char * what() const throw()
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "boost::bad_visit: "
|
||||
"failed visitation using boost::apply_visitor";
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
|
||||
#include "boost/variant/detail/apply_visitor_unary.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
||||
#include "boost/utility/enable_if.hpp"
|
||||
#include "boost/mpl/not.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -48,7 +52,7 @@ private: // representation
|
||||
|
||||
public: // structors
|
||||
|
||||
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
|
||||
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, value1_(value1)
|
||||
{
|
||||
@@ -63,6 +67,9 @@ public: // visitor interfaces
|
||||
return visitor_(value1_, value2);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor, typename Visitable2>
|
||||
@@ -80,7 +87,7 @@ private: // representation
|
||||
|
||||
public: // structors
|
||||
|
||||
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
|
||||
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, visitable2_(visitable2)
|
||||
{
|
||||
@@ -100,6 +107,9 @@ public: // visitor interfaces
|
||||
return boost::apply_visitor(invoker, visitable2_);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
@@ -146,8 +156,6 @@ 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(
|
||||
@@ -165,8 +173,6 @@ 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)
|
||||
explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
{
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public: // unary visitor interface
|
||||
|
||||
template <typename Visitable>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
||||
operator()(Visitable& visitable)
|
||||
operator()(Visitable& visitable) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitable);
|
||||
}
|
||||
@@ -67,11 +67,14 @@ public: // binary visitor interface
|
||||
|
||||
template <typename Visitable1, typename Visitable2>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
||||
operator()(Visitable1& visitable1, Visitable2& visitable2)
|
||||
operator()(Visitable1& visitable1, Visitable2& visitable2) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitable1, visitable2);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor>
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
||||
#include "boost/utility/enable_if.hpp"
|
||||
#include "boost/mpl/not.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -62,8 +66,6 @@ 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)
|
||||
@@ -72,8 +74,6 @@ 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,6 +13,7 @@
|
||||
#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
|
||||
#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/assert.hpp"
|
||||
|
||||
namespace boost {
|
||||
@@ -27,12 +28,12 @@ private: // representation
|
||||
|
||||
public: // structors
|
||||
|
||||
~backup_holder()
|
||||
~backup_holder() BOOST_NOEXCEPT
|
||||
{
|
||||
delete backup_;
|
||||
}
|
||||
|
||||
explicit backup_holder(T* backup)
|
||||
explicit backup_holder(T* backup) BOOST_NOEXCEPT
|
||||
: backup_(backup)
|
||||
{
|
||||
}
|
||||
@@ -53,7 +54,7 @@ public: // modifiers
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(backup_holder& rhs)
|
||||
void swap(backup_holder& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
T* tmp = rhs.backup_;
|
||||
rhs.backup_ = this->backup_;
|
||||
@@ -62,12 +63,12 @@ public: // modifiers
|
||||
|
||||
public: // queries
|
||||
|
||||
T& get()
|
||||
T& get() BOOST_NOEXCEPT
|
||||
{
|
||||
return *backup_;
|
||||
}
|
||||
|
||||
const T& get() const
|
||||
const T& get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return *backup_;
|
||||
}
|
||||
@@ -83,7 +84,7 @@ backup_holder<T>::backup_holder(const backup_holder&)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs)
|
||||
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
@@ -25,19 +25,13 @@ namespace detail { namespace variant {
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
inline T& cast_storage(
|
||||
void* storage
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
|
||||
)
|
||||
inline T& cast_storage(void* storage)
|
||||
{
|
||||
return *static_cast<T*>(storage);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const T& cast_storage(
|
||||
const void* storage
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
|
||||
)
|
||||
inline const T& cast_storage(const void* storage)
|
||||
{
|
||||
return *static_cast<const T*>(storage);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
//
|
||||
#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,7 +78,6 @@ 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
|
||||
@@ -112,34 +111,6 @@ 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,11 +17,7 @@
|
||||
|
||||
#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 {
|
||||
@@ -32,7 +28,6 @@ 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
|
||||
@@ -40,20 +35,6 @@ 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
|
||||
@@ -61,7 +42,6 @@ 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
|
||||
@@ -75,15 +55,6 @@ 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) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include "boost/type_traits/remove_reference.hpp"
|
||||
#endif
|
||||
|
||||
@@ -32,13 +32,12 @@ 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( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
|
||||
inline T forced_return()
|
||||
{
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
@@ -49,7 +48,7 @@ inline T forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void forced_return<void>( BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(void) )
|
||||
inline void forced_return<void>()
|
||||
{
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
@@ -66,7 +65,7 @@ inline void forced_return<void>( BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(void) )
|
||||
template <typename T>
|
||||
inline
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
|
||||
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
|
||||
forced_return()
|
||||
{
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
@@ -88,7 +87,7 @@ inline void forced_return_no_return() {};
|
||||
template <typename T>
|
||||
inline
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
|
||||
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
|
||||
forced_return()
|
||||
{
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
|
||||
// (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
|
||||
@@ -1,100 +0,0 @@
|
||||
|
||||
// (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
|
||||
@@ -0,0 +1,47 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "boost/call_traits.hpp"
|
||||
#include "boost/detail/reference_content.hpp"
|
||||
#include "boost/variant/recursive_wrapper_fwd.hpp"
|
||||
#include "boost/variant/detail/move.hpp"
|
||||
|
||||
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
# include "boost/mpl/aux_/value_wknd.hpp"
|
||||
@@ -79,8 +80,22 @@ struct make_initializer_node
|
||||
recursive_enabled_T;
|
||||
typedef typename unwrap_recursive<recursive_enabled_T>::type
|
||||
public_T;
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef boost::is_reference<public_T>
|
||||
is_reference_content_t;
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, public_T, const public_T& >::type
|
||||
param_T;
|
||||
|
||||
template <class T> struct disable_overload{};
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, disable_overload<public_T>, public_T&& >::type
|
||||
param2_T;
|
||||
#else
|
||||
typedef typename call_traits<public_T>::param_type
|
||||
param_T;
|
||||
#endif
|
||||
|
||||
public: // static functions
|
||||
|
||||
@@ -96,6 +111,18 @@ struct make_initializer_node
|
||||
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
static int initialize(void* dest, param2_T operand)
|
||||
{
|
||||
// This assert must newer trigger, because all the reference contents are
|
||||
// handled by the initilize(void* dest, param_T operand) function above
|
||||
BOOST_ASSERT(!is_reference_content_t::value);
|
||||
|
||||
typedef typename boost::mpl::if_<is_reference_content_t, param2_T, recursive_enabled_T>::type value_T;
|
||||
new(dest) value_T( boost::detail::variant::move(operand) );
|
||||
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
friend class initializer_node;
|
||||
@@ -125,12 +152,12 @@ public: // static functions
|
||||
|
||||
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
|
||||
// Obsolete. Remove.
|
||||
#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) \
|
||||
@@ -140,25 +167,18 @@ public: // static functions
|
||||
>::param_type BOOST_PP_CAT(param_T,N); \
|
||||
/**/
|
||||
|
||||
# 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 >
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) >
|
||||
struct preprocessor_list_initializer
|
||||
{
|
||||
public: // static functions
|
||||
|
||||
#define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \
|
||||
BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(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); \
|
||||
static int initialize( \
|
||||
void* dest \
|
||||
, BOOST_PP_CAT(param_T,N) operand \
|
||||
@@ -183,22 +203,6 @@ 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
|
||||
@@ -229,34 +233,14 @@ struct preprocessor_list_initializer<
|
||||
|
||||
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
|
||||
// Obsolete. Remove.
|
||||
#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_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
|
||||
BOOST_VARIANT_ENUM_PARAMS(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) 2002-2003 Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2013 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -31,6 +31,17 @@ 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
|
||||
{
|
||||
@@ -54,6 +65,8 @@ public: // metafunction result
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//
|
||||
// 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
|
||||
@@ -24,92 +25,11 @@
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/mpl/if.hpp"
|
||||
#include "boost/type_traits/is_base_and_derived.hpp"
|
||||
#include "boost/move/move.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
namespace boost { namespace detail { namespace variant {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
|
||||
};
|
||||
using boost::move;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// function template move_swap
|
||||
@@ -118,47 +38,30 @@ public: // metafunction result
|
||||
// types and on non-conforming compilers.
|
||||
//
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
|
||||
namespace move_swap_fallback {
|
||||
|
||||
// [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)
|
||||
template <typename T1, typename T2>
|
||||
inline void swap(T1& lhs, T2& rhs)
|
||||
{
|
||||
T tmp( boost::detail::variant::move(lhs) );
|
||||
T1 tmp( boost::detail::variant::move(lhs) );
|
||||
lhs = boost::detail::variant::move(rhs);
|
||||
rhs = boost::detail::variant::move(tmp);
|
||||
}
|
||||
|
||||
#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
|
||||
} // namespace move_swap_fallback
|
||||
|
||||
template <typename T>
|
||||
inline void move_swap(T& lhs, T& rhs)
|
||||
{
|
||||
using detail::move_swap::swap;
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
move_swap_fallback::swap(lhs, rhs);
|
||||
#else
|
||||
using move_swap_fallback::swap;
|
||||
swap(lhs, rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // workaround
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
}}} // namespace boost::detail::variant
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_MOVE_HPP
|
||||
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
#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 {
|
||||
@@ -44,7 +38,6 @@ 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
|
||||
@@ -58,36 +51,6 @@ 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,7 +28,6 @@
|
||||
#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,6 +64,9 @@ public: // visitor interface
|
||||
out_ << operand;
|
||||
}
|
||||
|
||||
private:
|
||||
printer& operator=(const printer&);
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
@@ -33,8 +33,12 @@
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
#include "boost/type_traits/is_same.hpp"
|
||||
#include "boost/type_traits/has_nothrow_copy.hpp"
|
||||
#include "boost/variant/detail/has_nothrow_move.hpp"
|
||||
#include "boost/type_traits/is_nothrow_move_constructible.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable : 4702) //unreachable code
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
|
||||
@@ -63,7 +67,6 @@ 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
|
||||
@@ -83,29 +86,6 @@ 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
|
||||
@@ -159,11 +139,11 @@ visitation_impl_invoke(
|
||||
{
|
||||
typedef typename mpl::or_<
|
||||
NoBackupFlag
|
||||
, has_nothrow_move_constructor<T>
|
||||
, is_nothrow_move_constructible<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()
|
||||
);
|
||||
@@ -242,7 +222,7 @@ visitation_impl(
|
||||
// ...applying the appropriate case:
|
||||
# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
|
||||
case (Which::value + (N)): \
|
||||
return visitation_impl_invoke( \
|
||||
return (visitation_impl_invoke)( \
|
||||
internal_which, visitor, storage \
|
||||
, static_cast<BOOST_PP_CAT(T,N)*>(0) \
|
||||
, no_backup_flag, 1L \
|
||||
@@ -257,6 +237,7 @@ visitation_impl(
|
||||
|
||||
# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
// If not handled in this iteration, continue unrolling:
|
||||
@@ -283,4 +264,8 @@ visitation_impl(
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
|
||||
|
||||
@@ -17,18 +17,13 @@
|
||||
|
||||
#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 {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -41,7 +36,7 @@ class bad_get
|
||||
{
|
||||
public: // std::exception implementation
|
||||
|
||||
virtual const char * what() const throw()
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "boost::bad_get: "
|
||||
"failed value get using boost::get";
|
||||
@@ -77,59 +72,22 @@ public: // visitor typedefs
|
||||
|
||||
public: // visitor interfaces
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
pointer operator()(reference operand) const
|
||||
pointer operator()(reference operand) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::addressof(operand);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
pointer operator()(const U&) const
|
||||
pointer operator()(const U&) const BOOST_NOEXCEPT
|
||||
{
|
||||
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) \
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
#else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
@@ -141,7 +99,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);
|
||||
@@ -156,7 +114,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);
|
||||
@@ -177,7 +135,7 @@ get(
|
||||
U_ptr result = get<U>(&operand);
|
||||
|
||||
if (!result)
|
||||
throw bad_get();
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -193,7 +151,7 @@ get(
|
||||
U_ptr result = get<const U>(&operand);
|
||||
|
||||
if (!result)
|
||||
throw bad_get();
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// 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
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman
|
||||
// Copyright (c) 2003 Eric Friedman
|
||||
// Copyright (c) 2013 Antony Polukhin
|
||||
//
|
||||
// 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"
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
# include "boost/mpl/eval_if.hpp"
|
||||
# include "boost/mpl/identity.hpp"
|
||||
# include "boost/mpl/protect.hpp"
|
||||
# include "boost/mpl/transform.hpp"
|
||||
#else
|
||||
# include "boost/preprocessor/cat.hpp"
|
||||
# include "boost/preprocessor/repeat.hpp"
|
||||
#endif
|
||||
#include "boost/mpl/equal.hpp"
|
||||
#include "boost/mpl/eval_if.hpp"
|
||||
#include "boost/mpl/identity.hpp"
|
||||
#include "boost/mpl/if.hpp"
|
||||
#include "boost/mpl/protect.hpp"
|
||||
#include "boost/mpl/transform.hpp"
|
||||
#include "boost/type_traits/is_same.hpp"
|
||||
#include "boost/preprocessor/cat.hpp"
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/is_sequence.hpp"
|
||||
@@ -74,33 +74,64 @@ template <
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
::boost::variant<
|
||||
::boost::detail::variant::over_sequence< T0 >
|
||||
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
|
||||
>
|
||||
, RecursiveVariant
|
||||
, ::boost::recursive_variant_
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
::boost::detail::variant::is_over_sequence<T0>
|
||||
, mpl::identity< T0 >
|
||||
, make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
>::type initial_types;
|
||||
typedef T0 initial_types;
|
||||
|
||||
typedef typename mpl::transform<
|
||||
initial_types
|
||||
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
|
||||
>::type types;
|
||||
|
||||
public: // metafunction result
|
||||
public:
|
||||
|
||||
typedef ::boost::variant< types > type;
|
||||
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;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
, typename RecursiveVariant
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
|
||||
, RecursiveVariant
|
||||
, ::boost::recursive_variant_
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
#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
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
@@ -123,9 +154,7 @@ private: // helpers, for metafunction result (below)
|
||||
public: // metafunction result
|
||||
|
||||
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
|
||||
|
||||
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
|
||||
@@ -165,9 +194,7 @@ 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
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define BOOST_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
|
||||
#include "boost/variant/recursive_wrapper_fwd.hpp"
|
||||
#include "boost/variant/detail/move.hpp"
|
||||
#include "boost/checked_delete.hpp"
|
||||
|
||||
namespace boost {
|
||||
@@ -43,6 +44,11 @@ public: // structors
|
||||
recursive_wrapper(const recursive_wrapper& operand);
|
||||
recursive_wrapper(const T& operand);
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
recursive_wrapper(recursive_wrapper&& operand);
|
||||
recursive_wrapper(T&& operand);
|
||||
#endif
|
||||
|
||||
private: // helpers, for modifiers (below)
|
||||
|
||||
void assign(const T& rhs);
|
||||
@@ -61,13 +67,28 @@ public: // modifiers
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(recursive_wrapper& operand)
|
||||
void swap(recursive_wrapper& operand) BOOST_NOEXCEPT
|
||||
{
|
||||
T* temp = operand.p_;
|
||||
operand.p_ = p_;
|
||||
p_ = temp;
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
recursive_wrapper& operator=(recursive_wrapper&& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
recursive_wrapper& operator=(T&& rhs)
|
||||
{
|
||||
get() = detail::variant::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
public: // queries
|
||||
|
||||
T& get() { return *get_pointer(); }
|
||||
@@ -102,6 +123,20 @@ recursive_wrapper<T>::recursive_wrapper(const T& operand)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
|
||||
: p_(new T( detail::variant::move(operand.get()) ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T&& operand)
|
||||
: p_(new T( detail::variant::move(operand) ))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void recursive_wrapper<T>::assign(const T& rhs)
|
||||
{
|
||||
@@ -113,7 +148,7 @@ void recursive_wrapper<T>::assign(const T& rhs)
|
||||
// Swaps two recursive_wrapper<T> objects of the same type T.
|
||||
//
|
||||
template <typename T>
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs)
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
#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"
|
||||
|
||||
@@ -56,7 +50,6 @@ template <typename T> class recursive_wrapper;
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct is_recursive_wrapper_impl
|
||||
@@ -70,28 +63,6 @@ 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
|
||||
|
||||
@@ -107,7 +78,6 @@ 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
|
||||
@@ -125,20 +95,6 @@ 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
|
||||
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
#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"
|
||||
|
||||
@@ -52,10 +48,13 @@ public: // typedefs
|
||||
typedef R result_type;
|
||||
|
||||
protected: // for use as base class only
|
||||
|
||||
static_visitor() { }
|
||||
~static_visitor() { }
|
||||
|
||||
#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
static_visitor() = default;
|
||||
~static_visitor() = default;
|
||||
#else
|
||||
static_visitor() BOOST_NOEXCEPT { }
|
||||
~static_visitor() BOOST_NOEXCEPT { }
|
||||
#endif
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+701
-185
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2003 Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2013 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -71,6 +71,54 @@
|
||||
# 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
|
||||
//
|
||||
@@ -100,6 +148,7 @@
|
||||
#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 {
|
||||
|
||||
@@ -168,6 +217,11 @@ 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
|
||||
//
|
||||
@@ -196,6 +250,8 @@ BOOST_PP_REPEAT(
|
||||
) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class template variant (concept inspired by Andrei Alexandrescu)
|
||||
//
|
||||
@@ -229,7 +285,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
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#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"
|
||||
@@ -54,7 +55,7 @@ private: // private typedefs
|
||||
|
||||
public: // structors
|
||||
|
||||
explicit visitor_ptr_t(visitor_t visitor)
|
||||
explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
{
|
||||
}
|
||||
@@ -64,7 +65,7 @@ public: // static visitor interfaces
|
||||
template <typename U>
|
||||
result_type operator()(const U&) const
|
||||
{
|
||||
throw bad_visit();
|
||||
boost::throw_exception(bad_visit());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_VOID_RETURNS)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#==============================================================================
|
||||
# Copyright (c) 2012 Antony Polukhin
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#==============================================================================
|
||||
|
||||
# performance tests
|
||||
import testing ;
|
||||
import path ;
|
||||
|
||||
path-constant TEST_DIR : . ;
|
||||
|
||||
project performance/test
|
||||
: source-location ./
|
||||
: requirements
|
||||
# <library>/boost/chrono//boost_chrono
|
||||
# <library>/boost/system//boost_system
|
||||
<link>static
|
||||
<target-os>freebsd:<linkflags>"-lrt"
|
||||
<target-os>linux:<linkflags>"-lrt"
|
||||
<toolset>gcc:<cxxflags>-fvisibility=hidden
|
||||
<toolset>intel-linux:<cxxflags>-fvisibility=hidden
|
||||
<toolset>sun:<cxxflags>-xldscope=hidden
|
||||
: default-build release
|
||||
;
|
||||
|
||||
run move_perf.cpp : $(TEST_DIR) ;
|
||||
|
||||
Executable
+229
@@ -0,0 +1,229 @@
|
||||
// (C) Copyright Antony Polukhin 2012.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/config for most recent version.
|
||||
|
||||
//
|
||||
// Testing variant performance rvalue copy/assign performance
|
||||
//
|
||||
|
||||
#define BOOST_ERROR_CODE_HEADER_ONLY
|
||||
#define BOOST_CHRONO_HEADER_ONLY
|
||||
#include <boost/chrono.hpp>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct scope {
|
||||
typedef boost::chrono::steady_clock test_clock;
|
||||
typedef boost::chrono::milliseconds duration_t;
|
||||
test_clock::time_point start_;
|
||||
const char* const message_;
|
||||
|
||||
explicit scope(const char* const message)
|
||||
: start_(test_clock::now())
|
||||
, message_(message)
|
||||
{}
|
||||
|
||||
~scope() {
|
||||
std::cout << message_ << " " << boost::chrono::duration_cast<duration_t>(test_clock::now() - start_) << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void do_test(bool do_count_cleanup_time = false) {
|
||||
BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
|
||||
typedef std::vector<char> str_t;
|
||||
typedef boost::variant<int, str_t, float> var_t;
|
||||
|
||||
const char hello1_c[] = "hello long word";
|
||||
const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));
|
||||
|
||||
const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
|
||||
const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
std::cout << "#############################################\n";
|
||||
std::cout << "#############################################\n";
|
||||
std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
|
||||
std::cout << "#############################################\n";
|
||||
}
|
||||
|
||||
std::vector<var_t> data_from, data_to;
|
||||
data_from.resize(c_run_count, hello1);
|
||||
data_to.reserve(c_run_count);
|
||||
{
|
||||
scope sc("boost::variant(const variant&) copying speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to.push_back(data_from[i]);
|
||||
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello1);
|
||||
data_to.clear();
|
||||
data_to.reserve(c_run_count);
|
||||
{
|
||||
scope sc("boost::variant(variant&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to.push_back(std::move(data_from[i]));
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on same types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on same types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, hello2);
|
||||
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on different types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
data_from.clear();
|
||||
data_from.resize(c_run_count, var_t(0));
|
||||
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(const variant&) copying speed on different types II");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = data_from[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
data_from.resize(c_run_count, var_t(0));
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, hello2);
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types II");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
data_from.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cout << "#############################################\n";
|
||||
|
||||
std::vector<str_t> s1(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
|
||||
{
|
||||
scope sc("boost::variant=(const T&) copying speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = s1[i];
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
s1.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<str_t> s2(c_run_count, hello2);
|
||||
data_to.clear();
|
||||
data_to.resize(c_run_count, var_t(0));
|
||||
{
|
||||
scope sc("boost::variant=(T&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(s2[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
data_to.clear();
|
||||
s2.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
do_test(false);
|
||||
do_test(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# 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.
|
||||
@@ -11,6 +12,18 @@
|
||||
# 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
|
||||
:
|
||||
@@ -27,4 +40,20 @@ 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 ]
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2011
|
||||
// Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant/detail/hash_variant.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/functional/hash/hash.hpp"
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef boost::variant<bool, int, unsigned int, double> variant_type;
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
variant_type bool_variant1 = true;
|
||||
variant_type bool_variant2 = false;
|
||||
variant_type int_variant = 1;
|
||||
variant_type float_variant = 1.0;
|
||||
variant_type uint_variant = static_cast<unsigned int>(1);
|
||||
|
||||
BOOST_CHECK(hasher(bool_variant1) != hasher(bool_variant2));
|
||||
BOOST_CHECK(hasher(bool_variant1) == hasher(bool_variant1));
|
||||
BOOST_CHECK(hasher(int_variant) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(float_variant) != hasher(uint_variant));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
run();
|
||||
return 0;
|
||||
}
|
||||
+4
-23
@@ -232,29 +232,6 @@ struct int_adder : boost::static_visitor<>
|
||||
|
||||
|
||||
|
||||
|
||||
struct held_type_name : boost::static_visitor<std::string>
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
std::string operator()(const T& ) const
|
||||
{
|
||||
ost_ << '[' << typeid(T).name() << ']';
|
||||
return result();
|
||||
}
|
||||
|
||||
std::string result() const
|
||||
{
|
||||
return ost_.str();
|
||||
}
|
||||
|
||||
mutable std::ostringstream ost_;
|
||||
|
||||
}; //held_type_name
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct spec
|
||||
{
|
||||
@@ -267,7 +244,9 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
|
||||
const VariantType& cvar = var;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() == typeid(S));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
@@ -316,7 +295,9 @@ inline void verify_not(VariantType& var, spec<S>)
|
||||
{
|
||||
const VariantType& cvar = var;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() != typeid(S));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
|
||||
+213
-14
@@ -3,19 +3,51 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003
|
||||
// Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2003 Eric Friedman, Itay Maman
|
||||
// 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"
|
||||
|
||||
// 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/variant.hpp"
|
||||
#include "boost/mpl/vector.hpp"
|
||||
#include "boost/mpl/copy.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
struct vector_printer
|
||||
: boost::static_visitor<std::string>
|
||||
@@ -45,24 +77,191 @@ struct vector_printer
|
||||
}
|
||||
};
|
||||
|
||||
int test_main(int , char* [])
|
||||
void test_recursive_variant()
|
||||
{
|
||||
typedef boost::make_recursive_variant<
|
||||
int
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>::type var_t;
|
||||
>::type var1_t;
|
||||
|
||||
std::vector<var_t> vec;
|
||||
vec.push_back(3);
|
||||
vec.push_back(5);
|
||||
vec.push_back(vec);
|
||||
vec.push_back(7);
|
||||
std::vector<var1_t> vec1;
|
||||
vec1.push_back(3);
|
||||
vec1.push_back(5);
|
||||
vec1.push_back(vec1);
|
||||
vec1.push_back(7);
|
||||
|
||||
var_t var(vec);
|
||||
std::string result( boost::apply_visitor( vector_printer(), var ) );
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
|
||||
std::cout << "result: " << result << '\n';
|
||||
BOOST_CHECK(result == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
boost::variant<int, double>
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>::type var2_t;
|
||||
|
||||
std::vector<var2_t> vec2;
|
||||
vec2.push_back(boost::variant<int, double>(3));
|
||||
vec2.push_back(boost::variant<int, double>(3.5));
|
||||
vec2.push_back(vec2);
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
int
|
||||
, std::vector<
|
||||
boost::variant<
|
||||
double
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>
|
||||
>::type var3_t;
|
||||
|
||||
typedef boost::variant<double, std::vector<var3_t> > var4_t;
|
||||
|
||||
std::vector<var3_t> vec3;
|
||||
vec3.push_back(3);
|
||||
vec3.push_back(5);
|
||||
std::vector<var4_t> vec4;
|
||||
vec4.push_back(3.5);
|
||||
vec4.push_back(vec3);
|
||||
vec3.push_back(vec4);
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var4(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
double,
|
||||
std::vector<var1_t>
|
||||
>::type var5_t;
|
||||
|
||||
std::vector<var5_t> vec5;
|
||||
vec5.push_back(3.5);
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
int,
|
||||
std::map<int, boost::recursive_variant_>
|
||||
>::type var6_t;
|
||||
var6_t var6;
|
||||
}
|
||||
|
||||
void test_recursive_variant_over()
|
||||
{
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
int
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type var1_t;
|
||||
|
||||
std::vector<var1_t> vec1;
|
||||
vec1.push_back(3);
|
||||
vec1.push_back(5);
|
||||
vec1.push_back(vec1);
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
boost::make_variant_over<boost::mpl::vector<int, double> >::type
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type var2_t;
|
||||
|
||||
std::vector<var2_t> vec2;
|
||||
vec2.push_back(boost::variant<int, double>(3));
|
||||
vec2.push_back(boost::variant<int, double>(3.5));
|
||||
vec2.push_back(vec2);
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
int
|
||||
, std::vector<
|
||||
boost::make_variant_over<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<boost::recursive_variant_>
|
||||
>
|
||||
>::type
|
||||
>
|
||||
>
|
||||
>::type var3_t;
|
||||
|
||||
typedef boost::make_variant_over<
|
||||
boost::mpl::copy<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<var3_t>
|
||||
>
|
||||
>::type
|
||||
>::type var4_t;
|
||||
|
||||
std::vector<var3_t> vec3;
|
||||
vec3.push_back(3);
|
||||
vec3.push_back(5);
|
||||
std::vector<var4_t> vec4;
|
||||
vec4.push_back(3.5);
|
||||
vec4.push_back(vec3);
|
||||
vec3.push_back(vec4);
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var3(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
double
|
||||
, std::vector<var1_t>
|
||||
>
|
||||
>::type var5_t;
|
||||
|
||||
std::vector<var5_t> vec5;
|
||||
vec5.push_back(3.5);
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
test_recursive_variant();
|
||||
test_recursive_variant_over();
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from const int to const short
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
|
||||
+7
-2
@@ -11,6 +11,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
@@ -38,10 +43,10 @@ struct short_string
|
||||
using std::strlen;
|
||||
#endif // BOOST_NO_STDC_NAMESPACE
|
||||
|
||||
size_t e_limit = this->e_limit; // avoid warnings on some compilers
|
||||
size_t limit = this->e_limit; // avoid warnings on some compilers
|
||||
size_t src_len = strlen(src);
|
||||
|
||||
len_ = (std::min)(src_len, e_limit-1);
|
||||
len_ = (std::min)(src_len, limit-1);
|
||||
std::copy(src, src + len_, buffer_);
|
||||
buffer_[len_] = '\0';
|
||||
}
|
||||
|
||||
@@ -122,7 +122,9 @@ int test_main(int, char* [])
|
||||
std::ostringstream e1_str;
|
||||
e1_str << e1;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(e1.type() == typeid(Add));
|
||||
#endif
|
||||
BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))");
|
||||
|
||||
//Evaluate expression
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/config.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
@@ -197,6 +203,9 @@ public:
|
||||
|
||||
ValueType& expected_;
|
||||
|
||||
private:
|
||||
compare_helper& operator=(const compare_helper&);
|
||||
|
||||
};
|
||||
|
||||
template<typename VariantType, typename ExpectedType>
|
||||
|
||||
@@ -63,6 +63,7 @@ void check_fail(Variant& v)
|
||||
try
|
||||
{
|
||||
T& r = get<T>(v);
|
||||
(void)r; // suppress warning about r not being used
|
||||
BOOST_CHECK(false && &r); // should never reach
|
||||
}
|
||||
catch(boost::bad_get&)
|
||||
@@ -110,3 +111,4 @@ int test_main(int , char* [])
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
@@ -77,8 +77,6 @@ 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
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user