mirror of
https://github.com/boostorg/variant.git
synced 2026-07-22 13:53:38 +00:00
Compare commits
122 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1de9d246c0 | |||
| 0b9cb5792b | |||
| aad58b5fe5 | |||
| 34e2a9dec8 | |||
| 2b2cc6543c | |||
| 3d4b1ed964 | |||
| 7a0b343681 | |||
| a9049106d7 | |||
| 5c9b7b0105 | |||
| da6494128d | |||
| b38a79116e | |||
| 812f62ba79 | |||
| 1cec2c9e93 | |||
| e00c75c20d | |||
| adfd722858 | |||
| 57090d9209 | |||
| b3aedaabc4 | |||
| d05232522b | |||
| 428433f497 | |||
| da89ab5633 | |||
| 1e1a81536c | |||
| 36a45459f1 | |||
| 7c8b70cb9d | |||
| 3b84e2b981 | |||
| 6db01d6494 | |||
| a090e75efe | |||
| ceb56996d6 | |||
| 12ab1675c7 | |||
| a79b3978a5 | |||
| 3e9aec5371 | |||
| ff52de9d5a | |||
| e2525d1baf | |||
| 8c385d9874 | |||
| 1a67de834e | |||
| 4ea8838167 | |||
| cbf4bbf1b1 | |||
| 46250fa7d2 | |||
| bcf506a296 | |||
| 1231f51501 | |||
| 5cd1e3ee85 | |||
| 0231eefd43 | |||
| 2770d7569e | |||
| 6fff67381e | |||
| 6db941f3dd | |||
| ecdde80ea5 | |||
| 940cfef1f6 | |||
| adb3d5c9bb | |||
| 20c7019799 | |||
| 6e31806038 | |||
| f8a29a0d2f | |||
| 81ef9229fb | |||
| 21eeb2e4d4 | |||
| 7fc1b93794 | |||
| 4352cb4c17 | |||
| 2131e0255f | |||
| 9ae87bfbd0 | |||
| 29e6bd2c43 | |||
| 4a55d87943 | |||
| ad350dde6e | |||
| 302afed1ba | |||
| 2569ca18ce | |||
| a8b920532d | |||
| 384ac0dd4a | |||
| 3bb91f9a39 | |||
| ed614a6260 | |||
| 30adb7fd45 | |||
| db42afbdfa | |||
| 8f111d3126 | |||
| 7c85a3a6bb | |||
| 433d3aecab | |||
| 1b50119b21 | |||
| cf3875bc22 | |||
| 65dae1db5a | |||
| 4ad95f185b | |||
| 0367512bc7 | |||
| e1a611c000 | |||
| 134dfbf46e | |||
| 92a530a2b9 | |||
| 9bc9c1c143 | |||
| 5398f31ea2 | |||
| e30800b534 | |||
| 9b04ff9221 | |||
| 7a5b0f2538 | |||
| 01a9630c37 | |||
| 0396d6c73d | |||
| 63fb3ff427 | |||
| 0d226eb597 | |||
| 464799f446 | |||
| f59cdef172 | |||
| e20324e2c4 | |||
| 592e1b5339 | |||
| a2523c620d | |||
| e70b03583f | |||
| e05edc0248 | |||
| 76f2c0fc19 | |||
| 8507087c59 | |||
| f17d91a8b4 | |||
| 3e02b4963d | |||
| a4eaf348ea | |||
| 54ea9c42a1 | |||
| eb17a6afd8 | |||
| 3891cde7ed | |||
| 591ae9bf26 | |||
| 5b34fe155f | |||
| 2a6c6f3948 | |||
| c13372a092 | |||
| 64d68fc379 | |||
| 19ba44bb3f | |||
| 4d02fbcd84 | |||
| 4f4555fa93 | |||
| e0151cc209 | |||
| 3bc66e9264 | |||
| aa1eeb3b0f | |||
| a400952c16 | |||
| dcc25e1a1d | |||
| c7d1cccc13 | |||
| 5edc863174 | |||
| d465155ccc | |||
| ddf192fc53 | |||
| de56bdaa0a | |||
| 2d1dea19ba | |||
| 39469616d2 |
+85
@@ -0,0 +1,85 @@
|
||||
# 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)
|
||||
#
|
||||
# Copyright Antony Polukhin 2014.
|
||||
|
||||
#
|
||||
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
|
||||
# and how it can be used with Boost libraries.
|
||||
#
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
env:
|
||||
- CXX_STANDARD=c++98
|
||||
- CXX_STANDARD=c++0x
|
||||
|
||||
before_install:
|
||||
# Set this to the name of your Boost library
|
||||
# Autodetect library name by using the following code: - PROJECT_TO_TEST=$(basename $(pwd))
|
||||
- PROJECT_TO_TEST=$(basename $(pwd))
|
||||
|
||||
# Autodetect Boost branch by using the following code: - BRANCH_TO_TEST=`git rev-parse --abbrev-ref HEAD`
|
||||
# or by - BRANCH_TO_TEST=$TRAVIS_BRANCH or just directly specify it
|
||||
- BRANCH_TO_TEST=$TRAVIS_BRANCH
|
||||
|
||||
# Files, which coverage results must be ignored (files from other projects). Example: - IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/path.cpp'
|
||||
- IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/path.cpp */numeric/conversion/converter_policies.hpp'
|
||||
|
||||
|
||||
# From this point and below code is same for all the Boost libs
|
||||
# Cloning Boost libraries (fast nondeep cloning)
|
||||
- PROJECT_DIR=`pwd`
|
||||
- BOOST=$HOME/boost-local
|
||||
- git init $BOOST
|
||||
- cd $BOOST
|
||||
- git remote add --no-tags -t $BRANCH_TO_TEST origin https://github.com/boostorg/boost.git
|
||||
- git fetch --depth=1
|
||||
- git checkout $BRANCH_TO_TEST
|
||||
- git submodule update --init --merge
|
||||
- git remote set-branches --add origin $BRANCH_TO_TEST
|
||||
- git pull --recurse-submodules
|
||||
- git submodule update --init
|
||||
- git checkout $BRANCH_TO_TEST
|
||||
- git submodule foreach "git reset --quiet --hard; git clean -fxd"
|
||||
- git reset --hard; git clean -fxd
|
||||
- git status
|
||||
- rm -rf $BOOST/libs/$PROJECT_TO_TEST
|
||||
- mv $PROJECT_DIR/../$PROJECT_TO_TEST/ $BOOST/libs/$PROJECT_TO_TEST
|
||||
- PROJECT_DIR=$BOOST/libs/$PROJECT_TO_TEST
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- if [ "$CCFLAGS" != "" ]; then FLAGS="cxxflags=\"$CCFLAGS\" linkflags=\"$LINKFLAGS\""; else FLAGS=""; fi
|
||||
- cd $BOOST/libs/$PROJECT_TO_TEST/test/
|
||||
# `--coverage` flags required to generate coverage info for Coveralls
|
||||
- ../../../b2 cxxflags="--coverage -std=$CXX_STANDARD" linkflags="--coverage"
|
||||
|
||||
after_success:
|
||||
# Copying Coveralls data to a separate folder
|
||||
- mkdir -p $PROJECT_DIR/coverals
|
||||
- find ../../../bin.v2/ -name "*.gcda" -exec cp "{}" $PROJECT_DIR/coverals/ \;
|
||||
- find ../../../bin.v2/ -name "*.gcno" -exec cp "{}" $PROJECT_DIR/coverals/ \;
|
||||
|
||||
# Preparing Coveralls data by
|
||||
# ... installing the tools
|
||||
- sudo apt-get install -qq python-yaml lcov
|
||||
# ... changind data format to a readable one
|
||||
- lcov --directory $PROJECT_DIR/coverals --base-directory ./ --capture --output-file $PROJECT_DIR/coverals/coverage.info
|
||||
|
||||
# ... erasing /test/ /example/ folder data
|
||||
- cd $BOOST
|
||||
- lcov --remove $PROJECT_DIR/coverals/coverage.info "/usr*" "*/$PROJECT_TO_TEST/test/*" $IGNORE_COVERAGE "*/$PROJECT_TO_TEST/tests/*" "*/$PROJECT_TO_TEST/examples/*" "*/$PROJECT_TO_TEST/example/*" -o $PROJECT_DIR/coverals/coverage.info
|
||||
|
||||
# ... erasing data that is not related to this project directly
|
||||
- OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$PROJECT_TO_TEST\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
|
||||
- echo $OTHER_LIBS
|
||||
- eval "lcov --remove $PROJECT_DIR/coverals/coverage.info $OTHER_LIBS -o $PROJECT_DIR/coverals/coverage.info"
|
||||
|
||||
# Sending data to Coveralls
|
||||
- cd $PROJECT_DIR
|
||||
- gem install coveralls-lcov
|
||||
- coveralls-lcov coverals/coverage.info
|
||||
@@ -0,0 +1,16 @@
|
||||
#[Boost.Variant](http://boost.org/libs/variant)
|
||||
Boost.Variant, part of collection of the [Boost C++ Libraries](http://github.com/boostorg). It is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner.
|
||||
|
||||
### Test results
|
||||
|
||||
@ | Build | Tests coverage | More info
|
||||
----------------|-------------- | -------------- |-----------
|
||||
Develop branch: | [](https://travis-ci.org/apolukhin/variant) | [](https://coveralls.io/r/apolukhin/variant?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/variant.html)
|
||||
Master branch: | [](https://travis-ci.org/apolukhin/variant) | [](https://coveralls.io/r/apolukhin/variant?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/variant.html)
|
||||
|
||||
|
||||
[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=variant)
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
+10
-1
@@ -1,4 +1,13 @@
|
||||
project boost/doc ;
|
||||
# Boost.Variant Library doc Jamfile
|
||||
#
|
||||
# Copyright (C) 2003, Eric Friedman, Itay Maman.
|
||||
#
|
||||
# Use, modification and distribution is 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)
|
||||
#
|
||||
|
||||
project variant/doc ;
|
||||
import boostbook : boostbook ;
|
||||
|
||||
boostbook variant-doc
|
||||
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.refs">
|
||||
<title>References</title>
|
||||
|
||||
@@ -109,4 +115,4 @@
|
||||
2002.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
+7
-24
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.design">
|
||||
<title>Design Overview</title>
|
||||
|
||||
@@ -270,29 +276,6 @@
|
||||
|
||||
</para>
|
||||
|
||||
<para><emphasis role="bold">Caveat</emphasis>: On most platforms, the
|
||||
<libraryname>Type Traits</libraryname> templates
|
||||
<code>has_nothrow_copy</code> and <code>has_nothrow_constructor</code>
|
||||
by default return <code>false</code> for all <code>class</code> and
|
||||
<code>struct</code> types. It is necessary therefore to provide
|
||||
specializations of these templates as appropriate for user-defined
|
||||
types, as demonstrated in the following:
|
||||
|
||||
<programlisting>// ...in your code (at file scope)...
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <>
|
||||
struct <classname>has_nothrow_copy</classname>< myUDT >
|
||||
: <classname>mpl::true_</classname>
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para><emphasis role="bold">Implementation Note</emphasis>: So as to make
|
||||
the behavior of <code>variant</code> more predictable in the aftermath
|
||||
of an exception, the current implementation prefers to default-construct
|
||||
@@ -324,4 +307,4 @@ namespace boost {
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
@@ -132,4 +138,4 @@ int main()
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.misc">
|
||||
<title>Miscellaneous Notes</title>
|
||||
|
||||
@@ -232,4 +238,4 @@ interface, and implementation of the library.</para>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
+109
-11
@@ -1,6 +1,13 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
Copyright 2013-2014 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)
|
||||
-->
|
||||
<header name="boost/variant/apply_visitor.hpp">
|
||||
<namespace name="boost">
|
||||
<class name="apply_visitor_delayed_t">
|
||||
@@ -14,6 +21,9 @@
|
||||
<simpara>See the "visitor-only" form of
|
||||
<code><functionname>apply_visitor</functionname></code> for a simple
|
||||
way to create <code>apply_visitor_delayed_t</code> objects.</simpara>
|
||||
<simpara>See <code><classname>apply_visitor_delayed_cpp14_t</classname></code>
|
||||
which is used on C++14 compatible compilers when <code>Visitor</code> has no
|
||||
<code>result_type</code> typedef.</simpara>
|
||||
</description>
|
||||
|
||||
<template>
|
||||
@@ -37,6 +47,18 @@
|
||||
|
||||
<method-group name="function object interface">
|
||||
<overloaded-method name="operator()">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="... Variant"/>
|
||||
</template>
|
||||
|
||||
<type>result_type</type>
|
||||
<parameter name="operand">
|
||||
<paramtype>Variant&...</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="Variant"/>
|
||||
@@ -69,10 +91,69 @@
|
||||
<code><functionname>apply_visitor</functionname></code> on the
|
||||
stored visitor using the given operands.</simpara>
|
||||
</description>
|
||||
<notes>Version with variadic templates is used by default if
|
||||
<macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname> is not defined.</notes>
|
||||
</overloaded-method>
|
||||
</method-group>
|
||||
</class>
|
||||
|
||||
|
||||
<class name="apply_visitor_delayed_cpp14_t">
|
||||
<purpose>Adapts a visitor for use as a function object.</purpose>
|
||||
<description>
|
||||
<simpara>Adapts the function given at construction for use as a
|
||||
function object. This is useful, for example, when one needs to
|
||||
operate on each element of a sequence of variant objects using a
|
||||
standard library algorithm such as
|
||||
<code>std::for_each</code>.</simpara>
|
||||
<simpara>See the "visitor-only" form of
|
||||
<code><functionname>apply_visitor</functionname></code> for a simple
|
||||
way to create <code>apply_visitor_delayed_t</code> objects.</simpara>
|
||||
<simpara>See <code><classname>apply_visitor_delayed_t</classname></code>
|
||||
which is used when <code>Visitor</code> has <code>result_type</code>
|
||||
typedef.</simpara>
|
||||
<simpara>Available only if macro
|
||||
<macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname> is not defined and
|
||||
compiler supports <code>decltype(auto)</code> and <code>decltype(some-expression)</code>.</simpara>
|
||||
</description>
|
||||
|
||||
<template>
|
||||
<template-type-parameter name="Visitor"/>
|
||||
</template>
|
||||
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="visitor">
|
||||
<paramtype>Visitor &</paramtype>
|
||||
</parameter>
|
||||
|
||||
<effects>
|
||||
<simpara>Constructs the function object with the given
|
||||
visitor.</simpara>
|
||||
</effects>
|
||||
</constructor>
|
||||
|
||||
<method-group name="function object interface">
|
||||
<overloaded-method name="operator()">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="... Variant"/>
|
||||
</template>
|
||||
|
||||
<type>decltype(auto)</type>
|
||||
<parameter name="operand">
|
||||
<paramtype>Variant&...</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>Function call operator.</purpose>
|
||||
<description>
|
||||
<simpara>Invokes
|
||||
<code><functionname>apply_visitor</functionname></code> on the
|
||||
stored visitor using the given operands.</simpara>
|
||||
</description>
|
||||
</overloaded-method>
|
||||
</method-group>
|
||||
</class>
|
||||
|
||||
<overloaded-function name="apply_visitor">
|
||||
<signature>
|
||||
<template>
|
||||
@@ -89,7 +170,7 @@
|
||||
<paramtype>Variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="Visitor"/>
|
||||
@@ -113,7 +194,7 @@
|
||||
<template-type-parameter name="Variant2"/>
|
||||
</template>
|
||||
|
||||
<type>typename BinaryVisitor::result_type</type>
|
||||
<type>typename BinaryVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>BinaryVisitor &</paramtype>
|
||||
@@ -133,7 +214,7 @@
|
||||
<template-type-parameter name="Variant2"/>
|
||||
</template>
|
||||
|
||||
<type>typename BinaryVisitor::result_type</type>
|
||||
<type>typename BinaryVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>const BinaryVisitor &</paramtype>
|
||||
@@ -154,7 +235,7 @@
|
||||
<template-type-parameter name="Variant3"/>
|
||||
</template>
|
||||
|
||||
<type>typename MultiVisitor::result_type</type>
|
||||
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>MultiVisitor &</paramtype>
|
||||
@@ -181,7 +262,7 @@
|
||||
<template-type-parameter name="Variant3"/>
|
||||
</template>
|
||||
|
||||
<type>typename MultiVisitor::result_type</type>
|
||||
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>const MultiVisitor &</paramtype>
|
||||
@@ -212,6 +293,19 @@
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="Visitor"/>
|
||||
</template>
|
||||
|
||||
<type><classname>apply_visitor_delayed_cpp14_t</classname><Visitor></type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>Visitor &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Allows compile-time checked type-safe application of the
|
||||
given visitor to the content of the given variant, ensuring that all
|
||||
@@ -236,13 +330,17 @@
|
||||
<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
|
||||
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>
|
||||
macro. Those functions are actually defined in a header <code>boost/variant/multivisitors.hpp</code>
|
||||
(See <xref linkend="header.boost.variant.multivisitors_hpp"/>). That header must be manually included
|
||||
if multi visitors are meant for use.</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
|
||||
<listitem>The overloads accepting only a visitor return a
|
||||
<classname alt="boost::apply_visitor_delayed_t">C++03 compatible generic function object</classname>
|
||||
or
|
||||
<classname alt="boost::apply_visitor_delayed_cpp14_t">C++14 compatible generic function object</classname>
|
||||
that accepts either one, two or arbitrary count of arguments and invoke
|
||||
<code><functionname>apply_visitor</functionname></code> using
|
||||
these arguments and <code>visitor</code>, thus behaving as
|
||||
specified above. (This behavior is particularly useful, for
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/bad_visit.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -20,4 +26,4 @@
|
||||
</class>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.concepts">
|
||||
<title>Concepts</title>
|
||||
|
||||
@@ -74,7 +82,9 @@
|
||||
<listitem>Must allow invocation as a function by overloading
|
||||
<code>operator()</code>, unambiguously accepting any value of type
|
||||
<code>T</code>.</listitem>
|
||||
<listitem>Must expose inner type <code>result_type</code>. (See
|
||||
<listitem>Must expose inner type <code>result_type</code>. C++14 compatible compilers
|
||||
could detect <code>result_type</code> automatically, but will stick to
|
||||
<code>result_type</code> if it is defined. (See
|
||||
<code><functionname>boost::visitor_ptr</functionname></code> for a
|
||||
solution to using functions as visitors.)</listitem>
|
||||
<listitem>If <code>result_type</code> is not <code>void</code>, then
|
||||
@@ -123,6 +133,18 @@ public:
|
||||
}
|
||||
};</programlisting>
|
||||
|
||||
<para>C++14 compatible compilers detect <code>result_type</code> automatically:</para>
|
||||
|
||||
<programlisting>
|
||||
<classname>boost::variant</classname><int, float> v;
|
||||
// ...
|
||||
|
||||
<functionname>boost::apply_visitor</functionname>(
|
||||
[](auto val) { return std::to_string(val); },
|
||||
v
|
||||
);
|
||||
</programlisting>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -151,4 +173,4 @@ public:
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
+175
-3
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/get.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -20,7 +26,7 @@
|
||||
</method>
|
||||
</class>
|
||||
|
||||
<overloaded-function name="get">
|
||||
<overloaded-function name="relaxed_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
@@ -52,7 +58,7 @@
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
@@ -87,7 +93,9 @@
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
<code><classname>variant</classname></code>. </simpara>
|
||||
<simpara>Unlike <functionname>strict_get</functionname> does not assert at compile time
|
||||
that type <code>U</code> is one of the types that can be stored in variant.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
@@ -96,6 +104,11 @@
|
||||
<code><classname>variant</classname></code>. The function succeeds
|
||||
only if the content is of the specified type <code>U</code>, with
|
||||
failure indicated as described below.</simpara>
|
||||
<simpara><emphasis role="bold">Recomendation</emphasis>: Use
|
||||
<functionname>get</functionname> or <functionname>strict_get</functionname> in new code.
|
||||
<functionname>strict_get</functionname>
|
||||
provides more compile time checks and it's behavior is closer to <code>std::get</code>
|
||||
from C++ Standard Library.</simpara>
|
||||
<simpara><emphasis role="bold">Warning</emphasis>: After either
|
||||
<code>operand</code> or its content is destroyed (e.g., when the
|
||||
given <code><classname>variant</classname></code> is assigned a
|
||||
@@ -142,5 +155,164 @@
|
||||
</rationale>
|
||||
</overloaded-function>
|
||||
|
||||
<overloaded-function name="strict_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>Acts exactly like <functionname>relaxed_get</functionname> but does a compile time check
|
||||
that type <code>U</code> is one of the types that can be stored in variant.</simpara>
|
||||
</description>
|
||||
</overloaded-function>
|
||||
|
||||
<overloaded-function name="get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>Evaluates to <functionname>strict_get</functionname> if <code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>
|
||||
is not defined. If <code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>
|
||||
is defined then evaluates to <functionname>relaxed_get</functionname>. </simpara>
|
||||
|
||||
<simpara><emphasis role="bold">Recomendation</emphasis>: Use
|
||||
<functionname>get</functionname> in new code without defining
|
||||
<code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>. In that way <functionname>get</functionname>
|
||||
provides more compile time checks and it's behavior is closer to <code>std::get</code>
|
||||
from C++ Standard Library.</simpara>
|
||||
</description>
|
||||
</overloaded-function>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2013-2014, 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)
|
||||
-->
|
||||
<header name="boost/variant/multivisitors.hpp">
|
||||
<using-namespace name="boost"/>
|
||||
|
||||
@@ -10,7 +16,9 @@
|
||||
<macro name="BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS">
|
||||
<purpose>
|
||||
<simpara>Controls maximum amount of <code><classname>variant</classname></code>
|
||||
parameters for multi visistors. </simpara>
|
||||
parameters for multi visistors. Not used when <code>std::tuple</code> is available and
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
@@ -38,7 +46,7 @@
|
||||
<template-type-parameter name="Variant3"/>
|
||||
</template>
|
||||
|
||||
<type>typename MultiVisitor::result_type</type>
|
||||
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>MultiVisitor &</paramtype>
|
||||
@@ -65,7 +73,7 @@
|
||||
<template-type-parameter name="Variant3"/>
|
||||
</template>
|
||||
|
||||
<type>typename MultiVisitor::result_type</type>
|
||||
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
|
||||
|
||||
<parameter name="visitor">
|
||||
<paramtype>const MultiVisitor &</paramtype>
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2013-20014, 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)
|
||||
-->
|
||||
<header name="boost/variant/polymorphic_get.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
<class name="bad_polymorphic_get">
|
||||
<inherit access="public">
|
||||
<classname>boost::bad_get</classname>
|
||||
</inherit>
|
||||
|
||||
<purpose>
|
||||
<simpara>The exception thrown in the event of a failed application of
|
||||
<code><functionname>boost::polymorphic_get</functionname></code> on the given
|
||||
operand value.</simpara>
|
||||
</purpose>
|
||||
|
||||
<method name="what" specifiers="virtual" cv="const">
|
||||
<type>const char *</type>
|
||||
</method>
|
||||
</class>
|
||||
|
||||
<overloaded-function name="polymorphic_relaxed_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
<simpara>Unlike <functionname>polymorphic_strict_get</functionname> does not assert at compile time
|
||||
that type <code>U</code> is one of the types that can be stored in variant.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>The <code>polymorphic_get</code> function allows run-time checked,
|
||||
type-safe retrieval of the content of the given
|
||||
<code><classname>variant</classname></code>. The function succeeds
|
||||
only if the content is of the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>, with
|
||||
failure indicated as described below.</simpara>
|
||||
<simpara><emphasis role="bold">Recomendation</emphasis>: Use
|
||||
<functionname>polymorphic_get</functionname> or <functionname>polymorphic_strict_get</functionname>
|
||||
in new code.
|
||||
<functionname>polymorphic_strict_get</functionname>
|
||||
provides more compile time checks and it's behavior is closer to <code>std::get</code>
|
||||
from C++ Standard Library.</simpara>
|
||||
<simpara><emphasis role="bold">Warning</emphasis>: After either
|
||||
<code>operand</code> or its content is destroyed (e.g., when the
|
||||
given <code><classname>variant</classname></code> is assigned a
|
||||
value of different type), the returned reference is invalidated.
|
||||
Thus, significant care and caution must be extended when handling
|
||||
the returned reference.</simpara>
|
||||
</description>
|
||||
|
||||
<notes>
|
||||
<simpara>As part of its guarantee of type-safety, <code>polymorphic_get</code>
|
||||
enforces <code>const</code>-correctness. Thus, the specified type
|
||||
<code>U</code> must be <code>const</code>-qualified whenever
|
||||
<code>operand</code> or its content is likewise
|
||||
<code>const</code>-qualified. The converse, however, is not required:
|
||||
that is, the specified type <code>U</code> may be
|
||||
<code>const</code>-qualified even when <code>operand</code> and its
|
||||
content are not.</simpara>
|
||||
</notes>
|
||||
|
||||
<returns>
|
||||
<simpara>If passed a pointer, <code>polymorphic_get</code> returns a pointer to
|
||||
the value content if it is of the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>;
|
||||
otherwise, a null pointer is returned. If passed a reference,
|
||||
<code>polymorphic_get</code> returns a reference to the value content if it is of
|
||||
the specified type <code>U</code> or of type
|
||||
derived from type <code>U</code>; otherwise, an exception is thrown
|
||||
(see below).</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>Overloads taking a
|
||||
<code><classname>variant</classname></code> pointer will not
|
||||
throw; the overloads taking a
|
||||
<code><classname>variant</classname></code> reference throw
|
||||
<code><classname>bad_polymorphic_get</classname></code> if the content is not of
|
||||
the specified type <code>U</code>or of type
|
||||
derived from type <code>U</code>.</simpara>
|
||||
</throws>
|
||||
|
||||
<rationale>
|
||||
<simpara>While visitation via
|
||||
<code><functionname>apply_visitor</functionname></code>
|
||||
is generally preferred due to its greater safety, <code>polymorphic_get</code> may
|
||||
may be more convenient in some cases due to its straightforward
|
||||
usage.</simpara>
|
||||
</rationale>
|
||||
</overloaded-function>
|
||||
|
||||
|
||||
|
||||
<overloaded-function name="polymorphic_strict_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>Acts exactly like <functionname>polymorphic_relaxed_get</functionname> but does a compile time check
|
||||
that type <code>U</code> is one of the types that can be stored in variant.</simpara>
|
||||
</description>
|
||||
</overloaded-function>
|
||||
|
||||
<overloaded-function name="polymorphic_get">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U *</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> *</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype><classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
<template-type-parameter name="T1"/>
|
||||
<template-type-parameter name="T2"/>
|
||||
<template-varargs/>
|
||||
<template-type-parameter name="TN"/>
|
||||
</template>
|
||||
|
||||
<type>const U &</type>
|
||||
|
||||
<parameter name="operand">
|
||||
<paramtype>const <classname>variant</classname><T1, T2, ..., TN> &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<simpara>Retrieves a value of a specified type from a given
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<simpara>Evaluates to <functionname>polymorphic_strict_get</functionname>
|
||||
if <code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>
|
||||
is not defined. If <code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>
|
||||
is defined then evaluates to <functionname>polymorphic_relaxed_get</functionname>. </simpara>
|
||||
|
||||
<simpara><emphasis role="bold">Recomendation</emphasis>: Use
|
||||
<functionname>polymorphic_get</functionname> in new code without defining
|
||||
<code>BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT</code>. In that way
|
||||
<functionname>polymorphic_get</functionname>
|
||||
provides more compile time checks and it's behavior is closer to <code>std::get</code>
|
||||
from C++ Standard Library.</simpara>
|
||||
</description>
|
||||
</overloaded-function>
|
||||
</namespace>
|
||||
</header>
|
||||
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/recursive_variant.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -108,4 +114,4 @@
|
||||
</class>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/recursive_wrapper.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -261,4 +267,4 @@
|
||||
</class>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library-reference PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<library-reference xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<xi:include href="concepts.xml"/>
|
||||
@@ -19,6 +25,7 @@
|
||||
<xi:include href="apply_visitor.xml"/>
|
||||
<xi:include href="multivisitor.xml"/>
|
||||
<xi:include href="get.xml"/>
|
||||
<xi:include href="polymorphic_get.xml"/>
|
||||
<xi:include href="bad_visit.xml"/>
|
||||
<xi:include href="static_visitor.xml"/>
|
||||
<xi:include href="visitor_ptr.xml"/>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/static_visitor.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -28,4 +34,4 @@
|
||||
</class>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
+203
-8
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/variant.hpp">
|
||||
<namespace name="boost">
|
||||
<class name="variant">
|
||||
@@ -502,6 +508,12 @@
|
||||
<method name="type" cv="const">
|
||||
<type>const std::type_info &</type>
|
||||
|
||||
<notes>
|
||||
<simpara><code>boost::variant</code> usues Boost.TypeIndex library so actually
|
||||
<code>const boost::typeindex::type_info &</code> is returned.
|
||||
This method is available even if RTTI is off.</simpara>
|
||||
</notes>
|
||||
|
||||
<returns>
|
||||
<simpara><code>typeid(x)</code>, where <code>x</code> is the the
|
||||
content of <code>*this</code>.</simpara>
|
||||
@@ -509,10 +521,6 @@
|
||||
|
||||
<throws>Will not throw.</throws>
|
||||
|
||||
<notes>
|
||||
<simpara>Not available when <code>BOOST_NO_TYPEID</code> is
|
||||
defined.</simpara>
|
||||
</notes>
|
||||
</method>
|
||||
|
||||
</method-group>
|
||||
@@ -528,7 +536,7 @@
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
@@ -554,14 +562,60 @@
|
||||
</requires>
|
||||
|
||||
<returns>
|
||||
<simpara><code>true</code> iff <code>which() == rhs.which()</code>
|
||||
<simpara><code>true</code> if <code>which() == rhs.which()</code>
|
||||
<emphasis>and</emphasis>
|
||||
<code>content_this == content_rhs</code>, where
|
||||
<code>content_this</code> is the content of <code>*this</code>
|
||||
and <code>content_rhs</code> is the content of
|
||||
<code>rhs</code>.</simpara>
|
||||
</returns>
|
||||
|
||||
|
||||
<throws>
|
||||
<simpara>If <code>which() == rhs.which()</code> then may fail with
|
||||
any exceptions arising from <code>operator==(T,T)</code>, where
|
||||
<code>T</code> is the contained type of
|
||||
<code>*this</code>.</simpara>
|
||||
</throws>
|
||||
</overloaded-method>
|
||||
|
||||
<overloaded-method name="operator!=" cv="const">
|
||||
<purpose>InEquality comparison.</purpose>
|
||||
|
||||
<signature cv="const">
|
||||
<type>bool</type>
|
||||
<parameter name="rhs">
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
</template>
|
||||
<parameter>
|
||||
<paramtype>const U &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<notes>
|
||||
<simpara>The overload returning <code>void</code> exists only to
|
||||
prohibit implicit conversion of the operator's right-hand side
|
||||
to <code>variant</code>; thus, its use will (purposefully)
|
||||
result in a compile-time error.</simpara>
|
||||
</notes>
|
||||
|
||||
<requires>
|
||||
<simpara>Every bounded type of the <code>variant</code> must
|
||||
fulfill the requirements of the
|
||||
<conceptname>EqualityComparable</conceptname>
|
||||
concept.</simpara>
|
||||
</requires>
|
||||
|
||||
<returns>
|
||||
<simpara><code>true</code> if <code>!(*this == rhs)</code>.</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>If <code>which() == rhs.which()</code> then may fail with
|
||||
any exceptions arising from <code>operator==(T,T)</code>, where
|
||||
@@ -579,7 +633,7 @@
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
@@ -620,6 +674,147 @@
|
||||
</throws>
|
||||
</overloaded-method>
|
||||
|
||||
|
||||
<overloaded-method name="operator>">
|
||||
<purpose>GreaterThan comparison.</purpose>
|
||||
|
||||
<signature cv="const">
|
||||
<type>bool</type>
|
||||
<parameter name="rhs">
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
</template>
|
||||
<parameter>
|
||||
<paramtype>const U &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<notes>
|
||||
<simpara>The overload returning <code>void</code> exists only to
|
||||
prohibit implicit conversion of the operator's right-hand side
|
||||
to <code>variant</code>; thus, its use will (purposefully)
|
||||
result in a compile-time error.</simpara>
|
||||
</notes>
|
||||
|
||||
<requires>
|
||||
<simpara>Every bounded type of the <code>variant</code> must
|
||||
fulfill the requirements of the
|
||||
<conceptname>LessThanComparable</conceptname>
|
||||
concept.</simpara>
|
||||
</requires>
|
||||
|
||||
<returns>
|
||||
<simpara>true if <code>rhs < *this</code>.</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>May fail with
|
||||
any exceptions arising from <code>operator<(T,T)</code>,
|
||||
where <code>T</code> is the contained type of
|
||||
<code>*this</code>.</simpara>
|
||||
</throws>
|
||||
</overloaded-method>
|
||||
|
||||
|
||||
<overloaded-method name="operator<=">
|
||||
<purpose>LessThan or Equal comparison.</purpose>
|
||||
|
||||
<signature cv="const">
|
||||
<type>bool</type>
|
||||
<parameter name="rhs">
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
</template>
|
||||
<parameter>
|
||||
<paramtype>const U &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<notes>
|
||||
<simpara>The overload returning <code>void</code> exists only to
|
||||
prohibit implicit conversion of the operator's right-hand side
|
||||
to <code>variant</code>; thus, its use will (purposefully)
|
||||
result in a compile-time error.</simpara>
|
||||
</notes>
|
||||
|
||||
<requires>
|
||||
<simpara>Every bounded type of the <code>variant</code> must
|
||||
fulfill the requirements of the
|
||||
<conceptname>LessThanComparable</conceptname>
|
||||
concept.</simpara>
|
||||
</requires>
|
||||
|
||||
<returns>
|
||||
<simpara>true if <code>!(*this > rhs)</code>.</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>May fail with
|
||||
any exceptions arising from <code>operator<(T,T)</code>,
|
||||
where <code>T</code> is the contained type of
|
||||
<code>*this</code>.</simpara>
|
||||
</throws>
|
||||
</overloaded-method>
|
||||
|
||||
|
||||
<overloaded-method name="operator>=">
|
||||
<purpose>GreaterThan or Equal comparison.</purpose>
|
||||
|
||||
<signature cv="const">
|
||||
<type>bool</type>
|
||||
<parameter name="rhs">
|
||||
<paramtype>const variant &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<signature cv="const">
|
||||
<type>void</type>
|
||||
<template>
|
||||
<template-type-parameter name="U"/>
|
||||
</template>
|
||||
<parameter>
|
||||
<paramtype>const U &</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<notes>
|
||||
<simpara>The overload returning <code>void</code> exists only to
|
||||
prohibit implicit conversion of the operator's right-hand side
|
||||
to <code>variant</code>; thus, its use will (purposefully)
|
||||
result in a compile-time error.</simpara>
|
||||
</notes>
|
||||
|
||||
<requires>
|
||||
<simpara>Every bounded type of the <code>variant</code> must
|
||||
fulfill the requirements of the
|
||||
<conceptname>LessThanComparable</conceptname>
|
||||
concept.</simpara>
|
||||
</requires>
|
||||
|
||||
<returns>
|
||||
<simpara>true if <code>!(*this < lhs)</code>.</simpara>
|
||||
</returns>
|
||||
|
||||
<throws>
|
||||
<simpara>May fail with
|
||||
any exceptions arising from <code>operator<(T,T)</code>,
|
||||
where <code>T</code> is the contained type of
|
||||
<code>*this</code>.</simpara>
|
||||
</throws>
|
||||
</overloaded-method>
|
||||
|
||||
</method-group>
|
||||
</class>
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/variant_fwd.hpp">
|
||||
<using-namespace name="boost"/>
|
||||
|
||||
@@ -14,7 +22,10 @@
|
||||
<purpose>
|
||||
<simpara>Expands to the length of the
|
||||
template parameter list for
|
||||
<code><classname>variant</classname></code>.</simpara>
|
||||
<code><classname>variant</classname></code>. Not used if
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined.
|
||||
</simpara>
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
@@ -25,6 +36,18 @@
|
||||
</description>
|
||||
</macro>
|
||||
|
||||
<macro name="BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES">
|
||||
<purpose>
|
||||
<simpara>If this macro is defined, then library won't use C++11 variadic templates.
|
||||
Users may define this macro to make
|
||||
<code><macroname>BOOST_VARIANT_ENUM_PARAMS</macroname></code>
|
||||
and <code><macroname>BOOST_VARIANT_ENUM_SHIFTED_PARAMS</macroname></code> expand
|
||||
to a comma-separated sequence instead of variadic templates. Define this macro if
|
||||
your compiler has problems with compilation of variadic templates.
|
||||
</simpara>
|
||||
</purpose>
|
||||
</macro>
|
||||
|
||||
<macro name="BOOST_VARIANT_ENUM_PARAMS" kind="functionlike">
|
||||
<macro-parameter name="param"/>
|
||||
|
||||
@@ -34,7 +57,21 @@
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<para>Expands to a comma-separated sequence of length
|
||||
<para> When variadic templates are available and
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined, expands to variadic template list in the following manner:
|
||||
<code><programlisting>
|
||||
BOOST_VARIANT_ENUM_PARAMS(T) => T0, TN...
|
||||
BOOST_VARIANT_ENUM_PARAMS(class T) => class T0, class... TN
|
||||
BOOST_VARIANT_ENUM_PARAMS(class Something) => class Something0, class... SomethingN
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename Something) => typename Something0, typename... SomethingN
|
||||
BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
|
||||
BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
|
||||
</programlisting></code>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Otherwise expands to a comma-separated sequence of length
|
||||
<code><macroname>BOOST_VARIANT_LIMIT_TYPES</macroname></code>, where
|
||||
each element in the sequence consists of the concatenation of
|
||||
<emphasis>param</emphasis> with its zero-based index into the
|
||||
@@ -59,7 +96,21 @@
|
||||
</purpose>
|
||||
|
||||
<description>
|
||||
<para>Expands to a comma-separated sequence of length
|
||||
<para> When variadic templates are available and
|
||||
<code><macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname></code>
|
||||
is not defined, expands to variadic template list in the following manner:
|
||||
<code><programlisting>
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) => TN...
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class T) => class... TN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something) => class... SomethingN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something) => typename... SomethingN
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
|
||||
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
|
||||
</programlisting></code>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Otherwise expands to a comma-separated sequence of length
|
||||
<code><macroname>BOOST_VARIANT_LIMIT_TYPES</macroname> - 1</code>,
|
||||
where each element in the sequence consists of the concatenation of
|
||||
<emphasis>param</emphasis> with its one-based index into the sequence.
|
||||
@@ -121,4 +172,4 @@
|
||||
full lambda support either.)</para>
|
||||
</description>
|
||||
</macro>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?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">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<header name="boost/variant/visitor_ptr.hpp">
|
||||
<namespace name="boost">
|
||||
|
||||
@@ -105,4 +111,4 @@
|
||||
</function>
|
||||
|
||||
</namespace>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
Copyright 2013-2014, 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)
|
||||
-->
|
||||
<section id="variant.tutorial.advanced">
|
||||
<title>Advanced Topics</title>
|
||||
|
||||
@@ -390,19 +397,20 @@ struct if_visitor: public <classname>boost::static_visitor</classname><arithm
|
||||
arguments by means of <code>apply_visitor</code>:
|
||||
|
||||
<programlisting>
|
||||
bool_like_t v0(1), v1(true), v2(1.0);
|
||||
bool_like_t v0(true), v1(1), v2(2.0);
|
||||
|
||||
assert(
|
||||
<functionname>boost::apply_visitor</functionname>(if_visitor(), v0, v1, v2)
|
||||
==
|
||||
arithmetics_t(true)
|
||||
arithmetics_t(1)
|
||||
);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>Finally, we must note that multi visitation does not support
|
||||
"delayed" form of
|
||||
<code><functionname>apply_visitor</functionname></code>.
|
||||
<code><functionname>apply_visitor</functionname> if
|
||||
<macroname>BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</macroname> is defined</code>.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section id="variant.tutorial.basic">
|
||||
<title>Basic Usage</title>
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="variant.tutorial">
|
||||
|
||||
<title>Tutorial</title>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
<!--
|
||||
Copyright 2003, Eric Friedman, Itay Maman.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<library name="Variant" dirname="variant"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude" id="variant">
|
||||
<libraryinfo>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2002-2003
|
||||
// Eric Friedman
|
||||
// Copyright (c) 2002-2003 Eric Friedman
|
||||
// Copyright (c) 2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -25,6 +25,11 @@
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
# include "boost/variant/detail/has_result_type.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -69,7 +74,6 @@ public: // visitor interfaces
|
||||
|
||||
private:
|
||||
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor, typename Visitable2>
|
||||
@@ -173,6 +177,104 @@ apply_visitor(
|
||||
return boost::apply_visitor(unwrapper, visitable1);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// function template apply_visitor(visitor, visitable1, visitable2)
|
||||
//
|
||||
// C++14 part.
|
||||
//
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
template <typename Visitor, typename Value1>
|
||||
class apply_visitor_binary_invoke_cpp14
|
||||
{
|
||||
Visitor& visitor_;
|
||||
Value1& value1_;
|
||||
|
||||
public: // structors
|
||||
|
||||
apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, value1_(value1)
|
||||
{
|
||||
}
|
||||
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename Value2>
|
||||
decltype(auto) operator()(Value2& value2)
|
||||
{
|
||||
return visitor_(value1_, value2);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
|
||||
};
|
||||
|
||||
template <typename Visitor, typename Visitable2>
|
||||
class apply_visitor_binary_unwrap_cpp14
|
||||
{
|
||||
Visitor& visitor_;
|
||||
Visitable2& visitable2_;
|
||||
|
||||
public: // structors
|
||||
|
||||
apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, visitable2_(visitable2)
|
||||
{
|
||||
}
|
||||
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename Value1>
|
||||
decltype(auto) operator()(Value1& value1)
|
||||
{
|
||||
apply_visitor_binary_invoke_cpp14<
|
||||
Visitor
|
||||
, Value1
|
||||
> invoker(visitor_, value1);
|
||||
|
||||
return boost::apply_visitor(invoker, visitable2_);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
template <typename Visitor, typename Visitable1, typename Visitable2>
|
||||
inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
|
||||
Visitor, Visitable2
|
||||
> unwrapper(visitor, visitable2);
|
||||
|
||||
return boost::apply_visitor(unwrapper, visitable1);
|
||||
}
|
||||
|
||||
template <typename Visitor, typename Visitable1, typename Visitable2>
|
||||
inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
|
||||
const Visitor, Visitable2
|
||||
> unwrapper(visitor, visitable2);
|
||||
|
||||
return boost::apply_visitor(unwrapper, visitable1);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
#include "boost/variant/detail/apply_visitor_unary.hpp"
|
||||
#include "boost/variant/detail/apply_visitor_binary.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
|
||||
|
||||
#include "boost/variant/detail/has_result_type.hpp"
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -54,6 +59,18 @@ public: // structors
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
public: // N-ary visitor interface
|
||||
template <typename... Visitables>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
|
||||
operator()(Visitables&... visitables) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitables...);
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
public: // unary visitor interface
|
||||
|
||||
template <typename Visitable>
|
||||
@@ -72,17 +89,63 @@ public: // binary visitor interface
|
||||
return apply_visitor(visitor_, visitable1, visitable2);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
private:
|
||||
apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor>
|
||||
inline apply_visitor_delayed_t<Visitor> apply_visitor(Visitor& visitor)
|
||||
inline typename boost::enable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>,
|
||||
apply_visitor_delayed_t<Visitor>
|
||||
>::type apply_visitor(Visitor& visitor)
|
||||
{
|
||||
return apply_visitor_delayed_t<Visitor>(visitor);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) \
|
||||
&& !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename Visitor>
|
||||
class apply_visitor_delayed_cpp14_t
|
||||
{
|
||||
private: // representation
|
||||
Visitor& visitor_;
|
||||
|
||||
public: // structors
|
||||
|
||||
explicit apply_visitor_delayed_cpp14_t(Visitor& visitor) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
{
|
||||
}
|
||||
|
||||
public: // N-ary visitor interface
|
||||
template <typename... Visitables>
|
||||
decltype(auto) operator()(Visitables&... visitables) const
|
||||
{
|
||||
return apply_visitor(visitor_, visitables...);
|
||||
}
|
||||
|
||||
private:
|
||||
apply_visitor_delayed_cpp14_t& operator=(const apply_visitor_delayed_cpp14_t&);
|
||||
|
||||
};
|
||||
|
||||
template <typename Visitor>
|
||||
inline typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>,
|
||||
apply_visitor_delayed_cpp14_t<Visitor>
|
||||
>::type apply_visitor(Visitor& visitor)
|
||||
{
|
||||
return apply_visitor_delayed_cpp14_t<Visitor>(visitor);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
// && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2002-2003
|
||||
// Eric Friedman
|
||||
// Copyright (c) 2002-2003 Eric Friedman
|
||||
// Copyright (c) 2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,11 +18,21 @@
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
|
||||
#include "boost/utility/enable_if.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/mpl/not.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
# include <boost/mpl/distance.hpp>
|
||||
# include <boost/mpl/advance.hpp>
|
||||
# include <boost/mpl/deref.hpp>
|
||||
# include <boost/mpl/size.hpp>
|
||||
# include <boost/utility/declval.hpp>
|
||||
# include <boost/core/enable_if.hpp>
|
||||
# include "boost/variant/detail/has_result_type.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -74,6 +84,90 @@ apply_visitor(const Visitor& visitor, Visitable& visitable)
|
||||
return visitable.apply_visitor(visitor);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
|
||||
// C++14
|
||||
namespace detail { namespace variant {
|
||||
|
||||
// This class serves only metaprogramming purposes. none of its methods must be called at runtime!
|
||||
template <class Visitor, class Variant>
|
||||
struct result_multideduce1 {
|
||||
typedef typename Variant::types types;
|
||||
typedef typename boost::mpl::begin<types>::type begin_it;
|
||||
typedef typename boost::mpl::advance<
|
||||
begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
|
||||
>::type last_it;
|
||||
|
||||
// For metaprogramming purposes ONLY! Do not use this method (and class) at runtime!
|
||||
static Visitor& vis() BOOST_NOEXCEPT {
|
||||
// Functions that work with lambdas must be defined in same translation unit.
|
||||
// Because of that, we can not use `boost::decval<Visitor&>()` here.
|
||||
Visitor&(*f)() = 0; // pointer to function
|
||||
return f();
|
||||
}
|
||||
|
||||
static decltype(auto) deduce_impl(last_it, unsigned /*helper*/) {
|
||||
typedef typename boost::mpl::deref<last_it>::type value_t;
|
||||
return vis()( boost::declval< value_t& >() );
|
||||
}
|
||||
|
||||
template <class It>
|
||||
static decltype(auto) deduce_impl(It, unsigned helper) {
|
||||
typedef typename boost::mpl::next<It>::type next_t;
|
||||
typedef typename boost::mpl::deref<It>::type value_t;
|
||||
if (helper == boost::mpl::distance<begin_it, It>::type::value) {
|
||||
return deduce_impl(next_t(), ++helper);
|
||||
}
|
||||
|
||||
return vis()( boost::declval< value_t& >() );
|
||||
}
|
||||
|
||||
static decltype(auto) deduce() {
|
||||
return deduce_impl(begin_it(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Visitor, class Variant>
|
||||
struct result_wrapper1
|
||||
{
|
||||
typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
|
||||
|
||||
Visitor& visitor_;
|
||||
explicit result_wrapper1(Visitor& visitor) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
result_type operator()(T& val) const {
|
||||
return visitor_(val);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
template <typename Visitor, typename Visitable>
|
||||
inline decltype(auto) apply_visitor(Visitor& visitor, Visitable& visitable,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(visitor);
|
||||
return visitable.apply_visitor(cpp14_vis);
|
||||
}
|
||||
|
||||
template <typename Visitor, typename Visitable>
|
||||
inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable& visitable,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
boost::detail::variant::result_wrapper1<const Visitor, Visitable> cpp14_vis(visitor);
|
||||
return visitable.apply_visitor(cpp14_vis);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/element_index.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2014-2015 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP
|
||||
#define BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/variant/recursive_wrapper_fwd.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
|
||||
#include "boost/type_traits/remove_cv.hpp"
|
||||
#include "boost/type_traits/remove_reference.hpp"
|
||||
#include "boost/mpl/find_if.hpp"
|
||||
|
||||
namespace boost { namespace detail { namespace variant {
|
||||
|
||||
template <class VariantElement, class T>
|
||||
struct variant_element_functor :
|
||||
boost::mpl::or_<
|
||||
boost::is_same<VariantElement, T>,
|
||||
boost::is_same<VariantElement, boost::recursive_wrapper<T> >,
|
||||
boost::is_same<VariantElement, T& >
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Types, class T>
|
||||
struct element_iterator_impl :
|
||||
boost::mpl::find_if<
|
||||
Types,
|
||||
boost::mpl::or_<
|
||||
variant_element_functor<boost::mpl::_1, T>,
|
||||
variant_element_functor<boost::mpl::_1, typename boost::remove_cv<T>::type >
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Variant, class T>
|
||||
struct element_iterator :
|
||||
element_iterator_impl< typename Variant::types, typename boost::remove_reference<T>::type >
|
||||
{};
|
||||
|
||||
template <class Variant, class T>
|
||||
struct holds_element :
|
||||
boost::mpl::not_<
|
||||
boost::is_same<
|
||||
typename boost::mpl::end<typename Variant::types>::type,
|
||||
typename element_iterator<Variant, T>::type
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
}}} // namespace boost::detail::variant
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_ELEMENT_INDEX_HPP
|
||||
@@ -17,10 +17,6 @@
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
#include "boost/assert.hpp"
|
||||
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include "boost/type_traits/remove_reference.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
@@ -42,9 +38,8 @@ inline T forced_return()
|
||||
// logical error: should never be here! (see above)
|
||||
BOOST_ASSERT(false);
|
||||
|
||||
typedef typename boost::remove_reference<T>::type basic_type;
|
||||
basic_type* dummy = 0;
|
||||
return *static_cast< basic_type* >(dummy);
|
||||
T (*dummy_function_ptr)() = 0;
|
||||
return dummy_function_ptr();
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -76,6 +71,8 @@ forced_return()
|
||||
|
||||
#else // defined(BOOST_MSVC)
|
||||
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4702 ) // unreachable code
|
||||
// msvc-specific implementation
|
||||
//
|
||||
// Leverages __declspec(noreturn) for optimized implementation.
|
||||
@@ -95,6 +92,8 @@ forced_return()
|
||||
forced_return_no_return();
|
||||
}
|
||||
|
||||
# pragma warning( pop )
|
||||
|
||||
#endif // BOOST_MSVC optimization
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/detail/has_result_type.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2014-2015 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
|
||||
#define BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/type_traits/remove_reference.hpp"
|
||||
|
||||
|
||||
namespace boost { namespace detail { namespace variant {
|
||||
|
||||
template <typename T >
|
||||
struct has_result_type {
|
||||
private:
|
||||
typedef char yes;
|
||||
typedef struct { char array[2]; } no;
|
||||
|
||||
template<typename C> static yes test(typename boost::remove_reference<typename C::result_type>::type*);
|
||||
template<typename C> static no test(...);
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test<T>(0)) == sizeof(yes));
|
||||
};
|
||||
|
||||
}}} // namespace boost::detail::variant
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace detail { namespace variant {
|
||||
// declaration workaround (below).
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
template < typename... T >
|
||||
struct make_variant_list
|
||||
@@ -40,7 +40,7 @@ struct make_variant_list
|
||||
typedef typename mpl::list< T... >::type type;
|
||||
};
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
struct make_variant_list
|
||||
@@ -65,7 +65,7 @@ public: // metafunction result
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
}} // namespace detail::variant
|
||||
} // namespace boost
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// Copyright (c) 2002-2003 Eric Friedman
|
||||
// Copyright (c) 2002 by Andrei Alexandrescu
|
||||
// Copyright (c) 2013 Antony Polukhin
|
||||
// Copyright (c) 2013-2014 Antony Polukhin
|
||||
//
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/move/move.hpp"
|
||||
#include "boost/move/adl_move_swap.hpp"
|
||||
|
||||
namespace boost { namespace detail { namespace variant {
|
||||
|
||||
@@ -38,27 +39,10 @@ using boost::move;
|
||||
// types and on non-conforming compilers.
|
||||
//
|
||||
|
||||
namespace move_swap_fallback {
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline void swap(T1& lhs, T2& rhs)
|
||||
{
|
||||
T1 tmp( boost::detail::variant::move(lhs) );
|
||||
lhs = boost::detail::variant::move(rhs);
|
||||
rhs = boost::detail::variant::move(tmp);
|
||||
}
|
||||
|
||||
} // namespace move_swap_fallback
|
||||
|
||||
template <typename T>
|
||||
inline void move_swap(T& lhs, T& rhs)
|
||||
{
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
move_swap_fallback::swap(lhs, rhs);
|
||||
#else
|
||||
using move_swap_fallback::swap;
|
||||
swap(lhs, rhs);
|
||||
#endif
|
||||
::boost::adl_move_swap(lhs, rhs);
|
||||
}
|
||||
|
||||
}}} // namespace boost::detail::variant
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
// Boost.Varaint
|
||||
// Contains multivisitors that are implemented via variadic templates and std::tuple
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013-2014.
|
||||
//
|
||||
// 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_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
|
||||
#define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant/detail/apply_visitor_unary.hpp>
|
||||
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
|
||||
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
# error "This file requires <tuple> and variadic templates support"
|
||||
#endif
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
// Implementing some of the C++14 features in C++11
|
||||
template <std::size_t... I> class index_sequence {};
|
||||
|
||||
template <std::size_t N, std::size_t... I>
|
||||
struct make_index_sequence
|
||||
: make_index_sequence<N-1, N-1, I...>
|
||||
{};
|
||||
template <std::size_t... I>
|
||||
struct make_index_sequence<0, I...>
|
||||
: index_sequence<I...>
|
||||
{};
|
||||
|
||||
template <class... Types>
|
||||
std::tuple<Types&...> forward_as_tuple_simple(Types&... args) BOOST_NOEXCEPT
|
||||
{
|
||||
return std::tuple<Types&...>(args...);
|
||||
}
|
||||
|
||||
// Implementing some of the helper tuple methods
|
||||
template <std::size_t... I, typename Tuple>
|
||||
std::tuple<typename std::tuple_element<I + 1, Tuple>::type...>
|
||||
tuple_tail_impl(const Tuple& tpl, index_sequence<I...>)
|
||||
{
|
||||
return std::tuple<
|
||||
typename std::tuple_element<I + 1, Tuple>::type...
|
||||
> (std::get<I + 1>(tpl)...);
|
||||
}
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...>& tpl)
|
||||
{
|
||||
return tuple_tail_impl(tpl, make_index_sequence<sizeof...(Tail)>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Forward declaration
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer;
|
||||
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
inline one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... >
|
||||
make_one_by_one_visitor_and_value_referer(
|
||||
Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
|
||||
)
|
||||
{
|
||||
return one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... > (
|
||||
visitor, visitables, values
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer
|
||||
{
|
||||
Visitor& visitor_;
|
||||
std::tuple<Values&...> values_;
|
||||
Visitables visitables_;
|
||||
|
||||
public: // structors
|
||||
one_by_one_visitor_and_value_referer(
|
||||
Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
|
||||
) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, values_(values)
|
||||
, visitables_(visitables)
|
||||
{}
|
||||
|
||||
public: // visitor interfaces
|
||||
typedef typename Visitor::result_type result_type;
|
||||
|
||||
template <typename Value>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
|
||||
{
|
||||
return ::boost::apply_visitor(
|
||||
make_one_by_one_visitor_and_value_referer(
|
||||
visitor_,
|
||||
tuple_tail(visitables_),
|
||||
std::tuple_cat(values_, std::tuple<Value&>(value))
|
||||
)
|
||||
, std::get<0>(visitables_) // getting Head element
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
one_by_one_visitor_and_value_referer& operator=(const one_by_one_visitor_and_value_referer&);
|
||||
};
|
||||
|
||||
template <typename Visitor, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer<Visitor, std::tuple<>, Values...>
|
||||
{
|
||||
Visitor& visitor_;
|
||||
std::tuple<Values&...> values_;
|
||||
|
||||
public:
|
||||
one_by_one_visitor_and_value_referer(
|
||||
Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values&...> values
|
||||
) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, values_(values)
|
||||
{}
|
||||
|
||||
typedef typename Visitor::result_type result_type;
|
||||
|
||||
template <class Tuple, std::size_t... I>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) do_call(Tuple t, index_sequence<I...>) const {
|
||||
return visitor_(std::get<I>(t)...);
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
|
||||
{
|
||||
return do_call(
|
||||
std::tuple_cat(values_, std::tuple<Value&>(value)),
|
||||
make_index_sequence<sizeof...(Values) + 1>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
template <class Visitor, class T1, class T2, class T3, class... TN>
|
||||
inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
|
||||
apply_visitor(const Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
|
||||
{
|
||||
return ::boost::apply_visitor(
|
||||
::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
|
||||
visitor,
|
||||
::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
|
||||
std::tuple<>()
|
||||
),
|
||||
v1
|
||||
);
|
||||
}
|
||||
|
||||
template <class Visitor, class T1, class T2, class T3, class... TN>
|
||||
inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
|
||||
apply_visitor(Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
|
||||
{
|
||||
return ::boost::apply_visitor(
|
||||
::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
|
||||
visitor,
|
||||
::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
|
||||
std::tuple<>()
|
||||
),
|
||||
v1
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
// Boost.Varaint
|
||||
// Contains multivisitors that are implemented via variadic templates, std::tuple
|
||||
// and decltype(auto)
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013-2014.
|
||||
//
|
||||
// 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_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
|
||||
#define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant/detail/multivisitors_cpp14_based.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
// Forward declaration
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer_cpp14;
|
||||
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
inline one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... >
|
||||
make_one_by_one_visitor_and_value_referer_cpp14(
|
||||
Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
|
||||
)
|
||||
{
|
||||
return one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... > (
|
||||
visitor, visitables, values
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Visitor, typename Visitables, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer_cpp14
|
||||
{
|
||||
Visitor& visitor_;
|
||||
std::tuple<Values&...> values_;
|
||||
Visitables visitables_;
|
||||
|
||||
public: // structors
|
||||
one_by_one_visitor_and_value_referer_cpp14(
|
||||
Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
|
||||
) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, values_(values)
|
||||
, visitables_(visitables)
|
||||
{}
|
||||
|
||||
public: // visitor interfaces
|
||||
template <typename Value>
|
||||
decltype(auto) operator()(Value& value) const
|
||||
{
|
||||
return ::boost::apply_visitor(
|
||||
make_one_by_one_visitor_and_value_referer_cpp14(
|
||||
visitor_,
|
||||
tuple_tail(visitables_),
|
||||
std::tuple_cat(values_, std::tuple<Value&>(value))
|
||||
)
|
||||
, std::get<0>(visitables_) // getting Head element
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
one_by_one_visitor_and_value_referer_cpp14& operator=(const one_by_one_visitor_and_value_referer_cpp14&);
|
||||
};
|
||||
|
||||
template <typename Visitor, typename... Values>
|
||||
class one_by_one_visitor_and_value_referer_cpp14<Visitor, std::tuple<>, Values...>
|
||||
{
|
||||
Visitor& visitor_;
|
||||
std::tuple<Values&...> values_;
|
||||
|
||||
public:
|
||||
one_by_one_visitor_and_value_referer_cpp14(
|
||||
Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values&...> values
|
||||
) BOOST_NOEXCEPT
|
||||
: visitor_(visitor)
|
||||
, values_(values)
|
||||
{}
|
||||
|
||||
template <class Tuple, std::size_t... I>
|
||||
decltype(auto) do_call(Tuple t, index_sequence<I...>) const {
|
||||
return visitor_(std::get<I>(t)...);
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
decltype(auto) operator()(Value& value) const
|
||||
{
|
||||
return do_call(
|
||||
std::tuple_cat(values_, std::tuple<Value&>(value)),
|
||||
make_index_sequence<sizeof...(Values) + 1>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
template <class Visitor, class T1, class T2, class T3, class... TN>
|
||||
inline decltype(auto) apply_visitor(const Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
return boost::apply_visitor(
|
||||
::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
|
||||
visitor,
|
||||
::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
|
||||
std::tuple<>()
|
||||
),
|
||||
v1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template <class Visitor, class T1, class T2, class T3, class... TN>
|
||||
inline decltype(auto) apply_visitor(Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn,
|
||||
typename boost::disable_if<
|
||||
boost::detail::variant::has_result_type<Visitor>
|
||||
>::type* = 0)
|
||||
{
|
||||
return ::boost::apply_visitor(
|
||||
::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
|
||||
visitor,
|
||||
::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
|
||||
std::tuple<>()
|
||||
),
|
||||
v1
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// Boost.Varaint
|
||||
// Contains multivisitors that are implemented via preprocessor magic
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013-2014.
|
||||
//
|
||||
// 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_DETAIL_MULTIVISITORS_PREPROCESSOR_BASED_HPP
|
||||
#define BOOST_VARIANT_DETAIL_MULTIVISITORS_PREPROCESSOR_BASED_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 suppress warnings and ensure 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_DETAIL_MULTIVISITORS_PREPROCESSOR_BASED_HPP
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "boost/mpl/aux_/config/ctps.hpp"
|
||||
|
||||
#include "boost/variant/detail/substitute_fwd.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
#include "boost/mpl/aux_/lambda_arity_param.hpp"
|
||||
#include "boost/mpl/aux_/preprocessor/params.hpp"
|
||||
#include "boost/mpl/aux_/preprocessor/repeat.hpp"
|
||||
@@ -125,6 +126,27 @@ struct substitute<
|
||||
// template expression (i.e., F<...>) specializations
|
||||
//
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <
|
||||
template <typename...> class F
|
||||
, typename... Ts
|
||||
, typename Dest
|
||||
, typename Source
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
|
||||
>
|
||||
struct substitute<
|
||||
F<Ts...>
|
||||
, Dest
|
||||
, Source
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
typedef F<typename substitute<
|
||||
Ts, Dest, Source
|
||||
>::type...> type;
|
||||
};
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
|
||||
typedef typename substitute< \
|
||||
BOOST_PP_CAT(U,N), Dest, Source \
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include "boost/variant/detail/cast_storage.hpp"
|
||||
#include "boost/variant/detail/forced_return.hpp"
|
||||
#include "boost/variant/detail/generic_result_type.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
|
||||
#include "boost/assert.hpp"
|
||||
#include "boost/mpl/eval_if.hpp"
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/identity.hpp"
|
||||
@@ -47,10 +47,18 @@
|
||||
// and potentially increase runtime performance. (TODO: Investigate further.)
|
||||
//
|
||||
#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
|
||||
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
# include "boost/mpl/limits/list.hpp"
|
||||
# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
|
||||
BOOST_MPL_LIMIT_LIST_SIZE
|
||||
#else
|
||||
# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
|
||||
BOOST_VARIANT_LIMIT_TYPES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail { namespace variant {
|
||||
|
||||
@@ -154,8 +162,7 @@ inline
|
||||
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
|
||||
visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
|
||||
{
|
||||
// should never be here at runtime:
|
||||
BOOST_ASSERT(false);
|
||||
// should never be here at runtime!
|
||||
typedef typename Visitor::result_type result_type;
|
||||
return ::boost::detail::variant::forced_return< result_type >();
|
||||
}
|
||||
@@ -179,8 +186,7 @@ visitation_impl(
|
||||
, NBF, W* = 0, S* = 0
|
||||
)
|
||||
{
|
||||
// should never be here at runtime:
|
||||
BOOST_ASSERT(false);
|
||||
// should never be here at runtime!
|
||||
typedef typename Visitor::result_type result_type;
|
||||
return ::boost::detail::variant::forced_return< result_type >();
|
||||
}
|
||||
|
||||
+163
-18
@@ -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) 2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/static_assert.hpp"
|
||||
#include "boost/throw_exception.hpp"
|
||||
#include "boost/utility/addressof.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
#include "boost/variant/detail/element_index.hpp"
|
||||
|
||||
#include "boost/type_traits/add_reference.hpp"
|
||||
#include "boost/type_traits/add_pointer.hpp"
|
||||
@@ -31,7 +33,7 @@ namespace boost {
|
||||
//
|
||||
// The exception thrown in the event of a failed get of a value.
|
||||
//
|
||||
class bad_get
|
||||
class BOOST_SYMBOL_VISIBLE bad_get
|
||||
: public std::exception
|
||||
{
|
||||
public: // std::exception implementation
|
||||
@@ -86,17 +88,22 @@ public: // visitor interfaces
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
#else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// relaxed_get<U>(variant) methods
|
||||
//
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
get(
|
||||
relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
@@ -111,7 +118,7 @@ get(
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
get(
|
||||
relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
@@ -126,19 +133,158 @@ get(
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
get(
|
||||
relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
U_ptr result = get<U>(&operand);
|
||||
U_ptr result = relaxed_get<U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
U_ptr result = relaxed_get<const U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// strict_get<U>(variant) methods
|
||||
//
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get<U>(variant) methods
|
||||
//
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
@@ -147,12 +293,11 @@ get(
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
U_ptr result = get<const U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013.
|
||||
// Copyright Antony Polukhin, 2013-2014.
|
||||
//
|
||||
// Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
@@ -16,128 +16,17 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
|
||||
#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
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
# include <boost/variant/detail/multivisitors_cpp11_based.hpp>
|
||||
# if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
# include <boost/variant/detail/multivisitors_cpp14_based.hpp>
|
||||
# endif
|
||||
#else
|
||||
# include <boost/variant/detail/multivisitors_preprocessor_based.hpp>
|
||||
#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
|
||||
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/polymorphic_get.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2013-2015 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
#define BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#include "boost/static_assert.hpp"
|
||||
#include "boost/throw_exception.hpp"
|
||||
#include "boost/utility/addressof.hpp"
|
||||
#include "boost/variant/variant_fwd.hpp"
|
||||
#include "boost/variant/get.hpp"
|
||||
|
||||
#include "boost/type_traits/add_reference.hpp"
|
||||
#include "boost/type_traits/add_pointer.hpp"
|
||||
#include "boost/type_traits/is_base_of.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// class bad_polymorphic_get
|
||||
//
|
||||
// The exception thrown in the event of a failed get of a value.
|
||||
//
|
||||
class BOOST_SYMBOL_VISIBLE bad_polymorphic_get
|
||||
: public bad_get
|
||||
{
|
||||
public: // std::exception implementation
|
||||
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "boost::bad_polymorphic_get: "
|
||||
"failed value get using boost::polymorphic_get";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// function template get<T>
|
||||
//
|
||||
// Retrieves content of given variant object if content is of type T.
|
||||
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
|
||||
//
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// polymorphic metafunctions to detect index of a value
|
||||
//
|
||||
|
||||
template <class Types, class T>
|
||||
struct element_polymorphic_iterator_impl :
|
||||
boost::mpl::find_if<
|
||||
Types,
|
||||
boost::mpl::or_<
|
||||
variant_element_functor<boost::mpl::_1, T>,
|
||||
variant_element_functor<boost::mpl::_1, typename boost::remove_cv<T>::type >,
|
||||
boost::is_base_of<T, boost::mpl::_1>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Variant, class T>
|
||||
struct holds_element_polymorphic :
|
||||
boost::mpl::not_<
|
||||
boost::is_same<
|
||||
typename boost::mpl::end<typename Variant::types>::type,
|
||||
typename element_polymorphic_iterator_impl<typename Variant::types, typename boost::remove_reference<T>::type >::type
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
// (detail) class template get_polymorphic_visitor
|
||||
//
|
||||
// Generic static visitor that: if the value is of the specified
|
||||
// type or of a type derived from specified, returns a pointer
|
||||
// to the value it visits; else a null pointer.
|
||||
//
|
||||
template <typename Base>
|
||||
struct get_polymorphic_visitor
|
||||
{
|
||||
private: // private typedefs
|
||||
typedef get_polymorphic_visitor<Base> this_type;
|
||||
typedef typename add_pointer<Base>::type pointer;
|
||||
typedef typename add_reference<Base>::type reference;
|
||||
|
||||
pointer get(reference operand, boost::true_type) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::addressof(operand);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
pointer get(T&, boost::false_type) const BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<pointer>(0);
|
||||
}
|
||||
|
||||
public: // visitor interfaces
|
||||
typedef pointer result_type;
|
||||
|
||||
template <typename U>
|
||||
pointer operator()(U& operand) const BOOST_NOEXCEPT
|
||||
{
|
||||
typedef boost::integral_constant<
|
||||
bool,
|
||||
boost::mpl::or_<
|
||||
boost::is_base_of<Base, U>,
|
||||
boost::is_same<Base, U>,
|
||||
boost::is_same<typename boost::remove_cv<Base>::type, U >
|
||||
>::value
|
||||
> tag_t;
|
||||
|
||||
return this_type::get(operand, tag_t());
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// polymorphic_relaxed_get
|
||||
//
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
polymorphic_relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_polymorphic_visitor<U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
polymorphic_relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_polymorphic_visitor<const U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
polymorphic_relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
U_ptr result = polymorphic_relaxed_get<U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_polymorphic_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
polymorphic_relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
U_ptr result = polymorphic_relaxed_get<const U>(&operand);
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_polymorphic_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// polymorphic_strict_get
|
||||
//
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
polymorphic_strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::polymorphic_get<U>(boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
polymorphic_strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::polymorphic_get<U>(const boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
polymorphic_strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::polymorphic_get<U>(boost::variant<T...>&) will always throw boost::bad_polymorphic_get exception"
|
||||
);
|
||||
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
polymorphic_strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element_polymorphic<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::polymorphic_get<U>(const boost::variant<T...>&) will always throw boost::bad_polymorphic_get exception"
|
||||
);
|
||||
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// polymorphic_get<U>(variant) methods
|
||||
//
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
polymorphic_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
#else
|
||||
return polymorphic_strict_get<U>(operand);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
polymorphic_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
#else
|
||||
return polymorphic_strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
polymorphic_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
#else
|
||||
return polymorphic_strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
polymorphic_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return polymorphic_relaxed_get<U>(operand);
|
||||
#else
|
||||
return polymorphic_strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_POLYMORPHIC_GET_HPP
|
||||
@@ -116,7 +116,7 @@ struct substitute<
|
||||
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
|
||||
>
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
typedef ::boost::variant<
|
||||
typename enable_recursive<
|
||||
@@ -131,7 +131,7 @@ struct substitute<
|
||||
>::type...
|
||||
> type;
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
private: // helpers, for metafunction result (below)
|
||||
|
||||
@@ -154,7 +154,7 @@ private: // helpers, for metafunction result (below)
|
||||
public: // metafunction result
|
||||
|
||||
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
|
||||
#endif
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
};
|
||||
|
||||
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
|
||||
|
||||
#include "boost/mpl/aux_/config/ctps.hpp"
|
||||
|
||||
#include "boost/mpl/aux_/lambda_support.hpp"
|
||||
|
||||
// should be the last #include
|
||||
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -66,11 +63,12 @@ struct is_recursive_wrapper_impl< recursive_wrapper<T> >
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_recursive_wrapper
|
||||
, T
|
||||
, (::boost::detail::is_recursive_wrapper_impl<T>::value)
|
||||
)
|
||||
template< typename T > struct is_recursive_wrapper
|
||||
: public ::boost::integral_constant<bool,(::boost::detail::is_recursive_wrapper_impl<T>::value)>
|
||||
{
|
||||
public:
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T))
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// metafunction unwrap_recursive
|
||||
@@ -98,6 +96,4 @@ struct unwrap_recursive< recursive_wrapper<T> >
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include "boost/type_traits/detail/bool_trait_undef.hpp"
|
||||
|
||||
#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include "boost/mpl/if.hpp"
|
||||
#include "boost/type_traits/is_base_and_derived.hpp"
|
||||
|
||||
// should be the last #include
|
||||
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -48,7 +48,7 @@ public: // typedefs
|
||||
typedef R result_type;
|
||||
|
||||
protected: // for use as base class only
|
||||
#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
|
||||
static_visitor() = default;
|
||||
~static_visitor() = default;
|
||||
#else
|
||||
@@ -83,14 +83,13 @@ struct is_static_visitor_impl
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_static_visitor
|
||||
, T
|
||||
, (::boost::detail::is_static_visitor_impl<T>::value)
|
||||
)
|
||||
template< typename T > struct is_static_visitor
|
||||
: public ::boost::integral_constant<bool,(::boost::detail::is_static_visitor_impl<T>::value)>
|
||||
{
|
||||
public:
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_static_visitor,(T))
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include "boost/type_traits/detail/bool_trait_undef.hpp"
|
||||
|
||||
#endif // BOOST_VARIANT_STATIC_VISITOR_HPP
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2012-2013 Antony Polukhin
|
||||
// Copyright (c) 2012-2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,9 +18,7 @@
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <new> // for placement new
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
#include <typeinfo> // for typeid, std::type_info
|
||||
#endif // BOOST_NO_TYPEID
|
||||
#include "boost/type_index.hpp"
|
||||
|
||||
#include "boost/variant/detail/config.hpp"
|
||||
#include "boost/mpl/aux_/value_wknd.hpp"
|
||||
@@ -50,6 +48,7 @@
|
||||
#include "boost/type_traits/add_const.hpp"
|
||||
#include "boost/type_traits/has_nothrow_constructor.hpp"
|
||||
#include "boost/type_traits/has_nothrow_copy.hpp"
|
||||
#include "boost/type_traits/is_nothrow_move_assignable.hpp"
|
||||
#include "boost/type_traits/is_nothrow_move_constructible.hpp"
|
||||
#include "boost/type_traits/is_const.hpp"
|
||||
#include "boost/type_traits/is_same.hpp"
|
||||
@@ -346,20 +345,12 @@ public: // visitor interface
|
||||
return operand;
|
||||
}
|
||||
|
||||
#if defined BOOST_MSVC
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4702 ) // unreachable code
|
||||
#endif
|
||||
template <typename U>
|
||||
T& operator()(U&) const
|
||||
{
|
||||
// logical error to be here: see precondition above
|
||||
BOOST_ASSERT(false);
|
||||
return ::boost::detail::variant::forced_return< T& >();
|
||||
}
|
||||
#if defined BOOST_MSVC
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -689,10 +680,48 @@ private: // helpers, for visitor interface (below)
|
||||
new(addr) RhsT(*static_cast<const RhsT*>(obj));
|
||||
}
|
||||
|
||||
template <typename LhsT>
|
||||
void backup_assign_impl(
|
||||
backup_holder<LhsT>& lhs_content
|
||||
, mpl::false_ // is_nothrow_move_constructible
|
||||
, long
|
||||
)
|
||||
{
|
||||
// Move lhs content to backup...
|
||||
backup_holder<LhsT> backup_lhs_content(0);
|
||||
backup_lhs_content.swap(lhs_content); // nothrow
|
||||
|
||||
// ...destroy lhs content...
|
||||
lhs_content.~backup_holder<LhsT>(); // nothrow
|
||||
|
||||
BOOST_TRY
|
||||
{
|
||||
// ...and attempt to copy rhs content into lhs storage:
|
||||
copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
|
||||
}
|
||||
BOOST_CATCH (...)
|
||||
{
|
||||
// In case of failure, copy backup pointer to lhs storage...
|
||||
new(lhs_.storage_.address())
|
||||
backup_holder<LhsT>( 0 ); // nothrow
|
||||
|
||||
static_cast<backup_holder<LhsT>* >(lhs_.storage_.address())
|
||||
->swap(backup_lhs_content); // nothrow
|
||||
|
||||
// ...and rethrow:
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
||||
// In case of success, indicate new content type:
|
||||
lhs_.indicate_which(rhs_which_); // nothrow
|
||||
}
|
||||
|
||||
template <typename LhsT>
|
||||
void backup_assign_impl(
|
||||
LhsT& lhs_content
|
||||
, mpl::true_ // is_nothrow_move_constructible
|
||||
, int
|
||||
)
|
||||
{
|
||||
// Move lhs content to backup...
|
||||
@@ -729,6 +758,7 @@ private: // helpers, for visitor interface (below)
|
||||
void backup_assign_impl(
|
||||
LhsT& lhs_content
|
||||
, mpl::false_ // is_nothrow_move_constructible
|
||||
, int
|
||||
)
|
||||
{
|
||||
// Backup lhs content...
|
||||
@@ -772,7 +802,7 @@ public: // visitor interface
|
||||
typedef typename is_nothrow_move_constructible<LhsT>::type
|
||||
nothrow_move;
|
||||
|
||||
backup_assign_impl( lhs_content, nothrow_move() );
|
||||
backup_assign_impl( lhs_content, nothrow_move(), 1L);
|
||||
|
||||
BOOST_VARIANT_AUX_RETURN_VOID;
|
||||
}
|
||||
@@ -830,23 +860,19 @@ private:
|
||||
// Generic static visitor that performs a typeid on the value it visits.
|
||||
//
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
|
||||
class reflect
|
||||
: public static_visitor<const std::type_info&>
|
||||
: public static_visitor<const boost::typeindex::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return typeid(T);
|
||||
return boost::typeindex::type_id<T>().type_info();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TYPEID
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) class comparer
|
||||
//
|
||||
@@ -2155,13 +2181,11 @@ public: // queries
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
const std::type_info& type() const
|
||||
const boost::typeindex::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
#endif
|
||||
|
||||
public: // prevent comparison with foreign types
|
||||
|
||||
@@ -2181,6 +2205,30 @@ public: // prevent comparison with foreign types
|
||||
BOOST_STATIC_ASSERT( false && sizeof(U) );
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void operator!=(const U&) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT( false && sizeof(U) );
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void operator>(const U&) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT( false && sizeof(U) );
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void operator<=(const U&) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT( false && sizeof(U) );
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void operator>=(const U&) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT( false && sizeof(U) );
|
||||
}
|
||||
|
||||
public: // comparison operators
|
||||
|
||||
// [MSVC6 requires these operators appear after template operators]
|
||||
@@ -2211,6 +2259,28 @@ public: // comparison operators
|
||||
return rhs.apply_visitor(visitor);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// comparison operators != > <= >=
|
||||
inline bool operator!=(const variant& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
inline bool operator>(const variant& rhs) const
|
||||
{
|
||||
return rhs < *this;
|
||||
}
|
||||
|
||||
inline bool operator<=(const variant& rhs) const
|
||||
{
|
||||
return !(*this > rhs);
|
||||
}
|
||||
|
||||
inline bool operator>=(const variant& rhs) const
|
||||
{
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
// helpers, for visitation support (below) -- private when possible
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
|
||||
@@ -2319,6 +2389,7 @@ public: // metafunction result
|
||||
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// function template swap
|
||||
//
|
||||
|
||||
@@ -25,16 +25,6 @@
|
||||
#include "boost/preprocessor/enum_shifted_params.hpp"
|
||||
#include "boost/preprocessor/repeat.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_LIMIT_TYPES
|
||||
//
|
||||
// Implementation-defined preprocessor symbol describing the actual
|
||||
// length of variant's pseudo-variadic template parameter list.
|
||||
//
|
||||
#include "boost/mpl/limits/list.hpp"
|
||||
#define BOOST_VARIANT_LIMIT_TYPES \
|
||||
BOOST_MPL_LIMIT_LIST_SIZE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_NO_REFERENCE_SUPPORT
|
||||
//
|
||||
@@ -67,11 +57,36 @@
|
||||
#include "boost/variant/detail/substitute_fwd.hpp"
|
||||
|
||||
#if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
|
||||
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
//
|
||||
|
||||
/*
|
||||
GCC before 4.0 had no variadic tempaltes;
|
||||
GCC 4.6 has incomplete implementation of variadic templates.
|
||||
|
||||
MSVC2013 has variadic templates, but they have issues.
|
||||
|
||||
NOTE: Clang compiler defines __GNUC__
|
||||
*/
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
|
||||
|| (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) \
|
||||
|| (defined(_MSC_VER) && (_MSC_VER <= 1900)) \
|
||||
|| defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) \
|
||||
|| defined (BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
|
||||
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
# define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
|
||||
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
|
||||
@@ -104,7 +119,7 @@
|
||||
// Rationale: Cleaner, simpler code for clients of variant library. Minimal
|
||||
// code modifications to move from C++03 to C++11.
|
||||
//
|
||||
// Without !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
// With BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES defined
|
||||
// will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else`
|
||||
//
|
||||
|
||||
@@ -117,7 +132,17 @@
|
||||
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
|
||||
/**/
|
||||
|
||||
#else
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_LIMIT_TYPES
|
||||
//
|
||||
// Implementation-defined preprocessor symbol describing the actual
|
||||
// length of variant's pseudo-variadic template parameter list.
|
||||
//
|
||||
#include "boost/mpl/limits/list.hpp"
|
||||
#define BOOST_VARIANT_LIMIT_TYPES \
|
||||
BOOST_MPL_LIMIT_LIST_SIZE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
|
||||
@@ -148,7 +173,8 @@
|
||||
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -188,7 +214,6 @@ struct convert_void< void_ >
|
||||
//
|
||||
|
||||
#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
|
||||
|
||||
// (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES)
|
||||
//
|
||||
// Defines void types that are each unique and specializations of
|
||||
@@ -217,11 +242,10 @@ BOOST_PP_REPEAT(
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(BOOST_VARIANT_USE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
# define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
|
||||
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
|
||||
//
|
||||
@@ -250,7 +274,7 @@ BOOST_PP_REPEAT(
|
||||
) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class template variant (concept inspired by Andrei Alexandrescu)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"key": "variant",
|
||||
"name": "Variant",
|
||||
"authors": [
|
||||
"Eric Friedman",
|
||||
"Itay Maman"
|
||||
],
|
||||
"description": "Safe, generic, stack-based discriminated union container.",
|
||||
"category": [
|
||||
"Containers",
|
||||
"Data"
|
||||
],
|
||||
"maintainers": [
|
||||
"Eric Friedman <ericbrandon -at- gmail.com>"
|
||||
]
|
||||
}
|
||||
Executable → Regular
+13
-6
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Antony Polukhin 2012.
|
||||
// (C) Copyright Antony Polukhin 2012-2014.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -75,7 +75,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant(variant&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to.push_back(std::move(data_from[i]));
|
||||
data_to.push_back(boost::move(data_from[i]));
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -108,7 +108,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on same types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -142,7 +142,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -176,7 +176,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(variant&&) moving speed on different types II");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(data_from[i]);
|
||||
data_to[i] = boost::move(data_from[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -210,7 +210,7 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
{
|
||||
scope sc("boost::variant=(T&&) moving speed");
|
||||
for (std::size_t i = 0; i < c_run_count; ++i) {
|
||||
data_to[i] = std::move(s2[i]);
|
||||
data_to[i] = boost::move(s2[i]);
|
||||
}
|
||||
|
||||
if (do_count_cleanup_time) {
|
||||
@@ -222,6 +222,13 @@ static void do_test(bool do_count_cleanup_time = false) {
|
||||
|
||||
|
||||
int main () {
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
std::cout << "# Running tests in C++11 mode (with rvalues).\n";
|
||||
#else
|
||||
std::cout << "# Running tests in C++03 mode (without rvalues).\n";
|
||||
#endif
|
||||
|
||||
do_test(false);
|
||||
do_test(true);
|
||||
}
|
||||
|
||||
+9
-15
@@ -3,26 +3,14 @@
|
||||
# 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.
|
||||
#
|
||||
# Permission to use or copy this software for any purpose is hereby granted
|
||||
# without fee, provided the above notices are retained on all copies.
|
||||
# Permission to modify the code and to distribute modified code is granted,
|
||||
# provided the above notices are retained, and a notice that the code was
|
||||
# modified is included with the above copyright notice.
|
||||
# Use, modification and distribution is 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)
|
||||
#
|
||||
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
|
||||
@@ -30,6 +18,7 @@ test-suite variant
|
||||
[ run test1.cpp class_a.cpp : : : : variant_test1 ]
|
||||
[ run test2.cpp : : : : variant_test2 ]
|
||||
[ run test3.cpp : : : : variant_test3 ]
|
||||
[ run test3.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : variant_test3_no_rtti ]
|
||||
[ run test4.cpp class_a.cpp
|
||||
: : : : variant_test4 ]
|
||||
[ run test5.cpp : : : : variant_test5 ]
|
||||
@@ -40,9 +29,12 @@ test-suite variant
|
||||
[ run variant_reference_test.cpp ]
|
||||
[ run variant_comparison_test.cpp ]
|
||||
[ run variant_visit_test.cpp ]
|
||||
[ run variant_get_test.cpp ]
|
||||
[ run variant_polymorphic_get_test.cpp ]
|
||||
[ run variant_multivisit_test.cpp ]
|
||||
[ run hash_variant_test.cpp ]
|
||||
[ run rvalue_test.cpp ]
|
||||
[ run variant_nonempty_check.cpp ]
|
||||
[ run recursive_variant_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
|
||||
<toolset>gcc-4.3:<cxxflags>-fno-exceptions
|
||||
<toolset>gcc-4.4:<cxxflags>-fno-exceptions
|
||||
@@ -53,7 +45,9 @@ test-suite variant
|
||||
<toolset>clang:<cxxflags>-fno-exceptions
|
||||
: variant_noexcept_test
|
||||
]
|
||||
[ run recursive_variant_test.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : variant_no_rtti_test ]
|
||||
[ run variant_swap_test.cpp ]
|
||||
[ run auto_visitors.cpp ]
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/auto_visitors.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2014-2015 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/variant/multivisitors.hpp"
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
namespace has_result_type_tests {
|
||||
template <class T>
|
||||
struct wrap {
|
||||
typedef T result_type;
|
||||
};
|
||||
|
||||
struct s1 : wrap<int> {};
|
||||
struct s2 : wrap<int&> {};
|
||||
struct s3 : wrap<const int&> {};
|
||||
struct s4 {};
|
||||
struct s5 : wrap<int*> {};
|
||||
struct s6 : wrap<int**> {};
|
||||
struct s7 : wrap<const int*> {};
|
||||
struct s8 : wrap<boost::noncopyable> {};
|
||||
struct s9 : wrap<boost::noncopyable&> {};
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
struct s10 : wrap<boost::noncopyable&&> {};
|
||||
#endif
|
||||
struct s11 : wrap<const boost::noncopyable&> {};
|
||||
struct s12 : wrap<const boost::noncopyable*> {};
|
||||
struct s13 : wrap<boost::noncopyable*> {};
|
||||
struct s14 { typedef int result_type; };
|
||||
struct s15 { typedef int& result_type; };
|
||||
struct s16 { typedef const int& result_type; };
|
||||
}
|
||||
|
||||
|
||||
void test_has_result_type_triat() {
|
||||
using namespace has_result_type_tests;
|
||||
using boost::detail::variant::has_result_type;
|
||||
|
||||
BOOST_CHECK(has_result_type<s1>::value);
|
||||
BOOST_CHECK(has_result_type<s2>::value);
|
||||
BOOST_CHECK(has_result_type<s3>::value);
|
||||
BOOST_CHECK(!has_result_type<s4>::value);
|
||||
BOOST_CHECK(has_result_type<s5>::value);
|
||||
BOOST_CHECK(has_result_type<s6>::value);
|
||||
BOOST_CHECK(has_result_type<s7>::value);
|
||||
BOOST_CHECK(has_result_type<s8>::value);
|
||||
BOOST_CHECK(has_result_type<s9>::value);
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_CHECK(has_result_type<s10>::value);
|
||||
#endif
|
||||
BOOST_CHECK(has_result_type<s11>::value);
|
||||
BOOST_CHECK(has_result_type<s12>::value);
|
||||
BOOST_CHECK(has_result_type<s13>::value);
|
||||
BOOST_CHECK(has_result_type<s14>::value);
|
||||
BOOST_CHECK(has_result_type<s15>::value);
|
||||
BOOST_CHECK(has_result_type<s16>::value);
|
||||
}
|
||||
|
||||
struct lex_streamer_explicit: boost::static_visitor<std::string> {
|
||||
template <class T>
|
||||
const char* operator()(const T& ) {
|
||||
return "10";
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
const char* operator()(const T1& , const T2& ) {
|
||||
return "100";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void run_explicit()
|
||||
{
|
||||
typedef boost::variant<int, std::string, double> variant_type;
|
||||
variant_type v2("10"), v1("100");
|
||||
|
||||
lex_streamer_explicit visitor_ref;
|
||||
|
||||
// Must return instance of std::string
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v2).c_str() == std::string("10"));
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v2, v1).c_str() == std::string("100"));
|
||||
}
|
||||
|
||||
|
||||
// Most part of tests from this file require decltype(auto)
|
||||
|
||||
#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO
|
||||
|
||||
void run()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
void run2()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
|
||||
void run3()
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct lex_streamer {
|
||||
template <class T>
|
||||
std::string operator()(const T& val) const {
|
||||
return boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
};
|
||||
|
||||
struct lex_streamer_void {
|
||||
template <class T>
|
||||
void operator()(const T& val) const {
|
||||
std::cout << val << std::endl;
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
void operator()(const T1& val, const T2& val2) const {
|
||||
std::cout << val << '+' << val2 << std::endl;
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
void operator()(const T1& val, const T2& val2, const T3& val3) const {
|
||||
std::cout << val << '+' << val2 << '+' << val3 << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct lex_streamer2 {
|
||||
std::string res;
|
||||
|
||||
template <class T>
|
||||
const char* operator()(const T& val) const {
|
||||
return "fail";
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
const char* operator()(const T1& v1, const T2& v2) const {
|
||||
return "fail2";
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
const char* operator()(const T1& v1, const T2& v2, const T3& v3) const {
|
||||
return "fail3";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string& operator()(const T& val) {
|
||||
res = boost::lexical_cast<std::string>(val);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
std::string& operator()(const T1& v1, const T2& v2) {
|
||||
res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
std::string& operator()(const T1& v1, const T2& v2, const T3& v3) {
|
||||
res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2)
|
||||
+ "+" + boost::lexical_cast<std::string>(v3);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
# define BOOST_CHECK_IF_HAS_VARIADIC(x) BOOST_CHECK(x)
|
||||
#else
|
||||
# define BOOST_CHECK_IF_HAS_VARIADIC(x) /**/
|
||||
#endif
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef boost::variant<int, std::string, double> variant_type;
|
||||
variant_type v1(1), v2("10"), v3(100.0);
|
||||
lex_streamer lex_streamer_visitor;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(lex_streamer(), v1) == "1");
|
||||
BOOST_CHECK_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v1) == "1");
|
||||
BOOST_CHECK(boost::apply_visitor(lex_streamer(), v2) == "10");
|
||||
BOOST_CHECK_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v2) == "10");
|
||||
|
||||
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
|
||||
BOOST_CHECK(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v1) == "1");
|
||||
BOOST_CHECK(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v2) == "10");
|
||||
|
||||
// Retun type must be the same in all instances, so this code does not compile
|
||||
//boost::variant<int, short, unsigned> v_diff_types(1);
|
||||
//BOOST_CHECK(boost::apply_visitor([](auto v) { return v; }, v_diff_types) == 1);
|
||||
|
||||
boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v1);
|
||||
boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v2);
|
||||
#endif
|
||||
|
||||
lex_streamer2 visitor_ref;
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v1) == "1");
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v2) == "10");
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1);
|
||||
BOOST_CHECK(ref_to_string == "1");
|
||||
#endif
|
||||
lex_streamer_void lex_streamer_void_visitor;
|
||||
boost::apply_visitor(lex_streamer_void(), v1);
|
||||
boost::apply_visitor(lex_streamer_void(), v2);
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
boost::apply_visitor(lex_streamer_void_visitor)(v2);
|
||||
#endif
|
||||
|
||||
boost::ignore_unused(lex_streamer_visitor, visitor_ref, lex_streamer_void_visitor);
|
||||
}
|
||||
|
||||
|
||||
struct lex_combine {
|
||||
template <class T1, class T2>
|
||||
std::string operator()(const T1& v1, const T2& v2) const {
|
||||
return boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2);
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
std::string operator()(const T1& v1, const T2& v2, const T3& v3) const {
|
||||
return boost::lexical_cast<std::string>(v1) + "+"
|
||||
+ boost::lexical_cast<std::string>(v2) + '+'
|
||||
+ boost::lexical_cast<std::string>(v3);
|
||||
}
|
||||
};
|
||||
|
||||
void run2()
|
||||
{
|
||||
typedef boost::variant<int, std::string, double> variant_type;
|
||||
variant_type v1(1), v2("10"), v3(100.0);
|
||||
lex_combine lex_combine_visitor;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(lex_combine(), v1, v2) == "1+10");
|
||||
BOOST_CHECK(boost::apply_visitor(lex_combine(), v2, v1) == "10+1");
|
||||
BOOST_CHECK_IF_HAS_VARIADIC(boost::apply_visitor(lex_combine_visitor)(v2, v1) == "10+1");
|
||||
|
||||
|
||||
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
|
||||
BOOST_CHECK(
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2) {
|
||||
return boost::lexical_cast<std::string>(v1) + "+"
|
||||
+ boost::lexical_cast<std::string>(v2);
|
||||
}
|
||||
, v1
|
||||
, v2
|
||||
) == "1+10"
|
||||
);
|
||||
BOOST_CHECK(
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2) {
|
||||
return boost::lexical_cast<std::string>(v1) + "+"
|
||||
+ boost::lexical_cast<std::string>(v2);
|
||||
}
|
||||
, v2
|
||||
, v1
|
||||
) == "10+1"
|
||||
);
|
||||
|
||||
boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v1, v2);
|
||||
boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v2, v1);
|
||||
#endif
|
||||
|
||||
|
||||
lex_streamer2 visitor_ref;
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v2, v1) == "10+1");
|
||||
#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
std::string& ref_to_string = boost::apply_visitor(visitor_ref)(v1, v2);
|
||||
BOOST_CHECK(ref_to_string == "1+10");
|
||||
#endif
|
||||
|
||||
boost::apply_visitor(lex_streamer_void(), v1, v2);
|
||||
boost::apply_visitor(lex_streamer_void(), v2, v1);
|
||||
|
||||
boost::ignore_unused(lex_combine_visitor, visitor_ref);
|
||||
}
|
||||
|
||||
#undef BOOST_CHECK_IF_HAS_VARIADIC
|
||||
|
||||
void run3()
|
||||
{
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
typedef boost::variant<int, std::string, double> variant_type;
|
||||
variant_type v1(1), v2("10"), v3(100);
|
||||
lex_combine lex_combine_visitor;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(lex_combine(), v1, v2, v3) == "1+10+100");
|
||||
BOOST_CHECK(boost::apply_visitor(lex_combine(), v2, v1, v3) == "10+1+100");
|
||||
BOOST_CHECK(boost::apply_visitor(lex_combine_visitor)(v2, v1, v3) == "10+1+100");
|
||||
|
||||
|
||||
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
|
||||
BOOST_CHECK(
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2, auto v3) {
|
||||
return boost::lexical_cast<std::string>(v1) + "+"
|
||||
+ boost::lexical_cast<std::string>(v2) + "+"
|
||||
+ boost::lexical_cast<std::string>(v3);
|
||||
}
|
||||
, v1
|
||||
, v2
|
||||
, v3
|
||||
) == "1+10+100"
|
||||
);
|
||||
BOOST_CHECK(
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2, auto v3) {
|
||||
return boost::lexical_cast<std::string>(v1) + "+"
|
||||
+ boost::lexical_cast<std::string>(v2) + "+"
|
||||
+ boost::lexical_cast<std::string>(v3);
|
||||
}
|
||||
, v3
|
||||
, v1
|
||||
, v3
|
||||
) == "100+1+100"
|
||||
);
|
||||
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
|
||||
v1, v2, v3
|
||||
);
|
||||
boost::apply_visitor(
|
||||
[](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
|
||||
v2, v1, v3
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
lex_streamer2 visitor_ref;
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
|
||||
BOOST_CHECK(boost::apply_visitor(visitor_ref)(v2, v1) == "10+1");
|
||||
std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1, v2);
|
||||
BOOST_CHECK(ref_to_string == "1+10");
|
||||
|
||||
lex_streamer_void lex_streamer_void_visitor;
|
||||
boost::apply_visitor(lex_streamer_void(), v1, v2, v1);
|
||||
boost::apply_visitor(lex_streamer_void(), v2, v1, v1);
|
||||
boost::apply_visitor(lex_streamer_void_visitor)(v2, v1, v1);
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
run_explicit();
|
||||
run();
|
||||
run2();
|
||||
run3();
|
||||
test_has_result_type_triat();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+15
-11
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011
|
||||
// Copyright (c) 2011-2014
|
||||
// Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
@@ -6,25 +6,28 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant/detail/hash_variant.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/functional/hash/hash.hpp"
|
||||
|
||||
void run()
|
||||
{
|
||||
typedef boost::variant<bool, int, unsigned int, double> variant_type;
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
variant_type bool_variant1 = true;
|
||||
variant_type bool_variant2 = false;
|
||||
variant_type int_variant = 1;
|
||||
variant_type float_variant = 1.0;
|
||||
variant_type uint_variant = static_cast<unsigned int>(1);
|
||||
typedef boost::variant<bool, int, unsigned int, char> variant_type;
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
variant_type bool_variant1 = true;
|
||||
variant_type bool_variant2 = false;
|
||||
variant_type int_variant = 1;
|
||||
variant_type char_variant1 = '\1';
|
||||
variant_type char_variant2 = '\2';
|
||||
variant_type uint_variant = static_cast<unsigned int>(1);
|
||||
|
||||
BOOST_CHECK(hasher(bool_variant1) != hasher(bool_variant2));
|
||||
BOOST_CHECK(hasher(bool_variant1) == hasher(bool_variant1));
|
||||
BOOST_CHECK(hasher(int_variant) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(float_variant) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(char_variant1) != hasher(uint_variant));
|
||||
BOOST_CHECK(hasher(char_variant1) != hasher(char_variant2));
|
||||
BOOST_CHECK(hasher(char_variant1) == hasher(char_variant1));
|
||||
BOOST_CHECK(hasher(char_variant2) == hasher(char_variant2));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
@@ -32,3 +35,4 @@ int test_main(int , char* [])
|
||||
run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -25,6 +25,7 @@
|
||||
#include "boost/variant/apply_visitor.hpp"
|
||||
#include "boost/variant/static_visitor.hpp"
|
||||
|
||||
#include "boost/type_index.hpp"
|
||||
#include "boost/detail/workaround.hpp"
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# pragma warn -lvc
|
||||
@@ -244,9 +245,7 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
|
||||
const VariantType& cvar = var;
|
||||
|
||||
BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() == typeid(S));
|
||||
#endif
|
||||
BOOST_CHECK(cvar.type() == boost::typeindex::type_id<S>());
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
@@ -261,7 +260,7 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
|
||||
S& r = boost::get<S>(var);
|
||||
ptr1 = &r;
|
||||
}
|
||||
catch(boost::bad_get& )
|
||||
catch(const boost::bad_get& )
|
||||
{
|
||||
BOOST_ERROR( "get<S> failed unexpectedly" );
|
||||
}
|
||||
@@ -271,7 +270,7 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
|
||||
const S& cr = boost::get<S>(cvar);
|
||||
ptr2 = &cr;
|
||||
}
|
||||
catch(boost::bad_get& )
|
||||
catch(const boost::bad_get& )
|
||||
{
|
||||
BOOST_ERROR( "get<S> const failed unexpectedly" );
|
||||
}
|
||||
@@ -295,9 +294,7 @@ inline void verify_not(VariantType& var, spec<S>)
|
||||
{
|
||||
const VariantType& cvar = var;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(cvar.type() != typeid(S));
|
||||
#endif
|
||||
BOOST_CHECK(cvar.type() != boost::typeindex::type_id<S>());
|
||||
|
||||
//
|
||||
// Check get<>()
|
||||
@@ -314,7 +311,7 @@ inline void verify_not(VariantType& var, spec<S>)
|
||||
|
||||
ptr1 = &r;
|
||||
}
|
||||
catch(boost::bad_get& )
|
||||
catch(const boost::bad_get& )
|
||||
{
|
||||
// do nothing except pass-through
|
||||
}
|
||||
@@ -326,7 +323,7 @@ inline void verify_not(VariantType& var, spec<S>)
|
||||
|
||||
ptr2 = &cr;
|
||||
}
|
||||
catch(boost::bad_get& )
|
||||
catch(const boost::bad_get& )
|
||||
{
|
||||
// do nothing except pass-through
|
||||
}
|
||||
|
||||
+125
-10
@@ -48,10 +48,20 @@ int main( int argc, char* argv[] )
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#include <tuple>
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
struct vector_printer
|
||||
struct printer
|
||||
: boost::static_visitor<std::string>
|
||||
{
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
std::string operator()(
|
||||
const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &var) const
|
||||
{
|
||||
return boost::apply_visitor( printer(), var );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string operator()(const std::vector<T>& vec) const
|
||||
{
|
||||
@@ -61,13 +71,36 @@ struct vector_printer
|
||||
|
||||
typename std::vector<T>::const_iterator it = vec.begin();
|
||||
for (; it != vec.end(); ++it)
|
||||
ost << boost::apply_visitor( vector_printer(), *it );
|
||||
ost << printer()( *it );
|
||||
|
||||
ost << ") ";
|
||||
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
template <int...> struct indices {};
|
||||
template <typename... Ts, int... Is>
|
||||
std::string operator()(const std::tuple<Ts...>& tup, indices<Is...>)
|
||||
{
|
||||
std::ostringstream ost;
|
||||
ost << "( ";
|
||||
(void) (int []){0, (ost << printer()( std::get<Is>(tup) ), 0)... };
|
||||
ost << ") ";
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
template <int N, int... Is>
|
||||
struct make_indices : make_indices<N-1, N-1, Is...> {};
|
||||
template <int... Is>
|
||||
struct make_indices<0, Is...> : indices<Is...> {};
|
||||
template <typename... Ts>
|
||||
std::string operator()(const std::tuple<Ts...>& tup) const
|
||||
{
|
||||
return printer()(tup, make_indices<sizeof...(Ts)>());
|
||||
}
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
template <typename T>
|
||||
std::string operator()(const T& operand) const
|
||||
{
|
||||
@@ -91,11 +124,48 @@ void test_recursive_variant()
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
std::string result1( printer()(var1) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
std::vector<var1_t> vec1_copy = vec1;
|
||||
vec1_copy.erase(vec1_copy.begin() + 2);
|
||||
vec1_copy.insert(vec1_copy.begin() + 2, vec1_copy);
|
||||
var1 = vec1_copy;
|
||||
result1 = printer()(var1);
|
||||
std::cout << "result1+: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
|
||||
|
||||
// Uses move construction on compilers with rvalue references support
|
||||
result1 = printer()(
|
||||
var1_t(
|
||||
std::vector<var1_t>(vec1_copy)
|
||||
)
|
||||
);
|
||||
std::cout << "result1++: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
|
||||
|
||||
|
||||
var1_t vec1_another_copy(vec1_copy);
|
||||
vec1_copy[2].swap(vec1_another_copy);
|
||||
result1 = printer()(
|
||||
var1_t(vec1_copy)
|
||||
);
|
||||
std::cout << "result1+++1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
|
||||
|
||||
result1 = printer()(vec1_another_copy);
|
||||
std::cout << "result1++2: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 7 ) ");
|
||||
|
||||
vec1_copy[2].swap(vec1_copy[2]);
|
||||
result1 = printer()(
|
||||
var1_t(vec1_copy)
|
||||
);
|
||||
std::cout << "result1.2: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
boost::variant<int, double>
|
||||
, std::vector<boost::recursive_variant_>
|
||||
@@ -108,7 +178,7 @@ void test_recursive_variant()
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
std::string result2( printer()(var2) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
@@ -135,7 +205,7 @@ void test_recursive_variant()
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var4(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
|
||||
std::string result3( printer()(var4) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
@@ -150,7 +220,7 @@ void test_recursive_variant()
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
std::string result5( printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
@@ -160,6 +230,21 @@ void test_recursive_variant()
|
||||
std::map<int, boost::recursive_variant_>
|
||||
>::type var6_t;
|
||||
var6_t var6;
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
typedef boost::make_recursive_variant<
|
||||
int,
|
||||
std::tuple<int, boost::recursive_variant_>
|
||||
>::type var7_t;
|
||||
var7_t var7 = 0;
|
||||
var7 = std::tuple<int, var7_t>(1, var7);
|
||||
var7 = std::tuple<int, var7_t>(2, var7);
|
||||
|
||||
std::string result7( printer()(var7) );
|
||||
|
||||
std::cout << "result7: " << result7 << '\n';
|
||||
BOOST_CHECK(result7 == "( 2 ( 1 0 ) ) ");
|
||||
#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
}
|
||||
|
||||
void test_recursive_variant_over()
|
||||
@@ -178,11 +263,41 @@ void test_recursive_variant_over()
|
||||
vec1.push_back(7);
|
||||
|
||||
var1_t var1(vec1);
|
||||
std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
|
||||
std::string result1( printer()(var1) );
|
||||
|
||||
std::cout << "result1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
|
||||
|
||||
std::vector<var1_t> vec1_copy = vec1;
|
||||
vec1_copy.erase(vec1_copy.begin() + 2);
|
||||
vec1_copy.insert(vec1_copy.begin() + 2, vec1_copy);
|
||||
var1 = vec1_copy;
|
||||
result1 = printer()(var1);
|
||||
std::cout << "result1+: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
|
||||
|
||||
// Uses move construction on compilers with rvalue references support
|
||||
result1 = printer()(
|
||||
var1_t(
|
||||
std::vector<var1_t>(vec1_copy)
|
||||
)
|
||||
);
|
||||
std::cout << "result1++: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
|
||||
|
||||
|
||||
var1_t vec1_another_copy(vec1_copy);
|
||||
vec1_copy[2].swap(vec1_another_copy);
|
||||
result1 = printer()(
|
||||
var1_t(vec1_copy)
|
||||
);
|
||||
std::cout << "result1+++1: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
|
||||
|
||||
result1 = printer()(vec1_another_copy);
|
||||
std::cout << "result1++2: " << result1 << '\n';
|
||||
BOOST_CHECK(result1 == "( 3 5 7 ) ");
|
||||
|
||||
typedef boost::make_recursive_variant_over<
|
||||
boost::mpl::vector<
|
||||
boost::make_variant_over<boost::mpl::vector<int, double> >::type
|
||||
@@ -197,7 +312,7 @@ void test_recursive_variant_over()
|
||||
vec2.push_back(boost::variant<int, double>(7));
|
||||
|
||||
var2_t var2(vec2);
|
||||
std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
|
||||
std::string result2( printer()(var2) );
|
||||
|
||||
std::cout << "result2: " << result2 << '\n';
|
||||
BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
|
||||
@@ -235,7 +350,7 @@ void test_recursive_variant_over()
|
||||
vec3.push_back(7);
|
||||
|
||||
var4_t var3(vec3);
|
||||
std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
|
||||
std::string result3( printer()(var3) );
|
||||
|
||||
std::cout << "result2: " << result3 << '\n';
|
||||
BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
|
||||
@@ -252,7 +367,7 @@ void test_recursive_variant_over()
|
||||
vec5.push_back(vec1);
|
||||
vec5.push_back(17.25);
|
||||
|
||||
std::string result5( vector_printer()(vec5) );
|
||||
std::string result5( printer()(vec5) );
|
||||
|
||||
std::cout << "result5: " << result5 << '\n';
|
||||
BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
|
||||
|
||||
+57
-2
@@ -3,7 +3,7 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2012-2013 Antony Polukhin
|
||||
// Copyright (c) 2012-2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -14,10 +14,25 @@
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
#include "boost/type_traits/is_nothrow_move_assignable.hpp"
|
||||
#include "boost/mpl/bool.hpp"
|
||||
|
||||
#include <boost/blank.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
|
||||
namespace swap_ambiguouty_test_ns {
|
||||
struct A {};
|
||||
struct B {};
|
||||
|
||||
void swap_ambiguouty_test() {
|
||||
// If boost::blank is not used, then it compiles.
|
||||
typedef boost::variant<boost::blank, A, B> Variant;
|
||||
Variant v1, v2;
|
||||
swap(v1, v2);
|
||||
}
|
||||
} // namespace swap_ambiguouty_test_ns
|
||||
|
||||
// Most part of tests from this file require rvalue references support
|
||||
|
||||
|
||||
class move_copy_conting_class {
|
||||
public:
|
||||
static unsigned int moves_count;
|
||||
@@ -189,6 +204,13 @@ private:
|
||||
move_only_structure& operator=(const move_only_structure&);
|
||||
};
|
||||
|
||||
struct visitor_returning_move_only_type: boost::static_visitor<move_only_structure> {
|
||||
template <class T>
|
||||
move_only_structure operator()(const T&) const {
|
||||
return move_only_structure();
|
||||
}
|
||||
};
|
||||
|
||||
void run_move_only()
|
||||
{
|
||||
move_only_structure mo;
|
||||
@@ -204,6 +226,9 @@ void run_move_only()
|
||||
vi = static_cast<move_only_structure&&>(mo);
|
||||
vi2 = static_cast<move_only_structure&&>(mo);
|
||||
BOOST_CHECK(vi.which() == 1);
|
||||
|
||||
move_only_structure from_visitor = boost::apply_visitor(visitor_returning_move_only_type(), vi);
|
||||
(void)from_visitor;
|
||||
}
|
||||
|
||||
void run_moves_are_noexcept() {
|
||||
@@ -256,13 +281,43 @@ void run_tricky_compilation_test()
|
||||
v = nothrow_copyable_throw_movable();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_container : boost::mpl::false_ {};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<boost::variant<T> > : is_container<T> {};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct is_container<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
: boost::mpl::bool_<is_container<T0>::value
|
||||
|| is_container<boost::variant<BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)> >::value>
|
||||
{};
|
||||
|
||||
void run_is_container_compilation_test()
|
||||
{
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int> >::value));
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int, char> >::value));
|
||||
BOOST_CHECK((!is_container<boost::variant<double, int, char, float> >::value));
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
swap_ambiguouty_test_ns::swap_ambiguouty_test();
|
||||
run();
|
||||
run1();
|
||||
run_move_only();
|
||||
run_moves_are_noexcept();
|
||||
run_tricky_compilation_test();
|
||||
run_const_rvalues();
|
||||
run_is_container_compilation_test();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 6)
|
||||
# ifdef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
|
||||
BOOST_CHECK(false &&
|
||||
"Something wrong with macro definitions. GCC-4.7+ is known to work with variadic templates"
|
||||
);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-3
@@ -122,9 +122,7 @@ int test_main(int, char* [])
|
||||
std::ostringstream e1_str;
|
||||
e1_str << e1;
|
||||
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
BOOST_CHECK(e1.type() == typeid(Add));
|
||||
#endif
|
||||
BOOST_CHECK(e1.type() == boost::typeindex::type_id<Add>());
|
||||
BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))");
|
||||
|
||||
//Evaluate expression
|
||||
|
||||
+5
-5
@@ -58,17 +58,17 @@ T& check_pass(Variant& v, T value)
|
||||
template <typename T, typename Variant>
|
||||
void check_fail(Variant& v)
|
||||
{
|
||||
BOOST_CHECK(!get<T>(&v));
|
||||
BOOST_CHECK(!relaxed_get<T>(&v));
|
||||
|
||||
try
|
||||
{
|
||||
T& r = get<T>(v);
|
||||
T& r = relaxed_get<T>(v);
|
||||
(void)r; // suppress warning about r not being used
|
||||
BOOST_CHECK(false && &r); // should never reach
|
||||
BOOST_CHECK(false && relaxed_get<T>(&v)); // should never reach
|
||||
}
|
||||
catch(boost::bad_get&)
|
||||
catch(const boost::bad_get& e)
|
||||
{
|
||||
// (do nothing here)
|
||||
BOOST_CHECK(!!e.what()); // make sure that what() is const qualified and returnes something
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) 2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -34,6 +34,9 @@ void assert_equality_comparable(
|
||||
BOOST_CHECK( !(&x == &y) || (x == y) );
|
||||
BOOST_CHECK( !(&x == &z) || (x == z) );
|
||||
BOOST_CHECK( !(&y == &z) || (y == z) );
|
||||
BOOST_CHECK( !(&x == &y) || !(x != y) );
|
||||
BOOST_CHECK( !(&x == &z) || !(x != z) );
|
||||
BOOST_CHECK( !(&y == &z) || !(y != z) );
|
||||
|
||||
// reflexivity check
|
||||
BOOST_CHECK( (x == x) );
|
||||
@@ -43,12 +46,18 @@ void assert_equality_comparable(
|
||||
// symmetry check
|
||||
BOOST_CHECK( !(x == y) || (y == x) );
|
||||
BOOST_CHECK( !(y == x) || (x == y) );
|
||||
BOOST_CHECK( (x != y) || (y == x) );
|
||||
BOOST_CHECK( (y != x) || (x == y) );
|
||||
|
||||
BOOST_CHECK( !(x == z) || (z == x) );
|
||||
BOOST_CHECK( !(z == x) || (x == z) );
|
||||
BOOST_CHECK( (x != z) || (z == x) );
|
||||
BOOST_CHECK( (z != x) || (x == z) );
|
||||
|
||||
BOOST_CHECK( !(y == z) || (z == y) );
|
||||
BOOST_CHECK( !(z == y) || (y == z) );
|
||||
BOOST_CHECK( (y != z) || (z == y) );
|
||||
BOOST_CHECK( (z != y) || (y == z) );
|
||||
|
||||
// transitivity check
|
||||
BOOST_CHECK( !(x == y && y == z) || (x == z) );
|
||||
@@ -65,12 +74,34 @@ void assert_less_than_comparable(
|
||||
BOOST_CHECK( !(x < x) );
|
||||
BOOST_CHECK( !(y < y) );
|
||||
BOOST_CHECK( !(z < z) );
|
||||
BOOST_CHECK( !(x > x) );
|
||||
BOOST_CHECK( !(y > y) );
|
||||
BOOST_CHECK( !(z > z) );
|
||||
|
||||
BOOST_CHECK( (x <= x) );
|
||||
BOOST_CHECK( (y <= y) );
|
||||
BOOST_CHECK( (z <= z) );
|
||||
BOOST_CHECK( (x >= x) );
|
||||
BOOST_CHECK( (y >= y) );
|
||||
BOOST_CHECK( (z >= z) );
|
||||
|
||||
// transitivity check
|
||||
BOOST_CHECK( (x < y) );
|
||||
BOOST_CHECK( (y < z) );
|
||||
BOOST_CHECK( (x < z) );
|
||||
|
||||
BOOST_CHECK( (x <= y) );
|
||||
BOOST_CHECK( (y <= z) );
|
||||
BOOST_CHECK( (x <= z) );
|
||||
|
||||
BOOST_CHECK( (z > y) );
|
||||
BOOST_CHECK( (y > x) );
|
||||
BOOST_CHECK( (z > x) );
|
||||
|
||||
BOOST_CHECK( (z >= y) );
|
||||
BOOST_CHECK( (y >= x) );
|
||||
BOOST_CHECK( (z >= x) );
|
||||
|
||||
// antisymmetry check
|
||||
BOOST_CHECK( !(y < x) );
|
||||
BOOST_CHECK( !(z < y) );
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/variant_get_test.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2014-2015 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/variant/get.hpp"
|
||||
#include "boost/variant/variant.hpp"
|
||||
#include "boost/variant/polymorphic_get.hpp"
|
||||
#include "boost/variant/recursive_wrapper.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
struct base {
|
||||
int trash;
|
||||
|
||||
base() : trash(123) {}
|
||||
base(const base& b) : trash(b.trash) { int i = 100; (void)i; }
|
||||
const base& operator=(const base& b) {
|
||||
trash = b.trash;
|
||||
int i = 100; (void)i;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~base(){}
|
||||
};
|
||||
|
||||
struct derived1 : base{};
|
||||
struct derived2 : base{};
|
||||
|
||||
struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
|
||||
struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
|
||||
struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
|
||||
struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
|
||||
|
||||
typedef boost::variant<int, base, derived1, derived2, std::string> var_t;
|
||||
typedef boost::variant<int, derived1, derived2, std::string> var_t_shortened;
|
||||
typedef boost::variant<base, derived1, derived2> var_t_no_fallback;
|
||||
typedef boost::variant<int&, base&, derived1&, derived2&, std::string&> var_ref_t;
|
||||
typedef boost::variant<const int&, const base&, const derived1&, const derived2&, const std::string&> var_cref_t;
|
||||
|
||||
struct recursive_structure;
|
||||
typedef boost::variant<
|
||||
int, base, derived1, derived2, std::string, boost::recursive_wrapper<recursive_structure>
|
||||
> var_req_t;
|
||||
struct recursive_structure { var_req_t var; };
|
||||
|
||||
template <class T, class V, class TestType>
|
||||
inline void check_polymorphic_get_on_types_impl_single_type(V* v)
|
||||
{
|
||||
typedef typename boost::add_reference<TestType>::type ref_test_t;
|
||||
typedef typename boost::add_reference<const TestType>::type cref_test_t;
|
||||
const bool exact_same = !!boost::is_same<T, TestType>::value;
|
||||
const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
|
||||
|
||||
if (exact_same || ref_same) {
|
||||
BOOST_CHECK(boost::polymorphic_get<TestType>(v));
|
||||
BOOST_CHECK(boost::polymorphic_get<const TestType>(v));
|
||||
BOOST_CHECK(boost::polymorphic_strict_get<TestType>(v));
|
||||
BOOST_CHECK(boost::polymorphic_strict_get<const TestType>(v));
|
||||
BOOST_CHECK(boost::polymorphic_relaxed_get<TestType>(v));
|
||||
BOOST_CHECK(boost::polymorphic_relaxed_get<const TestType>(v));
|
||||
} else {
|
||||
if (ref_same) {
|
||||
BOOST_CHECK(boost::polymorphic_get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::polymorphic_get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::polymorphic_strict_get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::polymorphic_strict_get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::polymorphic_relaxed_get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::polymorphic_relaxed_get<cref_test_t>(v));
|
||||
}
|
||||
|
||||
BOOST_CHECK(!boost::polymorphic_get<TestType>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_get<const TestType>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_strict_get<TestType>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_strict_get<const TestType>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<TestType>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<const TestType>(v));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class V, class TestType>
|
||||
inline void check_get_on_types_impl_single_type(V* v)
|
||||
{
|
||||
typedef typename boost::add_reference<TestType>::type ref_test_t;
|
||||
typedef typename boost::add_reference<const TestType>::type cref_test_t;
|
||||
const bool exact_same = !!boost::is_same<T, TestType>::value;
|
||||
const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
|
||||
|
||||
if (exact_same || ref_same) {
|
||||
BOOST_CHECK(boost::get<TestType>(v));
|
||||
BOOST_CHECK(boost::get<const TestType>(v));
|
||||
BOOST_CHECK(boost::strict_get<TestType>(v));
|
||||
BOOST_CHECK(boost::strict_get<const TestType>(v));
|
||||
BOOST_CHECK(boost::relaxed_get<TestType>(v));
|
||||
BOOST_CHECK(boost::relaxed_get<const TestType>(v));
|
||||
|
||||
BOOST_CHECK(boost::get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::strict_get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
|
||||
} else {
|
||||
if (ref_same) {
|
||||
BOOST_CHECK(boost::get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::strict_get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::strict_get<cref_test_t>(v));
|
||||
BOOST_CHECK(boost::relaxed_get<ref_test_t>(v));
|
||||
BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
|
||||
}
|
||||
|
||||
BOOST_CHECK(!boost::get<TestType>(v));
|
||||
BOOST_CHECK(!boost::get<const TestType>(v));
|
||||
BOOST_CHECK(!boost::strict_get<TestType>(v));
|
||||
BOOST_CHECK(!boost::strict_get<const TestType>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<TestType>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<const TestType>(v));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline void check_get_on_types_impl(V* v)
|
||||
{
|
||||
check_get_on_types_impl_single_type<T, V, int>(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<T, V, int>(v);
|
||||
|
||||
check_get_on_types_impl_single_type<T, V, base>(v);
|
||||
|
||||
check_get_on_types_impl_single_type<T, V, derived1>(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<T, V, derived1>(v);
|
||||
|
||||
check_get_on_types_impl_single_type<T, V, derived2>(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<T, V, derived2>(v);
|
||||
|
||||
check_get_on_types_impl_single_type<T, V, std::string>(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<T, V, std::string>(v);
|
||||
|
||||
// Never exist in here
|
||||
BOOST_CHECK(!boost::relaxed_get<short>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<const short>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<char>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<char*>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<bool>(v));
|
||||
BOOST_CHECK(!boost::relaxed_get<const bool>(v));
|
||||
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<short>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<const short>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<char>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<char*>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<bool>(v));
|
||||
BOOST_CHECK(!boost::polymorphic_relaxed_get<const bool>(v));
|
||||
|
||||
boost::get<T>(*v); // Must compile
|
||||
boost::get<const T>(*v); // Must compile
|
||||
boost::strict_get<T>(*v); // Must compile
|
||||
boost::strict_get<const T>(*v); // Must compile
|
||||
|
||||
boost::polymorphic_get<T>(*v); // Must compile
|
||||
boost::polymorphic_get<const T>(*v); // Must compile
|
||||
boost::polymorphic_strict_get<T>(*v); // Must compile
|
||||
boost::polymorphic_strict_get<const T>(*v); // Must compile
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline void check_get_on_types(V* v)
|
||||
{
|
||||
check_get_on_types_impl<T, V>(v);
|
||||
check_get_on_types_impl<T, const V>(v);
|
||||
}
|
||||
|
||||
inline void get_test()
|
||||
{
|
||||
var_t v;
|
||||
check_get_on_types<int>(&v);
|
||||
|
||||
var_t(base()).swap(v);
|
||||
check_get_on_types<base>(&v);
|
||||
|
||||
var_t(derived1()).swap(v);
|
||||
check_get_on_types<derived1>(&v);
|
||||
|
||||
var_t(derived2()).swap(v);
|
||||
check_get_on_types<derived2>(&v);
|
||||
|
||||
var_t(std::string("Hello")).swap(v);
|
||||
check_get_on_types<std::string>(&v);
|
||||
|
||||
var_t_shortened vs = derived2();
|
||||
check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
|
||||
check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
|
||||
// Checking that Base is really determinated
|
||||
check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
|
||||
|
||||
vs = derived1();
|
||||
check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
|
||||
check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
|
||||
// Checking that Base is really determinated
|
||||
check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
|
||||
}
|
||||
|
||||
inline void get_test_no_fallback()
|
||||
{
|
||||
var_t_no_fallback v;
|
||||
var_t_no_fallback(base()).swap(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
|
||||
check_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
|
||||
check_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
|
||||
|
||||
var_t_no_fallback(derived1()).swap(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
|
||||
check_get_on_types_impl_single_type<derived1, var_t_no_fallback, derived1>(&v);
|
||||
check_get_on_types_impl_single_type<derived1, const var_t_no_fallback, derived1>(&v);
|
||||
|
||||
var_t_no_fallback(derived2()).swap(v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
|
||||
check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
|
||||
check_get_on_types_impl_single_type<derived2, var_t_no_fallback, derived2>(&v);
|
||||
check_get_on_types_impl_single_type<derived2, const var_t_no_fallback, derived2>(&v);
|
||||
}
|
||||
|
||||
inline void get_ref_test()
|
||||
{
|
||||
int i = 0;
|
||||
var_ref_t v(i);
|
||||
check_get_on_types<int>(&v);
|
||||
|
||||
base b;
|
||||
var_ref_t v1(b);
|
||||
check_get_on_types<base>(&v1);
|
||||
|
||||
derived1 d1;
|
||||
var_ref_t v2(d1);
|
||||
check_get_on_types<derived1>(&v2);
|
||||
|
||||
derived2 d2;
|
||||
var_ref_t v3(d2);
|
||||
check_get_on_types<derived2>(&v3);
|
||||
|
||||
std::string s("Hello");
|
||||
var_ref_t v4(s);
|
||||
check_get_on_types<std::string>(&v4);
|
||||
}
|
||||
|
||||
|
||||
inline void get_cref_test()
|
||||
{
|
||||
int i = 0;
|
||||
var_cref_t v(i);
|
||||
BOOST_CHECK(boost::get<const int>(&v));
|
||||
BOOST_CHECK(!boost::get<const base>(&v));
|
||||
|
||||
base b;
|
||||
var_cref_t v1(b);
|
||||
BOOST_CHECK(boost::get<const base>(&v1));
|
||||
BOOST_CHECK(!boost::get<const derived1>(&v1));
|
||||
BOOST_CHECK(!boost::get<const int>(&v1));
|
||||
|
||||
std::string s("Hello");
|
||||
const var_cref_t v4 = s;
|
||||
BOOST_CHECK(boost::get<const std::string>(&v4));
|
||||
BOOST_CHECK(!boost::get<const int>(&v4));
|
||||
}
|
||||
|
||||
inline void get_recursive_test()
|
||||
{
|
||||
var_req_t v;
|
||||
check_get_on_types<int>(&v);
|
||||
|
||||
var_req_t(base()).swap(v);
|
||||
check_get_on_types<base>(&v);
|
||||
|
||||
var_req_t(derived1()).swap(v);
|
||||
check_get_on_types<derived1>(&v);
|
||||
|
||||
var_req_t(derived2()).swap(v);
|
||||
check_get_on_types<derived2>(&v);
|
||||
|
||||
var_req_t(std::string("Hello")).swap(v);
|
||||
check_get_on_types<std::string>(&v);
|
||||
|
||||
recursive_structure s = { v }; // copying "v"
|
||||
v = s;
|
||||
check_get_on_types<recursive_structure>(&v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void check_that_does_not_exist_impl()
|
||||
{
|
||||
using namespace boost::detail::variant;
|
||||
|
||||
BOOST_CHECK((holds_element<T, const int>::value));
|
||||
BOOST_CHECK((!holds_element<T, short>::value));
|
||||
BOOST_CHECK((!holds_element<T, short>::value));
|
||||
BOOST_CHECK((!holds_element<T, const short>::value));
|
||||
BOOST_CHECK((!holds_element<T, char*>::value));
|
||||
BOOST_CHECK((!holds_element<T, const char*>::value));
|
||||
BOOST_CHECK((!holds_element<T, char[5]>::value));
|
||||
BOOST_CHECK((!holds_element<T, const char[5]>::value));
|
||||
BOOST_CHECK((!holds_element<T, bool>::value));
|
||||
BOOST_CHECK((!holds_element<T, const bool>::value));
|
||||
|
||||
BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<int> >::value));
|
||||
BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<short> >::value));
|
||||
BOOST_CHECK((!holds_element<T, boost::detail::reference_content<short> >::value));
|
||||
|
||||
|
||||
BOOST_CHECK((holds_element_polymorphic<T, const int>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, const short>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, char*>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, const char*>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, char[5]>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, const char[5]>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, bool>::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, const bool>::value));
|
||||
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
|
||||
BOOST_CHECK((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
|
||||
}
|
||||
|
||||
inline void check_that_does_not_exist()
|
||||
{
|
||||
using namespace boost::detail::variant;
|
||||
|
||||
BOOST_CHECK((holds_element<var_t, int>::value));
|
||||
BOOST_CHECK((holds_element<var_ref_t, int>::value));
|
||||
BOOST_CHECK((!holds_element<var_cref_t, int>::value));
|
||||
|
||||
check_that_does_not_exist_impl<var_t>();
|
||||
check_that_does_not_exist_impl<var_ref_t>();
|
||||
check_that_does_not_exist_impl<var_cref_t>();
|
||||
check_that_does_not_exist_impl<var_req_t>();
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
get_test();
|
||||
get_test_no_fallback();
|
||||
get_ref_test();
|
||||
get_cref_test();
|
||||
get_recursive_test();
|
||||
check_that_does_not_exist();
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
@@ -3,37 +3,46 @@
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2013
|
||||
// Antony Polukhin
|
||||
// Copyright (c) 2013-2015 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/noncopyable.hpp"
|
||||
#define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
|
||||
#include "boost/variant/multivisitors.hpp"
|
||||
#include "boost/variant.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
struct my_noncopyable : boost::noncopyable {
|
||||
my_noncopyable(){}
|
||||
~my_noncopyable(){}
|
||||
};
|
||||
|
||||
typedef boost::variant<my_noncopyable, int> variant_noncopy_t;
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
void operator()(T1&, T2&, T3&, T4&, T5&) const
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
@@ -62,15 +71,30 @@ struct test_visitor: boost::static_visitor<> {
|
||||
BOOST_CHECK(v3 == 3);
|
||||
BOOST_CHECK(v4 == 4);
|
||||
}
|
||||
|
||||
|
||||
// Noncopyables
|
||||
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
};
|
||||
|
||||
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) {
|
||||
template <class T0, class T1, class T2>
|
||||
arithmetics_t operator()(T0 b, T1 v1, T2 v2) const {
|
||||
if (!!b) {
|
||||
return v1;
|
||||
} else {
|
||||
return v2;
|
||||
@@ -112,13 +136,24 @@ int test_main(int , char* [])
|
||||
arithmetics_t(true)
|
||||
);
|
||||
|
||||
/* Delayed multi visitation is not implemented
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
if_visitor if_vis;
|
||||
BOOST_CHECK(
|
||||
boost::apply_visitor(if_vis)(v0, v1, v2)
|
||||
==
|
||||
arithmetics_t(true)
|
||||
);
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
variant_noncopy_t vnonc[6];
|
||||
boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2]);
|
||||
boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3]);
|
||||
|
||||
#ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
|
||||
boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4]);
|
||||
boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4], vnonc[5]);
|
||||
#endif
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,474 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/variant_nonempty_check.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2014 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)
|
||||
|
||||
|
||||
// In this file we are making tests to ensure that variant guarantees nonemptiness.
|
||||
//
|
||||
// For that purpose we create a `throwing_class`, that throws exception at a specified
|
||||
// assignment attempt. If exception was thrown during move/assignemnt operation we make sure
|
||||
// that data in variant is same as before move/assignemnt operation or that a fallback type is
|
||||
// stored in variant.
|
||||
//
|
||||
// Different nonthrowing_class'es are used to tests different variant internal policies:
|
||||
// with/without fallback type + throw/nothrow copyable + throw/nothrow movable
|
||||
|
||||
|
||||
#include "boost/variant/variant.hpp"
|
||||
#include "boost/variant/get.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
struct exception_on_assignment : std::exception {};
|
||||
struct exception_on_move_assignment : exception_on_assignment {};
|
||||
|
||||
void prevent_compiler_noexcept_detection() {
|
||||
char* p = new char;
|
||||
*p = '\0';
|
||||
delete p;
|
||||
}
|
||||
|
||||
|
||||
struct throwing_class {
|
||||
int trash;
|
||||
enum helper_enum {
|
||||
do_not_throw = 780,
|
||||
throw_after_5,
|
||||
throw_after_4,
|
||||
throw_after_3,
|
||||
throw_after_2,
|
||||
throw_after_1
|
||||
};
|
||||
|
||||
bool is_throw() {
|
||||
if (trash < do_not_throw) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (trash > do_not_throw && trash <= throw_after_1) {
|
||||
++ trash;
|
||||
return false;
|
||||
}
|
||||
|
||||
return trash != do_not_throw;
|
||||
}
|
||||
|
||||
throwing_class(int value = 123) BOOST_NOEXCEPT_IF(false) : trash(value) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
throwing_class(const throwing_class& b) BOOST_NOEXCEPT_IF(false) : trash(b.trash) {
|
||||
if (is_throw()) {
|
||||
throw exception_on_assignment();
|
||||
}
|
||||
}
|
||||
|
||||
const throwing_class& operator=(const throwing_class& b) BOOST_NOEXCEPT_IF(false) {
|
||||
trash = b.trash;
|
||||
if (is_throw()) {
|
||||
throw exception_on_assignment();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
throwing_class(throwing_class&& b) BOOST_NOEXCEPT_IF(false) : trash(b.trash) {
|
||||
if (is_throw()) {
|
||||
throw exception_on_move_assignment();
|
||||
}
|
||||
}
|
||||
|
||||
const throwing_class& operator=(throwing_class&& b) BOOST_NOEXCEPT_IF(false) {
|
||||
trash = b.trash;
|
||||
if (is_throw()) {
|
||||
throw exception_on_move_assignment();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual ~throwing_class() {}
|
||||
};
|
||||
|
||||
struct nonthrowing_class {
|
||||
int trash;
|
||||
|
||||
nonthrowing_class() BOOST_NOEXCEPT_IF(false) : trash(123) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
nonthrowing_class(const nonthrowing_class&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
const nonthrowing_class& operator=(const nonthrowing_class&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
nonthrowing_class(nonthrowing_class&&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
const nonthrowing_class& operator=(nonthrowing_class&&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nonthrowing_class2 {
|
||||
int trash;
|
||||
|
||||
nonthrowing_class2() BOOST_NOEXCEPT_IF(false) : trash(123) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
};
|
||||
|
||||
struct nonthrowing_class3 {
|
||||
int trash;
|
||||
|
||||
nonthrowing_class3() BOOST_NOEXCEPT_IF(true) : trash(123) {}
|
||||
|
||||
nonthrowing_class3(const nonthrowing_class3&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
const nonthrowing_class3& operator=(const nonthrowing_class3&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
nonthrowing_class3(nonthrowing_class3&&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
const nonthrowing_class3& operator=(nonthrowing_class3&&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nonthrowing_class4 {
|
||||
int trash;
|
||||
|
||||
nonthrowing_class4() BOOST_NOEXCEPT_IF(false) : trash(123) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
nonthrowing_class4(const nonthrowing_class4&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
}
|
||||
|
||||
const nonthrowing_class4& operator=(const nonthrowing_class4&) BOOST_NOEXCEPT_IF(false) {
|
||||
prevent_compiler_noexcept_detection();
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
nonthrowing_class4(nonthrowing_class4&&) BOOST_NOEXCEPT_IF(true) {
|
||||
}
|
||||
|
||||
const nonthrowing_class4& operator=(nonthrowing_class4&&) BOOST_NOEXCEPT_IF(true) {
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// Tests /////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template <class Nonthrowing>
|
||||
inline void check_1_impl(int helper)
|
||||
{
|
||||
boost::variant<throwing_class, Nonthrowing> v;
|
||||
try {
|
||||
v = throwing_class(helper);
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
}
|
||||
|
||||
try {
|
||||
throwing_class tc(helper);
|
||||
v = tc;
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
}
|
||||
}
|
||||
|
||||
inline void check_1(int helper = 1)
|
||||
{
|
||||
check_1_impl<nonthrowing_class>(helper);
|
||||
check_1_impl<nonthrowing_class2>(helper);
|
||||
check_1_impl<nonthrowing_class3>(helper);
|
||||
check_1_impl<nonthrowing_class4>(helper);
|
||||
check_1_impl<boost::blank>(helper);
|
||||
}
|
||||
|
||||
template <class Nonthrowing>
|
||||
inline void check_2_impl(int helper)
|
||||
{
|
||||
boost::variant<Nonthrowing, throwing_class> v;
|
||||
try {
|
||||
v = throwing_class(helper);
|
||||
BOOST_CHECK(v.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v));
|
||||
}
|
||||
|
||||
try {
|
||||
throwing_class cl(helper);
|
||||
v = cl;
|
||||
BOOST_CHECK(v.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v));
|
||||
}
|
||||
}
|
||||
|
||||
inline void check_2(int helper = 1)
|
||||
{
|
||||
check_2_impl<nonthrowing_class>(helper);
|
||||
check_2_impl<nonthrowing_class2>(helper);
|
||||
check_2_impl<nonthrowing_class3>(helper);
|
||||
check_2_impl<nonthrowing_class4>(helper);
|
||||
check_2_impl<boost::blank>(helper);
|
||||
}
|
||||
|
||||
template <class Nonthrowing>
|
||||
inline void check_3_impl(int helper)
|
||||
{
|
||||
boost::variant<Nonthrowing, throwing_class> v1, v2;
|
||||
|
||||
swap(v1, v2);
|
||||
try {
|
||||
v1 = throwing_class(helper);
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v1.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v1));
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
v2 = throwing_class(helper);
|
||||
BOOST_CHECK(v2.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v2));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v2.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v2));
|
||||
}
|
||||
|
||||
|
||||
if (!v1.which() && !v2.which()) {
|
||||
swap(v1, v2); // Make sure that two backup holders swap well
|
||||
BOOST_CHECK(!v1.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v1));
|
||||
BOOST_CHECK(!v2.which());
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v2));
|
||||
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
inline void check_3(int helper = 1)
|
||||
{
|
||||
check_3_impl<nonthrowing_class>(helper);
|
||||
check_3_impl<nonthrowing_class2>(helper);
|
||||
check_3_impl<nonthrowing_class3>(helper);
|
||||
check_3_impl<nonthrowing_class4>(helper);
|
||||
check_3_impl<boost::blank>(helper);
|
||||
}
|
||||
|
||||
inline void check_4(int helper = 1)
|
||||
{
|
||||
// This one has a fallback
|
||||
boost::variant<int, throwing_class> v1, v2;
|
||||
|
||||
swap(v1, v2);
|
||||
try {
|
||||
v1 = throwing_class(helper);
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v1.which());
|
||||
BOOST_CHECK(boost::get<int>(&v1));
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
v2 = throwing_class(helper);
|
||||
BOOST_CHECK(v2.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v2));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(!v2.which());
|
||||
BOOST_CHECK(boost::get<int>(&v2));
|
||||
}
|
||||
|
||||
if (!v1.which() && !v2.which()) {
|
||||
swap(v1, v2);
|
||||
BOOST_CHECK(!v1.which());
|
||||
BOOST_CHECK(boost::get<int>(&v1));
|
||||
BOOST_CHECK(!v2.which());
|
||||
BOOST_CHECK(boost::get<int>(&v2));
|
||||
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Nonthrowing>
|
||||
inline void check_5_impl(int helper)
|
||||
{
|
||||
boost::variant<Nonthrowing, throwing_class> v1, v2;
|
||||
throwing_class throw_not_now;
|
||||
throw_not_now.trash = throwing_class::do_not_throw;
|
||||
v1 = throw_not_now;
|
||||
v2 = throw_not_now;
|
||||
|
||||
boost::get<throwing_class>(v1).trash = 1;
|
||||
boost::get<throwing_class>(v2).trash = 1;
|
||||
|
||||
try {
|
||||
v1 = throwing_class(helper);
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
}
|
||||
|
||||
boost::get<throwing_class>(v1).trash = throwing_class::do_not_throw;
|
||||
boost::get<throwing_class>(v2).trash = throwing_class::do_not_throw;
|
||||
v1 = Nonthrowing();
|
||||
v2 = Nonthrowing();
|
||||
try {
|
||||
v1 = throwing_class(helper);
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v1.which() == 0);
|
||||
BOOST_CHECK(boost::get<Nonthrowing>(&v1));
|
||||
}
|
||||
|
||||
int v1_type = v1.which();
|
||||
int v2_type = v2.which();
|
||||
try {
|
||||
swap(v1, v2); // Make sure that backup holders swap well
|
||||
BOOST_CHECK(v1.which() == v2_type);
|
||||
BOOST_CHECK(v2.which() == v1_type);
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v1.which() == v1_type);
|
||||
BOOST_CHECK(v2.which() == v2_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void check_5(int helper = 1)
|
||||
{
|
||||
check_5_impl<nonthrowing_class>(helper);
|
||||
check_5_impl<nonthrowing_class2>(helper);
|
||||
check_5_impl<nonthrowing_class3>(helper);
|
||||
check_5_impl<nonthrowing_class4>(helper);
|
||||
check_5_impl<boost::blank>(helper);
|
||||
}
|
||||
|
||||
template <class Nonthrowing>
|
||||
inline void check_6_impl(int helper)
|
||||
{
|
||||
boost::variant<Nonthrowing, throwing_class> v1, v2;
|
||||
throwing_class throw_not_now;
|
||||
throw_not_now.trash = throwing_class::do_not_throw;
|
||||
v1 = throw_not_now;
|
||||
v2 = throw_not_now;
|
||||
|
||||
v1 = throw_not_now;
|
||||
v2 = throw_not_now;
|
||||
swap(v1, v2);
|
||||
boost::get<throwing_class>(v1).trash = 1;
|
||||
boost::get<throwing_class>(v2).trash = 1;
|
||||
|
||||
v1 = throwing_class(throw_not_now);
|
||||
v2 = v1;
|
||||
|
||||
v1 = Nonthrowing();
|
||||
try {
|
||||
throwing_class tc;
|
||||
tc.trash = helper;
|
||||
v1 = tc;
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(boost::get<throwing_class>(&v1));
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v1.which() == 0);
|
||||
}
|
||||
|
||||
v2 = Nonthrowing();
|
||||
try {
|
||||
v2 = 2;
|
||||
BOOST_CHECK(false);
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v2.which() == 0);
|
||||
}
|
||||
|
||||
// Probably the most significant test:
|
||||
// unsuccessful swap must preserve old values of vaiant
|
||||
v1 = throw_not_now;
|
||||
boost::get<throwing_class>(v1).trash = helper;
|
||||
try {
|
||||
swap(v1, v2);
|
||||
} catch (const exception_on_assignment& /*e*/) {
|
||||
BOOST_CHECK(v1.which() == 1);
|
||||
BOOST_CHECK(v2.which() == 0);
|
||||
BOOST_CHECK(boost::get<throwing_class>(v1).trash == helper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void check_6(int helper = 1)
|
||||
{
|
||||
check_6_impl<nonthrowing_class>(helper);
|
||||
check_6_impl<nonthrowing_class2>(helper);
|
||||
check_6_impl<nonthrowing_class3>(helper);
|
||||
check_6_impl<nonthrowing_class4>(helper);
|
||||
check_6_impl<boost::blank>(helper);
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
// throwing_class::throw_after_1 + 1 => throw on first assignment/construction
|
||||
// throwing_class::throw_after_1 => throw on second assignment/construction
|
||||
// throwing_class::throw_after_2 => throw on third assignment/construction
|
||||
// ...
|
||||
for (int i = throwing_class::throw_after_1 + 1; i != throwing_class::do_not_throw; --i) {
|
||||
check_1(i);
|
||||
check_2(i);
|
||||
check_3(i);
|
||||
check_4(i);
|
||||
check_5(i);
|
||||
check_6(i);
|
||||
}
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost-libs variant/test/variant_plymorphic_get_test.cpp source file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003 Eric Friedman
|
||||
// Copyright (c) 2013-2014 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/variant/variant.hpp"
|
||||
#include "boost/variant/apply_visitor.hpp"
|
||||
#include "boost/variant/static_visitor.hpp"
|
||||
#include "boost/variant/polymorphic_get.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
struct base {int trash;};
|
||||
struct derived1 : base{};
|
||||
struct derived2 : base{};
|
||||
|
||||
struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
|
||||
struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
|
||||
struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
|
||||
struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
|
||||
|
||||
template <class T, class Variant>
|
||||
inline void check_throws(Variant& v) {
|
||||
try {
|
||||
boost::polymorphic_get<T>(v);
|
||||
BOOST_CHECK(false);
|
||||
} catch (const boost::bad_polymorphic_get& e) {
|
||||
BOOST_CHECK(!!e.what());
|
||||
BOOST_CHECK(std::string(e.what()) != boost::bad_get().what());
|
||||
}
|
||||
}
|
||||
|
||||
int test_main(int , char* [])
|
||||
{
|
||||
typedef boost::variant<int, base, derived1, derived2> var_t;
|
||||
|
||||
var_t var1;
|
||||
BOOST_CHECK(!boost::polymorphic_get<base>(&var1));
|
||||
check_throws<base>(var1);
|
||||
BOOST_CHECK(!boost::polymorphic_get<const base>(&var1));
|
||||
check_throws<base, const var_t>(var1);
|
||||
|
||||
var1 = derived1();
|
||||
BOOST_CHECK(boost::polymorphic_get<base>(&var1));
|
||||
BOOST_CHECK(boost::polymorphic_get<const base>(&var1));
|
||||
|
||||
derived2 d;
|
||||
d.trash = 777;
|
||||
var_t var2 = d;
|
||||
BOOST_CHECK(boost::polymorphic_get<base>(var2).trash == 777);
|
||||
BOOST_CHECK(boost::polymorphic_get<const base>(var2).trash == 777);
|
||||
|
||||
var2 = 777;
|
||||
BOOST_CHECK(!boost::polymorphic_get<base>(&var2));
|
||||
check_throws<base>(var2);
|
||||
BOOST_CHECK(!boost::polymorphic_get<const base>(&var2));
|
||||
check_throws<base, const var_t>(var2);
|
||||
BOOST_CHECK(boost::polymorphic_get<int>(var2) == 777);
|
||||
BOOST_CHECK(boost::polymorphic_get<const int>(var2) == 777);
|
||||
|
||||
typedef boost::variant<int, vbase, vderived1, vderived2, vderived3> vvar_t;
|
||||
|
||||
vvar_t v = vderived3();
|
||||
boost::polymorphic_get<vderived3>(v).trash = 777;
|
||||
const vvar_t& cv = v;
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(cv).trash == 777);
|
||||
BOOST_CHECK(boost::polymorphic_get<const vbase>(cv).trash == 777);
|
||||
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(cv).foo() == 3);
|
||||
BOOST_CHECK(boost::polymorphic_get<vbase>(v).foo() == 3);
|
||||
BOOST_CHECK(boost::polymorphic_get<const vbase>(cv).foo() == 3);
|
||||
BOOST_CHECK(boost::polymorphic_get<const vbase>(v).foo() == 3);
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
Reference in New Issue
Block a user