Compare commits

..

1 Commits

Author SHA1 Message Date
Beman Dawes 967c14f7b5 Release
[SVN r43921]
2008-03-29 11:50:24 +00:00
108 changed files with 2417 additions and 8593 deletions
-11
View File
@@ -1,11 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
-168
View File
@@ -1,168 +0,0 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-12"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.8"
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-11"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.7"
- toolset: clang
compiler: clang++
cxxstd: "03,11,14,17,2a"
os: ubuntu-24.04
cxxflags: "cxxflags=-fsanitize=address,undefined,integer -fno-sanitize-recover=undefined"
linkflags: "linkflags=-fsanitize=address,undefined,integer"
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
rm -rf libs/$LIBRARY/*
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
./b2 -j4 variant=debug tools/inspect
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
dist/bin/inspect libs/$LIBRARY
- name: Prepare coverage data
if: matrix.gcov_tool
run: |
mkdir -p $GITHUB_WORKSPACE/coveralls
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
wget https://github.com/linux-test-project/lcov/archive/v1.16.zip
unzip v1.16.zip
LCOV="`pwd`/lcov-1.16/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
cd ../boost-root
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
echo $OTHER_LIBS
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
- name: Coveralls
uses: coverallsapp/github-action@master
if: matrix.gcov_tool
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coveralls/coverage.info
parallel: true
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: msvc
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2025
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2025
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
finish:
needs: posix
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}
parallel-finished: true
-27
View File
@@ -1,27 +0,0 @@
# Copyright 2019 Mike Dev
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required( VERSION 3.5...3.20 )
project( boost_variant VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )
add_library( boost_variant INTERFACE )
add_library( Boost::variant ALIAS boost_variant )
target_include_directories( boost_variant INTERFACE include )
target_link_libraries( boost_variant
INTERFACE
Boost::assert
Boost::config
Boost::container_hash
Boost::core
Boost::detail
Boost::integer
Boost::mpl
Boost::preprocessor
Boost::throw_exception
Boost::type_index
Boost::type_traits
Boost::utility
)
-16
View File
@@ -1,16 +0,0 @@
# [Boost.Variant](https://boost.org/libs/variant)
Boost.Variant, part of collection of the [Boost C++ Libraries](https://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: | [![CI](https://github.com/boostorg/variant/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/variant/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/bijfdoy7byfgc6e2/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/variant-ykfti/branch/develop) | [![Coverage Status](https://coveralls.io/repos/boostorg/variant/badge.png?branch=develop)](https://coveralls.io/r/apolukhin/variant?branch=develop) | [details...](https://regression.boost.io/develop/developer/variant.html)
Master branch: | [![CI](https://github.com/boostorg/variant/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/variant/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/bijfdoy7byfgc6e2/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/variant-ykfti/branch/master) | [![Coverage Status](https://coveralls.io/repos/boostorg/variant/badge.png?branch=master)](https://coveralls.io/r/apolukhin/variant?branch=master) | [details...](https://regression.boost.io/master/developer/variant.html)
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/variant.html)
### License
Distributed under the [Boost Software License, Version 1.0](https://boost.org/LICENSE_1_0.txt).
-34
View File
@@ -1,34 +0,0 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/container_hash//boost_container_hash
/boost/core//boost_core
/boost/detail//boost_detail
/boost/integer//boost_integer
/boost/mpl//boost_mpl
/boost/preprocessor//boost_preprocessor
/boost/throw_exception//boost_throw_exception
/boost/type_index//boost_type_index
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility ;
project /boost/variant
: common-requirements
<include>include
;
explicit
[ alias boost_variant : : : : <library>$(boost_dependencies) ]
[ alias all : boost_variant test ]
;
call-if : boost-library variant
;
+2 -26
View File
@@ -1,29 +1,5 @@
# 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 ;
project boost/doc ;
import boostbook : boostbook ;
boostbook variant-doc
:
variant.xml
:
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;
boostbook variant-doc : variant.xml ;
###############################################################################
alias boostdoc
: variant.xml
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;
+1 -7
View File
@@ -1,12 +1,6 @@
<?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>
@@ -115,4 +109,4 @@
2002.
</para>
</section>
</section>
+24 -7
View File
@@ -1,12 +1,6 @@
<?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>
@@ -276,6 +270,29 @@
</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 &lt;&gt;
struct <classname>has_nothrow_copy</classname>&lt; myUDT &gt;
: <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
@@ -307,4 +324,4 @@
</section>
</section>
</section>
+1 -7
View File
@@ -1,12 +1,6 @@
<?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>
@@ -138,4 +132,4 @@ int main()
</section>
</section>
</section>
+1 -7
View File
@@ -1,12 +1,6 @@
<?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>
@@ -238,4 +232,4 @@ interface, and implementation of the library.</para>
</section>
</section>
</section>
+15 -172
View File
@@ -1,13 +1,6 @@
<?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-2026 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">
@@ -21,9 +14,6 @@
<simpara>See the &quot;visitor-only&quot; 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>
@@ -47,18 +37,6 @@
<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&amp;...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Variant"/>
@@ -94,63 +72,7 @@
</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 &quot;visitor-only&quot; 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
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 &amp;</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&amp;...</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>
@@ -164,10 +86,10 @@
<paramtype>Visitor &amp;</paramtype>
</parameter>
<parameter name="operand">
<paramtype>Variant&amp;&amp;</paramtype>
<paramtype>Variant &amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Visitor"/>
@@ -180,7 +102,7 @@
<paramtype>const Visitor &amp;</paramtype>
</parameter>
<parameter name="operand">
<paramtype>Variant&amp;&amp;</paramtype>
<paramtype>Variant &amp;</paramtype>
</parameter>
</signature>
@@ -191,16 +113,16 @@
<template-type-parameter name="Variant2"/>
</template>
<type>typename BinaryVisitor::result_type OR decltype(auto)</type>
<type>typename BinaryVisitor::result_type</type>
<parameter name="visitor">
<paramtype>BinaryVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
<paramtype>Variant2 &amp;</paramtype>
</parameter>
</signature>
@@ -211,70 +133,16 @@
<template-type-parameter name="Variant2"/>
</template>
<type>typename BinaryVisitor::result_type OR decltype(auto)</type>
<type>typename BinaryVisitor::result_type</type>
<parameter name="visitor">
<paramtype>const BinaryVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
<paramtype>Variant1 &amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
<parameter name="visitor">
<paramtype>MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3&amp;&amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
<parameter name="visitor">
<paramtype>const MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3&amp;&amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
<paramtype>Variant2 &amp;</paramtype>
</parameter>
</signature>
@@ -290,19 +158,6 @@
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Visitor"/>
</template>
<type><classname>apply_visitor_delayed_cpp14_t</classname>&lt;Visitor&gt;</type>
<parameter name="visitor">
<paramtype>Visitor &amp;</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
@@ -312,8 +167,7 @@
<description>
<simpara>The behavior of <code>apply_visitor</code> is dependent on
the number of arguments on which it operates (i.e., other than the
visitor). If your compiler does not support the rvalue references or reference qualifiers then all the
forwarding references from above degrade to non const lvalue reference. The function behaves as follows:
visitor). The function behaves as follows:
<itemizedlist>
<listitem>Overloads accepting one operand invoke the unary function
@@ -325,20 +179,9 @@
the given <code><classname>variant</classname></code>
operands.</listitem>
<listitem>Overloads accepting three or more operands invoke the
function call operator of the given visitor on the content of
the given <code><classname>variant</classname></code>
operands. Maximum amount of parameters controlled by
<code><emphasis role="bold"><macroname>BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS</macroname></emphasis></code>
macro. Those functions are actually defined in 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 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
<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
<code><functionname>apply_visitor</functionname></code> using
these arguments and <code>visitor</code>, thus behaving as
specified above. (This behavior is particularly useful, for
@@ -373,4 +216,4 @@
</throws>
</overloaded-function>
</namespace>
</header>
</header>
+1 -7
View File
@@ -1,12 +1,6 @@
<?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">
@@ -26,4 +20,4 @@
</class>
</namespace>
</header>
</header>
+4 -48
View File
@@ -1,12 +1,4 @@
<?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)
-->
<?xml version="1.0" encoding="utf-8" ?>
<section id="variant.concepts">
<title>Concepts</title>
@@ -19,7 +11,7 @@
are as follows:</para>
<itemizedlist>
<listitem><conceptname>CopyConstructible</conceptname> or <conceptname>MoveConstructible</conceptname>.</listitem>
<listitem><conceptname>CopyConstructible</conceptname> [20.1.3].</listitem>
<listitem>Destructor upholds the no-throw exception-safety
guarantee.</listitem>
<listitem>Complete at the point of <code>variant</code> template
@@ -42,12 +34,6 @@
concept. (Note that top-level <code>const</code>-qualified types and
reference types do <emphasis>not</emphasis> meet these
requirements.)</listitem>
<listitem><conceptname>MoveAssignable</conceptname>:
<code>variant</code> is itself <emphasis>MoveAssignable</emphasis> if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level <code>const</code>-qualified types and
reference types do <emphasis>not</emphasis> meet these
requirements.)</listitem>
<listitem><conceptname>DefaultConstructible</conceptname> [20.1.4]:
<code>variant</code> is itself
<conceptname>DefaultConstructible</conceptname> if and only if its first
@@ -65,10 +51,6 @@
<code>variant</code> is itself <emphasis>OutputStreamable</emphasis>
if and only if every one of its bounded types meets the requirements
of the concept.</listitem>
<listitem><link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>:
<code>variant</code> is itself <emphasis>Hashable</emphasis>
if and only if every one of its bounded types meets the requirements
of the concept.</listitem>
</itemizedlist>
</section>
@@ -82,9 +64,7 @@
<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>. C++14 compatible compilers
could detect <code>result_type</code> automatically, but will stick to
<code>result_type</code> if it is defined. (See
<listitem>Must expose inner type <code>result_type</code>. (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
@@ -133,18 +113,6 @@ public:
}
};</programlisting>
<para>C++14 compatible compilers detect <code>result_type</code> automatically:</para>
<programlisting>
<classname>boost::variant</classname>&lt;int, float&gt; v;
// ...
<functionname>boost::apply_visitor</functionname>(
[](auto val) { return std::to_string(val); },
v
);
</programlisting>
</section>
</section>
@@ -161,16 +129,4 @@ public:
</itemizedlist>
</section>
<section id="variant.concepts.hashable">
<title><emphasis>Hashable</emphasis></title>
<para>The requirements on an <emphasis role="bold">hashable</emphasis> type <code>T</code> are as follows:</para>
<itemizedlist>
<listitem>For any object <code>t</code> of type <code>T</code>,
<code>boost::hash&lt;T&gt;()(t)</code> must be a valid
expression.</listitem>
</itemizedlist>
</section>
</section>
</section>
+7 -227
View File
@@ -1,12 +1,6 @@
<?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">
@@ -16,17 +10,17 @@
</inherit>
<purpose>
<simpara>The exception thrown in the event of a failed application of
<code><functionname>boost::get</functionname></code> on the given
<simpara>The exception thrown in the event of a failed application of
<code><functionname>boost::get</functionname></code> on the given
operand value.</simpara>
</purpose>
<method name="what" specifiers="virtual" cv="const">
<type>const char *</type>
<method name="what" specifiers="virtual" cv="const">
<type>const char *</type>
</method>
</class>
<overloaded-function name="relaxed_get">
<overloaded-function name="get">
<signature>
<template>
<template-type-parameter name="U"/>
@@ -58,7 +52,7 @@
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; *</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="U"/>
@@ -91,27 +85,9 @@
</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 &amp;&amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;&amp;</paramtype>
</parameter>
</signature>
<purpose>
<simpara>Retrieves a value of a specified type from a given
<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>
<code><classname>variant</classname></code>.</simpara>
</purpose>
<description>
@@ -120,11 +96,6 @@
<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 its 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
@@ -171,196 +142,5 @@
</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>&lt;T1, T2, ..., TN&gt; *</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>&lt;T1, T2, ..., TN&gt; *</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 &amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;</type>
<parameter name="operand">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;&amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;&amp;</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>&lt;T1, T2, ..., TN&gt; *</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>&lt;T1, T2, ..., TN&gt; *</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 &amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;</type>
<parameter name="operand">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;&amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;&amp;</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 its behavior is closer to <code>std::get</code>
from C++ Standard Library.</simpara>
</description>
</overloaded-function>
</namespace>
</header>
-80
View File
@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE header PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<!--
Copyright 2013-2026 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"/>
<para>Provides declarations of <functionname>apply_visitor</functionname> for three or more
<code><classname>variant</classname></code> parameters.</para>
<namespace name="boost">
<overloaded-function name="apply_visitor /*three or more variant parameters*/">
<description>
<simpara>Allows compile-time checked type-safe application of the
given visitor to the content of the given variant, ensuring that all
types are handled by the visitor. See <functionname>apply_visitor</functionname>
for more information.</simpara>
</description>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
<parameter name="visitor">
<paramtype>MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3&amp;&amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="MultiVisitor"/>
<template-type-parameter name="Variant1"/>
<template-type-parameter name="Variant2"/>
<template-type-parameter name="Variant3"/>
</template>
<type>typename MultiVisitor::result_type OR decltype(auto)</type>
<parameter name="visitor">
<paramtype>const MultiVisitor &amp;</paramtype>
</parameter>
<parameter name="operand1">
<paramtype>Variant1&amp;&amp;</paramtype>
</parameter>
<parameter name="operand2">
<paramtype>Variant2&amp;&amp;</paramtype>
</parameter>
<parameter name="operand3">
<paramtype>Variant3&amp;&amp;</paramtype>
</parameter>
<parameter name="other_operands">
<paramtype>...</paramtype>
</parameter>
</signature>
</overloaded-function>
</namespace>
</header>
-326
View File
@@ -1,326 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE header PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<!--
Copyright 2013-2026 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>&lt;T1, T2, ..., TN&gt; *</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>&lt;T1, T2, ..., TN&gt; *</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 &amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;</type>
<parameter name="operand">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 its 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>&lt;T1, T2, ..., TN&gt; *</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>&lt;T1, T2, ..., TN&gt; *</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 &amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;</type>
<parameter name="operand">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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>&lt;T1, T2, ..., TN&gt; *</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>&lt;T1, T2, ..., TN&gt; *</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 &amp;</type>
<parameter name="operand">
<paramtype><classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 &amp;</type>
<parameter name="operand">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</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 its behavior is closer to <code>std::get</code>
from C++ Standard Library.</simpara>
</description>
</overloaded-function>
</namespace>
</header>
+6 -7
View File
@@ -1,12 +1,6 @@
<?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">
@@ -104,9 +98,14 @@
<listitem><code>Sequence</code> must meet the requirements of
<libraryname>MPL</libraryname>'s <emphasis>Sequence</emphasis>
concept.</listitem>
<listitem>Due to standard conformance problems in several compilers,
<code>make_recursive_variant_over</code> may not be supported on
your compiler. See
<code><macroname>BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</macroname></code>
for more information.</listitem>
</itemizedlist>
</description>
</class>
</namespace>
</header>
</header>
+2 -8
View File
@@ -1,12 +1,6 @@
<?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">
@@ -267,4 +261,4 @@
</class>
</namespace>
</header>
</header>
+2 -10
View File
@@ -1,12 +1,6 @@
<?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"/>
@@ -14,7 +8,7 @@
<header name="boost/variant.hpp">
<section id="variant.header.include-all">
<para>This header exists simply as a convenience to the user, including
all of the headers in the <code>boost/variant</code> directory except &lt;boost/multivisiors.hpp&gt;.</para>
all of the headers in the <code>boost/variant</code> directory.</para>
</section>
</header>
@@ -23,10 +17,8 @@
<xi:include href="recursive_variant.xml"/>
<xi:include href="recursive_wrapper.xml"/>
<xi:include href="apply_visitor.xml"/>
<xi:include href="multivisitor.xml"/>
<xi:include href="get.xml"/>
<xi:include href="polymorphic_get.xml"/>
<xi:include href="bad_visit.xml"/>
<xi:include href="static_visitor.xml"/>
<xi:include href="visitor_ptr.xml"/>
</library-reference>
</library-reference>
+1 -7
View File
@@ -1,12 +1,6 @@
<?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">
@@ -34,4 +28,4 @@
</class>
</namespace>
</header>
</header>
+12 -394
View File
@@ -1,12 +1,6 @@
<?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">
@@ -116,26 +110,6 @@
copy constructor of <code>other</code>'s contained type.</simpara>
</throws>
</constructor>
<constructor>
<parameter name="other">
<paramtype>variant &amp;&amp;</paramtype>
</parameter>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<postconditions>
<simpara>Content of <code>*this</code> is move constructed from the content of
<code>other</code>.</simpara>
</postconditions>
<throws>
<simpara>May fail with any exceptions arising from the
move constructor of <code>other</code>'s contained type.</simpara>
</throws>
</constructor>
<constructor>
<template>
@@ -178,25 +152,6 @@
construction from temporaries.</simpara>
</notes>
</constructor>
<constructor>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="operand">
<paramtype>T &amp;&amp;</paramtype>
</parameter>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<notes>
<simpara>Same semantics as previous constructor, but allows
move construction if <code>operand</code> is an rvalue.</simpara>
</notes>
</constructor>
<constructor>
<template>
@@ -253,28 +208,6 @@
construction from temporaries.</simpara>
</notes>
</constructor>
<constructor>
<template>
<template-type-parameter name="U1"/>
<template-type-parameter name="U2"/>
<template-varargs/>
<template-type-parameter name="UN"/>
</template>
<requires>
<simpara>C++11 compatible compiler.</simpara>
</requires>
<parameter name="operand">
<paramtype>variant&lt;U1, U2, ..., UN&gt; &amp;&amp;</paramtype>
</parameter>
<notes>
<simpara>Same semantics as previous constructor, but allows
move construction.</simpara>
</notes>
</constructor>
<method-group name="modifiers">
@@ -287,7 +220,7 @@
<requires>
<simpara>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
<conceptname>Assignable</conceptname>
concept.</simpara>
</requires>
@@ -301,7 +234,7 @@
the contained type of <code>*this</code>, then may fail with any
exceptions arising from the <code>swap</code> of the contents of
<code>*this</code> and <code>other</code>. Otherwise, may fail
with any exceptions arising from either of the move or copy constructors
with any exceptions arising from either of the copy constructors
of the contained types. Also, in the event of insufficient
memory, may fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
@@ -341,43 +274,6 @@
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
<parameter name="rhs">
<paramtype>variant &amp;&amp;</paramtype>
</parameter>
<requires>
<itemizedlist>
<listitem>C++11 compatible compiler.</listitem>
<listitem>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
concept.</listitem>
</itemizedlist>
</requires>
<effects>
<simpara>If the contained type of <code>rhs</code> is the same as
the contained type of <code>*this</code>, then move assigns the
content of <code>rhs</code> into the content of
<code>*this</code>. Otherwise, move constructs
<code>*this</code> using the content of <code>rhs</code>,
destroying the previous content of <code>*this</code>.</simpara>
</effects>
<throws>
<simpara>If the contained type of <code>rhs</code> is the same as
the contained type of <code>*this</code>, then may fail with any
exceptions arising from the move assignment of the content of
<code>rhs</code> into the content <code>*this</code>. Otherwise,
may fail with any exceptions arising from the move constructor
of the contained type of <code>rhs</code>. Also, in the event of
insufficient memory, may fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
@@ -423,52 +319,6 @@
</throws>
</method>
<method name="operator=">
<type>variant &amp;</type>
<template>
<template-type-parameter name="T"/>
</template>
<parameter name="rhs">
<paramtype>T &amp;&amp;</paramtype>
</parameter>
<requires>
<itemizedlist>
<listitem>C++11 compatible compiler.</listitem>
<listitem><code>rhs</code> is an rvalue. Otherwise previous operator will be used.</listitem>
<listitem><code>T</code> must be unambiguously convertible to
one of the bounded types (i.e., <code>T1</code>,
<code>T2</code>, etc.).</listitem>
<listitem>Every bounded type must fulfill the requirements of the
<conceptname>MoveAssignable</conceptname>
concept.</listitem>
</itemizedlist>
</requires>
<effects>
<simpara>If the contained type of <code>*this</code> is
<code>T</code>, then move assigns <code>rhs</code> into the content
of <code>*this</code>. Otherwise, makes the content of
<code>*this</code> the best conversion of <code>rhs</code> to
one of the bounded types, as determined by standard overload
resolution rules, destroying the previous content of
<code>*this</code>(conversion is usually done via move construction).</simpara>
</effects>
<throws>
<simpara>If the contained type of <code>*this</code> is
<code>T</code>, then may fail with any exceptions arising from
the move assignment of <code>rhs</code> into the content
<code>*this</code>. Otherwise, may fail with any exceptions
arising from the conversion of <code>rhs</code> to one of the
bounded types. Also, in the event of insufficient memory, may
fail with <code>std::bad_alloc</code>
(<link linkend="variant.design.never-empty.problem">why?</link>).</simpara>
</throws>
</method>
</method-group>
<method-group name="queries">
@@ -508,19 +358,12 @@
<method name="type" cv="const">
<type>const std::type_info &amp;</type>
<notes>
<simpara><code>boost::variant</code> usues Boost.TypeIndex library so actually
<code>const boost::typeindex::type_info &amp;</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>
</returns>
<throws>Will not throw.</throws>
</method>
</method-group>
@@ -536,7 +379,7 @@
<paramtype>const variant &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
@@ -562,60 +405,14 @@
</requires>
<returns>
<simpara><code>true</code> if <code>which() == rhs.which()</code>
<simpara><code>true</code> iff <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 &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
<template-type-parameter name="U"/>
</template>
<parameter>
<paramtype>const U &amp;</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
@@ -633,7 +430,7 @@
<paramtype>const variant &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
@@ -674,147 +471,6 @@
</throws>
</overloaded-method>
<overloaded-method name="operator&gt;">
<purpose>GreaterThan comparison.</purpose>
<signature cv="const">
<type>bool</type>
<parameter name="rhs">
<paramtype>const variant &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
<template-type-parameter name="U"/>
</template>
<parameter>
<paramtype>const U &amp;</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 &lt; *this</code>.</simpara>
</returns>
<throws>
<simpara>May fail with
any exceptions arising from <code>operator&lt;(T,T)</code>,
where <code>T</code> is the contained type of
<code>*this</code>.</simpara>
</throws>
</overloaded-method>
<overloaded-method name="operator&lt;=">
<purpose>LessThan or Equal comparison.</purpose>
<signature cv="const">
<type>bool</type>
<parameter name="rhs">
<paramtype>const variant &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
<template-type-parameter name="U"/>
</template>
<parameter>
<paramtype>const U &amp;</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&lt;(T,T)</code>,
where <code>T</code> is the contained type of
<code>*this</code>.</simpara>
</throws>
</overloaded-method>
<overloaded-method name="operator&gt;=">
<purpose>GreaterThan or Equal comparison.</purpose>
<signature cv="const">
<type>bool</type>
<parameter name="rhs">
<paramtype>const variant &amp;</paramtype>
</parameter>
</signature>
<signature cv="const">
<type>void</type>
<template>
<template-type-parameter name="U"/>
</template>
<parameter>
<paramtype>const U &amp;</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 &lt; lhs)</code>.</simpara>
</returns>
<throws>
<simpara>May fail with
any exceptions arising from <code>operator&lt;(T,T)</code>,
where <code>T</code> is the contained type of
<code>*this</code>.</simpara>
</throws>
</overloaded-method>
</method-group>
</class>
@@ -880,49 +536,6 @@
<simpara>Calls <code>out &lt;&lt; x</code>, where <code>x</code> is
the content of <code>rhs</code>.</simpara>
</effects>
<notes>
<simpara>Not available when <code>BOOST_NO_IOSTREAM</code> is
defined.</simpara>
</notes>
</function>
<function name="hash_value">
<purpose>Provides hashing for <code>variant</code> types so
that <code>boost::hash</code> may compute hash.</purpose>
<template>
<template-type-parameter name="T1"/>
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
</template>
<type>std::size_t</type>
<parameter name="rhs">
<paramtype>const <classname>variant</classname>&lt;T1, T2, ..., TN&gt; &amp;</paramtype>
</parameter>
<requires>
<simpara>Every bounded type of the <code>variant</code> must
fulfill the requirements of the
<link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>
concept.</simpara>
</requires>
<effects>
<simpara>Calls <code>boost::hash&lt;T&gt;()(x)</code>, where <code>x</code> is
the content of <code>rhs</code> and <code>T</code> is its type.</simpara>
</effects>
<notes>
<simpara>Actually, this function is defined in
<code>&lt;boost/variant/detail/hash_variant.hpp&gt;</code>
header.</simpara>
</notes>
</function>
<class name="make_variant_over">
@@ -951,8 +564,13 @@
<listitem><code>Sequence</code> must meet the requirements of
<libraryname>MPL</libraryname>'s <emphasis>Sequence</emphasis>
concept.</listitem>
<listitem>Due to standard conformance problems in several compilers,
<code>make_variant_over</code> may not be supported on your
compiler. See
<code><macroname>BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</macroname></code>
for more information.</listitem>
</itemizedlist>
</description>
</class>
</namespace>
</header>
</header>
+42 -40
View File
@@ -1,13 +1,4 @@
<?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 2016-2026 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)
-->
<?xml version="1.0" encoding="utf-8" ?>
<header name="boost/variant/variant_fwd.hpp">
<using-namespace name="boost"/>
@@ -19,6 +10,21 @@
class templates and the <code>boost::recursive_variant_</code> tag type.
Also defines several preprocessor symbols, as described below.</para>
<macro name="BOOST_VARIANT_LIMIT_TYPES">
<purpose>
<simpara>Expands to the length of the
template parameter list for
<code><classname>variant</classname></code>.</simpara>
</purpose>
<description>
<para><emphasis role="bold">Note</emphasis>: Conforming
implementations of <code>variant</code> must allow at least ten
template arguments. That is, BOOST_VARIANT_LIMIT_TYPES must be greater
or equal to <code>10</code>.</para>
</description>
</macro>
<macro name="BOOST_VARIANT_ENUM_PARAMS" kind="functionlike">
<macro-parameter name="param"/>
@@ -28,19 +34,7 @@
</purpose>
<description>
<para> 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
<para>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
@@ -65,19 +59,7 @@
</purpose>
<description>
<para> 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
<para>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.
@@ -91,11 +73,31 @@
</description>
</macro>
<macro name="BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH">
<macro name="BOOST_VARIANT_NO_REFERENCE_SUPPORT">
<purpose>
<simpara>Define this macro if you do not wish to have a <code><classname>std::hash</classname></code> specialization for
<code><classname>boost::variant</classname></code>.</simpara>
<simpara>Indicates <code><classname>variant</classname></code> does not
support references as bounded types.</simpara>
</purpose>
<description>
<para>Defined only if <code><classname>variant</classname></code> does
not support references as bounded types.</para>
</description>
</macro>
<macro name="BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT">
<purpose>
<simpara>Indicates absence of support for specifying the bounded types
of a <code><classname>variant</classname></code> by the elements of a
type sequence.</simpara>
</purpose>
<description>
<para>Defined only if
<code><classname>make_variant_over</classname></code> and
<code><classname>make_recursive_variant_over</classname></code>
are not supported for some reason on the target compiler.</para>
</description>
</macro>
<macro name="BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT">
@@ -119,4 +121,4 @@
full lambda support either.)</para>
</description>
</macro>
</header>
</header>
+1 -7
View File
@@ -1,12 +1,6 @@
<?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">
@@ -111,4 +105,4 @@
</function>
</namespace>
</header>
</header>
+8 -60
View File
@@ -1,13 +1,6 @@
<?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-2026 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>
@@ -90,6 +83,13 @@ typedef <classname>mpl::push_front</classname>&lt; types_initial, int &gt;::type
</para>
<para><emphasis role="bold">Portability</emphasis>: Unfortunately, due to
standard conformance issues in several compilers,
<code>make_variant_over</code> is not universally available. On these
compilers the library indicates its lack of support for the syntax via the
definition of the preprocessor symbol
<code><macroname>BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</macroname></code>.</para>
</section>
<section id="variant.tutorial.recursive">
@@ -222,10 +222,6 @@ public:
</para>
<para><emphasis role="bold">Performance</emphasis>: <classname>boost::recursive_wrapper</classname>
has no empty state, which makes its move constructor not very optimal. Consider using <code>std::unique_ptr</code>
or some other safe pointer for better performance on C++11 compatible compilers.</para>
</section>
<section id="variant.tutorial.recursive.recursive-variant">
@@ -347,7 +343,7 @@ seq2.push_back(3.14);
are_strict_equals visitor;
assert( std::equal(
seq1.begin(), seq1.end(), seq2.begin()
v1.begin(), v1.end(), v2.begin()
, <functionname>boost::apply_visitor</functionname>( visitor )
) );</programlisting>
@@ -355,52 +351,4 @@ assert( std::equal(
</section>
<section id="variant.tutorial.multi-visitation">
<title>Multi visitation</title>
<para>Multi visitation extends the power and flexibility of visitation by allowing simultaneous
visitation of the content of three and more different <code>variant</code>
objects. Note that header for multi visitors shall be included separately.</para>
<para>Notably this feature requires that multi visitors are incompatible
with the visitor objects discussed in the tutorial above, as they must
operate on same amout of arguments that was passed to <code>apply_visitor</code>.
The following demonstrates the implementation of a multi visitor for three parameters:
<programlisting>
#include &lt;boost/variant/multivisitors.hpp&gt;
typedef <classname>boost::variant</classname>&lt;int, double, bool&gt; bool_like_t;
typedef <classname>boost::variant</classname>&lt;int, double&gt; arithmetics_t;
struct if_visitor: public <classname>boost::static_visitor</classname>&lt;arithmetics_t&gt; {
template &lt;class T1, class T2&gt;
arithmetics_t operator()(bool b, T1 v1, T2 v2) const {
if (b) {
return v1;
} else {
return v2;
}
}
};
</programlisting>
</para>
<para>As expected, the visitor is applied to three <code>variant</code>
arguments by means of <code>apply_visitor</code>:
<programlisting>
bool_like_t v0(true), v1(1), v2(2.0);
assert(
<functionname>boost::apply_visitor</functionname>(if_visitor(), v0, v1, v2)
==
arithmetics_t(1)
);
</programlisting>
</para>
</section>
</section>
+2 -8
View File
@@ -1,12 +1,6 @@
<?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>
@@ -89,9 +83,9 @@ str += " world! ";</programlisting>
<programlisting>void times_two( boost::variant&lt; int, std::string &gt; &amp; operand )
{
if ( int* pi = <functionname>boost::get</functionname>&lt;int&gt;( &amp;operand ) )
if ( int* pi = <functionname>boost::get</functionname>&lt;int&gt;( &amp;v ) )
*pi *= 2;
else if ( std::string* pstr = <functionname>boost::get</functionname>&lt;std::string&gt;( &amp;operand ) )
else if ( std::string* pstr = <functionname>boost::get</functionname>&lt;std::string&gt;( &amp;v ) )
*pstr += *pstr;
}</programlisting>
-6
View File
@@ -1,12 +1,6 @@
<?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>
+10 -15
View File
@@ -1,12 +1,6 @@
<?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>
@@ -26,16 +20,17 @@
<holder>Itay Maman</holder>
</copyright>
<copyright>
<year>2014-2026</year>
<holder>Antony Polukhin</holder>
</copyright>
<legalnotice>
<para>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at
<ulink
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
</para>
<para>Permission to copy, use, sell and distribute this software
is granted provided this copyright notice appears in all copies.
Permission to modify the code and to distribute modified code is
granted provided this copyright notice appears in all copies, and
a notice that the code was modified is included with the copyright
notice.</para>
<para> This software is provided "as is" without express or
implied warranty, and with no claim as to its suitability for any
purpose.</para>
</legalnotice>
<librarypurpose>Safe, generic, stack-based discriminated union container</librarypurpose>
+7 -7
View File
@@ -14,14 +14,14 @@
#define BOOST_VARIANT_HPP
// variant "main"
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>
#include "boost/variant/variant.hpp"
#include "boost/variant/recursive_variant.hpp"
#include "boost/variant/recursive_wrapper.hpp"
// common applications
#include <boost/variant/get.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/visitor_ptr.hpp>
#include "boost/variant/get.hpp"
#include "boost/variant/apply_visitor.hpp"
#include "boost/variant/static_visitor.hpp"
#include "boost/variant/visitor_ptr.hpp"
#endif // BOOST_VARIANT_HPP
+3 -3
View File
@@ -13,8 +13,8 @@
#ifndef BOOST_VARIANT_APPLY_VISITOR_HPP
#define BOOST_VARIANT_APPLY_VISITOR_HPP
#include <boost/variant/detail/apply_visitor_unary.hpp>
#include <boost/variant/detail/apply_visitor_binary.hpp>
#include <boost/variant/detail/apply_visitor_delayed.hpp>
#include "boost/variant/detail/apply_visitor_unary.hpp"
#include "boost/variant/detail/apply_visitor_binary.hpp"
#include "boost/variant/detail/apply_visitor_delayed.hpp"
#endif // BOOST_VARIANT_APPLY_VISITOR_HPP
+2 -4
View File
@@ -13,8 +13,6 @@
#ifndef BOOST_VARIANT_BAD_VISIT_HPP
#define BOOST_VARIANT_BAD_VISIT_HPP
#include <boost/config.hpp>
#include <exception>
namespace boost {
@@ -25,12 +23,12 @@ namespace boost {
// Exception thrown when a visitation attempt via apply_visitor fails due
// to invalid visited subtype or contents.
//
struct BOOST_SYMBOL_VISIBLE bad_visit
struct bad_visit
: std::exception
{
public: // std::exception interface
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
virtual const char * what() const throw()
{
return "boost::bad_visit: "
"failed visitation using boost::apply_visitor";
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003 Eric Friedman
// Copyright (c) 2014-2026 Antony Polukhin
// Copyright (c) 2002-2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,18 +13,13 @@
#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
#include <boost/config.hpp>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/variant/detail/generic_result_type.hpp"
#include <boost/variant/detail/apply_visitor_unary.hpp>
#include "boost/variant/detail/apply_visitor_unary.hpp"
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
# include <boost/variant/detail/has_result_type.hpp>
#endif
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <utility>
#include "boost/utility/enable_if.hpp"
namespace boost {
@@ -38,7 +33,7 @@ namespace boost {
namespace detail { namespace variant {
template <typename Visitor, typename Value1, bool MoveSemantics>
template <typename Visitor, typename Value1>
class apply_visitor_binary_invoke
{
public: // visitor typedefs
@@ -53,7 +48,7 @@ private: // representation
public: // structors
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
apply_visitor_binary_invoke(Visitor& visitor, Value1& value1)
: visitor_(visitor)
, value1_(value1)
{
@@ -62,24 +57,15 @@ public: // structors
public: // visitor interfaces
template <typename Value2>
typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
operator()(Value2&& value2)
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Value2& value2)
{
return visitor_(std::move(value1_), std::forward<Value2>(value2));
return visitor_(value1_, value2);
}
template <typename Value2>
typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
operator()(Value2&& value2)
{
return visitor_(value1_, std::forward<Value2>(value2));
}
private:
apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
};
template <typename Visitor, typename Visitable2, bool MoveSemantics>
template <typename Visitor, typename Visitable2>
class apply_visitor_binary_unwrap
{
public: // visitor typedefs
@@ -94,7 +80,7 @@ private: // representation
public: // structors
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2)
: visitor_(visitor)
, visitable2_(visitable2)
{
@@ -103,34 +89,17 @@ public: // structors
public: // visitor interfaces
template <typename Value1>
typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
operator()(Value1&& value1)
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Value1& value1)
{
apply_visitor_binary_invoke<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, std::move(visitable2_));
}
template <typename Value1>
typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
operator()(Value1&& value1)
{
apply_visitor_binary_invoke<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, visitable2_);
}
private:
apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
};
}} // namespace detail::variant
@@ -139,152 +108,64 @@ private:
// nonconst-visitor version:
//
#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
/**/
#else // EDG-based compilers
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
typename enable_if< \
mpl::not_< is_const< V > > \
, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
>::type \
/**/
#endif // EDG-based compilers workaround
template <typename Visitor, typename Visitable1, typename Visitable2>
inline typename Visitor::result_type
apply_visitor( Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2)
inline
BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
apply_visitor(
Visitor& visitor
, Visitable1& visitable1, Visitable2& visitable2
)
{
::boost::detail::variant::apply_visitor_binary_unwrap<
Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
Visitor, Visitable2
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
return boost::apply_visitor(unwrapper, visitable1);
}
#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
//
// const-visitor version:
//
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template <typename Visitor, typename Visitable1, typename Visitable2>
inline typename Visitor::result_type
apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2)
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
typename Visitor::result_type
)
apply_visitor(
const Visitor& visitor
, Visitable1& visitable1, Visitable2& visitable2
)
{
::boost::detail::variant::apply_visitor_binary_unwrap<
const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
const Visitor, Visitable2
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
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, bool MoveSemantics>
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, typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
{
return visitor_(std::move(value1_), std::forward<Value2>(value2));
}
template <typename Value2>
decltype(auto) operator()(Value2&& value2, typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
{
return visitor_(value1_, std::forward<Value2>(value2));
}
private:
apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
};
template <typename Visitor, typename Visitable2, bool MoveSemantics>
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, typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
{
apply_visitor_binary_invoke_cpp14<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> invoker(visitor_, value1);
return boost::apply_visitor(invoker, std::move(visitable2_));
}
template <typename Value1>
decltype(auto) operator()(Value1&& value1, typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
{
apply_visitor_binary_invoke_cpp14<
Visitor
, Value1
, ! ::boost::is_lvalue_reference<Value1>::value
> 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>,
bool
>::type = true)
{
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, std::forward<Visitable1>(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>,
bool
>::type = true)
{
::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
> unwrapper(visitor, visitable2);
return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
}
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
#endif // MSVC7 and below exclusion
} // namespace boost
@@ -13,13 +13,10 @@
#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
#include <boost/variant/detail/apply_visitor_unary.hpp>
#include <boost/variant/detail/apply_visitor_binary.hpp>
#include <boost/variant/variant_fwd.hpp>
#include "boost/variant/detail/generic_result_type.hpp"
#include <boost/variant/detail/has_result_type.hpp>
#include <boost/core/enable_if.hpp>
#include "boost/variant/detail/apply_visitor_unary.hpp"
#include "boost/variant/detail/apply_visitor_binary.hpp"
namespace boost {
@@ -52,71 +49,37 @@ private: // representation
public: // structors
explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
explicit apply_visitor_delayed_t(Visitor& visitor)
: visitor_(visitor)
{
}
public: // N-ary visitor interface
template <typename... Visitables>
result_type operator()(Visitables&... visitables) const
public: // unary visitor interface
template <typename Visitable>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Visitable& visitable)
{
return apply_visitor(visitor_, visitables...);
return apply_visitor(visitor_, visitable);
}
private:
apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
public: // binary visitor interface
template <typename Visitable1, typename Visitable2>
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(Visitable1& visitable1, Visitable2& visitable2)
{
return apply_visitor(visitor_, visitable1, visitable2);
}
};
template <typename Visitor>
inline typename boost::enable_if<
boost::detail::variant::has_result_type<Visitor>,
apply_visitor_delayed_t<Visitor>
>::type apply_visitor(Visitor& visitor)
inline apply_visitor_delayed_t<Visitor> apply_visitor(Visitor& visitor)
{
return apply_visitor_delayed_t<Visitor>(visitor);
}
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO)
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)
} // 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) 2014-2026 Antony Polukhin
// Copyright (c) 2002-2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,20 +13,11 @@
#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
#include <boost/config.hpp>
#include <utility>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/variant/detail/generic_result_type.hpp"
#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/type_traits/copy_cv_ref.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/variant/detail/has_result_type.hpp>
#endif
#include "boost/utility/enable_if.hpp"
namespace boost {
@@ -40,87 +31,48 @@ namespace boost {
// nonconst-visitor version:
//
#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
/**/
#else // EDG-based compilers
# define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
typename enable_if< \
mpl::not_< is_const< V > > \
, BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
>::type \
/**/
#endif // EDG-based compilers workaround
template <typename Visitor, typename Visitable>
inline typename Visitor::result_type
apply_visitor(Visitor& visitor, Visitable&& visitable)
inline
BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
apply_visitor(Visitor& visitor, Visitable& visitable)
{
return std::forward<Visitable>(visitable).apply_visitor(visitor);
return visitable.apply_visitor(visitor);
}
#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
//
// const-visitor version:
//
template <typename Visitor, typename Visitable>
inline typename Visitor::result_type
apply_visitor(const Visitor& visitor, Visitable&& visitable)
{
return std::forward<Visitable>(visitable).apply_visitor(visitor);
}
#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
#define BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
// 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 remove_reference<Variant>::type::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;
template <class It, class Dummy = void> // avoid explicit specialization in class scope
struct deduce_impl {
typedef typename boost::mpl::next<It>::type next_t;
typedef typename boost::mpl::deref<It>::type value_t;
typedef decltype(true ? boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )
: boost::declval< typename deduce_impl<next_t>::type >()) type;
};
template <class Dummy>
struct deduce_impl<last_it, Dummy> {
typedef typename boost::mpl::deref<last_it>::type value_t;
typedef decltype(boost::declval< Visitor& >()( boost::declval< copy_cv_ref_t< value_t, Variant > >() )) type;
};
typedef typename deduce_impl<begin_it>::type type;
};
template <class Visitor, class Variant>
struct result_wrapper1
{
typedef typename result_multideduce1<Visitor, Variant>::type result_type;
Visitor&& visitor_;
explicit result_wrapper1(Visitor&& visitor) BOOST_NOEXCEPT
: visitor_(std::forward<Visitor>(visitor))
{}
template <class T>
result_type operator()(T&& val) const {
return visitor_(std::forward<T>(val));
}
};
}} // namespace detail::variant
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
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>,
bool
>::type = true)
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
apply_visitor(const Visitor& visitor, Visitable& visitable)
{
boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(std::forward<Visitor>(visitor));
return std::forward<Visitable>(visitable).apply_visitor(cpp14_vis);
return visitable.apply_visitor(visitor);
}
#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
#endif // MSVC7 and below exclusion
} // namespace boost
@@ -13,8 +13,7 @@
#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include "boost/assert.hpp"
namespace boost {
namespace detail { namespace variant {
@@ -28,12 +27,12 @@ private: // representation
public: // structors
~backup_holder() BOOST_NOEXCEPT
~backup_holder()
{
delete backup_;
}
explicit backup_holder(T* backup) BOOST_NOEXCEPT
explicit backup_holder(T* backup)
: backup_(backup)
{
}
@@ -54,7 +53,7 @@ public: // modifiers
return *this;
}
void swap(backup_holder& rhs) BOOST_NOEXCEPT
void swap(backup_holder& rhs)
{
T* tmp = rhs.backup_;
rhs.backup_ = this->backup_;
@@ -63,12 +62,12 @@ public: // modifiers
public: // queries
T& get() BOOST_NOEXCEPT
T& get()
{
return *backup_;
}
const T& get() const BOOST_NOEXCEPT
const T& get() const
{
return *backup_;
}
@@ -84,7 +83,7 @@ backup_holder<T>::backup_holder(const backup_holder&)
}
template <typename T>
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT
void swap(backup_holder<T>& lhs, backup_holder<T>& rhs)
{
lhs.swap(rhs);
}
@@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// boost/variant/detail/bool_trait_def.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Needed until move-related traits incorporated into type_traits library.
// no include guards, the header is intended for multiple inclusion!
// should be the last #include
#include "boost/type_traits/detail/bool_trait_def.hpp"
#define BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(trait,T,C) \
template< typename T > struct trait \
BOOST_TT_AUX_BOOL_C_BASE(C) \
{ \
BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(C) \
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,trait,(T)) \
}; \
/**/
#define BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(arity, name) \
BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(arity, name) \
/**/
@@ -0,0 +1,21 @@
//-----------------------------------------------------------------------------
// boost/variant/detail/bool_trait_undef.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Needed until move-related traits incorporated into type_traits library.
// no include guards, the header is intended for multiple inclusion!
// should be the last #include
#include "boost/type_traits/detail/bool_trait_undef.hpp"
#undef BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1
#undef BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX
@@ -13,7 +13,7 @@
#ifndef BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP
#define BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP
#include <boost/config.hpp>
#include "boost/config.hpp"
namespace boost {
namespace detail { namespace variant {
@@ -25,13 +25,19 @@ namespace detail { namespace variant {
//
template <typename T>
inline T& cast_storage(void* storage)
inline T& cast_storage(
void* storage
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
)
{
return *static_cast<T*>(storage);
}
template <typename T>
inline const T& cast_storage(const void* storage)
inline const T& cast_storage(
const void* storage
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)
)
{
return *static_cast<const T*>(storage);
}
+23 -4
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,7 +13,26 @@
#ifndef BOOST_VARIANT_DETAIL_CONFIG_HPP
#define BOOST_VARIANT_DETAIL_CONFIG_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING
//
#if BOOST_WORKAROUND(__MWERKS__, <= 0x3201) \
|| BOOST_WORKAROUND(BOOST_INTEL, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
&& !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
# define BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING
#endif
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND
//
#if !defined(BOOST_NO_SFINAE) \
&& !BOOST_WORKAROUND(BOOST_INTEL, <= 700) \
&& !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
# define BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND
#endif
#endif // BOOST_VARIANT_DETAIL_CONFIG_HPP
@@ -1,63 +0,0 @@
//-----------------------------------------------------------------------------
// boost variant/detail/element_index.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2014-2026 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
@@ -13,39 +13,72 @@
#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_HPP
#include <boost/variant/detail/enable_recursive_fwd.hpp>
#include <boost/variant/variant_fwd.hpp>
#include "boost/variant/detail/enable_recursive_fwd.hpp"
#include "boost/variant/variant_fwd.hpp"
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
# include <boost/mpl/apply.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/lambda.hpp>
# include "boost/mpl/apply.hpp"
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/lambda.hpp"
#endif
#include <boost/variant/detail/substitute.hpp>
#include <boost/mpl/aux_/config/ctps.hpp>
#include <boost/mpl/bool_fwd.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include "boost/variant/detail/substitute.hpp"
#include "boost/mpl/aux_/config/ctps.hpp"
#include "boost/mpl/bool_fwd.hpp"
#include "boost/mpl/if.hpp"
#include "boost/mpl/or.hpp"
#include "boost/type_traits/is_pointer.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/type_traits/is_same.hpp"
#include <boost/variant/recursive_wrapper.hpp>
#include "boost/variant/recursive_wrapper.hpp"
namespace boost {
namespace detail { namespace variant {
#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
# define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \
substitute< T , Dest , Source > \
/**/
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
///////////////////////////////////////////////////////////////////////////////
// (detail) class template rebind1
//
// Limited workaround in case 'substitute' metafunction unavailable.
//
template <typename T, typename U1>
struct rebind1
{
private:
typedef typename mpl::lambda<
mpl::identity<T>
>::type le_;
public:
typedef typename mpl::eval_if<
is_same< le_, mpl::identity<T> >
, le_ // identity<T>
, mpl::apply1<le_, U1>
>::type type;
};
# define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(T,Dest,Source) \
rebind1< T , Dest > \
/**/
#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction enable_recursive
//
// See boost/variant/detail/enable_recursive_fwd.hpp for more information.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T, typename RecursiveVariant, typename NoWrapper>
struct enable_recursive
@@ -79,6 +112,34 @@ public: // metafunction result
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T, typename RecursiveVariant, typename NoWrapper>
struct enable_recursive
{
private: // helpers, for metafunction result (below)
typedef typename BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL(
T, RecursiveVariant, ::boost::recursive_variant_
)::type t_;
public: // metafunction result
// [Wrap with recursive_wrapper only if rebind really changed something:]
typedef typename mpl::if_<
mpl::or_<
NoWrapper
, is_same< t_,T >
, is_reference<t_>
, is_pointer<t_>
>
, t_
, boost::recursive_wrapper<t_>
>::type type;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction class quoted_enable_recursive
@@ -13,11 +13,15 @@
#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
#include <boost/mpl/aux_/config/ctps.hpp>
#include "boost/mpl/aux_/config/ctps.hpp"
#include <boost/mpl/bool_fwd.hpp>
#include "boost/mpl/bool_fwd.hpp"
# include <boost/mpl/bool.hpp>
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/bool.hpp"
#else
# include "boost/type_traits/is_base_and_derived.hpp"
#endif
namespace boost {
namespace detail { namespace variant {
@@ -28,6 +32,7 @@ namespace detail { namespace variant {
// Signifies that the variant should perform recursive substituion.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct recursive_flag
@@ -35,6 +40,20 @@ struct recursive_flag
typedef T type;
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
struct recursive_flag_tag
{
};
template <typename T>
struct recursive_flag
: recursive_flag_tag
{
typedef T type;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction is_recursive_flag
@@ -42,6 +61,7 @@ struct recursive_flag
// Signifies that the variant should perform recursive substituion.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_flag
@@ -55,6 +75,15 @@ struct is_recursive_flag< recursive_flag<T> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_flag
: is_base_and_derived< recursive_flag_tag,T >
{
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction enable_recursive
+70 -18
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman
// Copyright (c) 2015-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,16 +13,16 @@
#ifndef BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
#define BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include "boost/config.hpp"
#include "boost/variant/detail/generic_result_type.hpp"
#include "boost/assert.hpp"
#ifdef BOOST_MSVC
# pragma warning( push )
# pragma warning( disable : 4702 ) // unreachable code
#if !defined(BOOST_MSVC) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/type_traits/remove_reference.hpp"
#endif
namespace boost { namespace detail { namespace variant {
namespace boost {
namespace detail { namespace variant {
///////////////////////////////////////////////////////////////////////////////
// (detail) function template forced_return
@@ -30,23 +30,75 @@ namespace boost { namespace detail { namespace variant {
// Logical error to permit invocation at runtime, but (artificially) satisfies
// compile-time requirement of returning a result value.
//
#if !defined(BOOST_MSVC) \
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_NO_VOID_RETURNS)
// "standard" implementation:
template <typename T>
BOOST_NORETURN inline T
forced_return()
inline T forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
T (*dummy)() = 0;
(void)dummy;
BOOST_UNREACHABLE_RETURN(dummy());
typedef typename boost::remove_reference<T>::type basic_type;
basic_type* dummy = 0;
return *static_cast< basic_type* >(dummy);
}
}}} // namespace boost::detail::variant
template <>
inline void forced_return<void>( BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(void) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
}
#elif !defined(BOOST_MSVC)
#ifdef BOOST_MSVC
# pragma warning( pop )
#endif
// workaround implementation
//
// TODO: Determine the most efficient way to handle this -- as below? by
// throwing? by recursive call to forced_return itself? etc.
//
template <typename T>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) (*dummy)() = 0;
return dummy();
}
#else // defined(BOOST_MSVC)
// msvc-specific implementation
//
// Leverages __declspec(noreturn) for optimized implementation.
//
__declspec(noreturn)
inline void forced_return_no_return() {};
template <typename T>
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )
{
// logical error: should never be here! (see above)
BOOST_ASSERT(false);
forced_return_no_return();
}
#endif // BOOST_MSVC optimization
}} // namespace detail::variant
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
@@ -0,0 +1,88 @@
//-----------------------------------------------------------------------------
// boost variant/detail/generic_result_type.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
#define BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
#include "boost/config.hpp"
//////////////////////////////////////////////////////////////////////////
// (workaround) macro BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE
//
// On compilers with BOOST_NO_VOID_RETURNS, this macro provides a route
// to a single syntax for dealing with template functions that may (but
// not necessarily) return nothing (i.e. void).
//
// BOOST_VARIANT_AUX_RETURN_VOID provided for compilers w/ (erroneous?)
// warnings about non-void functions not returning a value.
//
#if !defined(BOOST_NO_VOID_RETURNS)
#define BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) \
T \
/**/
#define BOOST_VARIANT_AUX_RETURN_VOID \
/**/
#define BOOST_VARIANT_AUX_RETURN_VOID_TYPE \
void \
/**/
#else // defined(BOOST_NO_VOID_RETURNS)
namespace boost {
namespace detail { namespace variant {
struct fake_return_void
{
fake_return_void()
{
}
template <typename T>
fake_return_void(const T&)
{
}
};
template <typename T>
struct no_void_returns_helper
{
typedef T type;
};
template <>
struct no_void_returns_helper<void>
{
typedef fake_return_void type;
};
}} // namespace detail::variant
} // namespace boost
#define BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) \
BOOST_DEDUCED_TYPENAME \
::boost::detail::variant::no_void_returns_helper< T >::type \
/**/
#define BOOST_VARIANT_AUX_RETURN_VOID \
return ::boost::detail::variant::fake_return_void() \
/**/
#define BOOST_VARIANT_AUX_RETURN_VOID_TYPE \
::boost::detail::variant::fake_return_void
#endif // BOOST_NO_VOID_RETURNS workaround
#endif // BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
@@ -0,0 +1,106 @@
// (C) Copyright Eric Friedman 2002-2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
#define BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
#include "boost/config.hpp" // for STATIC_CONSTANT
#include "boost/variant/detail/has_trivial_move.hpp"
#include "boost/type_traits/has_nothrow_copy.hpp"
#include "boost/type_traits/has_nothrow_assign.hpp"
#include "boost/mpl/and.hpp"
#include "boost/mpl/or.hpp"
// should be the last #include
#include "boost/variant/detail/bool_trait_def.hpp"
namespace boost {
namespace detail { namespace variant {
// TRAIT: has_nothrow_move
template <typename T>
struct has_nothrow_move_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, ::boost::mpl::and_<
has_nothrow_copy<T>
, has_nothrow_assign<T>
>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move
, T
, (::boost::detail::variant::has_nothrow_move_impl<T>::value)
)
// TRAIT: has_nothrow_move_constructor
template <typename T>
struct has_nothrow_move_constructor_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_nothrow_move<T>
, has_trivial_move_constructor<T>
, has_nothrow_copy<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move_constructor
, T
, (::boost::detail::variant::has_nothrow_move_constructor_impl<T>::value)
)
// TRAIT: has_nothrow_move_assign
template <typename T>
struct has_nothrow_move_assign_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_nothrow_move<T>
, has_trivial_move_assign<T>
, has_nothrow_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_nothrow_move_assign
, T
, (::boost::detail::variant::has_nothrow_move_assign_impl<T>::value)
)
}} // namespace detail::variant
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move_constructor)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_nothrow_move_assign)
} // namespace boost
#include "boost/variant/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_DETAIL_HAS_NOTHROW_MOVE_HPP_INCLUDED
@@ -1,37 +0,0 @@
//-----------------------------------------------------------------------------
// boost variant/detail/has_result_type.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2014-2026 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
@@ -0,0 +1,100 @@
// (C) Copyright Eric Friedman 2002-2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#ifndef BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
#define BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
#include "boost/config.hpp" // for STATIC_CONSTANT
#include "boost/type_traits/has_trivial_copy.hpp"
#include "boost/type_traits/has_trivial_assign.hpp"
#include "boost/mpl/and.hpp"
#include "boost/mpl/or.hpp"
// should be the last #include
#include "boost/variant/detail/bool_trait_def.hpp"
namespace boost {
namespace detail { namespace variant {
// TRAIT: has_trivial_move
template <typename T>
struct has_trivial_move_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::and_<
has_trivial_copy<T>
, has_trivial_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move
, T
, (::boost::detail::variant::has_trivial_move_impl<T>::value)
)
// TRAIT: has_trivial_move_constructor
template <typename T>
struct has_trivial_move_constructor_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, has_trivial_copy<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move_constructor
, T
, (::boost::detail::variant::has_trivial_move_constructor_impl<T>::value)
)
// TRAIT: has_trivial_move_assign
template <typename T>
struct has_trivial_move_assign_impl
{
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::mpl::or_<
has_trivial_move<T>
, has_trivial_assign<T>
>::type::value
)
);
};
BOOST_VARIANT_TT_AUX_BOOL_TRAIT_DEF1(
has_trivial_move_assign
, T
, (::boost::detail::variant::has_trivial_move_assign_impl<T>::value)
)
}} // namespace detail::variant
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move_constructor)
BOOST_VARIANT_TT_AUX_TRAIT_SUFFIX(1,::boost::detail::variant::has_trivial_move_assign)
} // namespace boost
#include "boost/variant/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_DETAIL_HAS_TRIVIAL_MOVE_HPP_INCLUDED
@@ -1,46 +0,0 @@
//-----------------------------------------------------------------------------
// boost variant/detail/hash_variant.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2011-2026 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HASH_VARIANT_FUNCTION_HPP
#define BOOST_HASH_VARIANT_FUNCTION_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/functional/hash_fwd.hpp>
namespace boost {
namespace detail { namespace variant {
struct variant_hasher: public boost::static_visitor<std::size_t> {
template <class T>
std::size_t operator()(T const& val) const {
boost::hash<T> hasher;
return hasher(val);
}
};
}}
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
std::size_t hash_value(variant< BOOST_VARIANT_ENUM_PARAMS(T) > const& val) {
std::size_t seed = boost::apply_visitor(detail::variant::variant_hasher(), val);
hash_combine(seed, val.which());
return seed;
}
}
#endif
+136 -33
View File
@@ -15,21 +15,26 @@
#include <new> // for placement new
#include <boost/config.hpp>
#include "boost/config.hpp"
#include <boost/call_traits.hpp>
#include <boost/detail/reference_content.hpp>
#include <boost/variant/recursive_wrapper_fwd.hpp>
#include <boost/variant/detail/move.hpp>
# include <boost/mpl/aux_/value_wknd.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/iter_fold.hpp>
# include <boost/mpl/next.hpp>
# include <boost/mpl/deref.hpp>
# include <boost/mpl/pair.hpp>
# include <boost/mpl/protect.hpp>
#include "boost/call_traits.hpp"
#include "boost/detail/reference_content.hpp"
#include "boost/variant/recursive_wrapper_fwd.hpp"
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# include "boost/mpl/aux_/value_wknd.hpp"
# include "boost/mpl/int.hpp"
# include "boost/mpl/iter_fold.hpp"
# include "boost/mpl/next.hpp"
# include "boost/mpl/deref.hpp"
# include "boost/mpl/pair.hpp"
# include "boost/mpl/protect.hpp"
#else
# include "boost/variant/variant_fwd.hpp"
# include "boost/preprocessor/cat.hpp"
# include "boost/preprocessor/enum.hpp"
# include "boost/preprocessor/repeat.hpp"
#endif
namespace boost {
namespace detail { namespace variant {
@@ -47,6 +52,8 @@ namespace detail { namespace variant {
// size of the variant's psuedo-variadic template parameter list.
//
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
// (detail) quoted metafunction make_initializer_node
//
// Exposes a pair whose first type is a node in the initializer hierarchy.
@@ -72,18 +79,9 @@ struct make_initializer_node
recursive_enabled_T;
typedef typename unwrap_recursive<recursive_enabled_T>::type
public_T;
typedef boost::is_reference<public_T>
is_reference_content_t;
typedef typename boost::mpl::if_<is_reference_content_t, public_T, const public_T& >::type
typedef typename call_traits<public_T>::param_type
param_T;
template <class T> struct disable_overload{};
typedef typename boost::mpl::if_<is_reference_content_t, disable_overload<public_T>, public_T&& >::type
param2_T;
public: // static functions
using base::initialize;
@@ -98,16 +96,6 @@ struct make_initializer_node
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
}
static int initialize(void* dest, param2_T operand)
{
// This assert must newer trigger, because all the reference contents are
// handled by the initilize(void* dest, param_T operand) function above
BOOST_ASSERT(!is_reference_content_t::value);
typedef typename boost::mpl::if_<is_reference_content_t, param2_T, recursive_enabled_T>::type value_T;
new(dest) value_T( boost::detail::variant::move(operand) );
return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
}
};
friend class initializer_node;
@@ -135,6 +123,84 @@ public: // static functions
};
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \
BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \
/**/
#define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
typedef typename unwrap_recursive< \
BOOST_PP_CAT(recursive_enabled_T,N) \
>::type BOOST_PP_CAT(public_T,N); \
typedef typename call_traits< \
BOOST_PP_CAT(public_T,N) \
>::param_type BOOST_PP_CAT(param_T,N); \
/**/
# else // MSVC7 and below
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \
BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \
, BOOST_VARIANT_ENUM_PARAMS(typename param_T) \
/**/
#define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
/**/
# endif // MSVC7 and below workaround
template < BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS >
struct preprocessor_list_initializer
{
public: // static functions
#define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \
BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
static int initialize( \
void* dest \
, BOOST_PP_CAT(param_T,N) operand \
) \
{ \
typedef typename boost::detail::make_reference_content< \
BOOST_PP_CAT(recursive_enabled_T,N) \
>::type internal_T; \
\
new(dest) internal_T(operand); \
return (N); /*which*/ \
} \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION
, _
)
#undef BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION
};
# if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
#if !defined(BOOST_VARIANT_AUX_ECHO)
# define BOOST_VARIANT_AUX_ECHO(z,N,token) token
#endif
template <>
struct preprocessor_list_initializer<
BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, int)
, BOOST_PP_ENUM(BOOST_VARIANT_LIMIT_TYPES, BOOST_VARIANT_AUX_ECHO, const int)
>
{
};
# endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
}} // namespace detail::variant
} // namespace boost
@@ -146,6 +212,8 @@ public: // static functions
// most appropriate to the current compiler.
//
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \
::boost::mpl::iter_fold< \
mpl_seq \
@@ -159,4 +227,39 @@ public: // static functions
>::type::first \
/**/
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
BOOST_VARIANT_ENUM_PARAMS(typename_base) \
/**/
# else // MSVC7 and below
#define BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE(z,N,T) \
::boost::call_traits< \
::boost::unwrap_recursive<BOOST_PP_CAT(T,N)>::type \
>::param_type \
/**/
#define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
BOOST_VARIANT_ENUM_PARAMS(typename_base) \
, BOOST_PP_ENUM( \
BOOST_VARIANT_LIMIT_TYPES \
, BOOST_VARIANT_AUX_PP_INITIALIZER_ENUM_PARAM_TYPE \
, typename_base \
) \
/**/
# endif // MSVC7 workaround
#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \
::boost::detail::variant::preprocessor_list_initializer< \
BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
> \
/**/
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
#endif // BOOST_VARIANT_DETAIL_INITIALIZER_HPP
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
// Copyright (c) 2013-2026 Antony Polukhin
// Copyright (c) 2002-2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,13 +13,14 @@
#ifndef BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
#define BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
#include <boost/variant/variant_fwd.hpp>
#include "boost/variant/variant_fwd.hpp"
#include <boost/mpl/list.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/enum.hpp>
#include "boost/mpl/list.hpp"
#include "boost/preprocessor/cat.hpp"
#include "boost/preprocessor/enum.hpp"
namespace boost { namespace detail { namespace variant {
namespace boost {
namespace detail { namespace variant {
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction make_variant_list
@@ -30,13 +31,30 @@ namespace boost { namespace detail { namespace variant {
// Rationale: see class template convert_void (variant_fwd.hpp) and using-
// declaration workaround (below).
//
template < typename... T >
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
struct make_variant_list
{
typedef typename mpl::list< T... >::type type;
public: // metafunction result
// [Define a macro to convert any void(NN) tags to mpl::void...]
# define BOOST_VARIANT_AUX_CONVERT_VOID(z, N,_) \
typename convert_void< BOOST_PP_CAT(T,N) >::type
// [...so that the specified types can be passed to mpl::list...]
typedef typename mpl::list<
BOOST_PP_ENUM(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_CONVERT_VOID
, _
)
>::type type;
// [...and, finally, the conversion macro can be undefined:]
# undef BOOST_VARIANT_AUX_CONVERT_VOID
};
}}} // namespace boost::detail::variant
}} // namespace detail::variant
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
+124 -8
View File
@@ -5,7 +5,6 @@
//
// Copyright (c) 2002-2003 Eric Friedman
// Copyright (c) 2002 by Andrei Alexandrescu
// Copyright (c) 2013-2026 Antony Polukhin
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
@@ -20,13 +19,97 @@
#ifndef BOOST_VARIANT_DETAIL_MOVE_HPP
#define BOOST_VARIANT_DETAIL_MOVE_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <utility>
#include <iterator> // for iterator_traits
#include <new> // for placement new
namespace boost { namespace detail { namespace variant {
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/mpl/if.hpp"
#include "boost/type_traits/is_base_and_derived.hpp"
using std::move;
namespace boost {
namespace detail { namespace variant {
//////////////////////////////////////////////////////////////////////////
// forward declares
//
// NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
//
template <typename Deriving> class moveable;
template <typename T> class move_source;
template <typename T> class move_return;
namespace detail {
// (detail) moveable_tag
//
// Concrete type from which moveable<T> derives.
//
// TODO: Move into moveable_fwd.hpp and define has_move_constructor.
//
template <typename Deriving>
struct moveable_tag
{
};
} // namespace detail
//////////////////////////////////////////////////////////////////////////
// function template move
//
// Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
// the object; else, returns the T&.
//
namespace detail {
// (detail) class template move_type
//
// Metafunction that, given moveable T, provides move_source<T>, else T&.
//
template <typename T>
struct move_type
{
public: // metafunction result
typedef typename mpl::if_<
is_base_and_derived<detail::moveable_tag<T>, T>
, move_source<T>
, T&
>::type type;
};
} // namespace detail
template <typename T>
inline
typename detail::move_type<T>::type
move(T& source)
{
typedef typename detail::move_type<T>::type
move_t;
return move_t(source);
}
//////////////////////////////////////////////////////////////////////////
// class template return_t
//
// Metafunction that, given moveable T, provides move_return<T>, else T.
//
template <typename T>
struct return_t
{
public: // metafunction result
typedef typename mpl::if_<
is_base_and_derived<moveable<T>, T>
, move_return<T>
, T
>::type type;
};
//////////////////////////////////////////////////////////////////////////
// function template move_swap
@@ -35,14 +118,47 @@ using std::move;
// types and on non-conforming compilers.
//
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
|| BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
// [Indicate that move_swap by overload is disabled...]
#define BOOST_NO_MOVE_SWAP_BY_OVERLOAD
// [...and provide straight swap-by-move implementation:]
template <typename T>
inline void move_swap(T& lhs, T& rhs)
{
using std::swap;
T tmp( boost::detail::variant::move(lhs) );
lhs = boost::detail::variant::move(rhs);
rhs = boost::detail::variant::move(tmp);
}
#else// !workaround
namespace detail { namespace move_swap {
template <typename T>
inline void swap(T& lhs, T& rhs)
{
T tmp( boost::detail::variant::move(lhs) );
lhs = boost::detail::variant::move(rhs);
rhs = boost::detail::variant::move(tmp);
}
}} // namespace detail::move_swap
template <typename T>
inline void move_swap(T& lhs, T& rhs)
{
using detail::move_swap::swap;
swap(lhs, rhs);
}
}}} // namespace boost::detail::variant
#endif // workaround
}} // namespace detail::variant
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_MOVE_HPP
@@ -1,212 +0,0 @@
// 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-2024.
//
// 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>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/core/enable_if.hpp>
#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 <typename T_, bool MoveSemantics_>
struct MoveableWrapper //Just a reference with some metadata
{
typedef T_ T;
static constexpr bool MoveSemantics = MoveSemantics_;
T& v;
};
template <typename Tp, bool MoveSemantics>
MoveableWrapper<Tp, MoveSemantics>
wrap(Tp& t)
{
return MoveableWrapper<Tp, MoveSemantics>{t};
}
template <typename Wrapper>
typename enable_if_c<Wrapper::MoveSemantics, typename Wrapper::T>::type
unwrap(Wrapper& w)
{
return std::move(w.v);
}
template <typename Wrapper>
typename disable_if_c<Wrapper::MoveSemantics, typename Wrapper::T>::type &
unwrap(Wrapper& w)
{
return w.v;
}
// 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>
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::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value)))
)
, unwrap(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>
result_type do_call(Tuple t, index_sequence<I...>) const {
return visitor_(unwrap(std::get<I>(t))...);
}
template <typename Value>
result_type operator()(Value&& value) const
{
return do_call(
std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value))),
make_index_sequence<sizeof...(Values) + 1>()
);
}
};
}} // namespace detail::variant
template <class Visitor, class T1, class T2, class T3, class... TN>
inline 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,
std::make_tuple(
::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
),
std::tuple<>()
),
std::forward<T1>(v1)
);
}
template <class Visitor, class T1, class T2, class T3, class... TN>
inline 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,
std::make_tuple(
::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
),
std::tuple<>()
),
std::forward<T1>(v1)
);
}
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
@@ -1,152 +0,0 @@
// 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 <tuple>
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::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value)))
)
, unwrap(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_(unwrap(std::get<I>(t))...);
}
template <typename Value>
decltype(auto) operator()(Value&& value) const
{
return do_call(
std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::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>,
bool
>::type = true)
{
return boost::apply_visitor(
::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
visitor,
std::make_tuple(
::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
),
std::tuple<>()
),
std::forward<T1>(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>,
bool
>::type = true)
{
return ::boost::apply_visitor(
::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
visitor,
std::make_tuple(
::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
),
std::tuple<>()
),
std::forward<T1>(v1)
);
}
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
+38 -1
View File
@@ -15,7 +15,13 @@
#ifndef BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
#define BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
#include <boost/mpl/aux_/config/ctps.hpp>
#include "boost/mpl/aux_/config/ctps.hpp"
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/bool.hpp"
# include "boost/mpl/identity.hpp"
# include "boost/type.hpp"
#endif
namespace boost {
@@ -38,6 +44,7 @@ struct over_sequence
// Indicates whether the specified type is of form over_sequence<...> or not.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_over_sequence
@@ -51,6 +58,36 @@ struct is_over_sequence< over_sequence<Types> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef char (&yes_over_sequence_t)[1];
typedef char (&no_over_sequence_t)[2];
no_over_sequence_t is_over_sequence_test(...);
template<typename T>
yes_over_sequence_t is_over_sequence_test(
type< ::boost::detail::variant::over_sequence<T> >
);
template<typename T>
struct is_over_sequence_impl
{
BOOST_STATIC_CONSTANT(bool, value = (
sizeof(is_over_sequence_test(type<T>()))
== sizeof(yes_over_sequence_t)
));
};
template <typename T>
struct is_over_sequence
: mpl::bool_<
::boost::detail::variant::is_over_sequence_impl<T>::value
>
{
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
}} // namespace detail::variant
} // namespace boost
-46
View File
@@ -1,46 +0,0 @@
//-----------------------------------------------------------------------------
// boost variant/detail/std_hash.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2018-2026 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_STD_HASH_HPP
#define BOOST_VARIANT_DETAIL_STD_HASH_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/detail/hash_variant.hpp>
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH
//
// Define this macro if you do not wish to have a std::hash specialization for
// boost::variant.
#if !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#include <functional> // for std::hash
namespace std {
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
struct hash<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) > > {
std::size_t operator()(const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& val) const {
return ::boost::hash_value(val);
}
};
}
#endif // #if !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // BOOST_VARIANT_DETAIL_STD_HASH_HPP
+90 -25
View File
@@ -1,3 +1,8 @@
#if !defined(BOOST_PP_IS_ITERATING)
///// header body
//-----------------------------------------------------------------------------
// boost variant/detail/substitute.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
@@ -13,20 +18,24 @@
#ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
#define BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
#include <boost/mpl/aux_/config/ctps.hpp>
#include "boost/mpl/aux_/config/ctps.hpp"
#include <boost/variant/detail/substitute_fwd.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/mpl/aux_/lambda_arity_param.hpp>
#include <boost/mpl/aux_/preprocessor/params.hpp>
#include <boost/mpl/aux_/preprocessor/repeat.hpp>
#include <boost/mpl/int_fwd.hpp>
#include <boost/mpl/limits/arity.hpp>
#include <boost/preprocessor/empty.hpp>
#include "boost/variant/detail/substitute_fwd.hpp"
#include "boost/mpl/aux_/lambda_arity_param.hpp"
#include "boost/mpl/aux_/preprocessor/params.hpp"
#include "boost/mpl/aux_/preprocessor/repeat.hpp"
#include "boost/mpl/int_fwd.hpp"
#include "boost/mpl/limits/arity.hpp"
#include "boost/preprocessor/cat.hpp"
#include "boost/preprocessor/empty.hpp"
#include "boost/preprocessor/arithmetic/inc.hpp"
#include "boost/preprocessor/iterate.hpp"
namespace boost {
namespace detail { namespace variant {
#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
///////////////////////////////////////////////////////////////////////////////
// (detail) metafunction substitute
//
@@ -116,23 +125,58 @@ struct substitute<
// template expression (i.e., F<...>) specializations
//
#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
typedef typename substitute< \
BOOST_PP_CAT(U,N), Dest, Source \
>::type BOOST_PP_CAT(u,N); \
/**/
#define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \
BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
/**/
#define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
#define BOOST_PP_FILENAME_1 "boost/variant/detail/substitute.hpp"
#include BOOST_PP_ITERATE()
#undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL
#undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF
#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
}} // namespace detail::variant
} // namespace boost
#endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
///// iteration, depth == 1
#elif BOOST_PP_ITERATION_DEPTH() == 1
#define i BOOST_PP_FRAME_ITERATION(1)
#if i > 0
//
// template specializations
//
template <
template <typename...> class F
, typename... Ts
template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
, BOOST_MPL_PP_PARAMS(i,typename U)
, typename Dest
, typename Source
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
>
struct substitute<
F<Ts...>
T< BOOST_MPL_PP_PARAMS(i,U) >
, Dest
, Source
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
>
{
typedef F<typename substitute<
Ts, Dest, Source
>::type...> type;
private:
BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
public:
typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
};
//
@@ -140,12 +184,35 @@ struct substitute<
//
template <
typename R
, typename... A
, BOOST_MPL_PP_PARAMS(i,typename U)
, typename Dest
, typename Source
>
struct substitute<
R (*)(A...)
R (*)( BOOST_MPL_PP_PARAMS(i,U) )
, Dest
, Source
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
>
{
private:
typedef typename substitute< R, Dest, Source >::type r;
BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
public:
typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) );
};
#elif i == 0
//
// zero-arg function specialization
//
template <
typename R, typename Dest, typename Source
>
struct substitute<
R (*)( void )
, Dest
, Source
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
@@ -155,12 +222,10 @@ private:
typedef typename substitute< R, Dest, Source >::type r;
public:
typedef r (*type)(typename substitute<
A, Dest, Source
>::type...);
typedef r (*type)( void );
};
}} // namespace detail::variant
} // namespace boost
#endif // i
#endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
#undef i
#endif // BOOST_PP_IS_ITERATING
@@ -13,17 +13,31 @@
#ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP
#define BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP
#include <boost/mpl/aux_/lambda_arity_param.hpp>
#include <boost/mpl/aux_/template_arity.hpp>
#include <boost/mpl/int_fwd.hpp>
#include "boost/mpl/aux_/lambda_arity_param.hpp"
#include "boost/mpl/aux_/template_arity.hpp"
#include "boost/mpl/int_fwd.hpp"
#include <boost/mpl/aux_/config/ctps.hpp>
#include <boost/mpl/aux_/config/ttp.hpp>
///////////////////////////////////////////////////////////////////////////////
// BOOST_VARIANT_DETAIL_NO_SUBSTITUTE
//
// Defined if 'substitute' is not implementable on the current compiler.
//
#include "boost/mpl/aux_/config/ctps.hpp"
#include "boost/mpl/aux_/config/ttp.hpp"
#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
# define BOOST_VARIANT_DETAIL_NO_SUBSTITUTE
#endif
namespace boost {
namespace detail { namespace variant {
#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
///////////////////////////////////////////////////////////////////////////////
// metafunction substitute
//
@@ -37,6 +51,8 @@ template <
>
struct substitute;
#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
}} // namespace detail::variant
} // namespace boost
+21 -12
View File
@@ -15,8 +15,10 @@
#include <iosfwd> // for std::basic_ostream forward declare
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/static_visitor.hpp>
#include "boost/variant/variant_fwd.hpp"
#include "boost/detail/templated_streams.hpp"
#include "boost/variant/static_visitor.hpp"
namespace boost {
@@ -27,9 +29,14 @@ namespace boost {
//
// forward declare (allows output of embedded variant< variant< ... >, ... >)
template <class CharT, class Trait, typename... U>
inline std::basic_ostream<CharT, Trait>& operator<<(
std::basic_ostream<CharT, Trait>& out, const variant<U...>& rhs
template <
BOOST_TEMPLATED_STREAM_ARGS(E,T)
BOOST_TEMPLATED_STREAM_COMMA
BOOST_VARIANT_ENUM_PARAMS(typename U)
>
inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
BOOST_TEMPLATED_STREAM(ostream, E,T)& out
, const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs
);
namespace detail { namespace variant {
@@ -57,20 +64,22 @@ public: // visitor interface
out_ << operand;
}
private:
printer& operator=(const printer&);
};
}} // namespace detail::variant
template <class CharT, class Trait, typename... U>
inline std::basic_ostream<CharT, Trait>& operator<<(
std::basic_ostream<CharT, Trait>& out, const variant<U...>& rhs
template <
BOOST_TEMPLATED_STREAM_ARGS(E,T)
BOOST_TEMPLATED_STREAM_COMMA
BOOST_VARIANT_ENUM_PARAMS(typename U)
>
inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
BOOST_TEMPLATED_STREAM(ostream, E,T)& out
, const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs
)
{
detail::variant::printer<
std::basic_ostream<CharT, Trait>
BOOST_TEMPLATED_STREAM(ostream, E,T)
> visitor(out);
rhs.apply_visitor(visitor);
@@ -13,31 +13,28 @@
#ifndef BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
#define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
#include <boost/config.hpp>
#include "boost/config.hpp"
#include <boost/variant/detail/backup_holder.hpp>
#include <boost/variant/detail/cast_storage.hpp>
#include <boost/variant/detail/forced_return.hpp>
#include <boost/variant/variant_fwd.hpp>
#include "boost/variant/detail/backup_holder.hpp"
#include "boost/variant/detail/cast_storage.hpp"
#include "boost/variant/detail/forced_return.hpp"
#include "boost/variant/detail/generic_result_type.hpp"
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/or.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include "boost/assert.hpp"
#include "boost/mpl/eval_if.hpp"
#include "boost/mpl/bool.hpp"
#include "boost/mpl/identity.hpp"
#include "boost/mpl/int.hpp"
#include "boost/mpl/next.hpp"
#include "boost/mpl/deref.hpp"
#include "boost/mpl/or.hpp"
#include "boost/preprocessor/cat.hpp"
#include "boost/preprocessor/inc.hpp"
#include "boost/preprocessor/repeat.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/type_traits/has_nothrow_copy.hpp"
#include "boost/variant/detail/has_nothrow_move.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning (push)
# pragma warning (disable : 4702) //unreachable code
#endif
///////////////////////////////////////////////////////////////////////////////
// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
@@ -46,11 +43,8 @@
// and potentially increase runtime performance. (TODO: Investigate further.)
//
#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
# include <boost/mpl/limits/list.hpp>
# define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT \
BOOST_MPL_LIMIT_LIST_SIZE
BOOST_VARIANT_LIMIT_TYPES
#endif
namespace boost {
@@ -69,6 +63,7 @@ struct apply_visitor_unrolled {};
// "Never ending" iterator range facilitates visitation_impl unrolling.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename Iter, typename LastIter>
struct visitation_impl_step
@@ -88,6 +83,29 @@ struct visitation_impl_step< LastIter,LastIter >
typedef visitation_impl_step next;
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename Iter, typename LastIter>
struct visitation_impl_step
{
typedef typename mpl::eval_if<
is_same<Iter, LastIter>
, mpl::identity<apply_visitor_unrolled>
, Iter
>::type type;
typedef typename mpl::eval_if<
is_same<type, apply_visitor_unrolled> //is_same<Iter, LastIter>
, mpl::identity<LastIter>
, mpl::next<Iter>
>::type next_iter;
typedef visitation_impl_step<
next_iter, LastIter
> next;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
///////////////////////////////////////////////////////////////////////////////
// (detail) function template visitation_impl_invoke
@@ -96,7 +114,8 @@ struct visitation_impl_step< LastIter,LastIter >
//
template <typename Visitor, typename VoidPtrCV, typename T>
inline typename Visitor::result_type
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
visitation_impl_invoke_impl(
int, Visitor& visitor, VoidPtrCV storage, T*
, mpl::true_// never_uses_backup
@@ -108,7 +127,8 @@ visitation_impl_invoke_impl(
}
template <typename Visitor, typename VoidPtrCV, typename T>
inline typename Visitor::result_type
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
visitation_impl_invoke_impl(
int internal_which, Visitor& visitor, VoidPtrCV storage, T*
, mpl::false_// never_uses_backup
@@ -129,7 +149,8 @@ visitation_impl_invoke_impl(
}
template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
inline typename Visitor::result_type
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
visitation_impl_invoke(
int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
, NoBackupFlag
@@ -138,21 +159,23 @@ visitation_impl_invoke(
{
typedef typename mpl::or_<
NoBackupFlag
, is_nothrow_move_constructible<T>
, has_nothrow_move_constructor<T>
, has_nothrow_copy<T>
>::type never_uses_backup;
return (visitation_impl_invoke_impl)(
return visitation_impl_invoke_impl(
internal_which, visitor, storage, t
, never_uses_backup()
);
}
template <typename Visitor, typename VoidPtrCV, typename NBF>
inline typename Visitor::result_type
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!
// should never be here at runtime:
BOOST_ASSERT(false);
typedef typename Visitor::result_type result_type;
return ::boost::detail::variant::forced_return< result_type >();
}
@@ -168,14 +191,16 @@ template <
, typename Visitor, typename VPCV
, typename NBF
>
inline typename Visitor::result_type
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
visitation_impl(
int, int, Visitor&, VPCV
, mpl::true_ // is_apply_visitor_unrolled
, NBF, W* = nullptr, S* = nullptr
, NBF, W* = 0, S* = 0
)
{
// should never be here at runtime!
// should never be here at runtime:
BOOST_ASSERT(false);
typedef typename Visitor::result_type result_type;
return ::boost::detail::variant::forced_return< result_type >();
}
@@ -185,13 +210,14 @@ template <
, typename Visitor, typename VoidPtrCV
, typename NoBackupFlag
>
BOOST_FORCEINLINE typename Visitor::result_type
inline
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
visitation_impl(
const int internal_which, const int logical_which
, Visitor& visitor, VoidPtrCV storage
, mpl::false_ // is_apply_visitor_unrolled
, NoBackupFlag no_backup_flag
, Which* = nullptr, step0* = nullptr
, Which* = 0, step0* = 0
)
{
// Typedef apply_visitor_unrolled steps and associated types...
@@ -216,7 +242,7 @@ visitation_impl(
// ...applying the appropriate case:
# define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
case (Which::value + (N)): \
return (visitation_impl_invoke)( \
return visitation_impl_invoke( \
internal_which, visitor, storage \
, static_cast<BOOST_PP_CAT(T,N)*>(0) \
, no_backup_flag, 1L \
@@ -231,7 +257,6 @@ visitation_impl(
# undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
default: break;
}
// If not handled in this iteration, continue unrolling:
@@ -246,7 +271,7 @@ visitation_impl(
typedef typename is_same< next_type,apply_visitor_unrolled >::type
is_apply_visitor_unrolled;
return detail::variant::visitation_impl(
return visitation_impl(
internal_which, logical_which
, visitor, storage
, is_apply_visitor_unrolled()
@@ -258,8 +283,4 @@ visitation_impl(
}} // namespace detail::variant
} // namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
+70 -256
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2014-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,46 +15,39 @@
#include <exception>
#include <boost/config.hpp>
#include <boost/core/addressof.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/detail/element_index.hpp>
#include <boost/variant/detail/move.hpp>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/utility/addressof.hpp"
#include "boost/variant/variant_fwd.hpp"
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/add_pointer.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include "boost/mpl/bool.hpp"
# include "boost/mpl/or.hpp"
# include "boost/type_traits/is_same.hpp"
#endif
namespace boost {
#if defined(BOOST_CLANG)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif
//////////////////////////////////////////////////////////////////////////
// class bad_get
//
// The exception thrown in the event of a failed get of a value.
//
class BOOST_SYMBOL_VISIBLE bad_get
class bad_get
: public std::exception
{
public: // std::exception implementation
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
virtual const char * what() const throw()
{
return "boost::bad_get: "
"failed value get using boost::get";
}
};
#if defined(BOOST_CLANG)
# pragma clang diagnostic pop
#endif
//////////////////////////////////////////////////////////////////////////
// function template get<T>
@@ -84,44 +77,71 @@ public: // visitor typedefs
public: // visitor interfaces
pointer operator()(reference operand) const BOOST_NOEXCEPT
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
pointer operator()(reference operand) const
{
return boost::addressof(operand);
}
template <typename U>
pointer operator()(const U&) const BOOST_NOEXCEPT
pointer operator()(const U&) const
{
return static_cast<pointer>(0);
}
#else // MSVC6
private: // helpers, for visitor interfaces (below)
pointer execute_impl(reference operand, mpl::true_) const
{
return boost::addressof(operand);
}
template <typename U>
pointer execute_impl(const U& operand, mpl::false_) const
{
return static_cast<pointer>(0);
}
public: // visitor interfaces
template <typename U>
pointer operator()(U& operand) const
{
// MSVC6 finds normal implementation (above) ambiguous,
// so we must explicitly disambiguate
typedef typename mpl::or_<
is_same<U, T>
, is_same<const U, T>
>::type U_is_T;
return execute_impl(operand, U_is_T());
}
#endif // MSVC6 workaround
};
}} // namespace detail::variant
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
# else
# if defined(BOOST_NO_CXX11_NULLPTR)
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = 0
# else
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = nullptr
# endif
# endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
#else
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = 0
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// relaxed_get<U>(variant) methods
//
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
typename add_pointer<U>::type
relaxed_get(
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);
@@ -133,10 +153,10 @@ relaxed_get(
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
typename add_pointer<const U>::type
relaxed_get(
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);
@@ -148,241 +168,35 @@ relaxed_get(
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
typename add_reference<U>::type
relaxed_get(
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 = relaxed_get<U>(boost::addressof(operand));
U_ptr result = get<U>(&operand);
if (!result)
boost::throw_exception(bad_get());
throw bad_get();
return *result;
}
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
typename add_reference<const U>::type
relaxed_get(
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>(boost::addressof(operand));
U_ptr result = get<const U>(&operand);
if (!result)
boost::throw_exception(bad_get());
throw bad_get();
return *result;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined(BOOST_MSVC) && (_MSC_VER < 1900) // MSVC-2014 has fixed the incorrect diagnostics.
# pragma warning(push)
# pragma warning(disable: 4172) // returning address of local variable or temporary
#endif
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
U&&
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 = relaxed_get<U>(boost::addressof(operand));
if (!result)
boost::throw_exception(bad_get());
return static_cast<U&&>(*result);
}
#if defined(BOOST_MSVC) && (_MSC_VER < 1900)
# pragma warning(pop)
#endif
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
U&&
strict_get(
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
)
{
BOOST_STATIC_ASSERT_MSG(
(!boost::is_lvalue_reference<U>::value),
"remove ampersand '&' from template type U in boost::get<U>(boost::variant<T...>&&) "
);
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>(const boost::variant<T...>&) will always throw boost::bad_get exception"
);
return relaxed_get<U>(detail::variant::move(operand));
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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
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 relaxed_get<U>(operand);
#else
return strict_get<U>(operand);
#endif
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
U&&
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>(detail::variant::move(operand));
#else
return strict_get<U>(detail::variant::move(operand));
#endif
}
#endif
} // namespace boost
#endif // BOOST_VARIANT_GET_HPP
-28
View File
@@ -1,28 +0,0 @@
// Boost.Varaint
// Multivisitors defined here
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright (c) 2013-2026 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_MULTIVISITORS_HPP
#define BOOST_VARIANT_MULTIVISITORS_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/variant/variant_fwd.hpp>
#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
#endif // BOOST_VARIANT_MULTIVISITORS_HPP
-352
View File
@@ -1,352 +0,0 @@
//-----------------------------------------------------------------------------
// boost variant/polymorphic_get.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2013-2026 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/core/addressof.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.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>
#include <boost/type_traits/is_const.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 typename boost::remove_reference<Base>::type base_t;
typedef boost::integral_constant<
bool,
(
boost::is_base_of<base_t, U>::value &&
(boost::is_const<base_t>::value || !boost::is_const<U>::value)
)
|| boost::is_same<base_t, U>::value
|| boost::is_same<typename boost::remove_cv<base_t>::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(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
# else
# if defined(BOOST_NO_CXX11_NULLPTR)
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = 0
# else
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
, t* = nullptr
# endif
# 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
+70 -60
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman
// Copyright (c) 2013-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,27 +13,27 @@
#ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
#define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
#include <boost/variant/variant_fwd.hpp>
#include <boost/variant/detail/enable_recursive.hpp>
#include <boost/variant/detail/substitute_fwd.hpp>
#include <boost/variant/detail/make_variant_list.hpp>
#include <boost/variant/detail/over_sequence.hpp>
#include "boost/variant/variant_fwd.hpp"
#include "boost/variant/detail/enable_recursive.hpp"
#include "boost/variant/detail/substitute_fwd.hpp"
#include "boost/variant/detail/make_variant_list.hpp"
#include "boost/variant/detail/over_sequence.hpp"
#include <boost/mpl/aux_/lambda_arity_param.hpp>
#include "boost/mpl/aux_/lambda_arity_param.hpp"
#include <boost/mpl/equal.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/protect.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repeat.hpp>
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/identity.hpp"
# include "boost/mpl/protect.hpp"
# include "boost/mpl/transform.hpp"
#else
# include "boost/preprocessor/cat.hpp"
# include "boost/preprocessor/repeat.hpp"
#endif
#include <boost/mpl/bool.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/variant/variant.hpp>
#include "boost/mpl/bool.hpp"
#include "boost/mpl/is_sequence.hpp"
#include "boost/variant/variant.hpp"
namespace boost {
@@ -45,6 +45,8 @@ namespace detail { namespace variant {
// Handles embedded variant types when substituting for recursive_variant_.
//
#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
template <
BOOST_VARIANT_ENUM_PARAMS(typename T)
, typename RecursiveVariant
@@ -72,61 +74,67 @@ template <
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
>
struct substitute<
::boost::variant<
::boost::detail::variant::over_sequence< T0 >
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
>
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
, RecursiveVariant
, ::boost::recursive_variant_
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
>
{
private:
typedef T0 initial_types;
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
private: // helpers, for metafunction result (below)
typedef typename mpl::eval_if<
::boost::detail::variant::is_over_sequence<T0>
, mpl::identity< T0 >
, make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
>::type initial_types;
typedef typename mpl::transform<
initial_types
, mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
>::type types;
public:
public: // metafunction result
typedef ::boost::variant< types > type;
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
private: // helpers, for metafunction result (below)
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
typedef typename enable_recursive< \
BOOST_PP_CAT(T,N) \
, RecursiveVariant \
, mpl::true_ \
>::type BOOST_PP_CAT(wknd_T,N); \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
, _
)
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
public: // metafunction result
typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
typedef typename mpl::if_<
mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
, ::boost::variant<
::boost::detail::variant::over_sequence< T0 >
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
>
, ::boost::variant< over_sequence<types> >
>::type type;
};
template <
BOOST_VARIANT_ENUM_PARAMS(typename T)
, typename RecursiveVariant
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
>
struct substitute<
::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
, RecursiveVariant
, ::boost::recursive_variant_
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
>
{
typedef ::boost::variant<
typename enable_recursive<
T0
, RecursiveVariant
, mpl::true_
>::type,
typename enable_recursive<
TN
, RecursiveVariant
, mpl::true_
>::type...
> type;
};
#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
//
// no specializations: embedded variants unsupported on these compilers!
//
#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
}} // namespace detail::variant
@@ -157,7 +165,9 @@ struct make_recursive_variant_over
{
private: // precondition assertions
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
#endif
public: // metafunction result
+4 -39
View File
@@ -13,9 +13,8 @@
#ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_HPP
#define BOOST_VARIANT_RECURSIVE_WRAPPER_HPP
#include <boost/variant/recursive_wrapper_fwd.hpp>
#include <boost/variant/detail/move.hpp>
#include <boost/core/checked_delete.hpp>
#include "boost/variant/recursive_wrapper_fwd.hpp"
#include "boost/checked_delete.hpp"
namespace boost {
@@ -44,11 +43,6 @@ public: // structors
recursive_wrapper(const recursive_wrapper& operand);
recursive_wrapper(const T& operand);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
recursive_wrapper(recursive_wrapper&& operand);
recursive_wrapper(T&& operand);
#endif
private: // helpers, for modifiers (below)
void assign(const T& rhs);
@@ -67,28 +61,13 @@ public: // modifiers
return *this;
}
void swap(recursive_wrapper& operand) BOOST_NOEXCEPT
void swap(recursive_wrapper& operand)
{
T* temp = operand.p_;
operand.p_ = p_;
p_ = temp;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
recursive_wrapper& operator=(recursive_wrapper&& rhs) BOOST_NOEXCEPT
{
swap(rhs);
return *this;
}
recursive_wrapper& operator=(T&& rhs)
{
get() = detail::variant::move(rhs);
return *this;
}
#endif
public: // queries
T& get() { return *get_pointer(); }
@@ -123,20 +102,6 @@ recursive_wrapper<T>::recursive_wrapper(const T& operand)
{
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename T>
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
: p_(new T( detail::variant::move(operand.get()) ))
{
}
template <typename T>
recursive_wrapper<T>::recursive_wrapper(T&& operand)
: p_(new T( detail::variant::move(operand) ))
{
}
#endif
template <typename T>
void recursive_wrapper<T>::assign(const T& rhs)
{
@@ -148,7 +113,7 @@ void recursive_wrapper<T>::assign(const T& rhs)
// Swaps two recursive_wrapper<T> objects of the same type T.
//
template <typename T>
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) BOOST_NOEXCEPT
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs)
{
lhs.swap(rhs);
}
+60 -43
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002 Eric Friedman, Itay Maman
// Copyright (c) 2016-2026 Antony Polukhin
// Copyright (c) 2002
// Eric Friedman, Itay Maman
//
// Portions Copyright (C) 2002 David Abrahams
//
@@ -15,12 +15,18 @@
#ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/config/ctps.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_constructible.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include "boost/mpl/aux_/config/ctps.hpp"
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include "boost/mpl/eval_if.hpp"
# include "boost/mpl/bool.hpp"
# include "boost/mpl/identity.hpp"
# include "boost/type.hpp"
#endif
#include "boost/mpl/aux_/lambda_support.hpp"
// should be the last #include
#include "boost/type_traits/detail/bool_trait_def.hpp"
namespace boost {
@@ -42,42 +48,15 @@ namespace boost {
//
template <typename T> class recursive_wrapper;
///////////////////////////////////////////////////////////////////////////////
// metafunction is_constructible partial specializations.
//
// recursive_wrapper<T> is constructible only from T and recursive_wrapper<T>.
//
template <class T> struct is_constructible<recursive_wrapper<T>, T> : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, const T> : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, T&> : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, const T&> : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T> > : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T> > : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<T>& > : boost::true_type{};
template <class T> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<T>& > : boost::true_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, U > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, U& > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, const U& > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U> > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U> > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, recursive_wrapper<U>& > : boost::false_type{};
template <class T, class U> struct is_constructible<recursive_wrapper<T>, const recursive_wrapper<U>& > : boost::false_type{};
// recursive_wrapper is not nothrow move constructible, because it's constructor does dynamic memory allocation.
// This specialisation is required to workaround GCC6 issue: https://svn.boost.org/trac/boost/ticket/12680
template <class T> struct is_nothrow_move_constructible<recursive_wrapper<T> > : boost::false_type{};
///////////////////////////////////////////////////////////////////////////////
// metafunction is_recursive_wrapper (modeled on code by David Abrahams)
//
// True if specified type matches recursive_wrapper<T>.
// True iff specified type matches recursive_wrapper<T>.
//
namespace detail {
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct is_recursive_wrapper_impl
@@ -91,15 +70,36 @@ struct is_recursive_wrapper_impl< recursive_wrapper<T> >
{
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef char (&yes_recursive_wrapper_t)[1];
typedef char (&no_recursive_wrapper_t)[2];
no_recursive_wrapper_t is_recursive_wrapper_test(...);
template<typename T>
yes_recursive_wrapper_t is_recursive_wrapper_test(
type< ::boost::recursive_wrapper<T> >
);
template<typename T>
struct is_recursive_wrapper_impl
{
BOOST_STATIC_CONSTANT(bool, value = (
sizeof(is_recursive_wrapper_test(type<T>()))
== sizeof(yes_recursive_wrapper_t)
));
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
} // namespace detail
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))
};
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_recursive_wrapper
, T
, (::boost::detail::is_recursive_wrapper_impl<T>::value)
)
///////////////////////////////////////////////////////////////////////////////
// metafunction unwrap_recursive
@@ -107,6 +107,7 @@ public:
// If specified type T matches recursive_wrapper<U>, then U; else T.
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct unwrap_recursive
@@ -124,7 +125,23 @@ struct unwrap_recursive< recursive_wrapper<T> >
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T))
};
#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct unwrap_recursive
: mpl::eval_if<
is_recursive_wrapper<T>
, T
, mpl::identity< T >
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T))
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround
} // namespace boost
#include "boost/type_traits/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
+21 -17
View File
@@ -13,14 +13,18 @@
#ifndef BOOST_VARIANT_STATIC_VISITOR_HPP
#define BOOST_VARIANT_STATIC_VISITOR_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "boost/mpl/if.hpp"
#include "boost/type_traits/is_base_and_derived.hpp"
#include <boost/type_traits/integral_constant.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include "boost/type_traits/is_same.hpp"
#endif
// should be the last #include
#include "boost/type_traits/detail/bool_trait_def.hpp"
namespace boost {
@@ -48,11 +52,10 @@ public: // typedefs
typedef R result_type;
protected: // for use as base class only
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
static_visitor() = default;
#else
static_visitor() BOOST_NOEXCEPT { }
#endif
static_visitor() { }
~static_visitor() { }
};
//////////////////////////////////////////////////////////////////////////
@@ -81,13 +84,14 @@ struct is_static_visitor_impl
} // namespace detail
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))
};
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_static_visitor
, T
, (::boost::detail::is_static_visitor_impl<T>::value)
)
} // namespace boost
#include "boost/type_traits/detail/bool_trait_undef.hpp"
#endif // BOOST_VARIANT_STATIC_VISITOR_HPP
File diff suppressed because it is too large Load Diff
+133 -50
View File
@@ -3,8 +3,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2013-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,17 +13,47 @@
#ifndef BOOST_VARIANT_VARIANT_FWD_HPP
#define BOOST_VARIANT_VARIANT_FWD_HPP
#include <boost/variant/detail/config.hpp>
#include "boost/variant/detail/config.hpp"
#include <boost/blank_fwd.hpp>
#include <boost/mpl/arg.hpp>
#include <boost/mpl/limits/arity.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/enum.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_shifted_params.hpp>
#include <boost/preprocessor/repeat.hpp>
#include "boost/blank_fwd.hpp"
#include "boost/mpl/arg.hpp"
#include "boost/mpl/limits/arity.hpp"
#include "boost/mpl/aux_/na.hpp"
#include "boost/preprocessor/cat.hpp"
#include "boost/preprocessor/enum.hpp"
#include "boost/preprocessor/enum_params.hpp"
#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
//
// Defined if variant does not support references as bounded types.
//
#if defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) \
&& !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) \
&& !defined(BOOST_VARIANT_NO_REFERENCE_SUPPORT)
# define BOOST_VARIANT_NO_REFERENCE_SUPPORT
#endif
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
//
// Defined if variant does not support make_variant_over (see below).
//
#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
#endif
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
@@ -34,49 +64,41 @@
// so only types declared w/ MPL lambda workarounds will work.
//
#include <boost/variant/detail/substitute_fwd.hpp>
#include "boost/variant/detail/substitute_fwd.hpp"
#include <boost/preprocessor/seq/size.hpp>
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)(
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class...
#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename...
#define ARGS_VARIADER_1(x) x ## N...
#define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N
#define BOOST_VARIANT_MAKE_VARIADIC(sequence, x) BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x)
#define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x) BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x)
#define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig)
#if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \
&& !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
# define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
#endif
///////////////////////////////////////////////////////////////////////////////
// BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS
// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
//
// Convenience macro for enumeration of variant params.
// When variadic templates are available expands:
// BOOST_VARIANT_ENUM_PARAMS(class Something) => class Something0, class... SomethingN
// BOOST_VARIANT_ENUM_PARAMS(typename Something) => typename Something0, typename... SomethingN
// BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
// BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something) => class... SomethingN
// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something) => typename... SomethingN
// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
// BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
//
// Rationale: Cleaner, simpler code for clients of variant library. Minimal
// code modifications to move from C++03 to C++11.
// Exposes maximum allowed arity of class templates with recursive_variant
// arguments. That is,
// make_recursive_variant< ..., T<[1], recursive_variant_, ... [N]> >.
//
#include "boost/mpl/limits/arity.hpp"
#define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \
BOOST_MPL_LIMIT_METAFUNCTION_ARITY
#define BOOST_VARIANT_ENUM_PARAMS(x) \
x ## 0, \
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
/**/
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_ENUM_PARAMS
//
// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES params.
//
// Rationale: Cleaner, simpler code for clients of variant library.
//
#define BOOST_VARIANT_ENUM_PARAMS( param ) \
BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \
BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
/**/
///////////////////////////////////////////////////////////////////////////////
// macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS
//
// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params.
//
#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
namespace boost {
@@ -109,9 +131,70 @@ struct convert_void< void_ >
typedef mpl::na type;
};
///////////////////////////////////////////////////////////////////////////////
// (workaround) BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
//
// Needed to work around compilers that don't support using-declaration
// overloads. (See the variant::initializer workarounds below.)
//
#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
// convert_void that yields mpl::na for each voidNN type.
//
#define BOOST_VARIANT_DETAIL_DEFINE_VOID_N(z,N,_) \
struct BOOST_PP_CAT(void,N); \
\
template <> \
struct convert_void< BOOST_PP_CAT(void,N) > \
{ \
typedef mpl::na type; \
}; \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_DETAIL_DEFINE_VOID_N
, _
)
#undef BOOST_VARIANT_DETAIL_DEFINE_VOID_N
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
}} // namespace detail::variant
#define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
///////////////////////////////////////////////////////////////////////////////
// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
//
// Template parameter list for variant and recursive_variant declarations.
//
#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
typename BOOST_PP_CAT(T,N) = detail::variant::void_ \
/**/
#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
# define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \
/**/
#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
#define BOOST_VARIANT_AUX_DECLARE_PARAMS \
BOOST_PP_ENUM( \
BOOST_VARIANT_LIMIT_TYPES \
, BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \
, T \
) \
/**/
///////////////////////////////////////////////////////////////////////////////
// class template variant (concept inspired by Andrei Alexandrescu)
@@ -146,7 +229,7 @@ template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant;
// Tag type indicates where recursive variant substitution should occur.
//
#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
struct recursive_variant_ {};
struct recursive_variant_;
#else
typedef mpl::arg<1> recursive_variant_;
#endif
+38 -10
View File
@@ -13,15 +13,14 @@
#ifndef BOOST_VARIANT_VISITOR_PTR_HPP
#define BOOST_VARIANT_VISITOR_PTR_HPP
#include <boost/variant/bad_visit.hpp>
#include <boost/variant/static_visitor.hpp>
#include "boost/variant/bad_visit.hpp"
#include "boost/variant/static_visitor.hpp"
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_void.hpp>
#include "boost/mpl/eval_if.hpp"
#include "boost/mpl/identity.hpp"
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/type_traits/is_void.hpp"
namespace boost {
@@ -55,7 +54,7 @@ private: // private typedefs
public: // structors
explicit visitor_ptr_t(visitor_t visitor) BOOST_NOEXCEPT
explicit visitor_ptr_t(visitor_t visitor)
: visitor_(visitor)
{
}
@@ -65,9 +64,11 @@ public: // static visitor interfaces
template <typename U>
result_type operator()(const U&) const
{
boost::throw_exception(bad_visit());
throw bad_visit();
}
#if !defined(BOOST_NO_VOID_RETURNS)
public: // static visitor interfaces, cont.
result_type operator()(argument_fwd_type operand) const
@@ -75,6 +76,33 @@ public: // static visitor interfaces, cont.
return visitor_(operand);
}
#else // defined(BOOST_NO_VOID_RETURNS)
private: // helpers, for static visitor interfaces (below)
result_type execute_impl(argument_fwd_type operand, mpl::false_) const
{
return visitor_(operand);
}
BOOST_VARIANT_AUX_RETURN_VOID_TYPE
execute_impl(argument_fwd_type operand, mpl::true_) const
{
visitor_(operand);
BOOST_VARIANT_AUX_RETURN_VOID;
}
public: // static visitor interfaces, cont.
BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
operator()(argument_fwd_type operand) const
{
typedef typename is_void<result_type>::type has_void_result;
return execute_impl(operand, has_void_result());
}
#endif // BOOST_NO_VOID_RETURNS workaround
};
template <typename R, typename T>
+2 -28
View File
@@ -1,35 +1,9 @@
<!DOCTYPE html>
<!--
Copyright 2014-2026 Antony Polukhin
antoshkka at gmail dot com
Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt)
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; URL=../../doc/html/variant.html">
<title>Boost.Variant</title>
<style>
body {
background: #fff;
color: #000;
}
a {
color: #00f;
text-decoration: none;
}
</style>
</head>
<body>
<p>
Automatic redirection failed, please go to
<a href="../../doc/html/variant.html">../../doc/html/variant.html</a>
</p>
<p>
&copy; 2014-2024 Antony Polukhin
</p>
Automatic redirection failed, please go to
<a href="../../doc/html/variant.html">../../doc/html/variant.html</a>
</body>
</html>
-18
View File
@@ -1,18 +0,0 @@
{
"key": "variant",
"name": "Variant",
"authors": [
"Eric Friedman",
"Itay Maman"
],
"description": "Safe, generic, stack-based discriminated union container.",
"category": [
"Containers",
"Data"
],
"maintainers": [
"Antony Polukhin <antoshkka -at- gmail.com>",
"Eric Friedman <ericbrandon -at- gmail.com>"
],
"cxxstd": "11"
}
-29
View File
@@ -1,29 +0,0 @@
#==============================================================================
# Copyright (c) 2012-2026 Antony Polukhin
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#==============================================================================
# performance tests
import testing ;
import path ;
path-constant TEST_DIR : . ;
project performance/test
: source-location ./
: requirements
# <library>/boost/chrono//boost_chrono
# <library>/boost/system//boost_system
<link>static
<target-os>freebsd:<linkflags>"-lrt"
<target-os>linux:<linkflags>"-lrt"
<toolset>gcc:<cxxflags>-fvisibility=hidden
<toolset>intel-linux:<cxxflags>-fvisibility=hidden
<toolset>sun:<cxxflags>-xldscope=hidden
: default-build release
;
run move_perf.cpp : $(TEST_DIR) ;
-236
View File
@@ -1,236 +0,0 @@
// (C) Copyright Antony Polukhin 2012-2021.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/config for most recent version.
//
// Testing variant performance rvalue copy/assign performance
//
#define BOOST_ERROR_CODE_HEADER_ONLY
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono.hpp>
#include <boost/variant.hpp>
#include <string>
#include <vector>
struct scope {
typedef boost::chrono::steady_clock test_clock;
typedef boost::chrono::milliseconds duration_t;
test_clock::time_point start_;
const char* const message_;
explicit scope(const char* const message)
: start_(test_clock::now())
, message_(message)
{}
~scope() {
std::cout << message_ << " " << boost::chrono::duration_cast<duration_t>(test_clock::now() - start_) << std::endl;
}
};
static void do_test(bool do_count_cleanup_time = false) {
BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
typedef std::vector<char> str_t;
typedef boost::variant<int, str_t, float> var_t;
const char hello1_c[] = "hello long word";
const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));
const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));
if (do_count_cleanup_time) {
std::cout << "#############################################\n";
std::cout << "#############################################\n";
std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
std::cout << "#############################################\n";
}
std::vector<var_t> data_from, data_to;
data_from.resize(c_run_count, hello1);
data_to.reserve(c_run_count);
{
scope sc("boost::variant(const variant&) copying speed");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to.push_back(data_from[i]);
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
data_from.resize(c_run_count, hello1);
data_to.clear();
data_to.reserve(c_run_count);
{
scope sc("boost::variant(variant&&) moving speed");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to.push_back(boost::move(data_from[i]));
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
std::cout << "#############################################\n";
data_from.clear();
data_from.resize(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, hello2);
{
scope sc("boost::variant=(const variant&) copying speed on same types");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = data_from[i];
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
data_from.resize(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, hello2);
{
scope sc("boost::variant=(variant&&) moving speed on same types");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = boost::move(data_from[i]);
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
std::cout << "#############################################\n";
data_from.clear();
data_from.resize(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, var_t(0));
{
scope sc("boost::variant=(const variant&) copying speed on different types");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = data_from[i];
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
data_from.resize(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, var_t(0));
{
scope sc("boost::variant=(variant&&) moving speed on different types");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = boost::move(data_from[i]);
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
std::cout << "#############################################\n";
data_from.clear();
data_from.resize(c_run_count, var_t(0));
data_to.clear();
data_to.resize(c_run_count, hello2);
{
scope sc("boost::variant=(const variant&) copying speed on different types II");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = data_from[i];
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
data_from.resize(c_run_count, var_t(0));
data_to.clear();
data_to.resize(c_run_count, hello2);
{
scope sc("boost::variant=(variant&&) moving speed on different types II");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = boost::move(data_from[i]);
}
if (do_count_cleanup_time) {
data_to.clear();
data_from.clear();
}
}
std::cout << "#############################################\n";
std::vector<str_t> s1(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, var_t(0));
{
scope sc("boost::variant=(const T&) copying speed");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = s1[i];
}
if (do_count_cleanup_time) {
data_to.clear();
s1.clear();
}
}
std::vector<str_t> s2(c_run_count, hello2);
data_to.clear();
data_to.resize(c_run_count, var_t(0));
{
scope sc("boost::variant=(T&&) moving speed");
for (std::size_t i = 0; i < c_run_count; ++i) {
data_to[i] = boost::move(s2[i]);
}
if (do_count_cleanup_time) {
data_to.clear();
s2.clear();
}
}
}
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);
}
+13 -56
View File
@@ -1,73 +1,30 @@
# Boost.Variant Library test Jamfile
#
# Copyright (C) 2003, Eric Friedman, Itay Maman.
# Copyright (C) 2013-2026 Antony Polukhin.
#
# 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)
# This material is provided "as is", with absolutely no warranty expressed
# or implied. Any use is at your own risk.
#
require-b2 5.0.1 ;
import-search /boost/config/checks ;
import config : requires ;
import testing ;
local below_cpp14 = 98 03 0x 11 ;
local since_cpp20 = 2a 20 latest ;
project
: requirements
<library>/boost/variant//boost_variant
[ requires cxx11_rvalue_references ]
<toolset>msvc:<asynch-exceptions>on
;
# 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.
#
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 test4.cpp class_a.cpp
: : : : variant_test4 ]
[ run test5.cpp : : : : variant_test5 ]
[ run test6.cpp : : : : variant_test6 ]
[ run test7.cpp : : : : variant_test7 ]
[ run test8.cpp : : : : variant_test8 ]
[ run test9.cpp : : : <library>/boost/fusion//boost_fusion : variant_test9 ]
[ run recursive_variant_test.cpp ]
[ run variant_reference_test.cpp ]
[ run variant_comparison_test.cpp ]
[ run variant_visit_internal_linkage.cpp : : : "<cxxstd>$(below_cpp14)"\:<build>no ]
[ run variant_visit_test.cpp ]
[ run variant_get_test.cpp ]
[ compile-fail variant_rvalue_get_with_ampersand_test.cpp ]
[ compile-fail no_rvalue_to_nonconst_visitation.cpp ]
[ compile fusion_interop.cpp : <library>/boost/fusion//boost_fusion ]
[ 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
<toolset>gcc-4.5:<cxxflags>-fno-exceptions
<toolset>gcc-4.6:<cxxflags>-fno-exceptions
<toolset>gcc-4.7:<cxxflags>-fno-exceptions
<toolset>gcc-4.8:<cxxflags>-fno-exceptions
<toolset>clang:<cxxflags>-fno-exceptions
: variant_noexcept_test
]
[ run recursive_variant_test.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : variant_no_rtti_test ]
[ run hash_recursive_variant_test.cpp ]
[ run variant_swap_test.cpp ]
[ run auto_visitors.cpp : : : <library>/boost/lexical_cast//boost_lexical_cast ]
[ run issue42.cpp ]
[ compile issue53.cpp : <library>/boost/thread//boost_thread ]
[ run overload_selection.cpp : : : "<cxxstd>$(since_cpp20)"\:<build>no ]
[ run recursive_wrapper_move_test.cpp : : : <library>/boost/array//boost_array ]
[ run variant_over_joint_view_test.cpp ]
[ run const_ref_apply_visitor.cpp : : : <library>/boost/lexical_cast//boost_lexical_cast ]
;
;
-92
View File
@@ -1,92 +0,0 @@
# 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 2016-2021.
#
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
# and how it can be used with Boost libraries.
#
# File revision #7
init:
# boost-local/libs/ folder to put this library into. This may be useful, if you're for example running Travis
# from `Boost.DLL` repo while Boost already has `dll` and with to replace `dll` with content of`Boost.DLL`.
#
# Otherwise just leave the default value - set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
- set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
###############################################################################################################
# From this point and below code is same for all the Boost libs
###############################################################################################################
version: 1.71.{build}-{branch}
# branches to build
branches:
except:
- gh-pages
skip_tags: true
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1,clang-win
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
VARIANT: release # "variant_get_test.o: File too big" errors in debug
# MinGW 32-bit is not supported by Boost.System any more
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\mingw\bin;
# TOOLSET: gcc
# CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
VARIANT: release # "variant_get_test.o: File too big" errors in debug
before_build:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- echo "Testing %APPVEYOR_PROJECT_NAME%"
# Cloning Boost libraries (fast nondeep cloning)
- set BOOST=C:/boost-local
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
- cd %BOOST%
- git submodule update --init --depth 10 tools/build tools/boostdep
- rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%
- mv -f %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%BOOST_LIBS_FOLDER%
- python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" %BOOST_LIBS_FOLDER%
build_script:
- cmd /c bootstrap
- b2.exe headers
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
after_build:
before_test:
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- if "%VARIANT%"== "" set VARIANT=debug,release
- set VARIANT=variant=%VARIANT%
- echo "Running command ..\..\..\b2 -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release"
- ..\..\..\b2.exe -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% %VARIANT% cxxflags="-DBOOST_TRAVISCI_BUILD"
after_test:
on_success:
on_failure:
on_finish:
-370
View File
@@ -1,370 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/auto_visitors.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2014-2026 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/core/lightweight_test.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_TEST(has_result_type<s1>::value);
BOOST_TEST(has_result_type<s2>::value);
BOOST_TEST(has_result_type<s3>::value);
BOOST_TEST(!has_result_type<s4>::value);
BOOST_TEST(has_result_type<s5>::value);
BOOST_TEST(has_result_type<s6>::value);
BOOST_TEST(has_result_type<s7>::value);
BOOST_TEST(has_result_type<s8>::value);
BOOST_TEST(has_result_type<s9>::value);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST(has_result_type<s10>::value);
#endif
BOOST_TEST(has_result_type<s11>::value);
BOOST_TEST(has_result_type<s12>::value);
BOOST_TEST(has_result_type<s13>::value);
BOOST_TEST(has_result_type<s14>::value);
BOOST_TEST(has_result_type<s15>::value);
BOOST_TEST(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_TEST(boost::apply_visitor(visitor_ref, v2).c_str() == std::string("10"));
BOOST_TEST(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_TEST(true);
}
void run2()
{
BOOST_TEST(true);
}
void run3()
{
BOOST_TEST(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;
}
};
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_TEST(boost::apply_visitor(lex_streamer(), v1) == "1");
BOOST_TEST(boost::apply_visitor(lex_streamer_visitor)(v1) == "1");
BOOST_TEST(boost::apply_visitor(lex_streamer(), v2) == "10");
BOOST_TEST(boost::apply_visitor(lex_streamer_visitor)(v2) == "10");
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
BOOST_TEST(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v1) == "1");
BOOST_TEST(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_TEST(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_TEST(boost::apply_visitor(visitor_ref, v1) == "1");
BOOST_TEST(boost::apply_visitor(visitor_ref, v2) == "10");
std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1);
BOOST_TEST(ref_to_string == "1");
lex_streamer_void lex_streamer_void_visitor;
boost::apply_visitor(lex_streamer_void(), v1);
boost::apply_visitor(lex_streamer_void(), v2);
boost::apply_visitor(lex_streamer_void_visitor)(v2);
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_TEST(boost::apply_visitor(lex_combine(), v1, v2) == "1+10");
BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1) == "10+1");
BOOST_TEST(boost::apply_visitor(lex_combine_visitor)(v2, v1) == "10+1");
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
BOOST_TEST(
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_TEST(
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_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1) == "10+1");
std::string& ref_to_string = boost::apply_visitor(visitor_ref)(v1, v2);
BOOST_TEST(ref_to_string == "1+10");
boost::apply_visitor(lex_streamer_void(), v1, v2);
boost::apply_visitor(lex_streamer_void(), v2, v1);
boost::ignore_unused(lex_combine_visitor, visitor_ref);
}
void run3()
{
typedef boost::variant<int, std::string, double> variant_type;
variant_type v1(1), v2("10"), v3(100);
lex_combine lex_combine_visitor;
BOOST_TEST(boost::apply_visitor(lex_combine(), v1, v2, v3) == "1+10+100");
BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1, v3) == "10+1+100");
BOOST_TEST(boost::apply_visitor(lex_combine_visitor)(v2, v1, v3) == "10+1+100");
#ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
BOOST_TEST(
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_TEST(
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_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
BOOST_TEST(boost::apply_visitor(visitor_ref)(v2, v1) == "10+1");
std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1, v2);
BOOST_TEST(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
int main()
{
run_explicit();
run();
run2();
run3();
test_has_result_type_triat();
return boost::report_errors();
}
+2 -3
View File
@@ -13,8 +13,7 @@
#include <algorithm> // for std::swap
#include <sstream>
#include <iostream>
#include <boost/assert.hpp>
#include <assert.h>
#include "class_a.h"
@@ -23,7 +22,7 @@ using namespace std;
class_a::~class_a()
{
BOOST_ASSERT(self_p_ == this);
assert(self_p_ == this);
}
class_a::class_a(int n)
-334
View File
@@ -1,334 +0,0 @@
// Copyright (c) 2017 Levon Tarakchyan
//
// 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/core/lightweight_test.hpp"
#include "boost/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
#include "boost/variant/multivisitors.hpp"
#include "boost/lexical_cast.hpp"
#define lcs(val) boost::lexical_cast<std::string>(val)
struct construction_logger
{
int val_;
construction_logger(int val) : val_(val)
{
std::cout << val_ << " constructed\n";
}
construction_logger(const construction_logger& cl) :
val_(cl.val_)
{
std::cout << val_ << " copy constructed\n";
}
construction_logger(construction_logger&& cl) :
val_(cl.val_)
{
std::cout << val_ << " move constructed\n";
}
friend std::ostream& operator << (std::ostream& os, const construction_logger& cl)
{
return os << cl.val_;
}
friend std::istream& operator << (std::istream& is, construction_logger& cl)
{
return is >> cl.val_;
}
};
struct lex_streamer_explicit : boost::static_visitor<std::string>
{
template <class T>
std::string operator()(const T& val) const
{
return lcs(val);
}
template <class T, class V>
std::string operator()(const T& val, const V& val2) const
{
return lcs(val) + '+' + lcs(val2);
}
template <class T, class V, class P, class S>
std::string operator()(const T& val, const V& val2, const P& val3, const S& val4) const
{
return lcs(val) + '+' + lcs(val2) + '+' + lcs(val3) + '+' + lcs(val4);
}
};
struct lvalue_rvalue_detector : boost::static_visitor<std::string>
{
template <class T>
std::string operator()(T&&) const
{
return std::is_lvalue_reference<T>::value ? "lvalue reference"
: "rvalue reference";
}
template <class T, class V>
std::string operator()(T&& t, V&& v) const
{
return operator()(std::forward<T>(t)) + ", " + operator()(std::forward<V>(v));
}
template <class T, class V, class P>
std::string operator()(T&& t, V&& v, P&& p) const
{
return operator()(std::forward<T>(t), std::forward<V>(v)) + ", " + operator()(std::forward<P>(p));
}
template <class T, class V, class P, class S>
std::string operator()(T&& t, V&& v, P&& p, S&& s) const
{
return operator()(std::forward<T>(t), std::forward<V>(v), std::forward<P>(p)) + ", " + operator()(std::forward<S>(s));
}
};
typedef boost::variant<construction_logger, std::string> variant_type;
void test_const_ref_parameter(const variant_type& test_var)
{
std::cout << "Testing const lvalue reference visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var) == "lvalue reference");
}
void test_const_ref_parameter2(const variant_type& test_var, const variant_type& test_var2)
{
std::cout << "Testing const lvalue reference visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var, test_var2) == "lvalue reference, lvalue reference");
}
void test_const_ref_parameter4(const variant_type& test_var, const variant_type& test_var2, const variant_type& test_var3, const variant_type& test_var4)
{
std::cout << "Testing const lvalue reference visitable with multivisitor\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var, test_var2, test_var3, test_var4)
== "lvalue reference, lvalue reference, lvalue reference, lvalue reference");
}
void test_rvalue_parameter(variant_type&& test_var)
{
std::cout << "Testing rvalue visitable\n";
const auto expected_val = lcs(test_var);
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var)) == "rvalue reference");
}
void test_rvalue_parameter2(variant_type&& test_var, variant_type&& test_var2)
{
std::cout << "Testing rvalue visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var), std::move(test_var2)) == "rvalue reference, rvalue reference");
}
void test_rvalue_parameter4(variant_type&& test_var, variant_type&& test_var2, variant_type&& test_var3, variant_type&& test_var4)
{
std::cout << "Testing rvalue visitable with multivisitor\n";
auto result = boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var), std::move(test_var2), std::move(test_var3), std::move(test_var4));
std::cout << "result: " << result << std::endl;
BOOST_TEST(result == "rvalue reference, rvalue reference, rvalue reference, rvalue reference");
}
#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
#define FORWARD(x) std::forward<decltype(x)>(x)
void test_cpp14_visitor(const variant_type& test_var)
{
std::cout << "Testing const lvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto&& v) { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
}
void test_cpp14_mutable_visitor(const variant_type& test_var)
{
std::cout << "Testing const lvalue visitable for c++14 with inline mutable lambda\n";
BOOST_TEST(boost::apply_visitor([](auto&& v) mutable -> auto { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
}
void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_var2)
{
std::cout << "Testing const lvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& vv) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(vv)); }, test_var, test_var2)
== "lvalue reference, lvalue reference");
}
void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_var2, const variant_type& test_var3)
{
std::cout << "Testing const lvalue visitable for c++14\n";
auto result = boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
test_var, test_var2, test_var3);
std::cout << "result: " << result << std::endl;
BOOST_TEST(result == "lvalue reference, lvalue reference, lvalue reference");
}
void test_cpp14_visitor(variant_type& test_var)
{
std::cout << "Testing lvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto& v) { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
}
void test_cpp14_mutable_visitor(variant_type& test_var)
{
std::cout << "Testing lvalue visitable for c++14 with inline mutable lambda\n";
BOOST_TEST(boost::apply_visitor([](auto& v) mutable -> auto { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
}
void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2)
{
std::cout << "Testing lvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto& v, auto& vv) { return lvalue_rvalue_detector()(v, vv); }, test_var, test_var2)
== "lvalue reference, lvalue reference");
}
void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2, variant_type& test_var3)
{
std::cout << "Testing lvalue visitable for c++14\n";
auto result = boost::apply_visitor([](auto& v, auto& t, auto& p) { return lvalue_rvalue_detector()(v, t, p); },
test_var, test_var2, test_var3);
std::cout << "result: " << result << std::endl;
BOOST_TEST(result == "lvalue reference, lvalue reference, lvalue reference");
}
void test_cpp14_visitor(variant_type&& test_var)
{
std::cout << "Testing rvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto&& v) { return lvalue_rvalue_detector()(FORWARD(v)); }, std::move(test_var)) == "rvalue reference");
}
void test_cpp14_visitor(variant_type&& test_var, variant_type&& test_var2)
{
std::cout << "Testing rvalue visitable for c++14\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& vv) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(vv)); }, std::move(test_var), std::move(test_var2))
== "rvalue reference, rvalue reference");
}
void test_cpp14_visitor(variant_type&& test_var, variant_type&& test_var2, variant_type&& test_var3)
{
std::cout << "Testing rvalue visitable for c++14\n";
auto result = boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
std::move(test_var), std::move(test_var2), std::move(test_var3));
std::cout << "result: " << result << std::endl;
BOOST_TEST(result == "rvalue reference, rvalue reference, rvalue reference");
}
#endif // #ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
void run_const_lvalue_ref_tests()
{
const variant_type v1(1), v2(2), v3(3), v4(4);
test_const_ref_parameter(v1);
test_const_ref_parameter2(v1, v2);
test_const_ref_parameter4(v1, v2, v3, v4);
}
void run_rvalue_ref_tests()
{
variant_type v1(10), v2(20), v3(30);
test_rvalue_parameter(std::move(v1));
test_rvalue_parameter2(std::move(v2), std::move(v3));
variant_type vv1(100), vv2(200), vv3(300), vv4(400);
test_rvalue_parameter4(std::move(vv1), std::move(vv2), std::move(vv3), std::move(vv4));
}
void run_mixed_tests()
{
variant_type v1(1), v2(2);
std::cout << "Testing lvalue + rvalue visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, variant_type(10)) == "lvalue reference, rvalue reference");
std::cout << "Testing rvalue + lvalue visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), variant_type(10), v1) == "rvalue reference, lvalue reference");
std::cout << "Testing rvalue + lvalue + rvalue visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), variant_type(10), v1, variant_type(20)) == "rvalue reference, lvalue reference, rvalue reference");
std::cout << "Testing lvalue + rvalue + lvalue + rvalue visitable\n";
BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, variant_type(10), v2, variant_type(20)) == "lvalue reference, rvalue reference, lvalue reference, rvalue reference");
}
void run_cpp14_mixed_tests()
{
#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
variant_type v1(1), v2(2);
std::cout << "Testing lvalue + rvalue visitable\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t)); },
v1, variant_type(10)) == "lvalue reference, rvalue reference");
std::cout << "Testing rvalue + lvalue visitable\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t)); },
variant_type(10), v1) == "rvalue reference, lvalue reference");
std::cout << "Testing rvalue + lvalue + lvalue visitable\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
variant_type(10), v1, v2) == "rvalue reference, lvalue reference, lvalue reference");
std::cout << "Testing lvalue + rvalue + lvalue visitable\n";
BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
v1, variant_type(10), v2) == "lvalue reference, rvalue reference, lvalue reference");
#endif // #ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
}
void run_cpp14_tests()
{
#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
variant_type const c1(10), c2(20), c3(30);
variant_type v1(10), v2(20), v3(30);
test_cpp14_visitor(c1);
test_cpp14_mutable_visitor(c1);
test_cpp14_visitor(c2, c3);
test_cpp14_visitor(c1, c2, c3);
test_cpp14_visitor(v1);
test_cpp14_mutable_visitor(v1);
test_cpp14_visitor(v2, v3);
test_cpp14_visitor(v1, v2, v3);
test_cpp14_visitor(std::move(v1));
test_cpp14_visitor(std::move(v2), std::move(v3));
variant_type vv1(100), vv2(200), vv3(300);
test_cpp14_visitor(std::move(vv1), std::move(vv2), std::move(vv3));
#endif
}
int main()
{
run_const_lvalue_ref_tests();
run_rvalue_ref_tests();
run_mixed_tests();
run_cpp14_mixed_tests();
run_cpp14_tests();
return boost::report_errors();
}
-29
View File
@@ -1,29 +0,0 @@
// Copyright (c) 2021-2026 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)
// Test case from https://svn.boost.org/trac10/ticket/8721
#include <boost/variant.hpp>
#include <boost/fusion/include/vector.hpp>
struct emptyList {};
typedef boost::make_recursive_variant
< emptyList
, boost::fusion::vector
< int
, boost::recursive_variant_
>
>::type IntList;
const emptyList el = emptyList();
const IntList nil( el );
IntList cons( int head, IntList tail )
{
return IntList( boost::fusion::vector<int, IntList>( head, tail ) );
}
-73
View File
@@ -1,73 +0,0 @@
// Copyright (c) 2016
// Mikhail Maximov
//
// 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/core/lightweight_test.hpp"
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
// Test is based on reported issues:
// https://svn.boost.org/trac/boost/ticket/12508
// https://svn.boost.org/trac/boost/ticket/12645
// Following hash function was not found at compile time,
// because boost::variant construction from boost::recursive_variant_
// was forbidden.
#include <unordered_set>
#include "boost/variant.hpp"
struct hash;
using int_t = int;
template <typename T>
using basic_set_t = std::unordered_set<T, hash>;
using value_t = boost::make_recursive_variant<
int_t,
basic_set_t<boost::recursive_variant_>
>::type;
using set_t = basic_set_t<value_t>;
struct hash
{
size_t operator()(const value_t&) const
{
return 0;
}
};
void run()
{
set_t s;
int_t i = 3;
value_t v = i;
auto emplace_result = s.emplace(v); // raises error above
BOOST_TEST(emplace_result.second);
v = s;
const set_t& check_set = boost::get<set_t>(v);
BOOST_TEST(!check_set.empty());
for (const auto& check_v : check_set) {
BOOST_TEST(s.find(check_v) != s.end());
}
for (const auto& check_v : s) {
BOOST_TEST(check_set.find(check_v) != check_set.end());
}
}
#else // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
// if no unordered_set and template aliases - does nothing
void run() {}
#endif
int main()
{
run();
return boost::report_errors();
}
-54
View File
@@ -1,54 +0,0 @@
// Copyright (c) 2011-2026 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/core/lightweight_test.hpp"
#include "boost/config.hpp"
#include "boost/variant.hpp"
#include "boost/functional/hash/hash.hpp"
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH)
#include <unordered_set>
void test_std_hash() {
std::unordered_set<boost::variant<int, bool> > us;
us.insert(1);
us.insert(true);
BOOST_TEST(us.size() == 2);
}
#else
void test_std_hash() {}
#endif
void run() {
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_TEST(hasher(bool_variant1) != hasher(bool_variant2));
BOOST_TEST(hasher(bool_variant1) == hasher(bool_variant1));
BOOST_TEST(hasher(int_variant) != hasher(uint_variant));
BOOST_TEST(hasher(char_variant1) != hasher(uint_variant));
BOOST_TEST(hasher(char_variant1) != hasher(char_variant2));
BOOST_TEST(hasher(char_variant1) == hasher(char_variant1));
BOOST_TEST(hasher(char_variant2) == hasher(char_variant2));
}
int main() {
run();
test_std_hash();
return boost::report_errors();
}
-61
View File
@@ -1,61 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/issue42.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2018-2026 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)
// Test case from https://github.com/boostorg/variant/issues/42
#include <boost/variant.hpp>
#include <map>
#include <memory>
#include <vector>
#ifdef BOOST_NO_CXX11_SMART_PTR
template <class T> struct shared_ptr_like {};
typedef shared_ptr_like<boost::recursive_variant_> ptr_t;
#else
typedef std::shared_ptr<boost::recursive_variant_> ptr_t;
#endif
template <class F>
class func{};
int main() {
typedef boost::make_recursive_variant<
int,
ptr_t
>::type node;
node x = 1;
(void)x;
typedef boost::make_recursive_variant<
std::string, int, double, bool,
ptr_t,
std::map<const std::string, boost::recursive_variant_>,
std::vector<boost::recursive_variant_>
>::type node2;
node2 x2 = 1;
(void)x2;
typedef boost::make_recursive_variant<
int,
func<boost::recursive_variant_(*)(boost::recursive_variant_&, const boost::recursive_variant_&)>,
boost::recursive_variant_&(*)(boost::recursive_variant_, boost::recursive_variant_*),
ptr_t
>::type node3;
node3 x3 = func<node3(*)(node3&, const node3&)>();
(void)x3;
}
-58
View File
@@ -1,58 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/issue53.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2019-2026 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)
// Test case from https://github.com/boostorg/variant/issues/53
#include <boost/variant.hpp>
#include <boost/thread/lock_guard.hpp> // this line was causing problems on MSVC
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
struct spanac {};
struct ceapa{
double a,b;
};
typedef boost::variant<spanac, ceapa> var_t;
struct visitor_t : public boost::static_visitor<bool> {
bool operator() (const spanac&) const {
return true;
}
bool operator() (const ceapa&) const {
return false;
}
private:
double a, b;
};
var_t get(int k) {
if (k)
return spanac();
else
return ceapa();
}
int main(int argc, const char** argv) {
visitor_t v;
bool result = boost::apply_visitor(v, get(argc - 1));
(void)result;
}
#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
int main() {}
#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+38 -16
View File
@@ -25,9 +25,8 @@
#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(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
# pragma warn -lvc
#endif
@@ -233,6 +232,29 @@ struct int_adder : boost::static_visitor<>
struct held_type_name : boost::static_visitor<std::string>
{
template<typename T>
std::string operator()(const T& ) const
{
ost_ << '[' << typeid(T).name() << ']';
return result();
}
std::string result() const
{
return ost_.str();
}
mutable std::ostringstream ost_;
}; //held_type_name
template<typename T>
struct spec
{
@@ -244,14 +266,14 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
{
const VariantType& cvar = var;
BOOST_TEST(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
BOOST_TEST(cvar.type() == boost::typeindex::type_id<S>());
BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
BOOST_CHECK(cvar.type() == typeid(S));
//
// Check get<>()
//
BOOST_TEST(boost::get<S>(&var));
BOOST_TEST(boost::get<S>(&cvar));
BOOST_CHECK(boost::get<S>(&var));
BOOST_CHECK(boost::get<S>(&cvar));
const S* ptr1 = 0;
const S* ptr2 = 0;
@@ -260,7 +282,7 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
S& r = boost::get<S>(var);
ptr1 = &r;
}
catch(const boost::bad_get& )
catch(boost::bad_get& )
{
BOOST_ERROR( "get<S> failed unexpectedly" );
}
@@ -270,12 +292,12 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
const S& cr = boost::get<S>(cvar);
ptr2 = &cr;
}
catch(const boost::bad_get& )
catch(boost::bad_get& )
{
BOOST_ERROR( "get<S> const failed unexpectedly" );
}
BOOST_TEST(ptr1 != 0 && ptr2 == ptr1);
BOOST_CHECK(ptr1 != 0 && ptr2 == ptr1);
//
// Check string content
@@ -284,7 +306,7 @@ inline void verify(VariantType& var, spec<S>, std::string str = "")
{
std::string temp = boost::apply_visitor(to_text(), cvar);
std::cout << "temp = " << temp << ", str = " << str << std::endl;
BOOST_TEST(temp == str);
BOOST_CHECK(temp == str);
}
}
@@ -294,13 +316,13 @@ inline void verify_not(VariantType& var, spec<S>)
{
const VariantType& cvar = var;
BOOST_TEST(cvar.type() != boost::typeindex::type_id<S>());
BOOST_CHECK(cvar.type() != typeid(S));
//
// Check get<>()
//
BOOST_TEST(!boost::get<S>(&var));
BOOST_TEST(!boost::get<S>(&cvar));
BOOST_CHECK(!boost::get<S>(&var));
BOOST_CHECK(!boost::get<S>(&cvar));
const S* ptr1 = 0;
const S* ptr2 = 0;
@@ -311,7 +333,7 @@ inline void verify_not(VariantType& var, spec<S>)
ptr1 = &r;
}
catch(const boost::bad_get& )
catch(boost::bad_get& )
{
// do nothing except pass-through
}
@@ -323,12 +345,12 @@ inline void verify_not(VariantType& var, spec<S>)
ptr2 = &cr;
}
catch(const boost::bad_get& )
catch(boost::bad_get& )
{
// do nothing except pass-through
}
BOOST_TEST(ptr1 == 0 && ptr2 == 0);
BOOST_CHECK(ptr1 == 0 && ptr2 == 0);
}
-32
View File
@@ -1,32 +0,0 @@
// Copyright (c) 2017-2026 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/variant.hpp"
struct foo {};
struct some_user_provided_visitor_for_lvalues: boost::static_visitor<void> {
void operator()(foo& ) const {}
void operator()(int ) const {}
};
int main() {
boost::apply_visitor(
some_user_provided_visitor_for_lvalues(),
boost::variant<int, foo>(foo())
);
#ifdef __GNUC__
# if __GNUC__ < 5 && __GNUC_MINOR__ < 8
# error This test does not pass on GCC < 4.8 because of the incomplete C++11 support
# endif
#endif
#ifdef BOOST_MSVC
# error Temporaries/rvalues could bind to non-const lvalues on MSVC compilers
#endif
}
-215
View File
@@ -1,215 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/variant_get_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2016-2026 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)
// This test suite was created to cover issues reported in:
// https://svn.boost.org/trac/boost/ticket/5871
// https://svn.boost.org/trac/boost/ticket/11602
#include "boost/variant/variant.hpp"
#include "boost/variant/recursive_variant.hpp"
#include "boost/core/lightweight_test.hpp"
#include <string>
#include <list>
struct A{};
struct B{};
struct C{};
struct D{};
bool foo(const boost::variant<A, B>& ) {
return false;
}
bool foo(const boost::variant<C, D>& ) {
return true;
}
void test_overload_selection_variant_constructor() {
D d;
BOOST_TEST(foo(d));
boost::variant<B, A> v;
BOOST_TEST(!foo(v));
}
// Pre msvc-14.0 could not dustinguish between multiple assignment operators:
// warning C4522: 'assignment_tester' : multiple assignment operators specified
// error C2666: variant::operator =' : 3 overloads have similar conversions
// Old versions of GCC have same issue:
// error: variant::operator=(const T&) cannot be overloaded
#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_MSC_VER) && _MSC_VER < 1900)
void test_overload_selection_variant_assignment() {
BOOST_TEST(true);
}
#else
struct assignment_tester: boost::variant<C, D>, boost::variant<B, A> {
using boost::variant<B, A>::operator=;
using boost::variant<C, D>::operator=;
};
void test_overload_selection_variant_assignment() {
A a;
assignment_tester tester;
tester = a;
const int which0 = static_cast< boost::variant<B, A>& >(tester).which();
BOOST_TEST(which0 == 1);
boost::variant<A, B> b;
b = B();
tester = b;
const int which1 = static_cast< boost::variant<B, A>& >(tester).which();
BOOST_TEST(which1 == 0);
}
#endif
typedef boost::variant<int> my_variant;
struct convertible {
operator my_variant() const {
return my_variant();
}
};
void test_implicit_conversion_operator() {
// https://svn.boost.org/trac/boost/ticket/8555
my_variant y = convertible();
BOOST_TEST(y.which() == 0);
}
struct X: boost::variant< int > {};
class V1: public boost::variant<float,double> {};
struct AB: boost::variant<A, B> {};
void test_derived_from_variant_construction() {
// https://svn.boost.org/trac/boost/ticket/7120
X x;
boost::variant<X> y(x);
BOOST_TEST(y.which() == 0);
// https://svn.boost.org/trac/boost/ticket/10278
boost::variant<V1, std::string> v2 = V1();
BOOST_TEST(v2.which() == 0);
// https://svn.boost.org/trac/boost/ticket/12155
AB ab;
boost::variant<AB, C> ab_c(ab);
BOOST_TEST(ab_c.which() == 0);
boost::variant<A, B> a_b(ab);
BOOST_TEST(a_b.which() == 0);
boost::variant<B, C, A> b_c_a1(static_cast<boost::variant<A, B>& >(ab));
BOOST_TEST(b_c_a1.which() == 2);
// Following conversion seems harmful as it may lead to slicing:
// boost::variant<B, C, A> b_c_a(ab);
// BOOST_TEST(b_c_a.which() == 2);
}
void test_derived_from_variant_assignment() {
// https://svn.boost.org/trac/boost/ticket/7120
X x;
boost::variant<X> y;
y = x;
BOOST_TEST(y.which() == 0);
// https://svn.boost.org/trac/boost/ticket/10278
boost::variant<V1, std::string> v2;
v2 = V1();
BOOST_TEST(v2.which() == 0);
// https://svn.boost.org/trac/boost/ticket/12155
AB ab;
boost::variant<AB, C> ab_c;
ab_c = ab;
BOOST_TEST(ab_c.which() == 0);
boost::variant<A, B> a_b;
a_b = ab;
BOOST_TEST(a_b.which() == 0);
boost::variant<B, C, A> b_c_a1;
b_c_a1 = static_cast<boost::variant<A, B>& >(ab);
BOOST_TEST(b_c_a1.which() == 2);
// Following conversion seems harmful as it may lead to slicing:
// boost::variant<B, C, A> b_c_a;
// b_c_a = ab;
// BOOST_TEST(b_c_a.which() == 2);
}
// http://thread.gmane.org/gmane.comp.lib.boost.devel/267757
struct info {
struct nil_ {};
typedef
boost::variant<
nil_
, std::string
, boost::recursive_wrapper<info>
, boost::recursive_wrapper<std::pair<info, info> >
, boost::recursive_wrapper<std::list<info> >
>
value_type;
value_type v;
inline void test_on_incomplete_types() {
info i0;
i0.v = "Hello";
BOOST_TEST(i0.v.which() == 1);
info::value_type v0 = "Hello";
BOOST_TEST(v0.which() == 1);
info::value_type v1("Hello");
BOOST_TEST(v1.which() == 1);
info::value_type v2 = i0;
BOOST_TEST(v2.which() == 2);
info::value_type v3(i0);
BOOST_TEST(v3.which() == 2);
v0 = v3;
BOOST_TEST(v0.which() == 2);
v3 = v1;
BOOST_TEST(v3.which() == 1);
v3 = nil_();
BOOST_TEST(v3.which() == 0);
}
};
int main()
{
test_overload_selection_variant_constructor();
test_overload_selection_variant_assignment();
test_implicit_conversion_operator();
test_derived_from_variant_construction();
test_derived_from_variant_assignment();
info().test_on_incomplete_types();
return boost::report_errors();
}
+17 -320
View File
@@ -3,46 +3,23 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2013-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is used in two test cases:
//
// 1) recursive_variant_test.cpp that tests recursive usage of variant
//
// 2) variant_noexcept_test that tests Boost.Variant ability to compile
// and work with disabled exceptions
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "boost/mpl/vector.hpp"
#include "boost/mpl/copy.hpp"
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <tuple>
struct Nil {};
struct printer
struct vector_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
{
@@ -52,35 +29,13 @@ struct printer
typename std::vector<T>::const_iterator it = vec.begin();
for (; it != vec.end(); ++it)
ost << printer()( *it );
ost << boost::apply_visitor( vector_printer(), *it );
ost << ") ";
return ost.str();
}
template <int...> struct indices {};
template <typename... Ts, int... Is>
std::string operator()(const std::tuple<Ts...>& tup, indices<Is...>) const
{
std::ostringstream ost;
ost << "( ";
int a[] = {0, (ost << printer()( std::get<Is>(tup) ), 0)... };
(void)a;
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)>());
}
template <typename T>
std::string operator()(const T& operand) const
{
@@ -90,282 +45,24 @@ struct printer
}
};
void test_recursive_variant()
int test_main(int , char* [])
{
typedef boost::make_recursive_variant<
int
, std::vector<boost::recursive_variant_>
>::type var1_t;
>::type var_t;
std::vector<var1_t> vec1;
vec1.push_back(3);
vec1.push_back(5);
vec1.push_back(vec1);
vec1.push_back(7);
std::vector<var_t> vec;
vec.push_back(3);
vec.push_back(5);
vec.push_back(vec);
vec.push_back(7);
var1_t var1(vec1);
std::string result1( printer()(var1) );
var_t var(vec);
std::string result( boost::apply_visitor( vector_printer(), var ) );
std::cout << "result1: " << result1 << '\n';
BOOST_TEST(result1 == "( 3 5 ( 3 5 ) 7 ) ");
std::cout << "result: " << result << '\n';
BOOST_CHECK(result == "( 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_TEST(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_TEST(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_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
result1 = printer()(vec1_another_copy);
std::cout << "result1++2: " << result1 << '\n';
BOOST_TEST(result1 == "( 3 5 7 ) ");
vec1_copy[2].swap(vec1_copy[2]);
result1 = printer()(
var1_t(vec1_copy)
);
std::cout << "result1.2: " << result1 << '\n';
BOOST_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
typedef boost::make_recursive_variant<
boost::variant<int, double>
, std::vector<boost::recursive_variant_>
>::type var2_t;
std::vector<var2_t> vec2;
vec2.push_back(boost::variant<int, double>(3));
vec2.push_back(boost::variant<int, double>(3.5));
vec2.push_back(vec2);
vec2.push_back(boost::variant<int, double>(7));
var2_t var2(vec2);
std::string result2( printer()(var2) );
std::cout << "result2: " << result2 << '\n';
BOOST_TEST(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
typedef boost::make_recursive_variant<
int
, std::vector<
boost::variant<
double
, std::vector<boost::recursive_variant_>
>
>
>::type var3_t;
typedef boost::variant<double, std::vector<var3_t> > var4_t;
std::vector<var3_t> vec3;
vec3.push_back(3);
vec3.push_back(5);
std::vector<var4_t> vec4;
vec4.push_back(3.5);
vec4.push_back(vec3);
vec3.push_back(vec4);
vec3.push_back(7);
var4_t var4(vec3);
std::string result3( printer()(var4) );
std::cout << "result2: " << result3 << '\n';
BOOST_TEST(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
typedef boost::make_recursive_variant<
double,
std::vector<var1_t>
>::type var5_t;
std::vector<var5_t> vec5;
vec5.push_back(3.5);
vec5.push_back(vec1);
vec5.push_back(17.25);
std::string result5( printer()(vec5) );
std::cout << "result5: " << result5 << '\n';
BOOST_TEST(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
typedef boost::make_recursive_variant<
int,
std::map<int, boost::recursive_variant_>
>::type var6_t;
var6_t var6;
typedef boost::make_recursive_variant<
int,
std::tuple<int, boost::recursive_variant_>
>::type var7_t;
var7_t var7 = 0; // !!! Do not replace with `var7_t var7{0}` or `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_TEST(result7 == "( 2 ( 1 0 ) ) ");
}
void test_recursive_variant_over()
{
typedef boost::make_recursive_variant_over<
boost::mpl::vector<
int
, std::vector<boost::recursive_variant_>
>
>::type var1_t;
std::vector<var1_t> vec1;
vec1.push_back(3);
vec1.push_back(5);
vec1.push_back(vec1);
vec1.push_back(7);
var1_t var1(vec1);
std::string result1( printer()(var1) );
std::cout << "result1: " << result1 << '\n';
BOOST_TEST(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_TEST(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_TEST(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_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
result1 = printer()(vec1_another_copy);
std::cout << "result1++2: " << result1 << '\n';
BOOST_TEST(result1 == "( 3 5 7 ) ");
typedef boost::make_recursive_variant_over<
boost::mpl::vector<
boost::make_variant_over<boost::mpl::vector<int, double> >::type
, std::vector<boost::recursive_variant_>
>
>::type var2_t;
std::vector<var2_t> vec2;
vec2.push_back(boost::variant<int, double>(3));
vec2.push_back(boost::variant<int, double>(3.5));
vec2.push_back(vec2);
vec2.push_back(boost::variant<int, double>(7));
var2_t var2(vec2);
std::string result2( printer()(var2) );
std::cout << "result2: " << result2 << '\n';
BOOST_TEST(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
typedef boost::make_recursive_variant_over<
boost::mpl::vector<
int
, std::vector<
boost::make_variant_over<
boost::mpl::vector<
double
, std::vector<boost::recursive_variant_>
>
>::type
>
>
>::type var3_t;
typedef boost::make_variant_over<
boost::mpl::copy<
boost::mpl::vector<
double
, std::vector<var3_t>
>
>::type
>::type var4_t;
std::vector<var3_t> vec3;
vec3.push_back(3);
vec3.push_back(5);
std::vector<var4_t> vec4;
vec4.push_back(3.5);
vec4.push_back(vec3);
vec3.push_back(vec4);
vec3.push_back(7);
var4_t var3(vec3);
std::string result3( printer()(var3) );
std::cout << "result2: " << result3 << '\n';
BOOST_TEST(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
typedef boost::make_recursive_variant_over<
boost::mpl::vector<
double
, std::vector<var1_t>
>
>::type var5_t;
std::vector<var5_t> vec5;
vec5.push_back(3.5);
vec5.push_back(vec1);
vec5.push_back(17.25);
std::string result5( printer()(vec5) );
std::cout << "result5: " << result5 << '\n';
BOOST_TEST(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
}
void test_recursive_variant_from_variant()
{
// See https://github.com/boostorg/variant/issues/100
typedef boost::variant<Nil, double> Atom;
typedef boost::variant<Nil, boost::recursive_wrapper<Atom> > Variant;
BOOST_STATIC_ASSERT(!boost::is_constructible<Variant, Atom>::value);
BOOST_STATIC_ASSERT(boost::is_constructible<boost::variant<Nil, Atom>, Atom>::value);
}
int main()
{
test_recursive_variant();
test_recursive_variant_over();
test_recursive_variant_from_variant();
return boost::report_errors();
return boost::exit_success;
}
-77
View File
@@ -1,77 +0,0 @@
// Copyright (c) 2017
// Mikhail Maximov
//
// 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/core/lightweight_test.hpp"
#ifdef __cpp_inheriting_constructors
// Test is based on reported issue:
// https://svn.boost.org/trac/boost/ticket/12680
// GCC 6 crashed, trying to determine is boost::recursive_wrapper<Node>
// is_noexcept_move_constructible
#include <string>
#include <boost/variant.hpp>
#include <boost/array.hpp>
struct Leaf { };
struct Node;
typedef boost::variant<Leaf, boost::recursive_wrapper<Node>> TreeBase;
struct Tree : TreeBase {
using TreeBase::TreeBase;
template <typename Iter>
static Tree Create(Iter /*first*/, Iter /*last*/) { return Leaf{}; }
};
struct Node {
Tree left, right;
};
// Test from https://svn.boost.org/trac/boost/ticket/7120
template<class Node>
struct node1_type;
struct var_type;
using var_base = boost::variant<int,
boost::recursive_wrapper<node1_type<var_type>>
>;
template<class Node>
struct node1_type {
boost::array<Node, 1> children;
};
struct var_type : var_base {
using var_base::var_base;
};
void run() {
std::string input{"abracadabra"};
const Tree root = Tree::Create(input.begin(), input.end());
(void)root; // prevents unused variable warning
var_type v1 = 1;
(void)v1;
}
#else // #!ifdef __cpp_inheriting_constructors
// if compiler does not support inheriting constructors - does nothing
void run() {}
#endif
int main()
{
run();
return boost::report_errors();
}
-273
View File
@@ -1,273 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/rvalue_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2012-2026 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/core/lightweight_test.hpp"
#include "boost/variant.hpp"
#include "boost/type_traits/is_nothrow_move_assignable.hpp"
#include "boost/mpl/bool.hpp"
#include <boost/blank.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;
static unsigned int copy_count;
move_copy_conting_class(){}
move_copy_conting_class(move_copy_conting_class&& ) {
++ moves_count;
}
move_copy_conting_class& operator=(move_copy_conting_class&& ) {
++ moves_count;
return *this;
}
move_copy_conting_class(const move_copy_conting_class&) {
++ copy_count;
}
move_copy_conting_class& operator=(const move_copy_conting_class& ) {
++ copy_count;
return *this;
}
};
unsigned int move_copy_conting_class::moves_count = 0;
unsigned int move_copy_conting_class::copy_count = 0;
void run()
{
typedef boost::variant<int, move_copy_conting_class> variant_I_type;
variant_I_type v1, v2;
// Assuring that `move_copy_conting_class` was not created
BOOST_TEST(move_copy_conting_class::copy_count == 0);
BOOST_TEST(move_copy_conting_class::moves_count == 0);
v1 = move_copy_conting_class();
// Assuring that `move_copy_conting_class` was moved at least once
BOOST_TEST(move_copy_conting_class::moves_count != 0);
unsigned int total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
move_copy_conting_class var;
v1 = 0;
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v1 = var;
// Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v2 = std::move(v1);
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
BOOST_TEST(move_copy_conting_class::moves_count != 0);
BOOST_TEST(move_copy_conting_class::copy_count == 0);
v1 = move_copy_conting_class();
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v2 = std::move(v1);
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
BOOST_TEST(move_copy_conting_class::moves_count != 0);
BOOST_TEST(move_copy_conting_class::copy_count == 0);
total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v1 = v2;
// Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
typedef boost::variant<move_copy_conting_class, int> variant_II_type;
variant_II_type v3;
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v1 = std::move(v3);
// Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
BOOST_TEST(move_copy_conting_class::moves_count != 0);
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
v2 = std::move(v1);
// Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
BOOST_TEST(move_copy_conting_class::moves_count != 0);
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
variant_I_type v5(std::move(v1));
// Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
BOOST_TEST(move_copy_conting_class::moves_count != 0);
BOOST_TEST(move_copy_conting_class::copy_count == 0);
total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
variant_I_type v6(v1);
// Assuring that move constructor moves/copyes value not more times than copy constructor
BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
}
void run1()
{
move_copy_conting_class::moves_count = 0;
move_copy_conting_class::copy_count = 0;
move_copy_conting_class c1;
typedef boost::variant<int, move_copy_conting_class> variant_I_type;
variant_I_type v1(std::move(c1));
// Assuring that `move_copy_conting_class` was not copyied
BOOST_TEST(move_copy_conting_class::copy_count == 0);
BOOST_TEST(move_copy_conting_class::moves_count > 0);
}
struct move_only_structure {
move_only_structure(){}
move_only_structure(move_only_structure&&){}
move_only_structure& operator=(move_only_structure&&) { return *this; }
private:
move_only_structure(const move_only_structure&);
move_only_structure& operator=(const move_only_structure&);
};
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;
boost::variant<int, move_only_structure > vi, vi2(static_cast<move_only_structure&&>(mo));
BOOST_TEST(vi.which() == 0);
BOOST_TEST(vi2.which() == 1);
vi = 10;
vi2 = 10;
BOOST_TEST(vi.which() == 0);
BOOST_TEST(vi2.which() == 0);
vi = static_cast<move_only_structure&&>(mo);
vi2 = static_cast<move_only_structure&&>(mo);
BOOST_TEST(vi.which() == 1);
boost::variant<move_only_structure, int > rvi (1);
BOOST_TEST(rvi.which() == 1);
rvi = static_cast<move_only_structure&&>(mo);
BOOST_TEST(rvi.which() == 0);
rvi = 1;
BOOST_TEST(rvi.which() == 1);
rvi = static_cast<boost::variant<int, move_only_structure >&&>(vi2);
BOOST_TEST(rvi.which() == 0);
move_only_structure from_visitor = boost::apply_visitor(visitor_returning_move_only_type(), vi);
(void)from_visitor;
}
void run_moves_are_noexcept() {
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && (!defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || __GNUC_MINOR__ >= 8)
typedef boost::variant<int, short, double> variant_noexcept_t;
BOOST_TEST(boost::is_nothrow_move_assignable<variant_noexcept_t>::value);
BOOST_TEST(boost::is_nothrow_move_constructible<variant_noexcept_t>::value);
typedef boost::variant<int, short, double, move_only_structure> variant_except_t;
BOOST_TEST(!boost::is_nothrow_move_assignable<variant_except_t>::value);
BOOST_TEST(!boost::is_nothrow_move_constructible<variant_except_t>::value);
#endif
}
inline const std::string get_string() { return "test"; }
inline const boost::variant<int, std::string> get_variant() { return std::string("test"); }
inline const boost::variant<std::string, int> get_variant2() { return std::string("test"); }
void run_const_rvalues()
{
typedef boost::variant<int, std::string> variant_t;
const variant_t v1(get_string());
const variant_t v2(get_variant());
const variant_t v3(get_variant2());
variant_t v4, v5, v6, v7;
v4 = get_string();
v5 = get_variant();
v6 = get_variant2();
v7 = std::move(v1);
}
struct nothrow_copyable_throw_movable {
nothrow_copyable_throw_movable(){}
nothrow_copyable_throw_movable(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT {}
nothrow_copyable_throw_movable& operator=(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT { return *this; }
nothrow_copyable_throw_movable(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) {}
nothrow_copyable_throw_movable& operator=(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) { return *this; }
};
// This test is created to cover the following situation:
// https://svn.boost.org/trac/boost/ticket/8772
void run_tricky_compilation_test()
{
boost::variant<int, nothrow_copyable_throw_movable> v;
v = nothrow_copyable_throw_movable();
}
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_TEST((!is_container<boost::variant<double, int> >::value));
BOOST_TEST((!is_container<boost::variant<double, int, char> >::value));
BOOST_TEST((!is_container<boost::variant<double, int, char, float> >::value));
}
int main()
{
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();
return boost::report_errors();
}
+7 -13
View File
@@ -10,13 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/config.hpp"
#ifdef BOOST_MSVC
#pragma warning(disable:4244) // conversion from const int to const short
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "class_a.h"
@@ -121,11 +115,11 @@ void run()
v1 = 3.4f;
apply_visitor(ts, v1);
BOOST_TEST(ts.result() == sizeof(int) + sizeof(double)*2);
BOOST_CHECK(ts.result() == sizeof(int) + sizeof(double)*2);
v11 = 5;
string res_s = apply_visitor(int_printer(), v11);
BOOST_TEST(res_s == "5");
BOOST_CHECK(res_s == "5");
//
// A variant object holding an std::vector
@@ -138,13 +132,13 @@ void run()
v11 = int_vec_1;
res_s = apply_visitor(int_printer(), v11);
BOOST_TEST(res_s == ",512,256,128,64");
BOOST_CHECK(res_s == ",512,256,128,64");
}
int main()
int test_main(int , char* [])
{
run();
return boost::report_errors();
run();
return 0;
}
+6 -11
View File
@@ -11,12 +11,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/config.hpp"
#ifdef BOOST_MSVC
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "jobs.h"
@@ -43,10 +38,10 @@ struct short_string
using std::strlen;
#endif // BOOST_NO_STDC_NAMESPACE
size_t limit = this->e_limit; // avoid warnings on some compilers
size_t e_limit = this->e_limit; // avoid warnings on some compilers
size_t src_len = strlen(src);
len_ = (std::min)(src_len, limit-1);
len_ = (std::min)(src_len, e_limit-1);
std::copy(src, src + len_, buffer_);
buffer_[len_] = '\0';
}
@@ -141,9 +136,9 @@ void run()
}
int main()
int test_main(int , char* [])
{
run();
return boost::report_errors();
run();
return 0;
}
+6 -6
View File
@@ -10,7 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include <iostream>
@@ -113,7 +113,7 @@ struct Calculator : boost::static_visitor<int>
/////////////////////////////////////////////////////////////////////
int main()
int test_main(int, char* [])
{
int n = 13;
@@ -122,13 +122,13 @@ int main()
std::ostringstream e1_str;
e1_str << e1;
BOOST_TEST(e1.type() == boost::typeindex::type_id<Add>());
BOOST_TEST(e1_str.str() == "(13+((40+2)-(10+4)))");
BOOST_CHECK(e1.type() == typeid(Add));
BOOST_CHECK(e1_str.str() == "(13+((40+2)-(10+4)))");
//Evaluate expression
int res = boost::apply_visitor(Calculator(), e1);
BOOST_TEST(res == n + 28);
BOOST_CHECK(res == n + 28);
return boost::report_errors();
return 0;
}
+3 -9
View File
@@ -10,13 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/config.hpp"
#ifdef BOOST_MSVC
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "jobs.h"
@@ -32,7 +26,7 @@ typedef variant<std::string, class_a, short> var_type_2;
#include "class_a.h"
int main()
int test_main(int , char* [])
{
using namespace boost;
@@ -53,5 +47,5 @@ int main()
v2 = 5;
v1 = v2;
return boost::report_errors();
return boost::exit_success;
}
+6 -6
View File
@@ -10,7 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "jobs.h"
@@ -58,14 +58,14 @@ void run()
verify(v3, spec<int>());
BOOST_TEST(apply_visitor(sum_int(), v2) == c0);
BOOST_TEST(apply_visitor(sum_int(), v3) == c0);
BOOST_CHECK(apply_visitor(sum_int(), v2) == c0);
BOOST_CHECK(apply_visitor(sum_int(), v3) == c0);
sum_int adder;
apply_visitor(adder, v2);
apply_visitor(adder, v3);
BOOST_TEST(adder.result() == 2*c0);
BOOST_CHECK(adder.result() == 2*c0);
//
// A variant holding a variant
@@ -82,9 +82,9 @@ void run()
int main()
int test_main(int , char* [])
{
run();
return boost::report_errors();
return 0;
}
+3 -3
View File
@@ -10,7 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include <iostream>
@@ -66,9 +66,9 @@ void run()
int main()
int test_main(int , char* [])
{
run();
return boost::report_errors();
return 0;
}
+11 -20
View File
@@ -10,13 +10,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/config.hpp"
#ifdef BOOST_MSVC
#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include "jobs.h"
@@ -69,8 +63,8 @@ struct Tracker
static void remove(const jas& j)
{
iterator_type iter = s_this_to_sn_.find(&j);
BOOST_TEST(iter != s_this_to_sn_.end());
BOOST_TEST( ((*iter).second) == j.sn_);
BOOST_CHECK(iter != s_this_to_sn_.end());
BOOST_CHECK( ((*iter).second) == j.sn_);
int sn = (*iter).second;
if(sn != j.sn_)
@@ -79,7 +73,7 @@ struct Tracker
<< ", other: this = " << &j << ", j.sn_ = " << j.sn_ << endl;
}
BOOST_TEST(sn == j.sn_);
BOOST_CHECK(sn == j.sn_);
@@ -91,7 +85,7 @@ struct Tracker
static void check()
{
BOOST_TEST(s_this_to_sn_.empty());
BOOST_CHECK(s_this_to_sn_.empty());
}
};
@@ -203,9 +197,6 @@ public:
ValueType& expected_;
private:
compare_helper& operator=(const compare_helper&);
};
template<typename VariantType, typename ExpectedType>
@@ -214,13 +205,13 @@ void var_compare(const VariantType& v, ExpectedType expected)
compare_helper<ExpectedType> ch(expected);
bool checks = boost::apply_visitor(ch, v);
BOOST_TEST(checks);
BOOST_CHECK(checks);
}
void run()
{
boost::variant<string, short> v0;
variant<string, short> v0;
var_compare(v0, string(""));
@@ -230,7 +221,7 @@ void run()
v0 = "penny lane";
var_compare(v0, string("penny lane"));
boost::variant<jas, string, int> v1, v2 = jas(195);
variant<jas, string, int> v1, v2 = jas(195);
var_compare(v1, jas(364));
v1 = jas(500);
@@ -240,16 +231,16 @@ void run()
var_compare(v2, jas(500));
boost::variant<string, int> v3;
variant<string, int> v3;
var_compare(v3, string(""));
}
int main()
int test_main(int , char* [])
{
run();
Tracker::check();
return boost::report_errors();
return 0;
}
+14 -15
View File
@@ -10,13 +10,14 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include "boost/variant.hpp"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
using namespace boost;
typedef variant<float, std::string, int, std::vector<std::string> > t_var1;
@@ -40,12 +41,12 @@ struct int_sum : static_visitor<>
template <typename T, typename Variant>
T& check_pass(Variant& v, T value)
{
BOOST_TEST(get<T>(&v));
BOOST_CHECK(get<T>(&v));
try
{
T& r = get<T>(v);
BOOST_TEST(r == value);
BOOST_CHECK(r == value);
return r;
}
catch(boost::bad_get&)
@@ -57,21 +58,20 @@ T& check_pass(Variant& v, T value)
template <typename T, typename Variant>
void check_fail(Variant& v)
{
BOOST_TEST(!relaxed_get<T>(&v));
BOOST_CHECK(!get<T>(&v));
try
{
T& r = relaxed_get<T>(v);
(void)r; // suppress warning about r not being used
BOOST_TEST(false && relaxed_get<T>(&v)); // should never reach
T& r = get<T>(v);
BOOST_CHECK(false && &r); // should never reach
}
catch(const boost::bad_get& e)
catch(boost::bad_get&)
{
BOOST_TEST(!!e.what()); // make sure that what() is const qualified and returnes something
// (do nothing here)
}
}
int main()
int test_main(int , char* [])
{
int_sum acc;
t_var1 v1 = 800;
@@ -87,12 +87,12 @@ int main()
check_fail<const short>(v1);
apply_visitor(acc, v1);
BOOST_TEST(acc.result_ == 800);
BOOST_CHECK(acc.result_ == 800);
r1 = 920; // NOTE: modifies content of v1
apply_visitor(acc, v1);
BOOST_TEST(cr1 == 920);
BOOST_TEST(acc.result_ == 800 + 920);
BOOST_CHECK(cr1 == 920);
BOOST_CHECK(acc.result_ == 800 + 920);
}
// check const correctness:
@@ -108,6 +108,5 @@ int main()
//check_fail<short>(c);
}
return boost::report_errors();
return boost::exit_success;
}
-22
View File
@@ -1,22 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/test9.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2016-2026 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)
// Test from https://github.com/boostorg/variant/pull/21
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/variant/variant.hpp>
int main() {
boost::make_variant_over<boost::fusion::vector<int, char> >::type t;
(void)t;
}
+31 -68
View File
@@ -3,15 +3,15 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2003 Eric Friedman, Itay Maman
// Copyright (c) 2014-2026 Antony Polukhin
// Copyright (c) 2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/variant/variant.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/test/minimal.hpp"
#include <iostream>
#include <sstream>
@@ -21,7 +21,7 @@
#include <vector>
#include "boost/detail/workaround.hpp"
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
# pragma warn -lvc // temporary used for parameter warning
#endif
@@ -31,38 +31,29 @@ void assert_equality_comparable(
)
{
// identity check
BOOST_TEST( !(&x == &y) || (x == y) );
BOOST_TEST( !(&x == &z) || (x == z) );
BOOST_TEST( !(&y == &z) || (y == z) );
BOOST_TEST( !(&x == &y) || !(x != y) );
BOOST_TEST( !(&x == &z) || !(x != z) );
BOOST_TEST( !(&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_TEST( (x == x) );
BOOST_TEST( (y == y) );
BOOST_TEST( (z == z) );
BOOST_CHECK( (x == x) );
BOOST_CHECK( (y == y) );
BOOST_CHECK( (z == z) );
// symmetry check
BOOST_TEST( !(x == y) || (y == x) );
BOOST_TEST( !(y == x) || (x == y) );
BOOST_TEST( (x != y) || (y == x) );
BOOST_TEST( (y != x) || (x == y) );
BOOST_CHECK( !(x == y) || (y == x) );
BOOST_CHECK( !(y == x) || (x == y) );
BOOST_TEST( !(x == z) || (z == x) );
BOOST_TEST( !(z == x) || (x == z) );
BOOST_TEST( (x != z) || (z == x) );
BOOST_TEST( (z != x) || (x == z) );
BOOST_CHECK( !(x == z) || (z == x) );
BOOST_CHECK( !(z == x) || (x == z) );
BOOST_TEST( !(y == z) || (z == y) );
BOOST_TEST( !(z == y) || (y == z) );
BOOST_TEST( (y != z) || (z == y) );
BOOST_TEST( (z != y) || (y == z) );
BOOST_CHECK( !(y == z) || (z == y) );
BOOST_CHECK( !(z == y) || (y == z) );
// transitivity check
BOOST_TEST( !(x == y && y == z) || (x == z) );
BOOST_TEST( !(x == z && z == y) || (x == y) );
BOOST_TEST( !(y == z && z == x) || (y == x) );
BOOST_CHECK( !(x == y && y == z) || (x == z) );
BOOST_CHECK( !(x == z && z == y) || (x == y) );
BOOST_CHECK( !(y == z && z == x) || (y == x) );
}
template <typename T>
@@ -71,41 +62,19 @@ void assert_less_than_comparable(
)
{
// irreflexivity check
BOOST_TEST( !(x < x) );
BOOST_TEST( !(y < y) );
BOOST_TEST( !(z < z) );
BOOST_TEST( !(x > x) );
BOOST_TEST( !(y > y) );
BOOST_TEST( !(z > z) );
BOOST_TEST( (x <= x) );
BOOST_TEST( (y <= y) );
BOOST_TEST( (z <= z) );
BOOST_TEST( (x >= x) );
BOOST_TEST( (y >= y) );
BOOST_TEST( (z >= z) );
BOOST_CHECK( !(x < x) );
BOOST_CHECK( !(y < y) );
BOOST_CHECK( !(z < z) );
// transitivity check
BOOST_TEST( (x < y) );
BOOST_TEST( (y < z) );
BOOST_TEST( (x < z) );
BOOST_TEST( (x <= y) );
BOOST_TEST( (y <= z) );
BOOST_TEST( (x <= z) );
BOOST_TEST( (z > y) );
BOOST_TEST( (y > x) );
BOOST_TEST( (z > x) );
BOOST_TEST( (z >= y) );
BOOST_TEST( (y >= x) );
BOOST_TEST( (z >= x) );
BOOST_CHECK( (x < y) );
BOOST_CHECK( (y < z) );
BOOST_CHECK( (x < z) );
// antisymmetry check
BOOST_TEST( !(y < x) );
BOOST_TEST( !(z < y) );
BOOST_TEST( !(z < x) );
BOOST_CHECK( !(y < x) );
BOOST_CHECK( !(z < y) );
BOOST_CHECK( !(z < x) );
}
template <typename It>
@@ -122,7 +91,7 @@ std::string print_range(It first, It last)
return result.str();
}
int main()
int test_main(int , char* [])
{
typedef boost::variant<int, std::string> var_t;
@@ -146,13 +115,7 @@ int main()
std::sort(vec.begin(), vec.end());
std::string sort_result( print_range(vec.begin(), vec.end()) );
BOOST_TEST( sort_result == "3 5 goodbye hello " );
BOOST_CHECK( sort_result == "3 5 goodbye hello " );
// https://svn.boost.org/trac/boost/ticket/11751
int a = 0, b = 0;
boost::variant< int& > v (a), u (b);
BOOST_TEST(v == u);
return boost::report_errors();
return boost::exit_success;
}
-417
View File
@@ -1,417 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/variant_get_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2014-2026 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)
#ifdef _MSC_VER
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable: 4181) // qualifier applied to reference type; ignored
#endif
#include "boost/variant/get.hpp"
#include "boost/variant/variant.hpp"
#include "boost/variant/polymorphic_get.hpp"
#include "boost/variant/recursive_wrapper.hpp"
#include "boost/core/lightweight_test.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 TypeInVariant, 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<TypeInVariant, TestType>::value;
const bool ref_same = !!boost::is_same<TypeInVariant, ref_test_t>::value;
if (exact_same || ref_same) {
BOOST_TEST(boost::polymorphic_get<TestType>(v));
BOOST_TEST(boost::polymorphic_get<const TestType>(v));
BOOST_TEST(boost::polymorphic_strict_get<TestType>(v));
BOOST_TEST(boost::polymorphic_strict_get<const TestType>(v));
BOOST_TEST(boost::polymorphic_relaxed_get<TestType>(v));
BOOST_TEST(boost::polymorphic_relaxed_get<const TestType>(v));
BOOST_TEST(boost::polymorphic_get<cref_test_t>(v));
BOOST_TEST(boost::polymorphic_strict_get<cref_test_t>(v));
BOOST_TEST(boost::polymorphic_relaxed_get<cref_test_t>(v));
if (ref_same) {
BOOST_TEST(boost::polymorphic_get<ref_test_t>(v));
BOOST_TEST(boost::polymorphic_get<cref_test_t>(v));
BOOST_TEST(boost::polymorphic_strict_get<ref_test_t>(v));
BOOST_TEST(boost::polymorphic_strict_get<cref_test_t>(v));
BOOST_TEST(boost::polymorphic_relaxed_get<ref_test_t>(v));
BOOST_TEST(boost::polymorphic_relaxed_get<cref_test_t>(v));
}
} else {
BOOST_TEST(!boost::polymorphic_get<TestType>(v));
BOOST_TEST(!boost::polymorphic_get<const TestType>(v));
BOOST_TEST(!boost::polymorphic_strict_get<TestType>(v));
BOOST_TEST(!boost::polymorphic_strict_get<const TestType>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<TestType>(v));
BOOST_TEST(!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_TEST(boost::get<TestType>(v));
BOOST_TEST(boost::get<const TestType>(v));
BOOST_TEST(boost::strict_get<TestType>(v));
BOOST_TEST(boost::strict_get<const TestType>(v));
BOOST_TEST(boost::relaxed_get<TestType>(v));
BOOST_TEST(boost::relaxed_get<const TestType>(v));
BOOST_TEST(boost::get<cref_test_t>(v));
BOOST_TEST(boost::strict_get<cref_test_t>(v));
BOOST_TEST(boost::relaxed_get<cref_test_t>(v));
if (ref_same) {
BOOST_TEST(boost::get<ref_test_t>(v));
BOOST_TEST(boost::get<cref_test_t>(v));
BOOST_TEST(boost::strict_get<ref_test_t>(v));
BOOST_TEST(boost::strict_get<cref_test_t>(v));
BOOST_TEST(boost::relaxed_get<ref_test_t>(v));
BOOST_TEST(boost::relaxed_get<cref_test_t>(v));
}
} else {
BOOST_TEST(!boost::get<TestType>(v));
BOOST_TEST(!boost::get<const TestType>(v));
BOOST_TEST(!boost::strict_get<TestType>(v));
BOOST_TEST(!boost::strict_get<const TestType>(v));
BOOST_TEST(!boost::relaxed_get<TestType>(v));
BOOST_TEST(!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_TEST(!boost::relaxed_get<short>(v));
BOOST_TEST(!boost::relaxed_get<const short>(v));
BOOST_TEST(!boost::relaxed_get<char>(v));
BOOST_TEST(!boost::relaxed_get<char*>(v));
BOOST_TEST(!boost::relaxed_get<bool>(v));
BOOST_TEST(!boost::relaxed_get<const bool>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<short>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<const short>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<char>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<char*>(v));
BOOST_TEST(!boost::polymorphic_relaxed_get<bool>(v));
BOOST_TEST(!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
bool is_ref = boost::is_lvalue_reference<T>::value;
(void)is_ref;
if (!is_ref) {
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);
check_get_on_types<int&>(&v);
base b;
var_ref_t v1(b);
check_get_on_types<base>(&v1);
check_get_on_types<base&>(&v1);
derived1 d1;
var_ref_t v2(d1);
check_get_on_types<derived1>(&v2);
check_get_on_types<derived1&>(&v2);
derived2 d2;
var_ref_t v3(d2);
check_get_on_types<derived2>(&v3);
check_get_on_types<derived2&>(&v3);
std::string s("Hello");
var_ref_t v4(s);
check_get_on_types<std::string>(&v4);
check_get_on_types<std::string&>(&v4);
}
inline void get_cref_test()
{
int i = 0;
var_cref_t v(i);
BOOST_TEST(boost::get<const int>(&v));
BOOST_TEST(boost::get<const int&>(&v));
BOOST_TEST(!boost::get<const base>(&v));
base b;
var_cref_t v1(b);
BOOST_TEST(boost::get<const base>(&v1));
BOOST_TEST(!boost::get<const derived1>(&v1));
BOOST_TEST(!boost::get<const int>(&v1));
std::string s("Hello");
const var_cref_t v4 = s;
BOOST_TEST(boost::get<const std::string>(&v4));
BOOST_TEST(!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_TEST((holds_element<T, const int>::value));
BOOST_TEST((!holds_element<T, short>::value));
BOOST_TEST((!holds_element<T, short>::value));
BOOST_TEST((!holds_element<T, const short>::value));
BOOST_TEST((!holds_element<T, char*>::value));
BOOST_TEST((!holds_element<T, const char*>::value));
BOOST_TEST((!holds_element<T, char[5]>::value));
BOOST_TEST((!holds_element<T, const char[5]>::value));
BOOST_TEST((!holds_element<T, bool>::value));
BOOST_TEST((!holds_element<T, const bool>::value));
BOOST_TEST((!holds_element<T, boost::recursive_wrapper<int> >::value));
BOOST_TEST((!holds_element<T, boost::recursive_wrapper<short> >::value));
BOOST_TEST((!holds_element<T, boost::detail::reference_content<short> >::value));
BOOST_TEST((holds_element_polymorphic<T, const int>::value));
BOOST_TEST((!holds_element_polymorphic<T, short>::value));
BOOST_TEST((!holds_element_polymorphic<T, short>::value));
BOOST_TEST((!holds_element_polymorphic<T, const short>::value));
BOOST_TEST((!holds_element_polymorphic<T, char*>::value));
BOOST_TEST((!holds_element_polymorphic<T, const char*>::value));
BOOST_TEST((!holds_element_polymorphic<T, char[5]>::value));
BOOST_TEST((!holds_element_polymorphic<T, const char[5]>::value));
BOOST_TEST((!holds_element_polymorphic<T, bool>::value));
BOOST_TEST((!holds_element_polymorphic<T, const bool>::value));
BOOST_TEST((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
BOOST_TEST((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
BOOST_TEST((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
}
inline void check_that_does_not_exist()
{
using namespace boost::detail::variant;
BOOST_TEST((holds_element<var_t, int>::value));
BOOST_TEST((holds_element<var_ref_t, int>::value));
BOOST_TEST((!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>();
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
class MoveonlyType {
public:
MoveonlyType() {}
~MoveonlyType() {}
MoveonlyType(MoveonlyType&&) {}
void operator=(MoveonlyType&&) {}
private:
MoveonlyType(const MoveonlyType&);
void operator=(const MoveonlyType&);
};
const boost::variant<int, std::string> foo1() { return ""; }
boost::variant<int, std::string> foo2() { return ""; }
inline void get_rvref_test()
{
boost::get<std::string>(foo1());
boost::get<std::string>(foo2());
boost::variant<MoveonlyType, int> v;
v = MoveonlyType();
boost::get<MoveonlyType>(std::move(v));
v = 3;
v = MoveonlyType();
boost::get<MoveonlyType>(v);
boost::relaxed_get<MoveonlyType&>(boost::variant<MoveonlyType, int>());
v = MoveonlyType();
MoveonlyType moved_from_variant(boost::get<MoveonlyType>(std::move(v)));
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
int main()
{
get_test();
get_test_no_fallback();
get_ref_test();
get_cref_test();
get_recursive_test();
check_that_does_not_exist();
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
get_rvref_test();
#endif
return boost::report_errors();
}
-156
View File
@@ -1,156 +0,0 @@
//-----------------------------------------------------------------------------
// boost-libs variant/test/variant_multivisit_test.cpp source file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2013-2026 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/core/lightweight_test.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> variant5_t;
struct test_visitor: boost::static_visitor<> {
// operators that shall not be called
template <class T1, class T2, class T3>
void operator()(T1&, T2&, T3&) const
{
BOOST_TEST(false);
}
template <class T1, class T2, class T3, class T4>
void operator()(T1&, T2&, T3&, T4&) const
{
BOOST_TEST(false);
}
template <class T1, class T2, class T3, class T4, class T5>
void operator()(T1&, T2&, T3&, T4&, T5&) const
{
BOOST_TEST(false);
}
// operators that are OK to call
void operator()(char v0, unsigned char v1, signed char v2) const
{
BOOST_TEST(v0 == 0);
BOOST_TEST(v1 == 1);
BOOST_TEST(v2 == 2);
}
void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const
{
BOOST_TEST(v0 == 0);
BOOST_TEST(v1 == 1);
BOOST_TEST(v2 == 2);
BOOST_TEST(v3 == 3);
}
void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const
{
BOOST_TEST(v0 == 0);
BOOST_TEST(v1 == 1);
BOOST_TEST(v2 == 2);
BOOST_TEST(v3 == 3);
BOOST_TEST(v4 == 4);
}
// Noncopyables
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
BOOST_TEST(true);
}
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
BOOST_TEST(true);
}
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
BOOST_TEST(true);
}
void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
BOOST_TEST(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 T0, class T1, class T2>
arithmetics_t operator()(T0 b, T1 v1, T2 v2) const {
if (!!b) {
return v1;
} else {
return v2;
}
}
};
int main()
{
test_visitor v;
variant5_t v_array5[5];
v_array5[0] = char(0);
v_array5[1] = static_cast<unsigned char>(1);
v_array5[2] = static_cast<signed char>(2);
v_array5[3] = static_cast<unsigned short>(3);
v_array5[4] = static_cast<int>(4);
boost::apply_visitor(v, v_array5[0], v_array5[1], v_array5[2]);
boost::apply_visitor(test_visitor(), v_array5[0], v_array5[1], v_array5[2]);
// Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
//#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
#ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
boost::apply_visitor(v, v_array5[0], v_array5[1], v_array5[2], v_array5[3]);
boost::apply_visitor(test_visitor(), v_array5[0], v_array5[1], v_array5[2], v_array5[3]);
boost::apply_visitor(v, v_array5[0], v_array5[1], v_array5[2], v_array5[3], v_array5[4]);
boost::apply_visitor(test_visitor(), v_array5[0], v_array5[1], v_array5[2], v_array5[3], v_array5[4]);
#endif
bool_like_t v0(1), v1(true), v2(1.0);
BOOST_TEST(
boost::apply_visitor(if_visitor(), v0, v1, v2)
==
arithmetics_t(true)
);
if_visitor if_vis;
BOOST_TEST(
boost::apply_visitor(if_vis)(v0, v1, v2)
==
arithmetics_t(true)
);
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::report_errors();
}

Some files were not shown because too many files have changed in this diff Show More