Compare commits

..

136 Commits

Author SHA1 Message Date
Antony Polukhin 464cca5bfa Merge pull request #19 from joto/patch-1
fix typo
2016-02-03 20:01:11 +03:00
Jochen Topf 32732fac1f fix typo 2016-02-02 09:31:44 +01:00
Antony Polukhin d2db11c5a4 Merge pull request #18 from jakobandersen/develop
Missing include in recursive_wrapper_fwd.hpp.
2015-12-30 00:20:26 +04:00
Jakob Lykke Andersen 29db6e3e21 Fix compilation error due to missing include.
Add include for mpl::true_/false_.
2015-12-25 19:05:15 +01:00
Antony Polukhin 5cfa5fcf87 Modernize .travis.yml 2015-12-18 22:10:18 +03:00
Antony Polukhin ec32d3c1c8 Fixed some warnings in test 2015-12-14 19:15:49 +03:00
Antony Polukhin 9807275140 Merge pull request #17 from jzmaddock/patch-4
Workaround for Oracle C++ compiler
2015-09-12 21:26:11 +04:00
Antony Polukhin 1da1f36c3e Merge pull request #16 from jzmaddock/type_traits_fix
Remove files which use deprecated type_traits features, and aren't in…
2015-09-12 19:17:04 +04:00
Antony Polukhin 73645c78b4 Travis fix 2015-08-22 19:45:09 +03:00
Antony Polukhin c8c769eeb8 Install valgrind in travisci runs 2015-08-22 16:24:53 +03:00
Antony Polukhin 81218d0f60 Fix travis build 2015-08-22 12:54:36 +03:00
Antony Polukhin d80f9b7f15 TravisCI now runs using valgrind 2015-08-22 12:24:37 +03:00
jzmaddock c3ee00a45e Workaround for Oracle C++ compiler 2015-08-20 13:34:11 +01:00
jzmaddock 3404daa2fa Remove files which use deprecated type_traits features, and aren't included by anything else anyway. 2015-07-25 11:58:55 +01:00
Antony Polukhin 1de9d246c0 Quckfix for C++14 tests 2015-06-26 00:53:21 +03:00
Antony Polukhin 0b9cb5792b Fixed some warnings in tests 2015-06-22 00:26:10 +03:00
Antony Polukhin aad58b5fe5 Fix issue with detection of result_type in has_result_type trait when result_type is a reference (refs track 11251,11285) 2015-06-17 21:25:11 +03:00
Antony Polukhin 34e2a9dec8 Relax compile time checks for all the 'get' functions and add more tests 2015-06-17 00:42:42 +03:00
Antony Polukhin 2b2cc6543c Fix error with missing include, that was found by Maarten de Vries 2015-05-10 21:53:27 +03:00
Antony Polukhin 3d4b1ed964 More RTTI off tests and make sure that all the tests pass with RTTI off 2015-04-25 15:06:39 +03:00
Antony Polukhin 7a0b343681 Merge pull request #12 from eldiener/develop
Removed reliance on deprecated type_traits header
2015-04-15 10:46:07 +04:00
Edward Diener a9049106d7 Removed reliance on deprecated type_traits header 2015-04-02 12:26:22 -04:00
Antony Polukhin 5c9b7b0105 Fix typo in docs 2015-03-09 14:47:10 +03:00
Antony Polukhin da6494128d Do check result type detection for delayed visitation ONLY if variadic templates are available 2015-02-11 12:05:47 +03:00
Antony Polukhin b38a79116e Merge branch 'develop' into alexhenrie-master 2015-01-31 18:03:23 +03:00
Alex Henrie 812f62ba79 Correct spelling of "suppress" and "ensure" 2015-01-30 15:25:40 -07:00
Antony Polukhin 1cec2c9e93 Disable variadic templates for MSVC-14 because of compiler implementation bugs 2015-01-27 16:11:40 +03:00
Antony Polukhin e00c75c20d Continue fixes, pointed out by Adam Wulkiewicz: removed unnecessary reference_content.hpp include, added missing static_assert.hpp include 2015-01-08 14:06:59 +03:00
Antony Polukhin adfd722858 Merge pull request #9 from awulkiew/fix/get
Your fix seems right. `resursive_wrapper_fwd.hpp` is meant to be lightweight and included everywhere.
2015-01-08 13:58:13 +03:00
Antony Polukhin 57090d9209 Fix test compilation (missing header) 2015-01-04 20:19:51 +03:00
Antony Polukhin b3aedaabc4 Merge pull request #10 from awulkiew/fix/headers
Add missing header in variant.hpp
2015-01-04 19:40:48 +03:00
Adam Wulkiewicz d05232522b Add missing header in variant.hpp
because of the recent TypeTraits dependency drop in Move.
2015-01-04 15:19:55 +01:00
Adam Wulkiewicz 428433f497 Add missing headers in get.hpp and element_index.hpp 2014-12-31 16:44:47 +01:00
Antony Polukhin da89ab5633 Add test for unambiguous call to swap (refs trac #10882) 2014-12-26 16:49:31 +03:00
Antony Polukhin 1e1a81536c Fix ambiguous cal to swap (refs trac #10882) 2014-12-26 15:12:34 +03:00
Antony Polukhin 36a45459f1 Use unified travis script 2014-12-18 22:50:38 +03:00
Antony Polukhin 7c8b70cb9d Include variant_fwd.hpp to avoid issues with undefined BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES 2014-12-17 10:43:51 +03:00
Antony Polukhin 3b84e2b981 Make the variant_nonempty_check check variant behavior on different internal policies: with/without fallback type + throw/nothrow copyable + throw/nothrow movable 2014-12-12 17:01:17 +03:00
Antony Polukhin 6db01d6494 Fixed a bug with copy constructing a backup holder; changed some tests 2014-12-12 16:05:52 +03:00
Antony Polukhin a090e75efe Throw exceptions on specified assignment numer N in variant_nonempty_check and make tests run on a multiple different Ns 2014-12-12 14:22:37 +03:00
Antony Polukhin ceb56996d6 Minor improvement to the autotest script 2014-12-11 19:40:34 +03:00
Antony Polukhin 12ab1675c7 Another attempt to improve tests coverage 2014-12-11 18:46:29 +03:00
Antony Polukhin a79b3978a5 Improve tests coverage: add tests to ensure varinat is in correct state after exception in assignment of move assignemnt functions; make sure that recursive varinats swap and assign well 2014-12-11 17:47:19 +03:00
Antony Polukhin 3e9aec5371 Avoid some non essential hard for compilers tests, improve tests coverage 2014-12-11 15:21:35 +03:00
Antony Polukhin ff52de9d5a Merge branch 'master' into develop 2014-12-10 14:46:33 +03:00
Antony Polukhin e2525d1baf Merge branch 'travisci' 2014-12-10 14:45:24 +03:00
Antony Polukhin 8c385d9874 Final update of README.md 2014-12-10 14:45:00 +03:00
Antony Polukhin 1a67de834e Updated README.md 2014-12-10 14:37:55 +03:00
Antony Polukhin 4ea8838167 Updated README.md 2014-12-10 14:33:14 +03:00
Antony Polukhin cbf4bbf1b1 Apply naming recomendations from mailing list discussion: unsafe=>relaxed, safe=>strict 2014-12-10 14:03:33 +03:00
Antony Polukhin 46250fa7d2 Make polymorphic_get U type compile time checked, add more tests and improve docs. Use strict as a default policy for polymorphic_get and get (as recomended at mailing list discussions) 2014-12-10 13:32:18 +03:00
Antony Polukhin bcf506a296 Started the work on polymorphic_get to determinate sanity/safety of getting Base type. Fixed an issue with polymorphic_get<const final>. More tests, added safe_get and unsafe_get methods. Minor update of the docs 2014-12-09 20:50:18 +03:00
Antony Polukhin 1231f51501 Initial implementation of a metaprogramming function, that is capable of detecting element index in variant::types. Some tests to make sure that no old valid code was broken 2014-12-09 17:31:41 +03:00
Antony Polukhin 5cd1e3ee85 More tests and minor fixes for variadic multi visitation 2014-12-08 14:00:42 +03:00
Antony Polukhin 0231eefd43 More docs and tests for new variadic templates related features; tune apply_visitor(visitor) to use variadic templates and be suitable for visitors with any count of input opertors 2014-12-05 18:02:46 +03:00
Antony Polukhin 2770d7569e Variadic templates based multivisitors now compile, result_type is determinated automatically if required 2014-12-05 14:51:58 +03:00
Antony Polukhin 6fff67381e Merge branch 'develop' into variadic_multivisitors 2014-12-05 12:01:38 +03:00
Antony Polukhin 6db941f3dd Added missing relational operators and their docs (refs trac #10811 and #8620) 2014-12-03 20:42:10 +03:00
Antony Polukhin ecdde80ea5 Some thoughts about multivisitors based on variadic templates 2014-12-03 19:25:47 +03:00
Antony Polukhin 940cfef1f6 Simplify Multi visitation section in Tutorial (refs trac #10653) 2014-12-02 19:52:26 +03:00
Antony Polukhin adb3d5c9bb Removed deprecated advice (refs trac #10273) 2014-12-02 19:16:19 +03:00
Antony Polukhin 20c7019799 Make sure that we do not occasionally disable variadic templates for Clang (refs trac #Clang compiler defines GNUC) 2014-12-02 19:10:18 +03:00
Antony Polukhin 6e31806038 Autodetect visitation result type for binary visitors (refs svn #10837) 2014-12-02 18:59:58 +03:00
Antony Polukhin f8a29a0d2f Autodetect visitation return type for unary visitors (refs svn #10837) 2014-12-02 17:48:57 +03:00
Antony Polukhin 81ef9229fb remove executable permission from a source file 2014-11-26 11:36:12 +03:00
Antony Polukhin 21eeb2e4d4 More Coverall fixes 2014-09-18 16:59:56 +04:00
Antony Polukhin 7fc1b93794 Final fixes 2014-09-18 16:42:30 +04:00
Antony Polukhin 4352cb4c17 Attempt to improve coverage tests 1 2014-09-18 16:24:36 +04:00
Antony Polukhin 2131e0255f Attempt to improve coverage tests 2014-09-18 16:15:25 +04:00
Antony Polukhin 9ae87bfbd0 More TravisCI fixes and README improved 2014-09-18 15:24:52 +04:00
Antony Polukhin 29e6bd2c43 More TravisCI fixes 2014-09-18 15:05:20 +04:00
Antony Polukhin 4a55d87943 Script unification and minor improvements 2014-09-18 14:52:32 +04:00
Antony Polukhin ad350dde6e Script unification 2014-09-18 14:37:56 +04:00
Antony Polukhin 302afed1ba unification of script 2014-09-18 14:17:42 +04:00
Antony Polukhin 2569ca18ce Fixes 1 2014-09-18 13:56:40 +04:00
Antony Polukhin a8b920532d Fixes 2014-09-18 13:44:47 +04:00
Antony Polukhin 384ac0dd4a Do not use nedpod archive 2014-09-18 13:37:49 +04:00
Antony Polukhin 3bb91f9a39 Add travisCI integration 2014-09-18 11:48:43 +04:00
Antony Polukhin ed614a6260 Applied patches from Boost.TypeIndex 2014-09-02 12:04:27 +04:00
Antony Polukhin 30adb7fd45 Merge pull request #8 from danieljames/metadata
Create metadata file.
2014-08-18 19:54:37 +04:00
Daniel James db42afbdfa Add metadata file. 2014-08-18 15:12:28 +01:00
Antony Polukhin 8f111d3126 Fix compilation of static visitors on GCC4.5.1 2014-08-15 11:48:26 +04:00
Antony Polukhin 7c85a3a6bb Merge pull request #6 from jzmaddock/patch-2
Update Jamfile.v2
2014-08-13 22:49:01 +04:00
jzmaddock 433d3aecab Update Jamfile.v2
There can only be one project named boost/doc and we have that already under /doc/
Rename to something unique.
2014-08-13 18:39:23 +01:00
Antony Polukhin 1b50119b21 Fix issues reported by Boost Inspection Tool 2014-08-01 14:09:36 +04:00
Antony Polukhin cf3875bc22 Merge branch 'master' into develop 2014-08-01 14:07:14 +04:00
Antony Polukhin 65dae1db5a Merge branch 'develop' 2014-06-25 20:26:25 +04:00
Antony Polukhin 4ad95f185b Minor improvements related to the forced_return() function 2014-06-23 21:04:48 +04:00
Antony Polukhin 0367512bc7 Fix for pull request #4 : make it possible to return movable-only structures; reduce resulting binary size by removing duplicate BOOST_ASSERTs 2014-06-23 20:10:10 +04:00
Antony Polukhin e1a611c000 Merge branch 'develop' 2014-05-18 11:58:19 +04:00
Antony Polukhin 134dfbf46e Do not use in hash tests. Added a few more tests for variant hashing 2014-05-07 18:49:09 +04:00
Antony Polukhin 92a530a2b9 Merge branch 'develop' 2014-05-04 14:12:28 +04:00
Antony Polukhin 9bc9c1c143 Do not use variadic templates on platforms that do not have full support of that feature 2014-04-24 11:53:00 +04:00
Antony Polukhin 5398f31ea2 Merge pull request #3 from ecatmur/make-recursive-variant-variadic
Substitute recursive variant tag within variadic templates (e.g. tuple)
2014-04-11 14:20:37 +04:00
Ed Catmur e30800b534 Substitute recursive variant tag within variadic templates (e.g. tuple)
Unspecialize variadic substitute on Arity to prevent ambiguity with boost::variant<...> partial specialization in recursive_variant.hpp; add test.

Add check for BOOST_NO_CXX11_HDR_TUPLE, in case we end up with a compiler with variadic templates but no std::tuple
2014-04-11 01:47:09 +01:00
Antony Polukhin 9b04ff9221 Merge branch 'develop' 2014-02-21 15:02:39 +04:00
Antony Polukhin 7a5b0f2538 Suppress warnings and add BOOST_SYMBOL_VISIBLE to exceptions 2014-02-11 11:05:33 +04:00
Antony Polukhin 01a9630c37 Merge branch 'develop' 2014-02-04 15:23:34 +04:00
Antony Polukhin 0396d6c73d Allow rvalue-preformance-tests compilation in C++03 mode. This may be useful to measure performance of copy constructors/operators in C++03 2014-02-03 16:52:34 +04:00
Antony Polukhin 63fb3ff427 Do not use variadic templates on MSVC2013 + add some tests to make sure that Spirit metaprogramming code works well with macro from Variant 2014-01-22 11:52:03 +04:00
Antony Polukhin 0d226eb597 Create first merge point for Git 2013-12-30 18:24:43 +04:00
Antony Polukhin 464799f446 Refs #9479 (polymorphic_get for Boost.Variant) 2013-12-10 16:13:49 +04:00
Antony Polukhin f59cdef172 Fix preprocessor code that detects variadic templates usabilty 2013-12-09 12:39:10 +04:00
Antony Polukhin e20324e2c4 Updated docs and variadic templates support 2013-12-09 11:50:15 +04:00
Antony Polukhin 592e1b5339 Merge some more changes to variant that accidentaly were not merged in r86650
[SVN r86676]
2013-11-13 12:24:00 +00:00
Antony Polukhin a2523c620d Merge some changes to variant that accidentaly were not merged in r86650
[SVN r86674]
2013-11-13 12:20:05 +00:00
Antony Polukhin e70b03583f Merge from trunk:
* dropped support of antique compilers
* fixed issue with ambiguity in swap (fixes #2839)
* added conditional noexcepts to move assignments, default and move constructors (fixes #7911)
* experimental variadic templates support (refs #9163)
* bunch of size optimizations for assignments and move assignments (refs #7960)
* minor changes and size optimizations

[SVN r86650]
2013-11-12 10:16:15 +00:00
Antony Polukhin e05edc0248 Merge from trunk:
* Add some merge infos
* Fix unreachable code warning (fixes #8665)

[SVN r85882]
2013-09-25 08:04:36 +00:00
Antony Polukhin 76f2c0fc19 Merge from trunk:
* Fix issue with const rvalue references in Boost.Variant (fixes #8988)
* Get rid of Boost.Variant hand written non-usable move emulation and use Boost.Move instead(refs #7601). This does not mean that Boost.Variant supports move emulation now, but removes duplicate/non-working code and makes sure that Boost.Variant is able to work with boost::move

[SVN r85408]
2013-08-20 09:03:29 +00:00
Antony Polukhin 8507087c59 Merge from trunk:
* make the library work on exception-disabled environments (fixes #8717)
* fix compilation of Boost.Variants move assignment for situations when one of the variant template classes has nothrow copy constructor and throwing move constructor (fixes #8772)
* mark move constructor of variant with BOOST_NOEXCEPT_IF (refs #7911)

[SVN r85157]
2013-07-25 08:42:44 +00:00
Antony Polukhin f17d91a8b4 Merge from trunk GCC workaround (fixes #8651)
[SVN r84747]
2013-06-12 08:08:58 +00:00
Antony Polukhin 3e02b4963d Merge Boost.Variant from trunk
* documentation, tests and implementation of multivisitors (fixes #8459)

[SVN r84282]
2013-05-14 18:19:39 +00:00
Antony Polukhin a4eaf348ea Merge from trunk:
* Update docs of Boost.Variant. Add advice about recursive_wrapper performance (fixes #7718)

[SVN r84105]
2013-05-02 09:58:56 +00:00
Antony Polukhin 54ea9c42a1 Merge fom trunk:
* Boost.Variant now uses traits from Boost.TypeTraits instead of its own (fixes #8296)

[SVN r83544]
2013-03-24 16:18:12 +00:00
Antony Polukhin eb17a6afd8 Merge variant from trunk:
* Fix #7718 (move constructor from template type added)
 * More tests and minor bugfixes
 * Deprecated macros replaced with new ones (thanks to Marshall Clow)


[SVN r81793]
2012-12-08 15:44:16 +00:00
Antony Polukhin 3891cde7ed Merge from trunk: merge performance tests (refs #7620)
[SVN r81456]
2012-11-21 14:51:12 +00:00
Antony Polukhin 591ae9bf26 Merge from trunk: added basic rvalue support and marked some functions with BOOST_NOEXCEPT (fixes #7620)
[SVN r81455]
2012-11-21 14:47:12 +00:00
Steven Watanabe 5b34fe155f Merge Variant from the trunk.
[SVN r78341]
2012-05-05 21:22:36 +00:00
Steven Watanabe 2a6c6f3948 Merge [71083] from the trunk.
[SVN r71345]
2011-04-17 00:23:44 +00:00
Steven Watanabe c13372a092 Merge variant from the trunk.
[SVN r70798]
2011-03-31 21:08:35 +00:00
Daniel James 64d68fc379 Merge documentation fixes.
* Use `doc/src/*.css` instead of `doc/html/*.css`.
* Remove wiki and people directories.
* Some documentation fixes.
* Left out `minimal.css` changes and boostbook changes because of clashes.


[SVN r63347]
2010-06-26 12:30:09 +00:00
Steven Watanabe 19ba44bb3f Merge variant from the trunk. Fixes #1507
[SVN r62742]
2010-06-10 15:32:07 +00:00
Hartmut Kaiser 4d02fbcd84 Variant: merged fixes for MSVC warnings from trunk
[SVN r57532]
2009-11-10 02:36:45 +00:00
Troy D. Straszheim 4f4555fa93 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Daniel James e0151cc209 Add boost license info to documentation for a few libraries.
Merged revisions 55098 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55098 | danieljames | 2009-07-22 23:35:08 +0100 (Wed, 22 Jul 2009) | 8 lines
  
  Add boost license info to documentation for a few libraries.
  
    * Boost.Any: Kevlin Henney is in blanket-permission.txt
    * Boost.Variant: Eric Friedman and Itay Maman are both in blanket-permissions.txt
    * Boost.Concept: Idiana University, University of Notre Dame du Lac, Jeremy Siek,
      Lie-Quan Lee, Andrew Lumsdaine are all listed under blanket permissions.
  
    SGI and HP aren't so their license is left alone.
........


[SVN r55188]
2009-07-26 20:11:03 +00:00
Troy D. Straszheim 3bc66e9264 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Daniel James aa1eeb3b0f Support BOOST_NO_TYPEID and BOOST_NO_IOSTREAM in Boost.Variant. Fixes #3051.
Merged revisions 53682 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53682 | danieljames | 2009-06-06 12:46:24 +0100 (Sat, 06 Jun 2009) | 1 line
  
  Support BOOST_NO_TYPEID and BOOST_NO_IOSTREAM in Boost.Variant. Fixes #3051.
........


[SVN r54398]
2009-06-27 07:34:42 +00:00
Steven Watanabe a400952c16 Merge [42989] and [53187] from the trunk.
[SVN r53196]
2009-05-23 05:27:24 +00:00
John Maddock dcc25e1a1d Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
Troy D. Straszheim c7d1cccc13 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Beman Dawes 5edc863174 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes d465155ccc Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody ddf192fc53 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

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