summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/variant
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boost/libs/variant/CMakeLists.txt33
-rw-r--r--src/boost/libs/variant/README.md16
-rw-r--r--src/boost/libs/variant/index.html9
-rw-r--r--src/boost/libs/variant/meta/libraries.json17
-rw-r--r--src/boost/libs/variant/perf/Jamfile.v229
-rw-r--r--src/boost/libs/variant/perf/move_perf.cpp236
-rw-r--r--src/boost/libs/variant/test/Jamfile.v266
-rw-r--r--src/boost/libs/variant/test/auto_visitors.cpp380
-rw-r--r--src/boost/libs/variant/test/class_a.cpp65
-rw-r--r--src/boost/libs/variant/test/class_a.h40
-rw-r--r--src/boost/libs/variant/test/const_ref_apply_visitor.cpp417
-rw-r--r--src/boost/libs/variant/test/hash_recursive_variant_test.cpp73
-rw-r--r--src/boost/libs/variant/test/hash_variant_test.cpp54
-rw-r--r--src/boost/libs/variant/test/issue42.cpp61
-rw-r--r--src/boost/libs/variant/test/issue53.cpp58
-rw-r--r--src/boost/libs/variant/test/jobs.h335
-rw-r--r--src/boost/libs/variant/test/no_rvalue_to_nonconst_visitation.cpp32
-rw-r--r--src/boost/libs/variant/test/overload_selection.cpp215
-rw-r--r--src/boost/libs/variant/test/recursive_variant_test.cpp364
-rw-r--r--src/boost/libs/variant/test/recursive_wrapper_move_test.cpp78
-rw-r--r--src/boost/libs/variant/test/rvalue_test.cpp332
-rw-r--r--src/boost/libs/variant/test/test1.cpp150
-rw-r--r--src/boost/libs/variant/test/test2.cpp149
-rw-r--r--src/boost/libs/variant/test/test3.cpp134
-rw-r--r--src/boost/libs/variant/test/test4.cpp57
-rw-r--r--src/boost/libs/variant/test/test5.cpp90
-rw-r--r--src/boost/libs/variant/test/test6.cpp74
-rw-r--r--src/boost/libs/variant/test/test7.cpp255
-rw-r--r--src/boost/libs/variant/test/test8.cpp113
-rw-r--r--src/boost/libs/variant/test/test9.cpp22
-rw-r--r--src/boost/libs/variant/test/variant_comparison_test.cpp158
-rw-r--r--src/boost/libs/variant/test/variant_get_test.cpp417
-rw-r--r--src/boost/libs/variant/test/variant_multivisit_test.cpp159
-rw-r--r--src/boost/libs/variant/test/variant_nonempty_check.cpp474
-rw-r--r--src/boost/libs/variant/test/variant_over_joint_view_test.cpp64
-rw-r--r--src/boost/libs/variant/test/variant_polymorphic_get_test.cpp81
-rw-r--r--src/boost/libs/variant/test/variant_reference_test.cpp116
-rw-r--r--src/boost/libs/variant/test/variant_rvalue_get_with_ampersand_test.cpp43
-rw-r--r--src/boost/libs/variant/test/variant_swap_test.cpp90
-rw-r--r--src/boost/libs/variant/test/variant_visit_internal_linkage.cpp41
-rw-r--r--src/boost/libs/variant/test/variant_visit_test.cpp170
-rw-r--r--src/boost/libs/variant2/CMakeLists.txt21
-rw-r--r--src/boost/libs/variant2/README.md21
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark1.cpp168
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark1.md267
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark2.cpp149
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark2.md207
-rw-r--r--src/boost/libs/variant2/index.html15
-rw-r--r--src/boost/libs/variant2/meta/libraries.json14
-rw-r--r--src/boost/libs/variant2/test/Jamfile105
-rw-r--r--src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt19
-rw-r--r--src/boost/libs/variant2/test/cmake_subdir_test/quick.cpp15
-rw-r--r--src/boost/libs/variant2/test/throw_exception.cpp20
-rw-r--r--src/boost/libs/variant2/test/variant_alternative.cpp154
-rw-r--r--src/boost/libs/variant2/test/variant_convert_construct.cpp175
-rw-r--r--src/boost/libs/variant2/test/variant_convert_construct_throw.cpp95
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign_cx.cpp116
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign_throw.cpp55
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct.cpp145
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct_cx.cpp112
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct_throw.cpp69
-rw-r--r--src/boost/libs/variant2/test/variant_default_construct.cpp103
-rw-r--r--src/boost/libs/variant2/test/variant_default_construct_cx.cpp51
-rw-r--r--src/boost/libs/variant2/test/variant_destroy.cpp205
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_index.cpp181
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_index_cx.cpp136
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_type.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_type_cx.cpp91
-rw-r--r--src/boost/libs/variant2/test/variant_eq_ne.cpp92
-rw-r--r--src/boost/libs/variant2/test/variant_eq_ne_cx.cpp98
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_index.cpp349
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_index_cx.cpp96
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_type.cpp307
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_type_cx.cpp90
-rw-r--r--src/boost/libs/variant2/test/variant_holds_alternative.cpp78
-rw-r--r--src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp43
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_index_construct.cpp138
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp116
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_type_construct.cpp134
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp110
-rw-r--r--src/boost/libs/variant2/test/variant_lt_gt.cpp85
-rw-r--r--src/boost/libs/variant2/test/variant_lt_gt_cx.cpp91
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign_cx.cpp107
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign_throw.cpp55
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct.cpp146
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct_cx.cpp104
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct_throw.cpp69
-rw-r--r--src/boost/libs/variant2/test/variant_size.cpp104
-rw-r--r--src/boost/libs/variant2/test/variant_subset.cpp159
-rw-r--r--src/boost/libs/variant2/test/variant_swap.cpp259
-rw-r--r--src/boost/libs/variant2/test/variant_value_assign.cpp206
-rw-r--r--src/boost/libs/variant2/test/variant_value_assign_cx.cpp106
-rw-r--r--src/boost/libs/variant2/test/variant_value_construct.cpp124
-rw-r--r--src/boost/libs/variant2/test/variant_value_construct_cx.cpp109
-rw-r--r--src/boost/libs/variant2/test/variant_valueless.cpp260
-rw-r--r--src/boost/libs/variant2/test/variant_visit.cpp126
98 files changed, 12819 insertions, 0 deletions
diff --git a/src/boost/libs/variant/CMakeLists.txt b/src/boost/libs/variant/CMakeLists.txt
new file mode 100644
index 00000000..1984c195
--- /dev/null
+++ b/src/boost/libs/variant/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright 2019 Mike Dev
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
+#
+# NOTE: CMake support for Boost.Variant is currently experimental at best
+# and the interface is likely to change in the future
+
+cmake_minimum_required( VERSION 3.5 )
+project( BoostVariant LANGUAGES CXX )
+
+add_library( boost_variant INTERFACE )
+add_library( Boost::variant ALIAS boost_variant )
+
+target_include_directories( boost_variant INTERFACE include )
+
+target_link_libraries( boost_variant
+ INTERFACE
+ Boost::assert
+ Boost::bind
+ Boost::config
+ Boost::container_hash
+ Boost::core
+ Boost::detail
+ Boost::integer
+ Boost::move
+ Boost::mpl
+ Boost::preprocessor
+ Boost::static_assert
+ Boost::throw_exception
+ Boost::type_index
+ Boost::type_traits
+ Boost::utility
+)
diff --git a/src/boost/libs/variant/README.md b/src/boost/libs/variant/README.md
new file mode 100644
index 00000000..f66db24a
--- /dev/null
+++ b/src/boost/libs/variant/README.md
@@ -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/boostorg/variant.svg?branch=develop)](https://travis-ci.org/boostorg/variant) [![Build status](https://ci.appveyor.com/api/projects/status/bijfdoy7byfgc6e2/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/variant-ykfti/branch/develop) | [![Coverage Status](https://coveralls.io/repos/boostorg/variant/badge.png?branch=develop)](https://coveralls.io/r/apolukhin/variant?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/variant.html)
+Master branch: | [![Build Status](https://travis-ci.org/boostorg/variant.svg?branch=master)](https://travis-ci.org/boostorg/variant) [![Build status](https://ci.appveyor.com/api/projects/status/bijfdoy7byfgc6e2/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/variant-ykfti/branch/master) | [![Coverage Status](https://coveralls.io/repos/boostorg/variant/badge.png?branch=master)](https://coveralls.io/r/apolukhin/variant?branch=master) | [details...](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).
diff --git a/src/boost/libs/variant/index.html b/src/boost/libs/variant/index.html
new file mode 100644
index 00000000..17fc68c6
--- /dev/null
+++ b/src/boost/libs/variant/index.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../doc/html/variant.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../../doc/html/variant.html">../../doc/html/variant.html</a>
+</body>
+</html>
diff --git a/src/boost/libs/variant/meta/libraries.json b/src/boost/libs/variant/meta/libraries.json
new file mode 100644
index 00000000..e0b9a598
--- /dev/null
+++ b/src/boost/libs/variant/meta/libraries.json
@@ -0,0 +1,17 @@
+{
+ "key": "variant",
+ "name": "Variant",
+ "authors": [
+ "Eric Friedman",
+ "Itay Maman"
+ ],
+ "description": "Safe, generic, stack-based discriminated union container.",
+ "category": [
+ "Containers",
+ "Data"
+ ],
+ "maintainers": [
+ "Antony Polukhin <antoshkka -at- gmail.com>",
+ "Eric Friedman <ericbrandon -at- gmail.com>"
+ ]
+}
diff --git a/src/boost/libs/variant/perf/Jamfile.v2 b/src/boost/libs/variant/perf/Jamfile.v2
new file mode 100644
index 00000000..302f2ef2
--- /dev/null
+++ b/src/boost/libs/variant/perf/Jamfile.v2
@@ -0,0 +1,29 @@
+#==============================================================================
+# Copyright (c) 2012-2019 Antony Polukhin
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#==============================================================================
+
+# performance tests
+import testing ;
+import path ;
+
+path-constant TEST_DIR : . ;
+
+project performance/test
+ : source-location ./
+ : requirements
+# <library>/boost/chrono//boost_chrono
+# <library>/boost/system//boost_system
+ <link>static
+ <target-os>freebsd:<linkflags>"-lrt"
+ <target-os>linux:<linkflags>"-lrt"
+ <toolset>gcc:<cxxflags>-fvisibility=hidden
+ <toolset>intel-linux:<cxxflags>-fvisibility=hidden
+ <toolset>sun:<cxxflags>-xldscope=hidden
+ : default-build release
+ ;
+
+run move_perf.cpp : $(TEST_DIR) ;
+
diff --git a/src/boost/libs/variant/perf/move_perf.cpp b/src/boost/libs/variant/perf/move_perf.cpp
new file mode 100644
index 00000000..efdd31d0
--- /dev/null
+++ b/src/boost/libs/variant/perf/move_perf.cpp
@@ -0,0 +1,236 @@
+// (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)
+
+// See http://www.boost.org/libs/config for most recent version.
+
+//
+// Testing variant performance rvalue copy/assign performance
+//
+
+#define BOOST_ERROR_CODE_HEADER_ONLY
+#define BOOST_CHRONO_HEADER_ONLY
+#include <boost/chrono.hpp>
+
+#include <boost/variant.hpp>
+#include <string>
+#include <vector>
+
+ struct scope {
+ typedef boost::chrono::steady_clock test_clock;
+ typedef boost::chrono::milliseconds duration_t;
+ test_clock::time_point start_;
+ const char* const message_;
+
+ explicit scope(const char* const message)
+ : start_(test_clock::now())
+ , message_(message)
+ {}
+
+ ~scope() {
+ std::cout << message_ << " " << boost::chrono::duration_cast<duration_t>(test_clock::now() - start_) << std::endl;
+ }
+ };
+
+
+
+static void do_test(bool do_count_cleanup_time = false) {
+ BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
+ typedef std::vector<char> str_t;
+ typedef boost::variant<int, str_t, float> var_t;
+
+ const char hello1_c[] = "hello long word";
+ const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));
+
+ const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
+ const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));
+
+ if (do_count_cleanup_time) {
+ std::cout << "#############################################\n";
+ std::cout << "#############################################\n";
+ std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
+ std::cout << "#############################################\n";
+ }
+
+ std::vector<var_t> data_from, data_to;
+ data_from.resize(c_run_count, hello1);
+ data_to.reserve(c_run_count);
+ {
+ scope sc("boost::variant(const variant&) copying speed");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to.push_back(data_from[i]);
+
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ data_from.resize(c_run_count, hello1);
+ data_to.clear();
+ data_to.reserve(c_run_count);
+ {
+ scope sc("boost::variant(variant&&) moving speed");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to.push_back(boost::move(data_from[i]));
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ std::cout << "#############################################\n";
+
+ data_from.clear();
+ data_from.resize(c_run_count, hello2);
+ data_to.clear();
+ data_to.resize(c_run_count, hello2);
+ {
+ scope sc("boost::variant=(const variant&) copying speed on same types");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = data_from[i];
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ data_from.resize(c_run_count, hello2);
+ data_to.clear();
+ data_to.resize(c_run_count, hello2);
+ {
+ scope sc("boost::variant=(variant&&) moving speed on same types");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = boost::move(data_from[i]);
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ std::cout << "#############################################\n";
+
+ data_from.clear();
+ data_from.resize(c_run_count, hello2);
+
+ data_to.clear();
+ data_to.resize(c_run_count, var_t(0));
+ {
+ scope sc("boost::variant=(const variant&) copying speed on different types");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = data_from[i];
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ data_from.resize(c_run_count, hello2);
+ data_to.clear();
+ data_to.resize(c_run_count, var_t(0));
+ {
+ scope sc("boost::variant=(variant&&) moving speed on different types");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = boost::move(data_from[i]);
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ std::cout << "#############################################\n";
+
+ data_from.clear();
+ data_from.resize(c_run_count, var_t(0));
+
+ data_to.clear();
+ data_to.resize(c_run_count, hello2);
+ {
+ scope sc("boost::variant=(const variant&) copying speed on different types II");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = data_from[i];
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+ data_from.resize(c_run_count, var_t(0));
+ data_to.clear();
+ data_to.resize(c_run_count, hello2);
+ {
+ scope sc("boost::variant=(variant&&) moving speed on different types II");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = boost::move(data_from[i]);
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ data_from.clear();
+ }
+ }
+
+
+ std::cout << "#############################################\n";
+
+ std::vector<str_t> s1(c_run_count, hello2);
+ data_to.clear();
+ data_to.resize(c_run_count, var_t(0));
+
+ {
+ scope sc("boost::variant=(const T&) copying speed");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = s1[i];
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ s1.clear();
+ }
+ }
+
+ std::vector<str_t> s2(c_run_count, hello2);
+ data_to.clear();
+ data_to.resize(c_run_count, var_t(0));
+ {
+ scope sc("boost::variant=(T&&) moving speed");
+ for (std::size_t i = 0; i < c_run_count; ++i) {
+ data_to[i] = boost::move(s2[i]);
+ }
+
+ if (do_count_cleanup_time) {
+ data_to.clear();
+ s2.clear();
+ }
+ }
+}
+
+
+int main () {
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ std::cout << "# Running tests in C++11 mode (with rvalues).\n";
+#else
+ std::cout << "# Running tests in C++03 mode (without rvalues).\n";
+#endif
+
+ do_test(false);
+ do_test(true);
+}
+
+
diff --git a/src/boost/libs/variant/test/Jamfile.v2 b/src/boost/libs/variant/test/Jamfile.v2
new file mode 100644
index 00000000..a2fe7383
--- /dev/null
+++ b/src/boost/libs/variant/test/Jamfile.v2
@@ -0,0 +1,66 @@
+# Boost.Variant Library test Jamfile
+#
+# Copyright (C) 2003, Eric Friedman, Itay Maman.
+# Copyright (C) 2013-2019 Antony Polukhin.
+#
+# Use, modification and distribution is subject to the Boost Software License,
+# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import testing ;
+
+local below-c++14 = 98 03 0x 11 ;
+
+project
+ : requirements
+ <toolset>msvc:<asynch-exceptions>on
+ ;
+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 ]
+ [ run test6.cpp : : : : variant_test6 ]
+ [ run test7.cpp : : : : variant_test7 ]
+ [ run test8.cpp : : : : variant_test8 ]
+ [ run test9.cpp : : : : variant_test9 ]
+ [ run recursive_variant_test.cpp ]
+ [ run variant_reference_test.cpp ]
+ [ run variant_comparison_test.cpp ]
+ [ run variant_visit_internal_linkage.cpp : : : "<cxxstd>$(below-c++14)":<build>no ]
+ [ run variant_visit_test.cpp ]
+ [ run variant_get_test.cpp ]
+ [ compile-fail variant_rvalue_get_with_ampersand_test.cpp ]
+ [ compile-fail no_rvalue_to_nonconst_visitation.cpp ]
+ [ run variant_polymorphic_get_test.cpp ]
+ [ run variant_multivisit_test.cpp ]
+ [ run hash_variant_test.cpp ]
+ [ run rvalue_test.cpp ]
+ [ run variant_nonempty_check.cpp ]
+ [ run recursive_variant_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
+ <toolset>gcc-4.3:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.4:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.5:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.6:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.7:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.8:<cxxflags>-fno-exceptions
+ <toolset>clang:<cxxflags>-fno-exceptions
+ : variant_noexcept_test
+ ]
+ [ run recursive_variant_test.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : variant_no_rtti_test ]
+ [ run hash_recursive_variant_test.cpp ]
+ [ run variant_swap_test.cpp ]
+ [ run auto_visitors.cpp ]
+ [ run issue42.cpp ]
+ #[ run issue53.cpp ]
+ [ run overload_selection.cpp ]
+ [ run recursive_wrapper_move_test.cpp ]
+ [ run variant_over_joint_view_test.cpp ]
+ [ run const_ref_apply_visitor.cpp ]
+ ;
+
+
diff --git a/src/boost/libs/variant/test/auto_visitors.cpp b/src/boost/libs/variant/test/auto_visitors.cpp
new file mode 100644
index 00000000..13a2e5f5
--- /dev/null
+++ b/src/boost/libs/variant/test/auto_visitors.cpp
@@ -0,0 +1,380 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/auto_visitors.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2014-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+#include "boost/variant/multivisitors.hpp"
+#include "boost/lexical_cast.hpp"
+
+#include <boost/noncopyable.hpp>
+#include <boost/core/ignore_unused.hpp>
+
+namespace has_result_type_tests {
+ template <class T>
+ struct wrap {
+ typedef T result_type;
+ };
+
+ struct s1 : wrap<int> {};
+ struct s2 : wrap<int&> {};
+ struct s3 : wrap<const int&> {};
+ struct s4 {};
+ struct s5 : wrap<int*> {};
+ struct s6 : wrap<int**> {};
+ struct s7 : wrap<const int*> {};
+ struct s8 : wrap<boost::noncopyable> {};
+ struct s9 : wrap<boost::noncopyable&> {};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ struct s10 : wrap<boost::noncopyable&&> {};
+#endif
+ struct s11 : wrap<const boost::noncopyable&> {};
+ struct s12 : wrap<const boost::noncopyable*> {};
+ struct s13 : wrap<boost::noncopyable*> {};
+ struct s14 { typedef int result_type; };
+ struct s15 { typedef int& result_type; };
+ struct s16 { typedef const int& result_type; };
+}
+
+
+void test_has_result_type_triat() {
+ using namespace has_result_type_tests;
+ using boost::detail::variant::has_result_type;
+
+ BOOST_TEST(has_result_type<s1>::value);
+ BOOST_TEST(has_result_type<s2>::value);
+ BOOST_TEST(has_result_type<s3>::value);
+ BOOST_TEST(!has_result_type<s4>::value);
+ BOOST_TEST(has_result_type<s5>::value);
+ BOOST_TEST(has_result_type<s6>::value);
+ BOOST_TEST(has_result_type<s7>::value);
+ BOOST_TEST(has_result_type<s8>::value);
+ BOOST_TEST(has_result_type<s9>::value);
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_TEST(has_result_type<s10>::value);
+#endif
+ BOOST_TEST(has_result_type<s11>::value);
+ BOOST_TEST(has_result_type<s12>::value);
+ BOOST_TEST(has_result_type<s13>::value);
+ BOOST_TEST(has_result_type<s14>::value);
+ BOOST_TEST(has_result_type<s15>::value);
+ BOOST_TEST(has_result_type<s16>::value);
+}
+
+struct lex_streamer_explicit: boost::static_visitor<std::string> {
+ template <class T>
+ const char* operator()(const T& ) {
+ return "10";
+ }
+
+ template <class T1, class T2>
+ const char* operator()(const T1& , const T2& ) {
+ return "100";
+ }
+};
+
+
+void run_explicit()
+{
+ typedef boost::variant<int, std::string, double> variant_type;
+ variant_type v2("10"), v1("100");
+
+ lex_streamer_explicit visitor_ref;
+
+ // Must return instance of std::string
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v2).c_str() == std::string("10"));
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1).c_str() == std::string("100"));
+}
+
+
+// Most part of tests from this file require decltype(auto)
+
+#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO
+
+void run()
+{
+ BOOST_TEST(true);
+}
+
+void run2()
+{
+ BOOST_TEST(true);
+}
+
+
+void run3()
+{
+ BOOST_TEST(true);
+}
+
+#else
+
+#include <iostream>
+
+struct lex_streamer {
+ template <class T>
+ std::string operator()(const T& val) const {
+ return boost::lexical_cast<std::string>(val);
+ }
+};
+
+struct lex_streamer_void {
+ template <class T>
+ void operator()(const T& val) const {
+ std::cout << val << std::endl;
+ }
+
+
+ template <class T1, class T2>
+ void operator()(const T1& val, const T2& val2) const {
+ std::cout << val << '+' << val2 << std::endl;
+ }
+
+
+ template <class T1, class T2, class T3>
+ void operator()(const T1& val, const T2& val2, const T3& val3) const {
+ std::cout << val << '+' << val2 << '+' << val3 << std::endl;
+ }
+};
+
+
+struct lex_streamer2 {
+ std::string res;
+
+ template <class T>
+ const char* operator()(const T& /*val*/) const {
+ return "fail";
+ }
+
+ template <class T1, class T2>
+ const char* operator()(const T1& /*v1*/, const T2& /*v2*/) const {
+ return "fail2";
+ }
+
+
+ template <class T1, class T2, class T3>
+ const char* operator()(const T1& /*v1*/, const T2& /*v2*/, const T3& /*v3*/) const {
+ return "fail3";
+ }
+
+ template <class T>
+ std::string& operator()(const T& val) {
+ res = boost::lexical_cast<std::string>(val);
+ return res;
+ }
+
+
+ template <class T1, class T2>
+ std::string& operator()(const T1& v1, const T2& v2) {
+ res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2);
+ return res;
+ }
+
+
+ template <class T1, class T2, class T3>
+ std::string& operator()(const T1& v1, const T2& v2, const T3& v3) {
+ res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2)
+ + "+" + boost::lexical_cast<std::string>(v3);
+ return res;
+ }
+};
+
+#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+# define BOOST_TEST_IF_HAS_VARIADIC(x) BOOST_TEST(x)
+#else
+# define BOOST_TEST_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_TEST(boost::apply_visitor(lex_streamer(), v1) == "1");
+ BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v1) == "1");
+ BOOST_TEST(boost::apply_visitor(lex_streamer(), v2) == "10");
+ BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v2) == "10");
+
+ #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
+ BOOST_TEST(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v1) == "1");
+ BOOST_TEST(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v2) == "10");
+
+ // Retun type must be the same in all instances, so this code does not compile
+ //boost::variant<int, short, unsigned> v_diff_types(1);
+ //BOOST_TEST(boost::apply_visitor([](auto v) { return v; }, v_diff_types) == 1);
+
+ boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v1);
+ boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v2);
+ #endif
+
+ lex_streamer2 visitor_ref;
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v1) == "1");
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v2) == "10");
+#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+ std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1);
+ BOOST_TEST(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_TEST(boost::apply_visitor(lex_combine(), v1, v2) == "1+10");
+ BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1) == "10+1");
+ BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_combine_visitor)(v2, v1) == "10+1");
+
+
+ #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
+ BOOST_TEST(
+ boost::apply_visitor(
+ [](auto v1, auto v2) {
+ return boost::lexical_cast<std::string>(v1) + "+"
+ + boost::lexical_cast<std::string>(v2);
+ }
+ , v1
+ , v2
+ ) == "1+10"
+ );
+ BOOST_TEST(
+ boost::apply_visitor(
+ [](auto v1, auto v2) {
+ return boost::lexical_cast<std::string>(v1) + "+"
+ + boost::lexical_cast<std::string>(v2);
+ }
+ , v2
+ , v1
+ ) == "10+1"
+ );
+
+ boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v1, v2);
+ boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v2, v1);
+ #endif
+
+
+ lex_streamer2 visitor_ref;
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1) == "10+1");
+#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+ std::string& ref_to_string = boost::apply_visitor(visitor_ref)(v1, v2);
+ BOOST_TEST(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_TEST_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_TEST(boost::apply_visitor(lex_combine(), v1, v2, v3) == "1+10+100");
+ BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1, v3) == "10+1+100");
+ BOOST_TEST(boost::apply_visitor(lex_combine_visitor)(v2, v1, v3) == "10+1+100");
+
+
+ #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
+ BOOST_TEST(
+ boost::apply_visitor(
+ [](auto v1, auto v2, auto v3) {
+ return boost::lexical_cast<std::string>(v1) + "+"
+ + boost::lexical_cast<std::string>(v2) + "+"
+ + boost::lexical_cast<std::string>(v3);
+ }
+ , v1
+ , v2
+ , v3
+ ) == "1+10+100"
+ );
+ BOOST_TEST(
+ boost::apply_visitor(
+ [](auto v1, auto v2, auto v3) {
+ return boost::lexical_cast<std::string>(v1) + "+"
+ + boost::lexical_cast<std::string>(v2) + "+"
+ + boost::lexical_cast<std::string>(v3);
+ }
+ , v3
+ , v1
+ , v3
+ ) == "100+1+100"
+ );
+
+ boost::apply_visitor(
+ [](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
+ v1, v2, v3
+ );
+ boost::apply_visitor(
+ [](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
+ v2, v1, v3
+ );
+ #endif
+
+
+ lex_streamer2 visitor_ref;
+ BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
+ BOOST_TEST(boost::apply_visitor(visitor_ref)(v2, v1) == "10+1");
+ std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1, v2);
+ BOOST_TEST(ref_to_string == "1+10");
+
+ lex_streamer_void lex_streamer_void_visitor;
+ boost::apply_visitor(lex_streamer_void(), v1, v2, v1);
+ boost::apply_visitor(lex_streamer_void(), v2, v1, v1);
+ boost::apply_visitor(lex_streamer_void_visitor)(v2, v1, v1);
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+}
+#endif
+
+
+int main()
+{
+ run_explicit();
+ run();
+ run2();
+ run3();
+ test_has_result_type_triat();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/class_a.cpp b/src/boost/libs/variant/test/class_a.cpp
new file mode 100644
index 00000000..7cb1ff81
--- /dev/null
+++ b/src/boost/libs/variant/test/class_a.cpp
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/class_a.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <algorithm> // for std::swap
+#include <sstream>
+#include <iostream>
+#include <assert.h>
+
+#include "class_a.h"
+
+
+using namespace std;
+
+class_a::~class_a()
+{
+ assert(self_p_ == this);
+}
+
+class_a::class_a(int n)
+{
+ n_ = n;
+ self_p_ = this;
+}
+
+class_a::class_a(const class_a& other)
+{
+ n_ = other.n_;
+ self_p_ = this;
+}
+
+
+class_a& class_a::operator=(const class_a& rhs)
+{
+ class_a temp(rhs);
+ swap(temp);
+
+ return *this;
+}
+
+void class_a::swap(class_a& other)
+{
+ std::swap(n_, other.n_);
+}
+
+int class_a::get() const
+{
+ return n_;
+}
+
+
+
+
+std::ostream& operator<<(std::ostream& strm, const class_a& a)
+{
+ return strm << "class_a(" << a.get() << ")";
+}
diff --git a/src/boost/libs/variant/test/class_a.h b/src/boost/libs/variant/test/class_a.h
new file mode 100644
index 00000000..097c2c40
--- /dev/null
+++ b/src/boost/libs/variant/test/class_a.h
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/libs/test/class_a.h header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef _CLASSA_H_INC_
+#define _CLASSA_H_INC_
+
+
+#include <iosfwd>
+
+struct class_a
+{
+ ~class_a();
+ class_a(int n = 5511);
+ class_a(const class_a& other);
+
+ class_a& operator=(const class_a& rhs);
+ void swap(class_a& other);
+
+ int get() const;
+
+private:
+ int n_;
+ class_a* self_p_;
+
+}; //Class_a
+
+std::ostream& operator<<(std::ostream& strm, const class_a& a);
+
+
+
+#endif //_CLASSA_H_INC_
diff --git a/src/boost/libs/variant/test/const_ref_apply_visitor.cpp b/src/boost/libs/variant/test/const_ref_apply_visitor.cpp
new file mode 100644
index 00000000..72afff9e
--- /dev/null
+++ b/src/boost/libs/variant/test/const_ref_apply_visitor.cpp
@@ -0,0 +1,417 @@
+// Copyright (c) 2017 Levon Tarakchyan
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+#include "boost/variant/apply_visitor.hpp"
+#include "boost/variant/multivisitors.hpp"
+#include "boost/lexical_cast.hpp"
+
+#define lcs(val) boost::lexical_cast<std::string>(val)
+
+struct construction_logger
+{
+ int val_;
+
+ construction_logger(int val) : val_(val)
+ {
+ std::cout << val_ << " constructed\n";
+ }
+
+ construction_logger(const construction_logger& cl) :
+ val_(cl.val_)
+ {
+ std::cout << val_ << " copy constructed\n";
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ construction_logger(construction_logger&& cl) :
+ val_(cl.val_)
+ {
+ std::cout << val_ << " move constructed\n";
+ }
+#endif
+
+ friend std::ostream& operator << (std::ostream& os, const construction_logger& cl)
+ {
+ return os << cl.val_;
+ }
+
+ friend std::istream& operator << (std::istream& is, construction_logger& cl)
+ {
+ return is >> cl.val_;
+ }
+};
+
+struct lex_streamer_explicit : boost::static_visitor<std::string>
+{
+ template <class T>
+ std::string operator()(const T& val) const
+ {
+ return lcs(val);
+ }
+
+ template <class T, class V>
+ std::string operator()(const T& val, const V& val2) const
+ {
+ return lcs(val) + '+' + lcs(val2);
+ }
+
+ template <class T, class V, class P, class S>
+ std::string operator()(const T& val, const V& val2, const P& val3, const S& val4) const
+ {
+ return lcs(val) + '+' + lcs(val2) + '+' + lcs(val3) + '+' + lcs(val4);
+ }
+};
+
+struct lvalue_rvalue_detector : boost::static_visitor<std::string>
+{
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class T>
+ std::string operator()(T&&) const
+ {
+ return std::is_lvalue_reference<T>::value ? "lvalue reference"
+ : "rvalue reference";
+ }
+
+ template <class T, class V>
+ std::string operator()(T&& t, V&& v) const
+ {
+ return operator()(std::forward<T>(t)) + ", " + operator()(std::forward<V>(v));
+ }
+
+ template <class T, class V, class P>
+ std::string operator()(T&& t, V&& v, P&& p) const
+ {
+ return operator()(std::forward<T>(t), std::forward<V>(v)) + ", " + operator()(std::forward<P>(p));
+ }
+
+ template <class T, class V, class P, class S>
+ std::string operator()(T&& t, V&& v, P&& p, S&& s) const
+ {
+ return operator()(std::forward<T>(t), std::forward<V>(v), std::forward<P>(p)) + ", " + operator()(std::forward<S>(s));
+ }
+#else
+ template <class T>
+ std::string operator()(T&) const
+ {
+ return "lvalue reference";
+ }
+
+ template <class T, class V>
+ std::string operator()(T&, V&) const
+ {
+ return "lvalue reference, lvalue reference";
+ }
+
+ template <class T, class V, class P>
+ std::string operator()(T&, V&, P&) const
+ {
+ return "lvalue reference, lvalue reference, lvalue reference";
+ }
+
+ template <class T, class V, class P, class S>
+ std::string operator()(T&, V&, P&, S&) const
+ {
+ return "lvalue reference, lvalue reference, lvalue reference, lvalue reference";
+ }
+#endif
+};
+
+typedef boost::variant<construction_logger, std::string> variant_type;
+
+void test_const_ref_parameter(const variant_type& test_var)
+{
+ std::cout << "Testing const lvalue reference visitable\n";
+
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var) == "lvalue reference");
+}
+
+void test_const_ref_parameter2(const variant_type& test_var, const variant_type& test_var2)
+{
+ std::cout << "Testing const lvalue reference visitable\n";
+
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var, test_var2) == "lvalue reference, lvalue reference");
+}
+
+void test_const_ref_parameter4(const variant_type& test_var, const variant_type& test_var2, const variant_type& test_var3, const variant_type& test_var4)
+{
+ std::cout << "Testing const lvalue reference visitable with multivisitor\n";
+
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), test_var, test_var2, test_var3, test_var4)
+ == "lvalue reference, lvalue reference, lvalue reference, lvalue reference");
+}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+
+void test_rvalue_parameter(variant_type&& test_var)
+{
+ std::cout << "Testing rvalue visitable\n";
+
+ const auto expected_val = lcs(test_var);
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var)) == "rvalue reference");
+}
+
+void test_rvalue_parameter2(variant_type&& test_var, variant_type&& test_var2)
+{
+ std::cout << "Testing rvalue visitable\n";
+
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var), std::move(test_var2)) == "rvalue reference, rvalue reference");
+}
+
+void test_rvalue_parameter4(variant_type&& test_var, variant_type&& test_var2, variant_type&& test_var3, variant_type&& test_var4)
+{
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing rvalue visitable with multivisitor\n";
+
+ auto result = boost::apply_visitor(lvalue_rvalue_detector(), std::move(test_var), std::move(test_var2), std::move(test_var3), std::move(test_var4));
+ std::cout << "result: " << result << std::endl;
+ BOOST_TEST(result == "rvalue reference, rvalue reference, rvalue reference, rvalue reference");
+#else
+ (void)test_var;
+ (void)test_var2;
+ (void)test_var3;
+ (void)test_var4;
+#endif
+}
+
+#endif
+
+#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
+
+#define FORWARD(x) std::forward<decltype(x)>(x)
+
+void test_cpp14_visitor(const variant_type& test_var)
+{
+ std::cout << "Testing const lvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto&& v) { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
+}
+
+void test_cpp14_mutable_visitor(const variant_type& test_var)
+{
+ std::cout << "Testing const lvalue visitable for c++14 with inline mutable lambda\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto&& v) mutable -> auto { return lvalue_rvalue_detector()(FORWARD(v)); }, test_var) == "lvalue reference");
+}
+
+void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_var2)
+{
+ std::cout << "Testing const lvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& vv) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(vv)); }, test_var, test_var2)
+ == "lvalue reference, lvalue reference");
+}
+
+void test_cpp14_visitor(const variant_type& test_var, const variant_type& test_var2, const variant_type& test_var3)
+{
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing const lvalue visitable for c++14\n";
+
+ auto result = boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
+ test_var, test_var2, test_var3);
+ std::cout << "result: " << result << std::endl;
+ BOOST_TEST(result == "lvalue reference, lvalue reference, lvalue reference");
+#else
+ (void)test_var;
+ (void)test_var2;
+ (void)test_var3;
+#endif
+}
+
+void test_cpp14_visitor(variant_type& test_var)
+{
+ std::cout << "Testing lvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto& v) { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
+}
+
+void test_cpp14_mutable_visitor(variant_type& test_var)
+{
+ std::cout << "Testing lvalue visitable for c++14 with inline mutable lambda\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto& v) mutable -> auto { return lvalue_rvalue_detector()(v); }, test_var) == "lvalue reference");
+}
+
+void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2)
+{
+ std::cout << "Testing lvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto& v, auto& vv) { return lvalue_rvalue_detector()(v, vv); }, test_var, test_var2)
+ == "lvalue reference, lvalue reference");
+}
+
+void test_cpp14_visitor(variant_type& test_var, variant_type& test_var2, variant_type& test_var3)
+{
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing lvalue visitable for c++14\n";
+
+ auto result = boost::apply_visitor([](auto& v, auto& t, auto& p) { return lvalue_rvalue_detector()(v, t, p); },
+ test_var, test_var2, test_var3);
+ std::cout << "result: " << result << std::endl;
+ BOOST_TEST(result == "lvalue reference, lvalue reference, lvalue reference");
+#else
+ (void)test_var;
+ (void)test_var2;
+ (void)test_var3;
+#endif
+}
+
+void test_cpp14_visitor(variant_type&& test_var)
+{
+ std::cout << "Testing rvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto&& v) { return lvalue_rvalue_detector()(FORWARD(v)); }, std::move(test_var)) == "rvalue reference");
+}
+
+void test_cpp14_visitor(variant_type&& test_var, variant_type&& test_var2)
+{
+ std::cout << "Testing rvalue visitable for c++14\n";
+
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& vv) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(vv)); }, std::move(test_var), std::move(test_var2))
+ == "rvalue reference, rvalue reference");
+}
+
+void test_cpp14_visitor(variant_type&& test_var, variant_type&& test_var2, variant_type&& test_var3)
+{
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing rvalue visitable for c++14\n";
+
+ auto result = boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
+ std::move(test_var), std::move(test_var2), std::move(test_var3));
+ std::cout << "result: " << result << std::endl;
+ BOOST_TEST(result == "rvalue reference, rvalue reference, rvalue reference");
+#else
+ (void)test_var;
+ (void)test_var2;
+ (void)test_var3;
+#endif
+}
+
+#endif
+
+void run_const_lvalue_ref_tests()
+{
+ const variant_type v1(1), v2(2), v3(3), v4(4);
+ test_const_ref_parameter(v1);
+ test_const_ref_parameter2(v1, v2);
+ test_const_ref_parameter4(v1, v2, v3, v4);
+}
+
+void run_rvalue_ref_tests()
+{
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ variant_type v1(10), v2(20), v3(30);
+ test_rvalue_parameter(boost::move(v1));
+ test_rvalue_parameter2(boost::move(v2), boost::move(v3));
+
+ variant_type vv1(100), vv2(200), vv3(300), vv4(400);
+ test_rvalue_parameter4(boost::move(vv1), boost::move(vv2), boost::move(vv3), boost::move(vv4));
+#endif
+}
+
+void run_mixed_tests()
+{
+ variant_type v1(1), v2(2);
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+ std::cout << "Testing lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, variant_type(10)) == "lvalue reference, rvalue reference");
+
+ std::cout << "Testing rvalue + lvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), variant_type(10), v1) == "rvalue reference, lvalue reference");
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing rvalue + lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), variant_type(10), v1, variant_type(20)) == "rvalue reference, lvalue reference, rvalue reference");
+
+ std::cout << "Testing lvalue + rvalue + lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, variant_type(10), v2, variant_type(20)) == "lvalue reference, rvalue reference, lvalue reference, rvalue reference");
+#endif
+
+#endif // #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ std::cout << "Testing lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, v1) == "lvalue reference, lvalue reference");
+
+ std::cout << "Testing rvalue + lvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), static_cast<const variant_type&>(variant_type(10)), v1) == "lvalue reference, lvalue reference");
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing rvalue + lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), static_cast<const variant_type&>(variant_type(10)), v1, static_cast<const variant_type&>(variant_type(20))) == "lvalue reference, lvalue reference, lvalue reference");
+
+ std::cout << "Testing lvalue + rvalue + lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor(lvalue_rvalue_detector(), v1, static_cast<const variant_type&>(variant_type(10)), v2, static_cast<const variant_type&>(variant_type(20))) == "lvalue reference, lvalue reference, lvalue reference, lvalue reference");
+#endif
+#endif
+}
+
+void run_cpp14_mixed_tests()
+{
+#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
+ variant_type v1(1), v2(2);
+
+ std::cout << "Testing lvalue + rvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t)); },
+ v1, variant_type(10)) == "lvalue reference, rvalue reference");
+
+ std::cout << "Testing rvalue + lvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t)); },
+ variant_type(10), v1) == "rvalue reference, lvalue reference");
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ std::cout << "Testing rvalue + lvalue + lvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
+ variant_type(10), v1, v2) == "rvalue reference, lvalue reference, lvalue reference");
+
+ std::cout << "Testing lvalue + rvalue + lvalue visitable\n";
+ BOOST_TEST(boost::apply_visitor([](auto&& v, auto&& t, auto&& p) { return lvalue_rvalue_detector()(FORWARD(v), FORWARD(t), FORWARD(p)); },
+ v1, variant_type(10), v2) == "lvalue reference, rvalue reference, lvalue reference");
+#endif
+#endif
+}
+
+void run_cpp14_tests()
+{
+#ifndef BOOST_NO_CXX14_DECLTYPE_AUTO
+ variant_type const c1(10), c2(20), c3(30);
+ variant_type v1(10), v2(20), v3(30);
+
+ test_cpp14_visitor(c1);
+ test_cpp14_mutable_visitor(c1);
+ test_cpp14_visitor(c2, c3);
+ test_cpp14_visitor(c1, c2, c3);
+
+ test_cpp14_visitor(v1);
+ test_cpp14_mutable_visitor(v1);
+ test_cpp14_visitor(v2, v3);
+ test_cpp14_visitor(v1, v2, v3);
+
+ test_cpp14_visitor(boost::move(v1));
+ test_cpp14_visitor(boost::move(v2), boost::move(v3));
+
+ variant_type vv1(100), vv2(200), vv3(300);
+ test_cpp14_visitor(boost::move(vv1), boost::move(vv2), boost::move(vv3));
+#endif
+}
+
+
+
+int main()
+{
+ run_const_lvalue_ref_tests();
+ run_rvalue_ref_tests();
+ run_mixed_tests();
+ run_cpp14_mixed_tests();
+ run_cpp14_tests();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/hash_recursive_variant_test.cpp b/src/boost/libs/variant/test/hash_recursive_variant_test.cpp
new file mode 100644
index 00000000..c6d5ef30
--- /dev/null
+++ b/src/boost/libs/variant/test/hash_recursive_variant_test.cpp
@@ -0,0 +1,73 @@
+// Copyright (c) 2016
+// Mikhail Maximov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
+// Test is based on reported issues:
+// https://svn.boost.org/trac/boost/ticket/12508
+// https://svn.boost.org/trac/boost/ticket/12645
+// Following hash function was not found at compile time,
+// because boost::variant construction from boost::recursive_variant_
+// was forbidden.
+
+#include <unordered_set>
+
+#include "boost/variant.hpp"
+
+struct hash;
+
+using int_t = int;
+
+template <typename T>
+using basic_set_t = std::unordered_set<T, hash>;
+
+using value_t = boost::make_recursive_variant<
+ int_t,
+ basic_set_t<boost::recursive_variant_>
+>::type;
+
+using set_t = basic_set_t<value_t>;
+
+struct hash
+{
+ size_t operator()(const value_t&) const
+ {
+ return 0;
+ }
+};
+
+void run()
+{
+ set_t s;
+ int_t i = 3;
+ value_t v = i;
+ auto emplace_result = s.emplace(v); // raises error above
+ BOOST_TEST(emplace_result.second);
+ v = s;
+ const set_t& check_set = boost::get<set_t>(v);
+ BOOST_TEST(!check_set.empty());
+ for (const auto& check_v : check_set) {
+ BOOST_TEST(s.find(check_v) != s.end());
+ }
+ for (const auto& check_v : s) {
+ BOOST_TEST(check_set.find(check_v) != check_set.end());
+ }
+}
+
+#else // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
+// if no unordered_set and template aliases - does nothing
+void run() {}
+#endif
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/hash_variant_test.cpp b/src/boost/libs/variant/test/hash_variant_test.cpp
new file mode 100644
index 00000000..3d4a03d9
--- /dev/null
+++ b/src/boost/libs/variant/test/hash_variant_test.cpp
@@ -0,0 +1,54 @@
+// Copyright (c) 2011-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+
+#include "boost/config.hpp"
+#include "boost/variant.hpp"
+#include "boost/functional/hash/hash.hpp"
+
+#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH)
+
+#include <unordered_set>
+
+void test_std_hash() {
+ std::unordered_set<boost::variant<int, bool> > us;
+ us.insert(1);
+ us.insert(true);
+ BOOST_TEST(us.size() == 2);
+}
+
+#else
+void test_std_hash() {}
+#endif
+
+
+void run() {
+ typedef boost::variant<bool, int, unsigned int, char> variant_type;
+ boost::hash<variant_type> hasher;
+
+ variant_type bool_variant1 = true;
+ variant_type bool_variant2 = false;
+ variant_type int_variant = 1;
+ variant_type char_variant1 = '\1';
+ variant_type char_variant2 = '\2';
+ variant_type uint_variant = static_cast<unsigned int>(1);
+
+ BOOST_TEST(hasher(bool_variant1) != hasher(bool_variant2));
+ BOOST_TEST(hasher(bool_variant1) == hasher(bool_variant1));
+ BOOST_TEST(hasher(int_variant) != hasher(uint_variant));
+ BOOST_TEST(hasher(char_variant1) != hasher(uint_variant));
+ BOOST_TEST(hasher(char_variant1) != hasher(char_variant2));
+ BOOST_TEST(hasher(char_variant1) == hasher(char_variant1));
+ BOOST_TEST(hasher(char_variant2) == hasher(char_variant2));
+}
+
+int main() {
+ run();
+ test_std_hash();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/issue42.cpp b/src/boost/libs/variant/test/issue42.cpp
new file mode 100644
index 00000000..5a1feaa6
--- /dev/null
+++ b/src/boost/libs/variant/test/issue42.cpp
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/issue42.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2018-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Test case from https://github.com/boostorg/variant/issues/42
+
+#include <boost/variant.hpp>
+#include <map>
+#include <memory>
+#include <vector>
+
+
+
+#ifdef BOOST_NO_CXX11_SMART_PTR
+ template <class T> struct shared_ptr_like {};
+ typedef shared_ptr_like<boost::recursive_variant_> ptr_t;
+#else
+ typedef std::shared_ptr<boost::recursive_variant_> ptr_t;
+#endif
+
+template <class F>
+class func{};
+
+int main() {
+ typedef boost::make_recursive_variant<
+ int,
+ ptr_t
+ >::type node;
+
+ node x = 1;
+ (void)x;
+
+
+ typedef boost::make_recursive_variant<
+ std::string, int, double, bool,
+ ptr_t,
+ std::map<const std::string, boost::recursive_variant_>,
+ std::vector<boost::recursive_variant_>
+ >::type node2;
+
+ node2 x2 = 1;
+ (void)x2;
+
+
+ typedef boost::make_recursive_variant<
+ int,
+ func<boost::recursive_variant_(*)(boost::recursive_variant_&, const boost::recursive_variant_&)>,
+ boost::recursive_variant_&(*)(boost::recursive_variant_, boost::recursive_variant_*),
+ ptr_t
+ >::type node3;
+
+ node3 x3 = func<node3(*)(node3&, const node3&)>();
+ (void)x3;
+}
diff --git a/src/boost/libs/variant/test/issue53.cpp b/src/boost/libs/variant/test/issue53.cpp
new file mode 100644
index 00000000..06124b82
--- /dev/null
+++ b/src/boost/libs/variant/test/issue53.cpp
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/issue53.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Test case from https://github.com/boostorg/variant/issues/53
+
+#include <boost/variant.hpp>
+#include <boost/thread/lock_guard.hpp> // this line was causing problems on MSVC
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+struct spanac {};
+
+struct ceapa{
+ double a,b;
+};
+
+typedef boost::variant<spanac, ceapa> var_t;
+
+struct visitor_t : public boost::static_visitor<bool> {
+ bool operator() (const spanac&) const {
+ return true;
+ }
+
+ bool operator() (const ceapa&) const {
+ return false;
+ }
+
+private:
+ double a, b;
+};
+
+var_t get(int k) {
+ if (k)
+ return spanac();
+ else
+ return ceapa();
+}
+
+int main(int argc, const char** argv) {
+ visitor_t v;
+
+ bool result = boost::apply_visitor(v, get(argc - 1));
+ (void)result;
+}
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+int main() {}
+
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
diff --git a/src/boost/libs/variant/test/jobs.h b/src/boost/libs/variant/test/jobs.h
new file mode 100644
index 00000000..9b965554
--- /dev/null
+++ b/src/boost/libs/variant/test/jobs.h
@@ -0,0 +1,335 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/libs/test/jobs.h header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef _JOBSH_INC_
+#define _JOBSH_INC_
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <typeinfo>
+#include <vector>
+
+#include "boost/variant/variant_fwd.hpp"
+#include "boost/variant/get.hpp"
+#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
+#endif
+
+struct to_text : boost::static_visitor<std::string>
+{
+private: // NO_FUNCTION_TEMPLATE_ORDERING workaround
+
+ template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
+ std::string to_text_impl(
+ const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) >& operand, long
+ ) const
+ {
+ std::ostringstream ost;
+ ost << "[V] " << boost::apply_visitor(to_text(), operand);
+
+ return ost.str();
+ }
+
+ template <typename Value>
+ std::string to_text_impl(const Value& operand, int) const
+ {
+ std::ostringstream ost;
+ ost << "[V] " << operand;
+
+ return ost.str();
+ }
+
+public:
+
+ template <typename T>
+ std::string operator()(const T& operand) const
+ {
+ return to_text_impl(operand, 1L);
+ }
+
+};
+
+struct total_sizeof : boost::static_visitor<int>
+{
+ total_sizeof() : total_(0) { }
+
+ template<class Value>
+ int operator()(const Value&) const
+ {
+ total_ += sizeof(Value);
+ return total_;
+ }
+
+ int result() const
+ {
+ return total_;
+ }
+
+ mutable int total_;
+
+}; // total_sizeof
+
+
+
+//Function object: sum_int
+//Description: Compute total sum of a series of numbers, (when called successively)
+//Use sizeof(T) if applied with a non-integral type
+struct sum_int : boost::static_visitor<int>
+{
+
+ sum_int() : total_(0) { }
+
+
+ template<int n>
+ struct int_to_type
+ {
+ BOOST_STATIC_CONSTANT(int, value = n);
+ };
+
+ //Integral type - add numerical value
+ template<typename T>
+ void add(T t, int_to_type<true> ) const
+ {
+ total_ += t;
+ }
+
+ //Other types - add sizeof<T>
+ template<typename T>
+ void add(T& , int_to_type<false> ) const
+ {
+ total_ += sizeof(T);
+ }
+
+ template<typename T>
+ int operator()(const T& t) const
+ {
+ //Int_to_type is used to select the correct add() overload
+ add(t, int_to_type<boost::is_integral<T>::value>());
+ return total_;
+ }
+
+ int result() const
+ {
+ return total_;
+ }
+
+private:
+ mutable int total_;
+
+}; //sum_int
+
+
+
+
+
+
+//Function object: sum_double
+//Description: Compute total sum of a series of numbers, (when called successively)
+//Accpetable input types: float, double (Other types are silently ignored)
+struct sum_double : boost::static_visitor<double>
+{
+
+ sum_double() : total_(0) { }
+
+ void operator()(float value) const
+ {
+ total_ += value;
+ }
+
+ void operator()(double value) const
+ {
+ total_ += value;
+ }
+
+ template<typename T>
+ void operator()(const T&) const
+ {
+ //Do nothing
+ }
+
+ double result() const
+ {
+ return total_;
+ }
+
+private:
+ mutable double total_;
+
+}; //sum_double
+
+
+
+struct int_printer : boost::static_visitor<std::string>
+{
+
+ int_printer(std::string prefix_s = "") : prefix_s_(prefix_s) { }
+ int_printer(const int_printer& other) : prefix_s_(other.prefix_s_)
+ {
+ ost_ << other.str();
+ }
+
+ std::string operator()(int x) const
+ {
+ ost_ << prefix_s_ << x;
+ return str();
+ }
+
+ std::string operator()(const std::vector<int>& x) const
+ {
+ ost_ << prefix_s_;
+
+ //Use another Int_printer object for printing a list of all integers
+ int_printer job(",");
+ ost_ << std::for_each(x.begin(), x.end(), job).str();
+
+ return str();
+ }
+
+ std::string str() const
+ {
+ return ost_.str();
+ }
+
+private:
+ std::string prefix_s_;
+ mutable std::ostringstream ost_;
+}; //int_printer
+
+
+struct int_adder : boost::static_visitor<>
+{
+
+ int_adder(int rhs) : rhs_(rhs) { }
+
+ result_type operator()(int& lhs) const
+ {
+ lhs += rhs_;
+ }
+
+ template<typename T>
+ result_type operator()(const T& ) const
+ {
+ //Do nothing
+ }
+
+ int rhs_;
+}; //int_adder
+
+
+
+template<typename T>
+struct spec
+{
+ typedef T result;
+};
+
+template<typename VariantType, typename S>
+inline void verify(VariantType& var, spec<S>, std::string str = "")
+{
+ const VariantType& cvar = var;
+
+ BOOST_TEST(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
+ BOOST_TEST(cvar.type() == boost::typeindex::type_id<S>());
+
+ //
+ // Check get<>()
+ //
+ BOOST_TEST(boost::get<S>(&var));
+ BOOST_TEST(boost::get<S>(&cvar));
+
+ const S* ptr1 = 0;
+ const S* ptr2 = 0;
+ try
+ {
+ S& r = boost::get<S>(var);
+ ptr1 = &r;
+ }
+ catch(const boost::bad_get& )
+ {
+ BOOST_ERROR( "get<S> failed unexpectedly" );
+ }
+
+ try
+ {
+ const S& cr = boost::get<S>(cvar);
+ ptr2 = &cr;
+ }
+ catch(const boost::bad_get& )
+ {
+ BOOST_ERROR( "get<S> const failed unexpectedly" );
+ }
+
+ BOOST_TEST(ptr1 != 0 && ptr2 == ptr1);
+
+ //
+ // Check string content
+ //
+ if(str.length() > 0)
+ {
+ std::string temp = boost::apply_visitor(to_text(), cvar);
+ std::cout << "temp = " << temp << ", str = " << str << std::endl;
+ BOOST_TEST(temp == str);
+ }
+}
+
+
+template<typename VariantType, typename S>
+inline void verify_not(VariantType& var, spec<S>)
+{
+ const VariantType& cvar = var;
+
+ BOOST_TEST(cvar.type() != boost::typeindex::type_id<S>());
+
+ //
+ // Check get<>()
+ //
+ BOOST_TEST(!boost::get<S>(&var));
+ BOOST_TEST(!boost::get<S>(&cvar));
+
+ const S* ptr1 = 0;
+ const S* ptr2 = 0;
+ try
+ {
+ S& r = boost::get<S>(var); // should throw
+ BOOST_ERROR( "get<S> passed unexpectedly" );
+
+ ptr1 = &r;
+ }
+ catch(const boost::bad_get& )
+ {
+ // do nothing except pass-through
+ }
+
+ try
+ {
+ const S& cr = boost::get<S>(var); // should throw
+ BOOST_ERROR( "get<S> const passed unexpectedly" );
+
+ ptr2 = &cr;
+ }
+ catch(const boost::bad_get& )
+ {
+ // do nothing except pass-through
+ }
+
+ BOOST_TEST(ptr1 == 0 && ptr2 == 0);
+}
+
+
+#endif //_JOBSH_INC_
diff --git a/src/boost/libs/variant/test/no_rvalue_to_nonconst_visitation.cpp b/src/boost/libs/variant/test/no_rvalue_to_nonconst_visitation.cpp
new file mode 100644
index 00000000..e13b7f2c
--- /dev/null
+++ b/src/boost/libs/variant/test/no_rvalue_to_nonconst_visitation.cpp
@@ -0,0 +1,32 @@
+// Copyright (c) 2017-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+#include "boost/variant.hpp"
+
+struct foo {};
+
+struct some_user_provided_visitor_for_lvalues: boost::static_visitor<void> {
+ void operator()(foo& ) const {}
+ void operator()(int ) const {}
+};
+
+int main() {
+ boost::apply_visitor(
+ some_user_provided_visitor_for_lvalues(),
+ boost::variant<int, foo>(foo())
+ );
+
+#ifdef __GNUC__
+# if __GNUC__ < 5 && __GNUC_MINOR__ < 8
+# error This test does not pass on GCC < 4.8 because of the incomplete C++11 support
+# endif
+#endif
+
+#ifdef BOOST_MSVC
+# error Temporaries/rvalues could bind to non-const lvalues on MSVC compilers
+#endif
+}
diff --git a/src/boost/libs/variant/test/overload_selection.cpp b/src/boost/libs/variant/test/overload_selection.cpp
new file mode 100644
index 00000000..e18dd7ed
--- /dev/null
+++ b/src/boost/libs/variant/test/overload_selection.cpp
@@ -0,0 +1,215 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_get_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2016-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+// This test suite was created to cover issues reported in:
+// https://svn.boost.org/trac/boost/ticket/5871
+// https://svn.boost.org/trac/boost/ticket/11602
+
+#include "boost/variant/variant.hpp"
+#include "boost/variant/recursive_variant.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#include <string>
+#include <list>
+
+struct A{};
+struct B{};
+struct C{};
+struct D{};
+
+
+bool foo(const boost::variant<A, B>& ) {
+ return false;
+}
+
+bool foo(const boost::variant<C, D>& ) {
+ return true;
+}
+
+void test_overload_selection_variant_constructor() {
+ D d;
+ BOOST_TEST(foo(d));
+
+ boost::variant<B, A> v;
+ BOOST_TEST(!foo(v));
+}
+
+// Pre msvc-14.0 could not dustinguish between multiple assignment operators:
+// warning C4522: 'assignment_tester' : multiple assignment operators specified
+// error C2666: variant::operator =' : 3 overloads have similar conversions
+// Old versions of GCC have same issue:
+// error: variant::operator=(const T&) cannot be overloaded
+#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_MSC_VER) && _MSC_VER < 1900)
+
+void test_overload_selection_variant_assignment() {
+ BOOST_TEST(true);
+}
+
+#else
+
+struct assignment_tester: boost::variant<C, D>, boost::variant<B, A> {
+ using boost::variant<B, A>::operator=;
+ using boost::variant<C, D>::operator=;
+};
+
+void test_overload_selection_variant_assignment() {
+ A a;
+ assignment_tester tester;
+ tester = a;
+ const int which0 = static_cast< boost::variant<B, A>& >(tester).which();
+ BOOST_TEST(which0 == 1);
+
+ boost::variant<A, B> b;
+ b = B();
+ tester = b;
+ const int which1 = static_cast< boost::variant<B, A>& >(tester).which();
+ BOOST_TEST(which1 == 0);
+}
+
+#endif
+
+typedef boost::variant<int> my_variant;
+
+struct convertible {
+ operator my_variant() const {
+ return my_variant();
+ }
+};
+
+void test_implicit_conversion_operator() {
+ // https://svn.boost.org/trac/boost/ticket/8555
+ my_variant y = convertible();
+ BOOST_TEST(y.which() == 0);
+}
+
+struct X: boost::variant< int > {};
+class V1: public boost::variant<float,double> {};
+
+struct AB: boost::variant<A, B> {};
+
+void test_derived_from_variant_construction() {
+ // https://svn.boost.org/trac/boost/ticket/7120
+ X x;
+ boost::variant<X> y(x);
+ BOOST_TEST(y.which() == 0);
+
+ // https://svn.boost.org/trac/boost/ticket/10278
+ boost::variant<V1, std::string> v2 = V1();
+ BOOST_TEST(v2.which() == 0);
+
+ // https://svn.boost.org/trac/boost/ticket/12155
+ AB ab;
+ boost::variant<AB, C> ab_c(ab);
+ BOOST_TEST(ab_c.which() == 0);
+
+ boost::variant<A, B> a_b(ab);
+ BOOST_TEST(a_b.which() == 0);
+
+ boost::variant<B, C, A> b_c_a1(static_cast<boost::variant<A, B>& >(ab));
+ BOOST_TEST(b_c_a1.which() == 2);
+
+
+// Following conversion seems harmful as it may lead to slicing:
+// boost::variant<B, C, A> b_c_a(ab);
+// BOOST_TEST(b_c_a.which() == 2);
+}
+
+void test_derived_from_variant_assignment() {
+ // https://svn.boost.org/trac/boost/ticket/7120
+ X x;
+ boost::variant<X> y;
+ y = x;
+ BOOST_TEST(y.which() == 0);
+
+ // https://svn.boost.org/trac/boost/ticket/10278
+ boost::variant<V1, std::string> v2;
+ v2 = V1();
+ BOOST_TEST(v2.which() == 0);
+
+ // https://svn.boost.org/trac/boost/ticket/12155
+ AB ab;
+ boost::variant<AB, C> ab_c;
+ ab_c = ab;
+ BOOST_TEST(ab_c.which() == 0);
+
+ boost::variant<A, B> a_b;
+ a_b = ab;
+ BOOST_TEST(a_b.which() == 0);
+
+ boost::variant<B, C, A> b_c_a1;
+ b_c_a1 = static_cast<boost::variant<A, B>& >(ab);
+ BOOST_TEST(b_c_a1.which() == 2);
+
+
+// Following conversion seems harmful as it may lead to slicing:
+// boost::variant<B, C, A> b_c_a;
+// b_c_a = ab;
+// BOOST_TEST(b_c_a.which() == 2);
+}
+
+
+// http://thread.gmane.org/gmane.comp.lib.boost.devel/267757
+struct info {
+ struct nil_ {};
+
+ typedef
+ boost::variant<
+ nil_
+ , std::string
+ , boost::recursive_wrapper<info>
+ , boost::recursive_wrapper<std::pair<info, info> >
+ , boost::recursive_wrapper<std::list<info> >
+ >
+ value_type;
+ value_type v;
+
+ inline void test_on_incomplete_types() {
+ info i0;
+ i0.v = "Hello";
+ BOOST_TEST(i0.v.which() == 1);
+
+ info::value_type v0 = "Hello";
+ BOOST_TEST(v0.which() == 1);
+
+ info::value_type v1("Hello");
+ BOOST_TEST(v1.which() == 1);
+
+ info::value_type v2 = i0;
+ BOOST_TEST(v2.which() == 2);
+
+ info::value_type v3(i0);
+ BOOST_TEST(v3.which() == 2);
+
+ v0 = v3;
+ BOOST_TEST(v0.which() == 2);
+
+ v3 = v1;
+ BOOST_TEST(v3.which() == 1);
+
+ v3 = nil_();
+ BOOST_TEST(v3.which() == 0);
+ }
+};
+
+
+
+int main()
+{
+ test_overload_selection_variant_constructor();
+ test_overload_selection_variant_assignment();
+ test_implicit_conversion_operator();
+ test_derived_from_variant_construction();
+ test_derived_from_variant_assignment();
+ info().test_on_incomplete_types();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/recursive_variant_test.cpp b/src/boost/libs/variant/test/recursive_variant_test.cpp
new file mode 100644
index 00000000..5df5dd1c
--- /dev/null
+++ b/src/boost/libs/variant/test/recursive_variant_test.cpp
@@ -0,0 +1,364 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/recursive_variant_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003 Eric Friedman, Itay Maman
+// Copyright (c) 2013-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+// This file is used in two test cases:
+//
+// 1) recursive_variant_test.cpp that tests recursive usage of variant
+//
+// 2) variant_noexcept_test that tests Boost.Variant ability to compile
+// and work with disabled exceptions
+
+
+#include "boost/core/lightweight_test.hpp"
+
+#include "boost/variant.hpp"
+#include "boost/mpl/vector.hpp"
+#include "boost/mpl/copy.hpp"
+
+#include <iostream>
+#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 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
+ {
+ std::ostringstream ost;
+
+ ost << "( ";
+
+ typename std::vector<T>::const_iterator it = vec.begin();
+ for (; it != vec.end(); ++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
+ {
+ std::ostringstream ost;
+ ost << operand << ' ';
+ return ost.str();
+ }
+};
+
+void test_recursive_variant()
+{
+ typedef boost::make_recursive_variant<
+ int
+ , std::vector<boost::recursive_variant_>
+ >::type var1_t;
+
+ std::vector<var1_t> vec1;
+ vec1.push_back(3);
+ vec1.push_back(5);
+ vec1.push_back(vec1);
+ vec1.push_back(7);
+
+ var1_t var1(vec1);
+ std::string result1( printer()(var1) );
+
+ std::cout << "result1: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 ) 7 ) ");
+
+ std::vector<var1_t> vec1_copy = vec1;
+ vec1_copy.erase(vec1_copy.begin() + 2);
+ vec1_copy.insert(vec1_copy.begin() + 2, vec1_copy);
+ var1 = vec1_copy;
+ result1 = printer()(var1);
+ std::cout << "result1+: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
+
+ // Uses move construction on compilers with rvalue references support
+ result1 = printer()(
+ var1_t(
+ std::vector<var1_t>(vec1_copy)
+ )
+ );
+ std::cout << "result1++: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
+
+
+ var1_t vec1_another_copy(vec1_copy);
+ vec1_copy[2].swap(vec1_another_copy);
+ result1 = printer()(
+ var1_t(vec1_copy)
+ );
+ std::cout << "result1+++1: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
+
+ result1 = printer()(vec1_another_copy);
+ std::cout << "result1++2: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 7 ) ");
+
+ vec1_copy[2].swap(vec1_copy[2]);
+ result1 = printer()(
+ var1_t(vec1_copy)
+ );
+ std::cout << "result1.2: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
+
+ typedef boost::make_recursive_variant<
+ boost::variant<int, double>
+ , std::vector<boost::recursive_variant_>
+ >::type var2_t;
+
+ std::vector<var2_t> vec2;
+ vec2.push_back(boost::variant<int, double>(3));
+ vec2.push_back(boost::variant<int, double>(3.5));
+ vec2.push_back(vec2);
+ vec2.push_back(boost::variant<int, double>(7));
+
+ var2_t var2(vec2);
+ std::string result2( printer()(var2) );
+
+ std::cout << "result2: " << result2 << '\n';
+ BOOST_TEST(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant<
+ int
+ , std::vector<
+ boost::variant<
+ double
+ , std::vector<boost::recursive_variant_>
+ >
+ >
+ >::type var3_t;
+
+ typedef boost::variant<double, std::vector<var3_t> > var4_t;
+
+ std::vector<var3_t> vec3;
+ vec3.push_back(3);
+ vec3.push_back(5);
+ std::vector<var4_t> vec4;
+ vec4.push_back(3.5);
+ vec4.push_back(vec3);
+ vec3.push_back(vec4);
+ vec3.push_back(7);
+
+ var4_t var4(vec3);
+ std::string result3( printer()(var4) );
+
+ std::cout << "result2: " << result3 << '\n';
+ BOOST_TEST(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
+
+ typedef boost::make_recursive_variant<
+ double,
+ std::vector<var1_t>
+ >::type var5_t;
+
+ std::vector<var5_t> vec5;
+ vec5.push_back(3.5);
+ vec5.push_back(vec1);
+ vec5.push_back(17.25);
+
+ std::string result5( printer()(vec5) );
+
+ std::cout << "result5: " << result5 << '\n';
+ BOOST_TEST(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
+
+ typedef boost::make_recursive_variant<
+ int,
+ std::map<int, boost::recursive_variant_>
+ >::type var6_t;
+ var6_t var6;
+
+#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; // !!! Do not replace with `var7_t var7{0}` or `var7_t var7(0)` !!!
+ var7 = std::tuple<int, var7_t>(1, var7);
+ var7 = std::tuple<int, var7_t>(2, var7);
+
+ std::string result7( printer()(var7) );
+
+ std::cout << "result7: " << result7 << '\n';
+ BOOST_TEST(result7 == "( 2 ( 1 0 ) ) ");
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+}
+
+void test_recursive_variant_over()
+{
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ int
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type var1_t;
+
+ std::vector<var1_t> vec1;
+ vec1.push_back(3);
+ vec1.push_back(5);
+ vec1.push_back(vec1);
+ vec1.push_back(7);
+
+ var1_t var1(vec1);
+ std::string result1( printer()(var1) );
+
+ std::cout << "result1: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 ) 7 ) ");
+
+ std::vector<var1_t> vec1_copy = vec1;
+ vec1_copy.erase(vec1_copy.begin() + 2);
+ vec1_copy.insert(vec1_copy.begin() + 2, vec1_copy);
+ var1 = vec1_copy;
+ result1 = printer()(var1);
+ std::cout << "result1+: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
+
+ // Uses move construction on compilers with rvalue references support
+ result1 = printer()(
+ var1_t(
+ std::vector<var1_t>(vec1_copy)
+ )
+ );
+ std::cout << "result1++: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 7 ) 7 ) ");
+
+
+ var1_t vec1_another_copy(vec1_copy);
+ vec1_copy[2].swap(vec1_another_copy);
+ result1 = printer()(
+ var1_t(vec1_copy)
+ );
+ std::cout << "result1+++1: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 ( 3 5 ( 3 5 7 ) 7 ) 7 ) ");
+
+ result1 = printer()(vec1_another_copy);
+ std::cout << "result1++2: " << result1 << '\n';
+ BOOST_TEST(result1 == "( 3 5 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ boost::make_variant_over<boost::mpl::vector<int, double> >::type
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type var2_t;
+
+ std::vector<var2_t> vec2;
+ vec2.push_back(boost::variant<int, double>(3));
+ vec2.push_back(boost::variant<int, double>(3.5));
+ vec2.push_back(vec2);
+ vec2.push_back(boost::variant<int, double>(7));
+
+ var2_t var2(vec2);
+ std::string result2( printer()(var2) );
+
+ std::cout << "result2: " << result2 << '\n';
+ BOOST_TEST(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ int
+ , std::vector<
+ boost::make_variant_over<
+ boost::mpl::vector<
+ double
+ , std::vector<boost::recursive_variant_>
+ >
+ >::type
+ >
+ >
+ >::type var3_t;
+
+ typedef boost::make_variant_over<
+ boost::mpl::copy<
+ boost::mpl::vector<
+ double
+ , std::vector<var3_t>
+ >
+ >::type
+ >::type var4_t;
+
+ std::vector<var3_t> vec3;
+ vec3.push_back(3);
+ vec3.push_back(5);
+ std::vector<var4_t> vec4;
+ vec4.push_back(3.5);
+ vec4.push_back(vec3);
+ vec3.push_back(vec4);
+ vec3.push_back(7);
+
+ var4_t var3(vec3);
+ std::string result3( printer()(var3) );
+
+ std::cout << "result2: " << result3 << '\n';
+ BOOST_TEST(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
+
+ typedef boost::make_recursive_variant_over<
+ boost::mpl::vector<
+ double
+ , std::vector<var1_t>
+ >
+ >::type var5_t;
+
+ std::vector<var5_t> vec5;
+ vec5.push_back(3.5);
+ vec5.push_back(vec1);
+ vec5.push_back(17.25);
+
+ std::string result5( printer()(vec5) );
+
+ std::cout << "result5: " << result5 << '\n';
+ BOOST_TEST(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
+}
+
+int main()
+{
+ test_recursive_variant();
+ test_recursive_variant_over();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/recursive_wrapper_move_test.cpp b/src/boost/libs/variant/test/recursive_wrapper_move_test.cpp
new file mode 100644
index 00000000..58041ec2
--- /dev/null
+++ b/src/boost/libs/variant/test/recursive_wrapper_move_test.cpp
@@ -0,0 +1,78 @@
+// Copyright (c) 2017
+// Mikhail Maximov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#ifdef __cpp_inheriting_constructors
+// Test is based on reported issue:
+// https://svn.boost.org/trac/boost/ticket/12680
+// GCC 6 crashed, trying to determine is boost::recursive_wrapper<Node>
+// is_noexcept_move_constructible
+
+#include <string>
+#include <iterator>
+
+#include <boost/variant.hpp>
+#include <boost/array.hpp>
+
+struct Leaf { };
+struct Node;
+
+typedef boost::variant<Leaf, boost::recursive_wrapper<Node>> TreeBase;
+
+struct Tree : TreeBase {
+ using TreeBase::TreeBase;
+
+ template <typename Iter>
+ static Tree Create(Iter /*first*/, Iter /*last*/) { return Leaf{}; }
+};
+
+struct Node {
+ Tree left, right;
+};
+
+
+// Test from https://svn.boost.org/trac/boost/ticket/7120
+template<class Node>
+struct node1_type;
+
+struct var_type;
+
+using var_base = boost::variant<int,
+ boost::recursive_wrapper<node1_type<var_type>>
+>;
+
+template<class Node>
+struct node1_type {
+ boost::array<Node, 1> children;
+};
+
+struct var_type : var_base {
+ using var_base::var_base;
+};
+
+void run() {
+ std::string input{"abracadabra"};
+ const Tree root = Tree::Create(input.begin(), input.end());
+ (void)root; // prevents unused variable warning
+
+ var_type v1 = 1;
+ (void)v1;
+}
+
+#else // #!ifdef __cpp_inheriting_constructors
+// if compiler does not support inheriting constructors - does nothing
+void run() {}
+#endif
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/rvalue_test.cpp b/src/boost/libs/variant/test/rvalue_test.cpp
new file mode 100644
index 00000000..9fcdee58
--- /dev/null
+++ b/src/boost/libs/variant/test/rvalue_test.cpp
@@ -0,0 +1,332 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/rvalue_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2012-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+#include "boost/type_traits/is_nothrow_move_assignable.hpp"
+#include "boost/mpl/bool.hpp"
+
+#include <boost/blank.hpp>
+#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;
+ static unsigned int copy_count;
+
+ move_copy_conting_class(){}
+ move_copy_conting_class(BOOST_RV_REF(move_copy_conting_class) ) {
+ ++ moves_count;
+ }
+
+ move_copy_conting_class& operator=(BOOST_RV_REF(move_copy_conting_class) ) {
+ ++ moves_count;
+ return *this;
+ }
+
+ move_copy_conting_class(const move_copy_conting_class&) {
+ ++ copy_count;
+ }
+ move_copy_conting_class& operator=(BOOST_COPY_ASSIGN_REF(move_copy_conting_class) ) {
+ ++ copy_count;
+ return *this;
+ }
+};
+
+unsigned int move_copy_conting_class::moves_count = 0;
+unsigned int move_copy_conting_class::copy_count = 0;
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+void run()
+{
+ // Making sure that internals of Boost.Move do not interfere with
+ // internals of Boost.Variant and in case of C++03 or C++98 compilation
+ // is still possible.
+ typedef boost::variant<int, move_copy_conting_class> variant_I_type;
+ variant_I_type v1, v2;
+ v1 = move_copy_conting_class();
+ v2 = v1;
+ v2 = boost::move(v1);
+ v1.swap(v2);
+
+ move_copy_conting_class val;
+ v2 = boost::move(val);
+ v2 = 10;
+
+ variant_I_type v3(boost::move(val));
+ variant_I_type v4(boost::move(v1));
+}
+
+void run1()
+{
+ BOOST_TEST(true);
+}
+
+void run_move_only()
+{
+ BOOST_TEST(true);
+}
+
+void run_moves_are_noexcept()
+{
+ BOOST_TEST(true);
+}
+
+
+void run_const_rvalues()
+{
+ BOOST_TEST(true);
+}
+
+
+#else
+
+
+void run()
+{
+ typedef boost::variant<int, move_copy_conting_class> variant_I_type;
+ variant_I_type v1, v2;
+
+ // Assuring that `move_copy_conting_class` was not created
+ BOOST_TEST(move_copy_conting_class::copy_count == 0);
+ BOOST_TEST(move_copy_conting_class::moves_count == 0);
+
+ v1 = move_copy_conting_class();
+ // Assuring that `move_copy_conting_class` was moved at least once
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+
+ unsigned int total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
+ move_copy_conting_class var;
+ v1 = 0;
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v1 = var;
+ // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
+ BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
+
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v2 = boost::move(v1);
+ // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+ BOOST_TEST(move_copy_conting_class::copy_count == 0);
+
+ v1 = move_copy_conting_class();
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v2 = boost::move(v1);
+ // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+ BOOST_TEST(move_copy_conting_class::copy_count == 0);
+ total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v1 = v2;
+ // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
+ BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
+
+
+ typedef boost::variant<move_copy_conting_class, int> variant_II_type;
+ variant_II_type v3;
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v1 = boost::move(v3);
+ // Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ v2 = boost::move(v1);
+ // Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ variant_I_type v5(boost::move(v1));
+ // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
+ BOOST_TEST(move_copy_conting_class::moves_count != 0);
+ BOOST_TEST(move_copy_conting_class::copy_count == 0);
+
+ total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+ variant_I_type v6(v1);
+ // Assuring that move constructor moves/copyes value not more times than copy constructor
+ BOOST_TEST(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
+}
+
+void run1()
+{
+ move_copy_conting_class::moves_count = 0;
+ move_copy_conting_class::copy_count = 0;
+
+ move_copy_conting_class c1;
+ typedef boost::variant<int, move_copy_conting_class> variant_I_type;
+ variant_I_type v1(boost::move(c1));
+
+ // Assuring that `move_copy_conting_class` was not copyied
+ BOOST_TEST(move_copy_conting_class::copy_count == 0);
+ BOOST_TEST(move_copy_conting_class::moves_count > 0);
+}
+
+struct move_only_structure {
+ move_only_structure(){}
+ move_only_structure(move_only_structure&&){}
+ move_only_structure& operator=(move_only_structure&&) { return *this; }
+
+private:
+ move_only_structure(const move_only_structure&);
+ move_only_structure& operator=(const move_only_structure&);
+};
+
+struct visitor_returning_move_only_type: boost::static_visitor<move_only_structure> {
+ template <class T>
+ move_only_structure operator()(const T&) const {
+ return move_only_structure();
+ }
+};
+
+void run_move_only()
+{
+ move_only_structure mo;
+ boost::variant<int, move_only_structure > vi, vi2(static_cast<move_only_structure&&>(mo));
+ BOOST_TEST(vi.which() == 0);
+ BOOST_TEST(vi2.which() == 1);
+
+ vi = 10;
+ vi2 = 10;
+ BOOST_TEST(vi.which() == 0);
+ BOOST_TEST(vi2.which() == 0);
+
+ vi = static_cast<move_only_structure&&>(mo);
+ vi2 = static_cast<move_only_structure&&>(mo);
+ BOOST_TEST(vi.which() == 1);
+
+ boost::variant<move_only_structure, int > rvi (1);
+ BOOST_TEST(rvi.which() == 1);
+ rvi = static_cast<move_only_structure&&>(mo);
+ BOOST_TEST(rvi.which() == 0);
+ rvi = 1;
+ BOOST_TEST(rvi.which() == 1);
+ rvi = static_cast<boost::variant<int, move_only_structure >&&>(vi2);
+ BOOST_TEST(rvi.which() == 0);
+
+ move_only_structure from_visitor = boost::apply_visitor(visitor_returning_move_only_type(), vi);
+ (void)from_visitor;
+}
+
+void run_moves_are_noexcept() {
+#if !defined(BOOST_NO_CXX11_NOEXCEPT) && (!defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || __GNUC_MINOR__ >= 8)
+ typedef boost::variant<int, short, double> variant_noexcept_t;
+ BOOST_TEST(boost::is_nothrow_move_assignable<variant_noexcept_t>::value);
+ BOOST_TEST(boost::is_nothrow_move_constructible<variant_noexcept_t>::value);
+
+ typedef boost::variant<int, short, double, move_only_structure> variant_except_t;
+ BOOST_TEST(!boost::is_nothrow_move_assignable<variant_except_t>::value);
+ BOOST_TEST(!boost::is_nothrow_move_constructible<variant_except_t>::value);
+#endif
+}
+
+inline const std::string get_string() { return "test"; }
+inline const boost::variant<int, std::string> get_variant() { return std::string("test"); }
+inline const boost::variant<std::string, int> get_variant2() { return std::string("test"); }
+
+void run_const_rvalues()
+{
+ typedef boost::variant<int, std::string> variant_t;
+ const variant_t v1(get_string());
+ const variant_t v2(get_variant());
+ const variant_t v3(get_variant2());
+
+ variant_t v4, v5, v6, v7;
+ v4 = get_string();
+ v5 = get_variant();
+ v6 = get_variant2();
+ v7 = boost::move(v1);
+}
+
+#endif
+
+struct nothrow_copyable_throw_movable {
+ nothrow_copyable_throw_movable(){}
+ nothrow_copyable_throw_movable(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT {}
+ nothrow_copyable_throw_movable& operator=(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT { return *this; }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ nothrow_copyable_throw_movable(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) {}
+ nothrow_copyable_throw_movable& operator=(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) { return *this; }
+#endif
+};
+
+// This test is created to cover the following situation:
+// https://svn.boost.org/trac/boost/ticket/8772
+void run_tricky_compilation_test()
+{
+ boost::variant<int, nothrow_copyable_throw_movable> v;
+ v = nothrow_copyable_throw_movable();
+}
+
+template <typename T>
+struct is_container : boost::mpl::false_ {};
+
+template <typename T>
+struct is_container<boost::variant<T> > : is_container<T> {};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct is_container<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ : boost::mpl::bool_<is_container<T0>::value
+ || is_container<boost::variant<BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)> >::value>
+{};
+
+void run_is_container_compilation_test()
+{
+ BOOST_TEST((!is_container<boost::variant<double, int> >::value));
+ BOOST_TEST((!is_container<boost::variant<double, int, char> >::value));
+ BOOST_TEST((!is_container<boost::variant<double, int, char, float> >::value));
+}
+
+int main()
+{
+ swap_ambiguouty_test_ns::swap_ambiguouty_test();
+ run();
+ run1();
+ run_move_only();
+ run_moves_are_noexcept();
+ run_tricky_compilation_test();
+ run_const_rvalues();
+ run_is_container_compilation_test();
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 6)
+# ifdef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+ BOOST_TEST(false &&
+ "Something wrong with macro definitions. GCC-4.7+ is known to work with variadic templates"
+ );
+# endif
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/test1.cpp b/src/boost/libs/variant/test/test1.cpp
new file mode 100644
index 00000000..b7b9494c
--- /dev/null
+++ b/src/boost/libs/variant/test/test1.cpp
@@ -0,0 +1,150 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test1.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4244) // conversion from const int to const short
+#endif
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include "class_a.h"
+#include "jobs.h"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+
+
+void run()
+{
+
+ using boost::apply_visitor;
+ using boost::variant;
+ using std::string;
+ using std::vector;
+ using std::cout;
+ using std::endl;
+
+ typedef variant< char*, string, short > t_var0;
+ typedef variant< int, string, double > t_var1;
+ typedef variant< short, const char* > t_var2;
+ typedef variant< string, char > t_var3;
+ typedef variant< unsigned short, const char* > t_var4;
+ typedef variant< unsigned short, const char*, t_var2 > t_var5;
+ typedef variant< unsigned short, const char*, t_var5 > t_var6;
+ typedef variant< class_a, const void* > t_var7;
+ typedef variant< t_var6, int > t_var8;
+ typedef variant< t_var8, unsigned short > t_var9;
+ typedef variant< char, unsigned char > t_var10;
+ typedef variant< short, int, vector<int>, long> t_var11;
+
+ t_var1 v1;
+ t_var0 v0;
+ t_var2 v2;
+ t_var3 v3;
+ t_var4 v4;
+ t_var5 v5;
+ t_var6 v6;
+ t_var7 v7;
+ t_var8 v8;
+ t_var9 v9;
+ t_var10 v10;
+ t_var11 v11;
+
+
+ //
+ // Check assignment rules
+ //
+
+ v2 = 4;
+ v4 = v2;
+ verify(v4, spec<unsigned short>());
+
+ v2 = "abc";
+ v4 = v2;
+ verify(v4, spec<const char*>(), "[V] abc");
+
+ v5 = "def";
+ verify(v5, spec<const char*>(), "[V] def");
+
+ v5 = v2;
+ verify(v5, spec<t_var2>(), "[V] [V] abc");
+
+ v6 = 58;
+ verify(v6, spec<unsigned short>(), "[V] 58");
+
+ v6 = v5;
+ verify(v6, spec<t_var5>(), "[V] [V] [V] abc");
+
+ v8 = v2;
+ verify(v8, spec<t_var6>(), "[V] [V] abc");
+
+ v8 = v6;
+ verify(v8, spec<t_var6>(), "[V] [V] [V] [V] abc");
+
+ v7 = v2;
+ verify(v7, spec<const void*>());
+
+ v7 = 199;
+ verify(v7, spec<class_a>(), "[V] class_a(199)");
+
+ v2 = 200;
+ v7 = v2;
+ verify(v7, spec<class_a>(), "[V] class_a(200)");
+
+
+
+ //
+ // Check sizes of held values
+ //
+ total_sizeof ts;
+
+ v1 = 5.9;
+ apply_visitor(ts, v1);
+
+ v1 = 'B';
+ apply_visitor(ts, v1);
+
+ v1 = 3.4f;
+ apply_visitor(ts, v1);
+
+ BOOST_TEST(ts.result() == sizeof(int) + sizeof(double)*2);
+
+ v11 = 5;
+ string res_s = apply_visitor(int_printer(), v11);
+ BOOST_TEST(res_s == "5");
+
+ //
+ // A variant object holding an std::vector
+ //
+ vector<int> int_vec_1;
+ int_vec_1.push_back(512);
+ int_vec_1.push_back(256);
+ int_vec_1.push_back(128);
+ int_vec_1.push_back(64);
+
+ v11 = int_vec_1;
+ res_s = apply_visitor(int_printer(), v11);
+ BOOST_TEST(res_s == ",512,256,128,64");
+}
+
+
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/test2.cpp b/src/boost/libs/variant/test/test2.cpp
new file mode 100644
index 00000000..12e31836
--- /dev/null
+++ b/src/boost/libs/variant/test/test2.cpp
@@ -0,0 +1,149 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test2.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
+#endif
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include "jobs.h"
+
+#include <cassert>
+#include <iostream>
+#include <algorithm>
+#include <cstring>
+
+using boost::apply_visitor;
+
+struct short_string
+{
+ BOOST_STATIC_CONSTANT(size_t, e_limit = 101);
+
+ short_string() : len_(0)
+ {
+ buffer_[0] = '\0';
+ }
+
+ short_string(const char* src)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::strlen;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ size_t limit = this->e_limit; // avoid warnings on some compilers
+ size_t src_len = strlen(src);
+
+ len_ = (std::min)(src_len, limit-1);
+ std::copy(src, src + len_, buffer_);
+ buffer_[len_] = '\0';
+ }
+
+ short_string(const short_string& other) : len_(other.len_)
+ {
+ std::copy(other.buffer_, other.buffer_ + e_limit, buffer_);
+ }
+
+ void swap(short_string& other)
+ {
+ char temp[e_limit];
+
+ std::copy(buffer_, buffer_ + e_limit, temp);
+ std::copy(other.buffer_, other.buffer_ + e_limit, buffer_);
+ std::copy(temp, temp + e_limit, other.buffer_);
+
+ std::swap(len_, other.len_);
+ }
+
+ short_string& operator=(const short_string& rhs)
+ {
+ short_string temp(rhs);
+ swap(temp);
+
+ return *this;
+ }
+
+ operator const char*() const
+ {
+ return buffer_;
+ }
+
+
+private:
+ char buffer_[e_limit];
+ size_t len_;
+}; //short_string
+
+
+std::ostream& operator<<(std::ostream& out, const short_string& s)
+{
+ out << static_cast<const char*>(s);
+ return out;
+}
+
+
+
+void run()
+{
+ using boost::variant;
+
+ variant<short, short_string> v0;
+ variant<char, const char*> v1;
+ variant<short_string, char > v2;
+
+ //
+ // Default construction
+ //
+ verify(v0, spec<short>());
+ verify(v1, spec<char>());
+ verify(v2, spec<short_string>());
+
+ //
+ // Implicit conversion to bounded type
+ //
+ v1 = "I am v1";
+ verify(v1, spec<const char*>(), "[V] I am v1");
+
+ v2 = "I am v2";
+ verify(v2, spec<short_string>(), "[V] I am v2");
+
+ //
+ // Variant-to-variant assignment
+ //
+
+ v0 = v1;
+ verify(v0, spec<short_string>(), "[V] I am v1");
+
+ v1 = v0;
+ verify(v1, spec<const char*>(), "[V] I am v1");
+
+ const int n0 = 88;
+ v1 = n0;
+ v0 = v1;
+
+ //
+ // Implicit conversion to bounded type
+ //
+ verify(v0, spec<short>(), "[V] 88");
+ verify(v1, spec<char>(), "[V] X");
+}
+
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test3.cpp b/src/boost/libs/variant/test/test3.cpp
new file mode 100644
index 00000000..27f0f589
--- /dev/null
+++ b/src/boost/libs/variant/test/test3.cpp
@@ -0,0 +1,134 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test3.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+/////////////////////////////////////////////////////////////////////
+
+using boost::variant;
+using boost::recursive_wrapper;
+using std::cout;
+using std::endl;
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+struct Add;
+struct Sub;
+
+typedef variant<int, recursive_wrapper<Add>, recursive_wrapper<Sub> > Expr;
+
+struct Sub
+{
+ Sub();
+ Sub(const Expr& l, const Expr& r);
+ Sub(const Sub& other);
+
+ Expr lhs_;
+ Expr rhs_;
+};
+
+struct Add
+{
+ Add() { }
+ Add(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
+ Add(const Add& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
+
+ Expr lhs_;
+ Expr rhs_;
+};
+
+Sub::Sub() { }
+Sub::Sub(const Expr& l, const Expr& r) : lhs_(l), rhs_(r) { }
+Sub::Sub(const Sub& other) : lhs_(other.lhs_), rhs_(other.rhs_) { }
+
+
+//
+// insert-to operators
+//
+std::ostream& operator<<(std::ostream& out, const Sub& a);
+
+std::ostream& operator<<(std::ostream& out, const Add& a)
+{
+ out << '(' << a.lhs_ << '+' << a.rhs_ << ')';
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const Sub& a)
+{
+ out << '(' << a.lhs_ << '-' << a.rhs_ << ')';
+ return out;
+}
+
+//
+// Expression evaluation visitor
+//
+struct Calculator : boost::static_visitor<int>
+{
+ Calculator() { }
+
+ int operator()(Add& x) const
+ {
+ Calculator calc;
+ int n1 = boost::apply_visitor(calc, x.lhs_);
+ int n2 = boost::apply_visitor(calc, x.rhs_);
+
+ return n1 + n2;
+ }
+
+ int operator()(Sub& x) const
+ {
+ return boost::apply_visitor(Calculator(), x.lhs_)
+ - boost::apply_visitor(Calculator(), x.rhs_);
+ }
+
+ int operator()(Expr& x) const
+ {
+ Calculator calc;
+ return boost::apply_visitor(calc, x);
+ }
+
+ int operator()(int x) const
+ {
+ return x;
+ }
+
+}; // Calculator
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+int main()
+{
+
+ int n = 13;
+ Expr e1( Add(n, Sub(Add(40,2),Add(10,4))) ); //n + (40+2)-(10+14) = n+28
+
+ std::ostringstream e1_str;
+ e1_str << e1;
+
+ BOOST_TEST(e1.type() == boost::typeindex::type_id<Add>());
+ BOOST_TEST(e1_str.str() == "(13+((40+2)-(10+4)))");
+
+ //Evaluate expression
+ int res = boost::apply_visitor(Calculator(), e1);
+ BOOST_TEST(res == n + 28);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test4.cpp b/src/boost/libs/variant/test/test4.cpp
new file mode 100644
index 00000000..bef83b36
--- /dev/null
+++ b/src/boost/libs/variant/test/test4.cpp
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test4.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
+#endif
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include "jobs.h"
+
+#include <string>
+
+struct class_a;
+
+using boost::variant;
+
+typedef variant<std::string, class_a, float> var_type_1;
+typedef variant<std::string, class_a, short> var_type_2;
+
+#include "class_a.h"
+
+int main()
+{
+ using namespace boost;
+
+ var_type_1 v1;
+ var_type_2 v2;
+
+ v1 = class_a();
+ verify(v1, spec<class_a>(), "[V] class_a(5511)");
+
+ verify(v2, spec<std::string>(), "[V] ");
+
+ v2 = "abcde";
+ verify(v2, spec<std::string>(), "[V] abcde");
+
+ v2 = v1;
+ verify(v2, spec<class_a>(), "[V] class_a(5511)");
+
+ v2 = 5;
+ v1 = v2;
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/test5.cpp b/src/boost/libs/variant/test/test5.cpp
new file mode 100644
index 00000000..5de06c8c
--- /dev/null
+++ b/src/boost/libs/variant/test/test5.cpp
@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test5.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include "jobs.h"
+
+#include <assert.h>
+#include <iostream>
+#include <string>
+#include <vector>
+
+
+void run()
+{
+ using std::string;
+ using boost::variant;
+ using boost::apply_visitor;
+
+ typedef variant<int, float, unsigned short, unsigned char> t_var1;
+ typedef variant<int, t_var1, unsigned short, unsigned char> t_var2;
+ typedef variant<string, int, t_var2> t_var3;
+
+ t_var1 v1;
+ t_var2 v2;
+ t_var2 v2_second;
+ t_var3 v3;
+
+ const char c0 = 'x';
+ v1 = c0;
+
+ //v2 and v3 are holding (aka: containing) a variant
+ v2 = v1;
+ v3 = v2;
+
+ verify(v1, spec<int>());
+ verify(v2, spec<t_var1>());
+ verify(v3, spec<t_var2>());
+
+
+ //
+ // assignment from const char (Converted to int)
+ //
+ v2 = c0;
+ v3 = c0;
+
+ verify(v2, spec<int>());
+ verify(v3, spec<int>());
+
+
+ BOOST_TEST(apply_visitor(sum_int(), v2) == c0);
+ BOOST_TEST(apply_visitor(sum_int(), v3) == c0);
+
+ sum_int adder;
+ apply_visitor(adder, v2);
+ apply_visitor(adder, v3);
+
+ BOOST_TEST(adder.result() == 2*c0);
+
+ //
+ // A variant holding a variant
+ //
+ typedef variant<unsigned char, float> t_var4;
+ typedef variant<string, t_var4> t_var5;
+
+ t_var4 v4;
+ t_var5 v5;
+
+ v5 = 22.5f;
+ verify(v5, spec<t_var4>(), "[V] [V] 22.5");
+}
+
+
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test6.cpp b/src/boost/libs/variant/test/test6.cpp
new file mode 100644
index 00000000..6a0c75d6
--- /dev/null
+++ b/src/boost/libs/variant/test/test6.cpp
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test6.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include <iostream>
+
+#include "jobs.h"
+
+
+//Just Another Class
+struct jac
+{
+ jac() { }
+ jac(int ) { }
+ jac(const char* ) { }
+};
+
+std::ostream& operator<<(std::ostream& out, const jac& )
+{
+ out << "jac ";
+ return out;
+}
+
+
+void run()
+{
+ using boost::variant;
+
+ variant<jac, int, double*, const double*> v1;
+ variant<int, char, double*, const double*, char*> v2;
+
+ v1 = v2;
+
+ verify(v1, spec<int>());
+ verify(v2, spec<int>());
+
+ verify_not(v1, spec<jac>());
+ verify_not(v1, spec<double*>());
+ verify_not(v1, spec<const double*>());
+
+ verify_not(v2, spec<char>());
+ verify_not(v2, spec<double*>());
+ verify_not(v2, spec<const double*>());
+ verify_not(v2, spec<char*>());
+
+
+ variant<jac, const double*> v3;
+ variant<int, unsigned char, double*> v4;
+
+ v3 = v4;
+ verify(v3, spec<jac>());
+ verify(v4, spec<int>());
+ verify_not(v4, spec<unsigned char>());
+}
+
+
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test7.cpp b/src/boost/libs/variant/test/test7.cpp
new file mode 100644
index 00000000..1acec31e
--- /dev/null
+++ b/src/boost/libs/variant/test/test7.cpp
@@ -0,0 +1,255 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test7.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4244) // conversion from 'const int' to 'const short'
+#endif
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include "jobs.h"
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+#include <map>
+
+#include "boost/detail/workaround.hpp"
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+# include "boost/mpl/bool.hpp"
+# include "boost/type_traits/is_same.hpp"
+#endif
+
+
+using namespace boost;
+using namespace std;
+
+
+struct jas
+{
+ jas(int n = 364);
+ jas(const jas& other);
+
+ ~jas();
+ jas& operator=(const jas& other);
+
+ void swap(jas& other);
+
+ int n_;
+
+ int sn_;
+ static int s_inst_id_;
+};
+
+struct Tracker
+{
+ typedef map<const jas*,int> table_type;
+ typedef table_type::iterator iterator_type;
+
+ static table_type s_this_to_sn_;
+
+ static void insert(const jas& j)
+ {
+ s_this_to_sn_[&j] = j.sn_;
+ cout << "jas( " << j.sn_ << ") Registered" << endl;
+ }
+
+ static void remove(const jas& j)
+ {
+ iterator_type iter = s_this_to_sn_.find(&j);
+ BOOST_TEST(iter != s_this_to_sn_.end());
+ BOOST_TEST( ((*iter).second) == j.sn_);
+
+ int sn = (*iter).second;
+ if(sn != j.sn_)
+ {
+ cout << "Mismatch: this = " << (*iter).first << ", sn_ = " << sn
+ << ", other: this = " << &j << ", j.sn_ = " << j.sn_ << endl;
+ }
+
+ BOOST_TEST(sn == j.sn_);
+
+
+
+
+
+ s_this_to_sn_.erase(&j);
+ cout << "jas( " << j.sn_ << ") Removed" << endl;
+ }
+
+ static void check()
+ {
+ BOOST_TEST(s_this_to_sn_.empty());
+ }
+};
+
+Tracker::table_type Tracker::s_this_to_sn_;
+
+
+
+jas::jas(int n) : n_(n)
+{
+ sn_ = s_inst_id_;
+ s_inst_id_ += 1;
+
+ Tracker::insert(*this);
+}
+
+jas::jas(const jas& other) : n_(other.n_)
+{
+ sn_ = s_inst_id_;
+ s_inst_id_ += 1;
+
+ Tracker::insert(*this);
+}
+
+jas::~jas()
+{
+ Tracker::remove(*this);
+}
+
+jas& jas::operator=(const jas& other)
+{
+ jas temp(other);
+ swap(temp);
+
+ return *this;
+}
+
+void jas::swap(jas& other)
+{
+ Tracker::remove(*this);
+ Tracker::remove(other);
+
+ std::swap(n_, other.n_);
+ std::swap(sn_, other.sn_);
+
+ Tracker::insert(*this);
+ Tracker::insert(other);
+}
+
+int jas::s_inst_id_ = 0;
+
+
+bool operator==(const jas& a, const jas& b)
+{
+ return a.n_ == b.n_;
+}
+
+ostream& operator<<(ostream& out, const jas& a)
+{
+ cout << "jas::n_ = " << a.n_;
+ return out;
+}
+
+
+template<typename ValueType>
+struct compare_helper : boost::static_visitor<bool>
+{
+ compare_helper(ValueType& expected) : expected_(expected) { }
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+
+ bool operator()(const ValueType& value)
+ {
+ return value == expected_;
+ }
+
+ template <typename T>
+ bool operator()(const T& )
+ {
+ return false;
+ }
+
+#else // MSVC6
+
+private:
+
+ bool compare_impl(const ValueType& value, boost::mpl::true_)
+ {
+ return value == expected_;
+ }
+
+ template <typename T>
+ bool compare_impl(const T&, boost::mpl::false_)
+ {
+ return false;
+ }
+
+public:
+
+ template <typename T>
+ bool operator()(const T& value)
+ {
+ typedef typename boost::is_same<T, ValueType>::type
+ T_is_ValueType;
+
+ return compare_impl(value, T_is_ValueType());
+ }
+
+#endif // MSVC6 workaround
+
+ ValueType& expected_;
+
+private:
+ compare_helper& operator=(const compare_helper&);
+
+};
+
+template<typename VariantType, typename ExpectedType>
+void var_compare(const VariantType& v, ExpectedType expected)
+{
+ compare_helper<ExpectedType> ch(expected);
+
+ bool checks = boost::apply_visitor(ch, v);
+ BOOST_TEST(checks);
+}
+
+
+void run()
+{
+ boost::variant<string, short> v0;
+
+ var_compare(v0, string(""));
+
+ v0 = 8;
+ var_compare(v0, static_cast<short>(8));
+
+ v0 = "penny lane";
+ var_compare(v0, string("penny lane"));
+
+ boost::variant<jas, string, int> v1, v2 = jas(195);
+ var_compare(v1, jas(364));
+
+ v1 = jas(500);
+ v1.swap(v2);
+
+ var_compare(v1, jas(195));
+ var_compare(v2, jas(500));
+
+
+ boost::variant<string, int> v3;
+ var_compare(v3, string(""));
+}
+
+
+int main()
+{
+ run();
+ Tracker::check();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test8.cpp b/src/boost/libs/variant/test/test8.cpp
new file mode 100644
index 00000000..94ef65ab
--- /dev/null
+++ b/src/boost/libs/variant/test/test8.cpp
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test8.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+using namespace boost;
+
+typedef variant<float, std::string, int, std::vector<std::string> > t_var1;
+
+struct int_sum : static_visitor<>
+{
+ int_sum() : result_(0) { }
+
+ void operator()(int t)
+ {
+ result_ += t;
+ }
+
+ result_type operator()(float ) { }
+ result_type operator()(const std::string& ) { }
+ result_type operator()(const std::vector<std::string>& ) { }
+
+ int result_;
+};
+
+template <typename T, typename Variant>
+T& check_pass(Variant& v, T value)
+{
+ BOOST_TEST(get<T>(&v));
+
+ try
+ {
+ T& r = get<T>(v);
+ BOOST_TEST(r == value);
+ return r;
+ }
+ catch(boost::bad_get&)
+ {
+ throw; // must never reach
+ }
+}
+
+template <typename T, typename Variant>
+void check_fail(Variant& v)
+{
+ BOOST_TEST(!relaxed_get<T>(&v));
+
+ try
+ {
+ T& r = relaxed_get<T>(v);
+ (void)r; // suppress warning about r not being used
+ BOOST_TEST(false && relaxed_get<T>(&v)); // should never reach
+ }
+ catch(const boost::bad_get& e)
+ {
+ BOOST_TEST(!!e.what()); // make sure that what() is const qualified and returnes something
+ }
+}
+
+int main()
+{
+ int_sum acc;
+ t_var1 v1 = 800;
+
+ // check get on non-const variant
+ {
+ int& r1 = check_pass<int>(v1, 800);
+ const int& cr1 = check_pass<const int>(v1, 800);
+
+ check_fail<float>(v1);
+ check_fail<const float>(v1);
+ check_fail<short>(v1);
+ check_fail<const short>(v1);
+
+ apply_visitor(acc, v1);
+ BOOST_TEST(acc.result_ == 800);
+
+ r1 = 920; // NOTE: modifies content of v1
+ apply_visitor(acc, v1);
+ BOOST_TEST(cr1 == 920);
+ BOOST_TEST(acc.result_ == 800 + 920);
+ }
+
+ // check const correctness:
+ {
+ const t_var1& c = v1;
+
+ check_pass<const int>(c, 920);
+
+ //check_fail<int>(c);
+ check_fail<const float>(c);
+ //check_fail<float>(c);
+ check_fail<const short>(c);
+ //check_fail<short>(c);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/test9.cpp b/src/boost/libs/variant/test/test9.cpp
new file mode 100644
index 00000000..465089cd
--- /dev/null
+++ b/src/boost/libs/variant/test/test9.cpp
@@ -0,0 +1,22 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/test9.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2016-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+// Test from https://github.com/boostorg/variant/pull/21
+
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/mpl.hpp>
+#include <boost/variant/variant.hpp>
+
+int main() {
+ boost::make_variant_over<boost::fusion::vector<int, char> >::type t;
+ (void)t;
+}
diff --git a/src/boost/libs/variant/test/variant_comparison_test.cpp b/src/boost/libs/variant/test/variant_comparison_test.cpp
new file mode 100644
index 00000000..a918a675
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_comparison_test.cpp
@@ -0,0 +1,158 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_comparison_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003 Eric Friedman, Itay Maman
+// Copyright (c) 2014-2019 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/core/lightweight_test.hpp"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <algorithm>
+#include <vector>
+
+#include "boost/detail/workaround.hpp"
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
+# pragma warn -lvc // temporary used for parameter warning
+#endif
+
+template <typename T>
+void assert_equality_comparable(
+ const T& x, const T& y, const T& z
+ )
+{
+ // identity check
+ BOOST_TEST( !(&x == &y) || (x == y) );
+ BOOST_TEST( !(&x == &z) || (x == z) );
+ BOOST_TEST( !(&y == &z) || (y == z) );
+ BOOST_TEST( !(&x == &y) || !(x != y) );
+ BOOST_TEST( !(&x == &z) || !(x != z) );
+ BOOST_TEST( !(&y == &z) || !(y != z) );
+
+ // reflexivity check
+ BOOST_TEST( (x == x) );
+ BOOST_TEST( (y == y) );
+ BOOST_TEST( (z == z) );
+
+ // symmetry check
+ BOOST_TEST( !(x == y) || (y == x) );
+ BOOST_TEST( !(y == x) || (x == y) );
+ BOOST_TEST( (x != y) || (y == x) );
+ BOOST_TEST( (y != x) || (x == y) );
+
+ BOOST_TEST( !(x == z) || (z == x) );
+ BOOST_TEST( !(z == x) || (x == z) );
+ BOOST_TEST( (x != z) || (z == x) );
+ BOOST_TEST( (z != x) || (x == z) );
+
+ BOOST_TEST( !(y == z) || (z == y) );
+ BOOST_TEST( !(z == y) || (y == z) );
+ BOOST_TEST( (y != z) || (z == y) );
+ BOOST_TEST( (z != y) || (y == z) );
+
+ // transitivity check
+ BOOST_TEST( !(x == y && y == z) || (x == z) );
+ BOOST_TEST( !(x == z && z == y) || (x == y) );
+ BOOST_TEST( !(y == z && z == x) || (y == x) );
+}
+
+template <typename T>
+void assert_less_than_comparable(
+ const T& x, const T& y, const T& z
+ )
+{
+ // irreflexivity check
+ BOOST_TEST( !(x < x) );
+ BOOST_TEST( !(y < y) );
+ BOOST_TEST( !(z < z) );
+ BOOST_TEST( !(x > x) );
+ BOOST_TEST( !(y > y) );
+ BOOST_TEST( !(z > z) );
+
+ BOOST_TEST( (x <= x) );
+ BOOST_TEST( (y <= y) );
+ BOOST_TEST( (z <= z) );
+ BOOST_TEST( (x >= x) );
+ BOOST_TEST( (y >= y) );
+ BOOST_TEST( (z >= z) );
+
+ // transitivity check
+ BOOST_TEST( (x < y) );
+ BOOST_TEST( (y < z) );
+ BOOST_TEST( (x < z) );
+
+ BOOST_TEST( (x <= y) );
+ BOOST_TEST( (y <= z) );
+ BOOST_TEST( (x <= z) );
+
+ BOOST_TEST( (z > y) );
+ BOOST_TEST( (y > x) );
+ BOOST_TEST( (z > x) );
+
+ BOOST_TEST( (z >= y) );
+ BOOST_TEST( (y >= x) );
+ BOOST_TEST( (z >= x) );
+
+ // antisymmetry check
+ BOOST_TEST( !(y < x) );
+ BOOST_TEST( !(z < y) );
+ BOOST_TEST( !(z < x) );
+}
+
+template <typename It>
+std::string print_range(It first, It last)
+{
+ std::ostringstream result;
+
+ while (first != last)
+ {
+ result << *first << ' ';
+ ++first;
+ }
+
+ return result.str();
+}
+
+int main()
+{
+ typedef boost::variant<int, std::string> var_t;
+
+ var_t var1(3);
+ var_t var2(5);
+ var_t var3("goodbye");
+ var_t var4("hello");
+
+ assert_equality_comparable(var1, var1, var1);
+ assert_equality_comparable(var_t(var1), var_t(var1), var_t(var1));
+ assert_equality_comparable(var1, var2, var3);
+
+ assert_less_than_comparable(var1, var2, var3);
+ assert_less_than_comparable(var2, var3, var4);
+
+ std::vector<var_t> vec;
+ vec.push_back( var3 );
+ vec.push_back( var2 );
+ vec.push_back( var4 );
+ vec.push_back( var1 );
+ std::sort(vec.begin(), vec.end());
+
+ std::string sort_result( print_range(vec.begin(), vec.end()) );
+ BOOST_TEST( sort_result == "3 5 goodbye hello " );
+
+ // https://svn.boost.org/trac/boost/ticket/11751
+ int a = 0, b = 0;
+
+ boost::variant< int& > v (a), u (b);
+ BOOST_TEST(v == u);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_get_test.cpp b/src/boost/libs/variant/test/variant_get_test.cpp
new file mode 100644
index 00000000..8fe09c1d
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_get_test.cpp
@@ -0,0 +1,417 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_get_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2014-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4127) // conditional expression is constant
+#pragma warning(disable: 4181) // qualifier applied to reference type; ignored
+#endif
+
+#include "boost/variant/get.hpp"
+#include "boost/variant/variant.hpp"
+#include "boost/variant/polymorphic_get.hpp"
+#include "boost/variant/recursive_wrapper.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+struct base {
+ int trash;
+
+ base() : trash(123) {}
+ base(const base& b) : trash(b.trash) { int i = 100; (void)i; }
+ const base& operator=(const base& b) {
+ trash = b.trash;
+ int i = 100; (void)i;
+
+ return *this;
+ }
+
+ virtual ~base(){}
+};
+
+struct derived1 : base{};
+struct derived2 : base{};
+
+struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
+struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
+struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
+struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
+
+typedef boost::variant<int, base, derived1, derived2, std::string> var_t;
+typedef boost::variant<int, derived1, derived2, std::string> var_t_shortened;
+typedef boost::variant<base, derived1, derived2> var_t_no_fallback;
+typedef boost::variant<int&, base&, derived1&, derived2&, std::string&> var_ref_t;
+typedef boost::variant<const int&, const base&, const derived1&, const derived2&, const std::string&> var_cref_t;
+
+struct recursive_structure;
+typedef boost::variant<
+ int, base, derived1, derived2, std::string, boost::recursive_wrapper<recursive_structure>
+> var_req_t;
+struct recursive_structure { var_req_t var; };
+
+template <class TypeInVariant, class V, class TestType>
+inline void check_polymorphic_get_on_types_impl_single_type(V* v)
+{
+ typedef typename boost::add_reference<TestType>::type ref_test_t;
+ typedef typename boost::add_reference<const TestType>::type cref_test_t;
+ const bool exact_same = !!boost::is_same<TypeInVariant, TestType>::value;
+ const bool ref_same = !!boost::is_same<TypeInVariant, ref_test_t>::value;
+
+ if (exact_same || ref_same) {
+ BOOST_TEST(boost::polymorphic_get<TestType>(v));
+ BOOST_TEST(boost::polymorphic_get<const TestType>(v));
+ BOOST_TEST(boost::polymorphic_strict_get<TestType>(v));
+ BOOST_TEST(boost::polymorphic_strict_get<const TestType>(v));
+ BOOST_TEST(boost::polymorphic_relaxed_get<TestType>(v));
+ BOOST_TEST(boost::polymorphic_relaxed_get<const TestType>(v));
+
+ BOOST_TEST(boost::polymorphic_get<cref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_strict_get<cref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_relaxed_get<cref_test_t>(v));
+
+ if (ref_same) {
+ BOOST_TEST(boost::polymorphic_get<ref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_get<cref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_strict_get<ref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_strict_get<cref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_relaxed_get<ref_test_t>(v));
+ BOOST_TEST(boost::polymorphic_relaxed_get<cref_test_t>(v));
+ }
+ } else {
+ BOOST_TEST(!boost::polymorphic_get<TestType>(v));
+ BOOST_TEST(!boost::polymorphic_get<const TestType>(v));
+ BOOST_TEST(!boost::polymorphic_strict_get<TestType>(v));
+ BOOST_TEST(!boost::polymorphic_strict_get<const TestType>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<TestType>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<const TestType>(v));
+ }
+}
+
+template <class T, class V, class TestType>
+inline void check_get_on_types_impl_single_type(V* v)
+{
+ typedef typename boost::add_reference<TestType>::type ref_test_t;
+ typedef typename boost::add_reference<const TestType>::type cref_test_t;
+ const bool exact_same = !!boost::is_same<T, TestType>::value;
+ const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
+
+ if (exact_same || ref_same) {
+ BOOST_TEST(boost::get<TestType>(v));
+ BOOST_TEST(boost::get<const TestType>(v));
+ BOOST_TEST(boost::strict_get<TestType>(v));
+ BOOST_TEST(boost::strict_get<const TestType>(v));
+ BOOST_TEST(boost::relaxed_get<TestType>(v));
+ BOOST_TEST(boost::relaxed_get<const TestType>(v));
+
+ BOOST_TEST(boost::get<cref_test_t>(v));
+ BOOST_TEST(boost::strict_get<cref_test_t>(v));
+ BOOST_TEST(boost::relaxed_get<cref_test_t>(v));
+
+ if (ref_same) {
+ BOOST_TEST(boost::get<ref_test_t>(v));
+ BOOST_TEST(boost::get<cref_test_t>(v));
+ BOOST_TEST(boost::strict_get<ref_test_t>(v));
+ BOOST_TEST(boost::strict_get<cref_test_t>(v));
+ BOOST_TEST(boost::relaxed_get<ref_test_t>(v));
+ BOOST_TEST(boost::relaxed_get<cref_test_t>(v));
+ }
+ } else {
+ BOOST_TEST(!boost::get<TestType>(v));
+ BOOST_TEST(!boost::get<const TestType>(v));
+ BOOST_TEST(!boost::strict_get<TestType>(v));
+ BOOST_TEST(!boost::strict_get<const TestType>(v));
+ BOOST_TEST(!boost::relaxed_get<TestType>(v));
+ BOOST_TEST(!boost::relaxed_get<const TestType>(v));
+ }
+}
+
+template <class T, class V>
+inline void check_get_on_types_impl(V* v)
+{
+ check_get_on_types_impl_single_type<T, V, int>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, int>(v);
+
+ check_get_on_types_impl_single_type<T, V, base>(v);
+
+ check_get_on_types_impl_single_type<T, V, derived1>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, derived1>(v);
+
+ check_get_on_types_impl_single_type<T, V, derived2>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, derived2>(v);
+
+ check_get_on_types_impl_single_type<T, V, std::string>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, std::string>(v);
+
+ // Never exist in here
+ BOOST_TEST(!boost::relaxed_get<short>(v));
+ BOOST_TEST(!boost::relaxed_get<const short>(v));
+ BOOST_TEST(!boost::relaxed_get<char>(v));
+ BOOST_TEST(!boost::relaxed_get<char*>(v));
+ BOOST_TEST(!boost::relaxed_get<bool>(v));
+ BOOST_TEST(!boost::relaxed_get<const bool>(v));
+
+ BOOST_TEST(!boost::polymorphic_relaxed_get<short>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<const short>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<char>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<char*>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<bool>(v));
+ BOOST_TEST(!boost::polymorphic_relaxed_get<const bool>(v));
+
+ boost::get<T>(*v); // Must compile
+ boost::get<const T>(*v); // Must compile
+ boost::strict_get<T>(*v); // Must compile
+ boost::strict_get<const T>(*v); // Must compile
+
+ bool is_ref = boost::is_lvalue_reference<T>::value;
+ (void)is_ref;
+ if (!is_ref) {
+ boost::polymorphic_get<T>(*v); // Must compile
+ boost::polymorphic_get<const T>(*v); // Must compile
+ boost::polymorphic_strict_get<T>(*v); // Must compile
+ boost::polymorphic_strict_get<const T>(*v); // Must compile
+ }
+}
+
+template <class T, class V>
+inline void check_get_on_types(V* v)
+{
+ check_get_on_types_impl<T, V>(v);
+ check_get_on_types_impl<T, const V>(v);
+}
+
+inline void get_test()
+{
+ var_t v;
+ check_get_on_types<int>(&v);
+
+ var_t(base()).swap(v);
+ check_get_on_types<base>(&v);
+
+ var_t(derived1()).swap(v);
+ check_get_on_types<derived1>(&v);
+
+ var_t(derived2()).swap(v);
+ check_get_on_types<derived2>(&v);
+
+ var_t(std::string("Hello")).swap(v);
+ check_get_on_types<std::string>(&v);
+
+ var_t_shortened vs = derived2();
+ check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
+ // Checking that Base is really determinated
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
+
+ vs = derived1();
+ check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
+ // Checking that Base is really determinated
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
+}
+
+inline void get_test_no_fallback()
+{
+ var_t_no_fallback v;
+ var_t_no_fallback(base()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+
+ var_t_no_fallback(derived1()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<derived1, var_t_no_fallback, derived1>(&v);
+ check_get_on_types_impl_single_type<derived1, const var_t_no_fallback, derived1>(&v);
+
+ var_t_no_fallback(derived2()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<derived2, var_t_no_fallback, derived2>(&v);
+ check_get_on_types_impl_single_type<derived2, const var_t_no_fallback, derived2>(&v);
+}
+
+inline void get_ref_test()
+{
+ int i = 0;
+ var_ref_t v(i);
+ check_get_on_types<int>(&v);
+ check_get_on_types<int&>(&v);
+
+ base b;
+ var_ref_t v1(b);
+ check_get_on_types<base>(&v1);
+ check_get_on_types<base&>(&v1);
+
+ derived1 d1;
+ var_ref_t v2(d1);
+ check_get_on_types<derived1>(&v2);
+ check_get_on_types<derived1&>(&v2);
+
+ derived2 d2;
+ var_ref_t v3(d2);
+ check_get_on_types<derived2>(&v3);
+ check_get_on_types<derived2&>(&v3);
+
+ std::string s("Hello");
+ var_ref_t v4(s);
+ check_get_on_types<std::string>(&v4);
+ check_get_on_types<std::string&>(&v4);
+}
+
+
+inline void get_cref_test()
+{
+ int i = 0;
+ var_cref_t v(i);
+ BOOST_TEST(boost::get<const int>(&v));
+ BOOST_TEST(boost::get<const int&>(&v));
+ BOOST_TEST(!boost::get<const base>(&v));
+
+ base b;
+ var_cref_t v1(b);
+ BOOST_TEST(boost::get<const base>(&v1));
+ BOOST_TEST(!boost::get<const derived1>(&v1));
+ BOOST_TEST(!boost::get<const int>(&v1));
+
+ std::string s("Hello");
+ const var_cref_t v4 = s;
+ BOOST_TEST(boost::get<const std::string>(&v4));
+ BOOST_TEST(!boost::get<const int>(&v4));
+}
+
+inline void get_recursive_test()
+{
+ var_req_t v;
+ check_get_on_types<int>(&v);
+
+ var_req_t(base()).swap(v);
+ check_get_on_types<base>(&v);
+
+ var_req_t(derived1()).swap(v);
+ check_get_on_types<derived1>(&v);
+
+ var_req_t(derived2()).swap(v);
+ check_get_on_types<derived2>(&v);
+
+ var_req_t(std::string("Hello")).swap(v);
+ check_get_on_types<std::string>(&v);
+
+ recursive_structure s = { v }; // copying "v"
+ v = s;
+ check_get_on_types<recursive_structure>(&v);
+}
+
+template <class T>
+inline void check_that_does_not_exist_impl()
+{
+ using namespace boost::detail::variant;
+
+ BOOST_TEST((holds_element<T, const int>::value));
+ BOOST_TEST((!holds_element<T, short>::value));
+ BOOST_TEST((!holds_element<T, short>::value));
+ BOOST_TEST((!holds_element<T, const short>::value));
+ BOOST_TEST((!holds_element<T, char*>::value));
+ BOOST_TEST((!holds_element<T, const char*>::value));
+ BOOST_TEST((!holds_element<T, char[5]>::value));
+ BOOST_TEST((!holds_element<T, const char[5]>::value));
+ BOOST_TEST((!holds_element<T, bool>::value));
+ BOOST_TEST((!holds_element<T, const bool>::value));
+
+ BOOST_TEST((!holds_element<T, boost::recursive_wrapper<int> >::value));
+ BOOST_TEST((!holds_element<T, boost::recursive_wrapper<short> >::value));
+ BOOST_TEST((!holds_element<T, boost::detail::reference_content<short> >::value));
+
+
+ BOOST_TEST((holds_element_polymorphic<T, const int>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, short>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, short>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, const short>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, char*>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, const char*>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, char[5]>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, const char[5]>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, bool>::value));
+ BOOST_TEST((!holds_element_polymorphic<T, const bool>::value));
+
+ BOOST_TEST((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
+ BOOST_TEST((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
+ BOOST_TEST((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
+}
+
+inline void check_that_does_not_exist()
+{
+ using namespace boost::detail::variant;
+
+ BOOST_TEST((holds_element<var_t, int>::value));
+ BOOST_TEST((holds_element<var_ref_t, int>::value));
+ BOOST_TEST((!holds_element<var_cref_t, int>::value));
+
+ check_that_does_not_exist_impl<var_t>();
+ check_that_does_not_exist_impl<var_ref_t>();
+ check_that_does_not_exist_impl<var_cref_t>();
+ check_that_does_not_exist_impl<var_req_t>();
+}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+class MoveonlyType {
+public:
+ MoveonlyType() {}
+ ~MoveonlyType() {}
+
+ MoveonlyType(MoveonlyType&&) {}
+ void operator=(MoveonlyType&&) {}
+
+private:
+ MoveonlyType(const MoveonlyType&);
+ void operator=(const MoveonlyType&);
+};
+
+const boost::variant<int, std::string> foo1() { return ""; }
+boost::variant<int, std::string> foo2() { return ""; }
+
+inline void get_rvref_test()
+{
+ boost::get<std::string>(foo1());
+ boost::get<std::string>(foo2());
+
+ boost::variant<MoveonlyType, int> v;
+
+ v = MoveonlyType();
+ boost::get<MoveonlyType>(boost::move(v));
+
+ v = 3;
+
+ v = MoveonlyType();
+ boost::get<MoveonlyType>(v);
+
+ boost::relaxed_get<MoveonlyType&>(boost::variant<MoveonlyType, int>());
+
+ v = MoveonlyType();
+ MoveonlyType moved_from_variant(boost::get<MoveonlyType>(boost::move(v)));
+}
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+int main()
+{
+ get_test();
+ get_test_no_fallback();
+ get_ref_test();
+ get_cref_test();
+ get_recursive_test();
+ check_that_does_not_exist();
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ get_rvref_test();
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_multivisit_test.cpp b/src/boost/libs/variant/test/variant_multivisit_test.cpp
new file mode 100644
index 00000000..a614dd33
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_multivisit_test.cpp
@@ -0,0 +1,159 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_multivisit_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2013-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+#include "boost/noncopyable.hpp"
+#define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
+#include "boost/variant/multivisitors.hpp"
+#include "boost/variant.hpp"
+
+#include "boost/core/lightweight_test.hpp"
+
+struct my_noncopyable : boost::noncopyable {
+ my_noncopyable(){}
+ ~my_noncopyable(){}
+};
+
+typedef boost::variant<my_noncopyable, int> variant_noncopy_t;
+
+
+typedef boost::variant<char, unsigned char, signed char, unsigned short, int, unsigned int> variant6_t;
+
+struct test_visitor: boost::static_visitor<> {
+ // operators that shall not be called
+ template <class T1, class T2, class T3>
+ void operator()(T1&, T2&, T3&) const
+ {
+ BOOST_TEST(false);
+ }
+
+ template <class T1, class T2, class T3, class T4>
+ void operator()(T1&, T2&, T3&, T4&) const
+ {
+ BOOST_TEST(false);
+ }
+
+ template <class T1, class T2, class T3, class T4, class T5>
+ void operator()(T1&, T2&, T3&, T4&, T5&) const
+ {
+ BOOST_TEST(false);
+ }
+
+ // operators that are OK to call
+ void operator()(char v0, unsigned char v1, signed char v2) const
+ {
+ BOOST_TEST(v0 == 0);
+ BOOST_TEST(v1 == 1);
+ BOOST_TEST(v2 == 2);
+ }
+
+ void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const
+ {
+ BOOST_TEST(v0 == 0);
+ BOOST_TEST(v1 == 1);
+ BOOST_TEST(v2 == 2);
+ BOOST_TEST(v3 == 3);
+ }
+
+ void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const
+ {
+ BOOST_TEST(v0 == 0);
+ BOOST_TEST(v1 == 1);
+ BOOST_TEST(v2 == 2);
+ BOOST_TEST(v3 == 3);
+ BOOST_TEST(v4 == 4);
+ }
+
+
+ // Noncopyables
+ void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
+ BOOST_TEST(true);
+ }
+ void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
+ BOOST_TEST(true);
+ }
+ void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
+ BOOST_TEST(true);
+ }
+ void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
+ BOOST_TEST(true);
+ }
+};
+
+typedef boost::variant<int, double, bool> bool_like_t;
+typedef boost::variant<int, double> arithmetics_t;
+
+struct if_visitor: public boost::static_visitor<arithmetics_t> {
+ template <class T0, class T1, class T2>
+ arithmetics_t operator()(T0 b, T1 v1, T2 v2) const {
+ if (!!b) {
+ return v1;
+ } else {
+ return v2;
+ }
+ }
+};
+
+
+int main()
+{
+ test_visitor v;
+
+ variant6_t v_array6[6];
+ v_array6[0] = char(0);
+ v_array6[1] = static_cast<unsigned char>(1);
+ v_array6[2] = static_cast<signed char>(2);
+ v_array6[3] = static_cast<unsigned short>(3);
+ v_array6[4] = static_cast<int>(4);
+ v_array6[5] = static_cast<unsigned int>(5);
+
+ boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2]);
+ boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2]);
+
+// Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
+//#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
+#ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
+ boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
+ boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
+
+ boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
+ boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
+#endif
+
+ bool_like_t v0(1), v1(true), v2(1.0);
+
+ BOOST_TEST(
+ boost::apply_visitor(if_visitor(), v0, v1, v2)
+ ==
+ arithmetics_t(true)
+ );
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+ if_visitor if_vis;
+ BOOST_TEST(
+ 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::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_nonempty_check.cpp b/src/boost/libs/variant/test/variant_nonempty_check.cpp
new file mode 100644
index 00000000..d6150e69
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_nonempty_check.cpp
@@ -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-2019 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/core/lightweight_test.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_TEST(!v.which());
+ BOOST_TEST(boost::get<throwing_class>(&v));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v.which());
+ BOOST_TEST(boost::get<throwing_class>(&v));
+ }
+
+ try {
+ throwing_class tc(helper);
+ v = tc;
+ BOOST_TEST(!v.which());
+ BOOST_TEST(boost::get<throwing_class>(&v));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v.which());
+ BOOST_TEST(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_TEST(v.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v.which());
+ BOOST_TEST(boost::get<Nonthrowing>(&v));
+ }
+
+ try {
+ throwing_class cl(helper);
+ v = cl;
+ BOOST_TEST(v.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v.which());
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v1));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v1.which());
+ BOOST_TEST(boost::get<Nonthrowing>(&v1));
+ }
+
+
+ try {
+ v2 = throwing_class(helper);
+ BOOST_TEST(v2.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v2));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v2.which());
+ BOOST_TEST(boost::get<Nonthrowing>(&v2));
+ }
+
+
+ if (!v1.which() && !v2.which()) {
+ swap(v1, v2); // Make sure that two backup holders swap well
+ BOOST_TEST(!v1.which());
+ BOOST_TEST(boost::get<Nonthrowing>(&v1));
+ BOOST_TEST(!v2.which());
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v1));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v1.which());
+ BOOST_TEST(boost::get<int>(&v1));
+ }
+
+
+ try {
+ v2 = throwing_class(helper);
+ BOOST_TEST(v2.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v2));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(!v2.which());
+ BOOST_TEST(boost::get<int>(&v2));
+ }
+
+ if (!v1.which() && !v2.which()) {
+ swap(v1, v2);
+ BOOST_TEST(!v1.which());
+ BOOST_TEST(boost::get<int>(&v1));
+ BOOST_TEST(!v2.which());
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v1));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(v1.which() == 1);
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v1));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(v1.which() == 0);
+ BOOST_TEST(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_TEST(v1.which() == v2_type);
+ BOOST_TEST(v2.which() == v1_type);
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(v1.which() == v1_type);
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(boost::get<throwing_class>(&v1));
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(v1.which() == 0);
+ }
+
+ v2 = Nonthrowing();
+ try {
+ v2 = 2;
+ BOOST_TEST(false);
+ } catch (const exception_on_assignment& /*e*/) {
+ BOOST_TEST(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_TEST(v1.which() == 1);
+ BOOST_TEST(v2.which() == 0);
+ BOOST_TEST(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 main()
+{
+ // 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::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_over_joint_view_test.cpp b/src/boost/libs/variant/test/variant_over_joint_view_test.cpp
new file mode 100644
index 00000000..c57302cb
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_over_joint_view_test.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) 2017
+// Mikhail Maximov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// The test is base on https://svn.boost.org/trac/boost/ticket/8554
+// variant was not able to extract types from mpl::joint_view
+
+#include <string>
+
+#include "boost/config.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#include "boost/variant.hpp"
+#include "boost/mpl/joint_view.hpp"
+#include "boost/mpl/insert_range.hpp"
+#include "boost/mpl/set.hpp"
+
+template<class T, class Variant>
+void check_exception_on_get(Variant& v) {
+ try {
+ boost::get<T>(v);
+ BOOST_ERROR("Expected exception boost::bad_get, but got nothing.");
+ } catch (boost::bad_get&) { //okay it is expected behaviour
+ } catch (...) { BOOST_ERROR("Expected exception boost::bad_get, but got something else."); }
+}
+
+void test_joint_view() {
+ typedef boost::variant<int> v1;
+ typedef boost::variant<std::string> v2;
+ typedef boost::make_variant_over<boost::mpl::joint_view<v1::types, v2::types>::type>::type v3;
+
+ v1 a = 1;
+ v2 b = "2";
+ v3 c = a;
+ BOOST_TEST(boost::get<int>(c) == 1);
+ BOOST_TEST(c.which() == 0);
+ v3 d = b;
+ BOOST_TEST(boost::get<std::string>(d) == "2");
+ BOOST_TEST(d.which() == 1);
+ check_exception_on_get<std::string>(c);
+ check_exception_on_get<int>(d);
+}
+
+void test_set() {
+ typedef boost::mpl::set2< std::string, int > types;
+ typedef boost::make_variant_over< types >::type v;
+
+ v a = 1;
+ BOOST_TEST(boost::get<int>(a) == 1);
+ check_exception_on_get<std::string>(a);
+ a = "2";
+ BOOST_TEST(boost::get<std::string>(a) == "2");
+ check_exception_on_get<int>(a);
+}
+
+int main()
+{
+ test_joint_view();
+ test_set();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_polymorphic_get_test.cpp b/src/boost/libs/variant/test/variant_polymorphic_get_test.cpp
new file mode 100644
index 00000000..e1afce6a
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_polymorphic_get_test.cpp
@@ -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-2019 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/core/lightweight_test.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_TEST(false);
+ } catch (const boost::bad_polymorphic_get& e) {
+ BOOST_TEST(!!e.what());
+ BOOST_TEST(std::string(e.what()) != boost::bad_get().what());
+ }
+}
+
+int main()
+{
+ typedef boost::variant<int, base, derived1, derived2> var_t;
+
+ var_t var1;
+ BOOST_TEST(!boost::polymorphic_get<base>(&var1));
+ check_throws<base>(var1);
+ BOOST_TEST(!boost::polymorphic_get<const base>(&var1));
+ check_throws<base, const var_t>(var1);
+
+ var1 = derived1();
+ BOOST_TEST(boost::polymorphic_get<base>(&var1));
+ BOOST_TEST(boost::polymorphic_get<const base>(&var1));
+
+ derived2 d;
+ d.trash = 777;
+ var_t var2 = d;
+ BOOST_TEST(boost::polymorphic_get<base>(var2).trash == 777);
+ BOOST_TEST(boost::polymorphic_get<const base>(var2).trash == 777);
+
+ var2 = 777;
+ BOOST_TEST(!boost::polymorphic_get<base>(&var2));
+ check_throws<base>(var2);
+ BOOST_TEST(!boost::polymorphic_get<const base>(&var2));
+ check_throws<base, const var_t>(var2);
+ BOOST_TEST(boost::polymorphic_get<int>(var2) == 777);
+ BOOST_TEST(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_TEST(boost::polymorphic_get<vbase>(cv).trash == 777);
+ BOOST_TEST(boost::polymorphic_get<const vbase>(cv).trash == 777);
+
+ BOOST_TEST(boost::polymorphic_get<vbase>(cv).foo() == 3);
+ BOOST_TEST(boost::polymorphic_get<vbase>(v).foo() == 3);
+ BOOST_TEST(boost::polymorphic_get<const vbase>(cv).foo() == 3);
+ BOOST_TEST(boost::polymorphic_get<const vbase>(v).foo() == 3);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_reference_test.cpp b/src/boost/libs/variant/test/variant_reference_test.cpp
new file mode 100644
index 00000000..3f7f5812
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_reference_test.cpp
@@ -0,0 +1,116 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_reference_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/variant.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#include "boost/mpl/bool.hpp"
+#include "boost/type_traits/add_reference.hpp"
+#include "boost/type_traits/is_pointer.hpp"
+
+/////
+// support types and functions
+
+struct base_t { };
+struct derived_t : base_t { };
+
+template <typename Base, typename Derived>
+bool check_base_derived(Base* b, Derived* d, long)
+{
+ return b == d;
+}
+
+template <typename Base, typename Derived>
+bool check_base_derived(Base& b, Derived& d, int)
+{
+ return &b == &d;
+}
+
+template <typename T>
+ typename boost::add_reference<T>::type
+wknd_get(boost::variant<T&>& var, long)
+{
+ return boost::get<T>(var);
+}
+
+template <typename T>
+ typename boost::add_reference<T>::type
+wknd_get(boost::variant<T>& var, int)
+{
+ return boost::get<T>(var);
+}
+
+/////
+// test functions
+
+template <typename T>
+void test_reference_content(T& t, const T& value1, const T& value2)
+{
+ BOOST_TEST( !(value1 == value2) );
+
+ /////
+
+ boost::variant< T& > var(t);
+ BOOST_TEST(( boost::get<T>(&var) == &t ));
+
+ t = value1;
+ BOOST_TEST(( boost::get<T>(var) == value1 ));
+
+ /////
+
+ boost::variant< T > var2(var);
+ BOOST_TEST(( boost::get<T>(var2) == value1 ));
+
+ t = value2;
+ BOOST_TEST(( boost::get<T>(var2) == value1 ));
+}
+
+template <typename Base, typename Derived>
+void base_derived_test(Derived d)
+{
+ Base b(d);
+ BOOST_TEST((check_base_derived(
+ b
+ , d
+ , 1L
+ )));
+
+ boost::variant<Base> base_var(d);
+ BOOST_TEST((check_base_derived(
+ wknd_get(base_var, 1L)
+ , d
+ , 1L
+ )));
+
+ boost::variant<Derived> derived_var(d);
+ boost::variant<Base> base_from_derived_var(derived_var);
+ BOOST_TEST((check_base_derived(
+ wknd_get(base_from_derived_var, 1L)
+ , wknd_get(derived_var, 1L)
+ , 1L
+ )));
+}
+
+int main()
+{
+ int i = 0;
+ test_reference_content(i, 1, 2);
+
+ /////
+
+ derived_t d;
+ base_derived_test< int&,int >(i);
+ base_derived_test< base_t*,derived_t* >(&d);
+ base_derived_test< base_t&,derived_t& >(d);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_rvalue_get_with_ampersand_test.cpp b/src/boost/libs/variant/test/variant_rvalue_get_with_ampersand_test.cpp
new file mode 100644
index 00000000..674412c8
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_rvalue_get_with_ampersand_test.cpp
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_get_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2017 Albert Sverdlov
+//
+// 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/core/lightweight_test.hpp"
+
+#include <boost/move/move.hpp>
+#include <boost/static_assert.hpp>
+
+#include <string>
+
+#define UNUSED(v) (void)(v)
+
+inline void run()
+{
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ typedef boost::variant<int, std::string> var_t;
+
+ std::string s = "abacaba";
+ var_t v = s;
+
+ // must spit an error at compile-time because of 'std::string&'
+ std::string new_s = boost::strict_get<std::string&>(boost::move(v));
+ UNUSED(new_s);
+#else
+ BOOST_STATIC_ASSERT_MSG(false, "Dummy compile-time error to pass the test on C++03");
+#endif
+}
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant/test/variant_swap_test.cpp b/src/boost/libs/variant/test/variant_swap_test.cpp
new file mode 100644
index 00000000..08e8e507
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_swap_test.cpp
@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_swap_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2009 ArtVPS Ltd.
+// Copyright (c) 2013-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/core/lightweight_test.hpp"
+#include "boost/variant.hpp"
+
+#include <vector>
+#include <algorithm>
+
+void run1()
+{
+ using boost::variant;
+ typedef variant< int, std::vector<int>* > t_var;
+
+ std::vector<int> vec;
+ t_var v0(23), v1(&vec);
+
+ BOOST_TEST(v0.which() == 0);
+ BOOST_TEST(v1.which() == 1);
+
+ swap(v0, v1);
+
+ BOOST_TEST(v0.which() == 1);
+ BOOST_TEST(v1.which() == 0);
+}
+
+void run2()
+{
+ using boost::variant;
+ using std::swap;
+ typedef variant< std::vector<int>, std::vector<double> > t_var;
+
+ std::vector<int> vec1;
+ std::vector<double> vec2;
+ t_var v0(vec1), v1(vec2);
+
+ BOOST_TEST(v0.which() == 0);
+ BOOST_TEST(v1.which() == 1);
+
+ swap(v0, v1);
+
+ BOOST_TEST(v0.which() == 1);
+ BOOST_TEST(v1.which() == 0);
+
+ v0.swap(v1);
+
+ BOOST_TEST(v0.which() == 0);
+ BOOST_TEST(v1.which() == 1);
+}
+
+void run3()
+{
+ using boost::variant;
+ using std::swap;
+ typedef variant< int, double > t_var;
+
+ t_var v0(1), v1(2.0);
+
+ BOOST_TEST(v0.which() == 0);
+ BOOST_TEST(v1.which() == 1);
+
+ swap(v0, v1);
+
+ BOOST_TEST(v0.which() == 1);
+ BOOST_TEST(v1.which() == 0);
+
+ v0.swap(v1);
+
+ BOOST_TEST(v0.which() == 0);
+ BOOST_TEST(v1.which() == 1);
+}
+
+int main()
+{
+ run1();
+ run2();
+ run3();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/variant/test/variant_visit_internal_linkage.cpp b/src/boost/libs/variant/test/variant_visit_internal_linkage.cpp
new file mode 100644
index 00000000..81afb8e5
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_visit_internal_linkage.cpp
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_visit_internal_linkage.cpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2018 Louis Dionne, Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This test checks that we can visit a variant containing a type that has
+// internal linkage (anonymous namespace).
+
+#include "boost/variant/variant.hpp"
+
+#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO
+
+void run() {}
+
+#else
+
+namespace {
+ struct Foo { };
+
+ struct Visitor {
+ void operator()(Foo const&) const { }
+ };
+}
+
+void run() {
+ boost::variant<Foo> v = Foo();
+ boost::apply_visitor(Visitor(), v);
+}
+
+#endif
+
+int main() {
+ run();
+}
+
diff --git a/src/boost/libs/variant/test/variant_visit_test.cpp b/src/boost/libs/variant/test/variant_visit_test.cpp
new file mode 100644
index 00000000..3a8dd1b9
--- /dev/null
+++ b/src/boost/libs/variant/test/variant_visit_test.cpp
@@ -0,0 +1,170 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_visit_test.cpp source 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)
+
+#include "boost/variant/variant.hpp"
+#include "boost/variant/apply_visitor.hpp"
+#include "boost/variant/static_visitor.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#include "boost/mpl/bool.hpp"
+#include "boost/mpl/and.hpp"
+#include "boost/type_traits/is_same.hpp"
+
+struct udt1
+{
+};
+
+struct udt2
+{
+};
+
+template <typename T>
+class unary_check_content_type
+ : public boost::static_visitor<bool>
+{
+public:
+
+ // not recommended design, but simplifies workarounds:
+
+ template <typename U>
+ bool operator()(U&) const
+ {
+ return ::boost::is_same<T,U>::value;
+ }
+
+};
+
+template <typename T1, typename T2>
+class binary_check_content_type
+ : public boost::static_visitor<bool>
+{
+public:
+
+ // not recommended design, but simplifies workarounds:
+
+ template <typename U1, typename U2>
+ bool operator()(U1&, U2&) const
+ {
+ return ::boost::mpl::and_<
+ boost::is_same<T1,U1>
+ , boost::is_same<T2,U2>
+ >::value;
+ }
+
+};
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS // BOOST_NO_CXX11_RVALUE_REFERENCES is not enough for disabling buggy GCCs < 4.8
+struct rvalue_ref_visitor
+{
+ typedef int result_type;
+ int operator()(udt1&&) const { return 0; }
+ int operator()(udt2&&) const { return 1; }
+};
+#endif
+#ifdef BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
+struct rvalue_ref_decltype_visitor
+{
+ int operator()(udt1&&) const { return 0; }
+ int operator()(udt2&&) const { return 1; }
+};
+#endif
+
+template <typename Checker, typename Variant>
+inline void unary_test(Variant& var, Checker* = 0)
+{
+ Checker checker;
+ const Checker& const_checker = checker;
+
+ // standard tests
+
+ BOOST_TEST( boost::apply_visitor(checker, var) );
+ BOOST_TEST( boost::apply_visitor(const_checker, var) );
+ BOOST_TEST( boost::apply_visitor(Checker(), var) );
+
+ // delayed tests
+
+ BOOST_TEST( boost::apply_visitor(checker)(var) );
+ BOOST_TEST( boost::apply_visitor(const_checker)(var) );
+}
+
+template <typename Checker, typename Variant1, typename Variant2>
+inline void binary_test(Variant1& var1, Variant2& var2, Checker* = 0)
+{
+ Checker checker;
+ const Checker& const_checker = checker;
+
+ // standard tests
+
+ BOOST_TEST( boost::apply_visitor(checker, var1, var2) );
+ BOOST_TEST( boost::apply_visitor(const_checker, var1, var2) );
+ BOOST_TEST( boost::apply_visitor(Checker(), var1, var2) );
+
+ // delayed tests
+
+ BOOST_TEST( boost::apply_visitor(checker)(var1, var2) );
+ BOOST_TEST( boost::apply_visitor(const_checker)(var1, var2) );
+}
+
+int main()
+{
+ typedef boost::variant<udt1,udt2> var_t;
+ udt1 u1;
+ var_t var1(u1);
+ udt2 u2;
+ var_t var2(u2);
+
+ const var_t& cvar1 = var1;
+ const var_t& cvar2 = var2;
+
+ //
+ // unary tests
+ //
+
+ typedef unary_check_content_type<udt1> check1_t;
+ typedef unary_check_content_type<const udt1> check1_const_t;
+ typedef unary_check_content_type<udt2> check2_t;
+ typedef unary_check_content_type<const udt2> check2_const_t;
+
+ unary_test< check1_t >(var1);
+ unary_test< check1_const_t >(cvar1);
+
+ unary_test< check2_t >(var2);
+ unary_test< check2_const_t >(cvar2);
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS // BOOST_NO_CXX11_RVALUE_REFERENCES is not enough for disabling buggy GCCs < 4.8
+ BOOST_TEST_EQ( (boost::apply_visitor(
+ rvalue_ref_visitor(),
+ boost::variant<udt1, udt2>(udt2()))), 1 );
+#endif
+#ifdef BOOST_VARIANT_HAS_DECLTYPE_APPLY_VISITOR_RETURN_TYPE
+ BOOST_TEST_EQ( (boost::apply_visitor(
+ rvalue_ref_decltype_visitor(),
+ boost::variant<udt1, udt2>(udt2()))), 1 );
+#endif
+
+ //
+ // binary tests
+ //
+
+ typedef binary_check_content_type<udt1,udt2> check12_t;
+ typedef binary_check_content_type<const udt1, const udt2> check12_const_t;
+ typedef binary_check_content_type<udt2,udt1> check21_t;
+ typedef binary_check_content_type<const udt2, const udt1> check21_const_t;
+
+ binary_test< check12_t >(var1,var2);
+ binary_test< check12_const_t >(cvar1,cvar2);
+
+ binary_test< check21_t >(var2,var1);
+ binary_test< check21_const_t >(cvar2,cvar1);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/CMakeLists.txt b/src/boost/libs/variant2/CMakeLists.txt
new file mode 100644
index 00000000..88ed21d9
--- /dev/null
+++ b/src/boost/libs/variant2/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright 2018, 2019 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# http://www.boost.org/LICENSE_1_0.txt
+
+# Partial (add_subdirectory only) and experimental CMake support
+# Subject to change; please do not rely on the contents of this file yet
+
+cmake_minimum_required(VERSION 3.5)
+
+project(BoostVariant2 LANGUAGES CXX)
+
+add_library(boost_variant2 INTERFACE)
+add_library(Boost::variant2 ALIAS boost_variant2)
+
+target_include_directories(boost_variant2 INTERFACE include)
+
+target_link_libraries(boost_variant2
+ INTERFACE
+ Boost::config
+ Boost::mp11
+)
diff --git a/src/boost/libs/variant2/README.md b/src/boost/libs/variant2/README.md
new file mode 100644
index 00000000..83a32fe2
--- /dev/null
+++ b/src/boost/libs/variant2/README.md
@@ -0,0 +1,21 @@
+# variant2
+
+This repository contains a never-valueless, strong guarantee, C++11/14/17
+implementation of [std::variant](http://en.cppreference.com/w/cpp/utility/variant).
+See [the documentation](https://www.boost.org/libs/variant2)
+for more information.
+
+The code requires [Boost.Mp11](https://github.com/boostorg/mp11) and
+Boost.Config.
+
+The library is part of Boost, starting from release 1.71, but the header
+`variant.hpp` will also work [standalone](https://godbolt.org/z/nVUNKX).
+
+Supported compilers:
+
+* g++ 4.8 or later with `-std=c++11` or above
+* clang++ 3.5 or later with `-std=c++11` or above
+* Visual Studio 2015, 2017, 2019
+
+Tested on [Travis](https://travis-ci.org/boostorg/variant2/) and
+[Appveyor](https://ci.appveyor.com/project/pdimov/variant2-fkab9).
diff --git a/src/boost/libs/variant2/benchmark/benchmark1.cpp b/src/boost/libs/variant2/benchmark/benchmark1.cpp
new file mode 100644
index 00000000..703f8911
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark1.cpp
@@ -0,0 +1,168 @@
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(ONLY_V2)
+# define NO_BV
+# define NO_SV
+#endif
+
+#if defined(ONLY_BV)
+# define NO_V2
+# define NO_SV
+#endif
+
+#if defined(ONLY_SV)
+# define NO_V2
+# define NO_BV
+#endif
+
+#if !defined(NO_V2)
+#include <boost/variant2/variant.hpp>
+#endif
+
+#if !defined(NO_BV)
+#include <boost/variant.hpp>
+#endif
+
+#if !defined(NO_SV)
+#include <variant>
+#endif
+
+#include <type_traits>
+#include <chrono>
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <map>
+#include <string>
+#include <stdexcept>
+
+template<class T> struct is_numeric: std::integral_constant<bool, std::is_integral<T>::value || std::is_floating_point<T>::value>
+{
+};
+
+template<class T, class U> struct have_addition: std::integral_constant<bool, is_numeric<T>::value && is_numeric<U>::value>
+{
+};
+
+template<class T, class U, class E = std::enable_if_t<have_addition<T, U>::value>> auto add( T const& t, U const& u )
+{
+ return t + u;
+}
+
+template<class T, class U, class E = std::enable_if_t<!have_addition<T, U>::value>> double add( T const& /*t*/, U const& /*u*/ )
+{
+ throw std::logic_error( "Invalid addition" );
+}
+
+inline double to_double( double const& v )
+{
+ return v;
+}
+
+#if !defined(NO_V2)
+
+template<class... T> boost::variant2::variant<T...> operator+( boost::variant2::variant<T...> const& v1, boost::variant2::variant<T...> const& v2 )
+{
+ return visit( [&]( auto const& x1, auto const & x2 ) -> boost::variant2::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( boost::variant2::variant<T...> const& v )
+{
+ return boost::variant2::get<double>( v );
+}
+
+#endif
+
+#if !defined(NO_BV)
+
+template<class... T> boost::variant<T...> operator+( boost::variant<T...> const& v1, boost::variant<T...> const& v2 )
+{
+ return boost::apply_visitor( [&]( auto const& x1, auto const & x2 ) -> boost::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( boost::variant<T...> const& v )
+{
+ return boost::get<double>( v );
+}
+
+#endif
+
+#if !defined(NO_SV)
+
+template<class... T> std::variant<T...> operator+( std::variant<T...> const& v1, std::variant<T...> const& v2 )
+{
+ return visit( [&]( auto const& x1, auto const & x2 ) -> std::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( std::variant<T...> const& v )
+{
+ return std::get<double>( v );
+}
+
+#endif
+
+template<class V> void test_( long long N )
+{
+ std::vector<V> w;
+ // lack of reserve is deliberate
+
+ auto tp1 = std::chrono::high_resolution_clock::now();
+
+ for( long long i = 0; i < N; ++i )
+ {
+ V v;
+
+ if( i % 7 == 0 )
+ {
+ v = i / 7;
+ }
+ else
+ {
+ v = i / 7.0;
+ }
+
+ w.push_back( v );
+ }
+
+ V s = 0.0;
+
+ for( long long i = 0; i < N; ++i )
+ {
+ s = s + w[ i ];
+ }
+
+ auto tp2 = std::chrono::high_resolution_clock::now();
+
+ std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << to_double( s ) << "\n";
+}
+
+template<class... T> void test( long long N )
+{
+ std::cout << "N=" << N << ":\n";
+
+ std::cout << " double: "; test_<double>( N );
+#if !defined(NO_V2)
+ std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
+#endif
+#if !defined(NO_BV)
+ std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
+#endif
+#if !defined(NO_SV)
+ std::cout << " std::variant: "; test_<std::variant<T...>>( N );
+#endif
+
+ std::cout << '\n';
+}
+
+int main()
+{
+ long long const N = 100'000'000LL;
+
+ test<long long, double>( N );
+ test<std::nullptr_t, long long, double, std::string, std::vector<std::string>, std::map<std::string, std::string>>( N );
+}
diff --git a/src/boost/libs/variant2/benchmark/benchmark1.md b/src/boost/libs/variant2/benchmark/benchmark1.md
new file mode 100644
index 00000000..aa3bb933
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark1.md
@@ -0,0 +1,267 @@
+# benchmark1.cpp results
+
+## VS 2017 15.9.7 64 bit (cl.exe 19.16, /EHsc /std:c++17)
+
+### /Od
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1837 ms
+boost::variant (-DONLY_BV): 2627 ms
+ std::variant (-DONLY_SV): 1425 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 9041 ms; S=7.14286e+14
+ variant2: 48367 ms; S=7.14286e+14
+boost::variant: 102776 ms; S=7.14286e+14
+ std::variant: 40590 ms; S=7.14286e+14
+
+N=100000000:
+ double: 9029 ms; S=7.14286e+14
+ variant2: 92962 ms; S=7.14286e+14
+boost::variant: 110441 ms; S=7.14286e+14
+ std::variant: 92974 ms; S=7.14286e+14
+```
+
+### /O2 /DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2571 ms
+boost::variant (-DONLY_BV): 3335 ms
+ std::variant (-DONLY_SV): 1903 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1949 ms; S=7.14286e+14
+ variant2: 4176 ms; S=7.14286e+14
+boost::variant: 11312 ms; S=7.14286e+14
+ std::variant: 4617 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1949 ms; S=7.14286e+14
+ variant2: 11807 ms; S=7.14286e+14
+boost::variant: 15632 ms; S=7.14286e+14
+ std::variant: 10725 ms; S=7.14286e+14
+```
+
+## g++ 7.4.0 -std=c++17 (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2734 ms
+boost::variant (-DONLY_BV): 4308 ms
+ std::variant (-DONLY_SV): 2298 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 3620 ms; S=7.14286e+14
+ variant2: 29214 ms; S=7.14286e+14
+boost::variant: 88492 ms; S=7.14286e+14
+ std::variant: 39510 ms; S=7.14286e+14
+
+N=100000000:
+ double: 3642 ms; S=7.14286e+14
+ variant2: 75822 ms; S=7.14286e+14
+boost::variant: 96680 ms; S=7.14286e+14
+ std::variant: 66411 ms; S=7.14286e+14
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2103 ms
+boost::variant (-DONLY_BV): 3398 ms
+ std::variant (-DONLY_SV): 1841 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1576 ms; S=7.14286e+14
+ variant2: 3424 ms; S=7.14286e+14
+boost::variant: 4356 ms; S=7.14286e+14
+ std::variant: 3764 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1582 ms; S=7.14286e+14
+ variant2: 9062 ms; S=7.14286e+14
+boost::variant: 9603 ms; S=7.14286e+14
+ std::variant: 8825 ms; S=7.14286e+14
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2276 ms
+boost::variant (-DONLY_BV): 3647 ms
+ std::variant (-DONLY_SV): 2111 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1643 ms; S=7.14286e+14
+ variant2: 3070 ms; S=7.14286e+14
+boost::variant: 3385 ms; S=7.14286e+14
+ std::variant: 3880 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1622 ms; S=7.14286e+14
+ variant2: 8101 ms; S=7.14286e+14
+boost::variant: 8611 ms; S=7.14286e+14
+ std::variant: 8694 ms; S=7.14286e+14
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2390 ms
+boost::variant (-DONLY_BV): 3768 ms
+ std::variant (-DONLY_SV): 2094 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1611 ms; S=7.14286e+14
+ variant2: 2975 ms; S=7.14286e+14
+boost::variant: 3232 ms; S=7.14286e+14
+ std::variant: 3726 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1603 ms; S=7.14286e+14
+ variant2: 8157 ms; S=7.14286e+14
+boost::variant: 8419 ms; S=7.14286e+14
+ std::variant: 8659 ms; S=7.14286e+14
+```
+
+## clang++ 5.0.1 -std=c++17 -stdlib=libc++ (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2190 ms
+boost::variant (-DONLY_BV): 3537 ms
+ std::variant (-DONLY_SV): 2151 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 6063 ms; S=7.14286e+14
+ variant2: 23616 ms; S=7.14286e+14
+boost::variant: 92730 ms; S=7.14286e+14
+ std::variant: 23160 ms; S=7.14286e+14
+
+N=100000000:
+ double: 6054 ms; S=7.14286e+14
+ variant2: 52738 ms; S=7.14286e+14
+boost::variant: 96896 ms; S=7.14286e+14
+ std::variant: 72595 ms; S=7.14286e+14
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2722 ms
+boost::variant (-DONLY_BV): 4337 ms
+ std::variant (-DONLY_SV): 2697 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 2171 ms; S=7.14286e+14
+ variant2: 9280 ms; S=7.14286e+14
+boost::variant: 51478 ms; S=7.14286e+14
+ std::variant: 5642 ms; S=7.14286e+14
+
+N=100000000:
+ double: 2171 ms; S=7.14286e+14
+ variant2: 22166 ms; S=7.14286e+14
+boost::variant: 54084 ms; S=7.14286e+14
+ std::variant: 14330 ms; S=7.14286e+14
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2499 ms
+boost::variant (-DONLY_BV): 3826 ms
+ std::variant (-DONLY_SV): 2645 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1604 ms; S=7.14286e+14
+ variant2: 2726 ms; S=7.14286e+14
+boost::variant: 6662 ms; S=7.14286e+14
+ std::variant: 3869 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1598 ms; S=7.14286e+14
+ variant2: 8136 ms; S=7.14286e+14
+boost::variant: 9236 ms; S=7.14286e+14
+ std::variant: 6279 ms; S=7.14286e+14
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2509 ms
+boost::variant (-DONLY_BV): 3845 ms
+ std::variant (-DONLY_SV): 2638 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1592 ms; S=7.14286e+14
+ variant2: 2697 ms; S=7.14286e+14
+boost::variant: 6648 ms; S=7.14286e+14
+ std::variant: 3826 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1614 ms; S=7.14286e+14
+ variant2: 8035 ms; S=7.14286e+14
+boost::variant: 9221 ms; S=7.14286e+14
+ std::variant: 6319 ms; S=7.14286e+14
+```
diff --git a/src/boost/libs/variant2/benchmark/benchmark2.cpp b/src/boost/libs/variant2/benchmark/benchmark2.cpp
new file mode 100644
index 00000000..bea5f3a9
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark2.cpp
@@ -0,0 +1,149 @@
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(ONLY_V2)
+# define NO_BV
+# define NO_SV
+#endif
+
+#if defined(ONLY_BV)
+# define NO_V2
+# define NO_SV
+#endif
+
+#if defined(ONLY_SV)
+# define NO_V2
+# define NO_BV
+#endif
+
+#if !defined(NO_V2)
+#include <boost/variant2/variant.hpp>
+#endif
+
+#if !defined(NO_BV)
+#include <boost/variant.hpp>
+#endif
+
+#if !defined(NO_SV)
+#include <variant>
+#endif
+
+#include <type_traits>
+#include <chrono>
+#include <iostream>
+#include <iomanip>
+#include <vector>
+
+struct prefix
+{
+ int v_;
+};
+
+struct X1: prefix {};
+struct X2: prefix {};
+struct X3: prefix {};
+struct X4: prefix {};
+struct X5: prefix {};
+struct X6: prefix {};
+struct X7: prefix {};
+struct X8: prefix {};
+struct X9: prefix {};
+struct X10: prefix {};
+struct X11: prefix {};
+struct X12: prefix {};
+
+inline int get_value( prefix const& v )
+{
+ return v.v_;
+}
+
+#if !defined(NO_V2)
+
+template<class... T> int get_value( boost::variant2::variant<T...> const& v )
+{
+ return visit( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+#if !defined(NO_BV)
+
+template<class... T> int get_value( boost::variant<T...> const& v )
+{
+ return boost::apply_visitor( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+#if !defined(NO_SV)
+
+template<class... T> int get_value( std::variant<T...> const& v )
+{
+ return visit( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+template<class V> void test_( int N )
+{
+ std::vector<V> w;
+ // lack of reserve is deliberate
+
+ auto tp1 = std::chrono::high_resolution_clock::now();
+
+ for( int i = 0; i < N / 12; ++i )
+ {
+ w.push_back( X1{ i } );
+ w.push_back( X2{ i } );
+ w.push_back( X3{ i } );
+ w.push_back( X4{ i } );
+ w.push_back( X5{ i } );
+ w.push_back( X6{ i } );
+ w.push_back( X7{ i } );
+ w.push_back( X8{ i } );
+ w.push_back( X9{ i } );
+ w.push_back( X10{ i } );
+ w.push_back( X11{ i } );
+ w.push_back( X12{ i } );
+ }
+
+ unsigned long long s = 0;
+
+ for( std::size_t i = 0, n = w.size(); i < n; ++i )
+ {
+ s = s + get_value( w[ i ] );
+ }
+
+ auto tp2 = std::chrono::high_resolution_clock::now();
+
+ std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << s << "\n";
+}
+
+template<class... T> void test( int N )
+{
+ std::cout << "N=" << N << ":\n";
+
+ std::cout << " prefix: "; test_<prefix>( N );
+#if !defined(NO_V2)
+ std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
+#endif
+#if !defined(NO_BV)
+ std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
+#endif
+#if !defined(NO_SV)
+ std::cout << " std::variant: "; test_<std::variant<T...>>( N );
+#endif
+
+ std::cout << '\n';
+}
+
+int main()
+{
+ int const N = 100'000'000;
+
+ test<X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12>( N );
+}
diff --git a/src/boost/libs/variant2/benchmark/benchmark2.md b/src/boost/libs/variant2/benchmark/benchmark2.md
new file mode 100644
index 00000000..9aad6488
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark2.md
@@ -0,0 +1,207 @@
+# benchmark2.cpp results
+
+## VS 2017 15.9.7 64 bit (cl.exe 19.16, /EHsc /std:c++17)
+
+### /Od
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1403 ms
+boost::variant (-DONLY_BV): 2972 ms
+ std::variant (-DONLY_SV): 1057 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 7016 ms; S=416666583333336
+ variant2: 24723 ms; S=416666583333336
+boost::variant: 60438 ms; S=416666583333336
+ std::variant: 20707 ms; S=416666583333336
+```
+
+### /O2 /DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1778 ms
+boost::variant (-DONLY_BV): 3252 ms
+ std::variant (-DONLY_SV): 1372 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 803 ms; S=416666583333336
+ variant2: 2124 ms; S=416666583333336
+boost::variant: 6191 ms; S=416666583333336
+ std::variant: 2193 ms; S=416666583333336
+```
+
+## g++ 7.4.0 -std=c++17 (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1739 ms
+boost::variant (-DONLY_BV): 3113 ms
+ std::variant (-DONLY_SV): 1719 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 5163 ms; S=416666583333336
+ variant2: 20628 ms; S=416666583333336
+boost::variant: 43308 ms; S=416666583333336
+ std::variant: 42375 ms; S=416666583333336
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1484 ms
+boost::variant (-DONLY_BV): 2947 ms
+ std::variant (-DONLY_SV): 1448 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 781 ms; S=416666583333336
+ variant2: 1992 ms; S=416666583333336
+boost::variant: 2249 ms; S=416666583333336
+ std::variant: 4843 ms; S=416666583333336
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1547 ms
+boost::variant (-DONLY_BV): 2999 ms
+ std::variant (-DONLY_SV): 1528 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 793 ms; S=416666583333336
+ variant2: 1686 ms; S=416666583333336
+boost::variant: 1833 ms; S=416666583333336
+ std::variant: 4340 ms; S=416666583333336
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1595 ms
+boost::variant (-DONLY_BV): 3084 ms
+ std::variant (-DONLY_SV): 1620 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 853 ms; S=416666583333336
+ variant2: 1681 ms; S=416666583333336
+boost::variant: 1773 ms; S=416666583333336
+ std::variant: 3989 ms; S=416666583333336
+```
+
+## clang++ 5.0.1 -std=c++17 -stdlib=libc++ (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1578 ms
+boost::variant (-DONLY_BV): 2623 ms
+ std::variant (-DONLY_SV): 1508 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 4447 ms; S=416666583333336
+ variant2: 16016 ms; S=416666583333336
+boost::variant: 42365 ms; S=416666583333336
+ std::variant: 17817 ms; S=416666583333336
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1841 ms
+boost::variant (-DONLY_BV): 2919 ms
+ std::variant (-DONLY_SV): 1776 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 1390 ms; S=416666583333336
+ variant2: 5397 ms; S=416666583333336
+boost::variant: 23234 ms; S=416666583333336
+ std::variant: 2807 ms; S=416666583333336
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1766 ms
+boost::variant (-DONLY_BV): 2817 ms
+ std::variant (-DONLY_SV): 1718 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 604 ms; S=416666583333336
+ variant2: 1625 ms; S=416666583333336
+boost::variant: 2735 ms; S=416666583333336
+ std::variant: 2664 ms; S=416666583333336
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1720 ms
+boost::variant (-DONLY_BV): 2806 ms
+ std::variant (-DONLY_SV): 1737 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 603 ms; S=416666583333336
+ variant2: 1608 ms; S=416666583333336
+boost::variant: 2696 ms; S=416666583333336
+ std::variant: 2668 ms; S=416666583333336
+```
diff --git a/src/boost/libs/variant2/index.html b/src/boost/libs/variant2/index.html
new file mode 100644
index 00000000..ce8b2263
--- /dev/null
+++ b/src/boost/libs/variant2/index.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/variant2.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/variant2.html">doc/html/variant2.html</a>.
+</body>
+</html>
+<!--
+ Copyright Beman Dawes, 2001
+ 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
+-->
diff --git a/src/boost/libs/variant2/meta/libraries.json b/src/boost/libs/variant2/meta/libraries.json
new file mode 100644
index 00000000..7d9337ec
--- /dev/null
+++ b/src/boost/libs/variant2/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "key": "variant2",
+ "name": "Variant2",
+ "authors": [
+ "Peter Dimov"
+ ],
+ "maintainers": [
+ "Peter Dimov <pdimov -at- pdimov.com>"
+ ],
+ "description": "A never-valueless, strong guarantee implementation of std::variant.",
+ "category": [
+ "Containers", "Data"
+ ]
+}
diff --git a/src/boost/libs/variant2/test/Jamfile b/src/boost/libs/variant2/test/Jamfile
new file mode 100644
index 00000000..1093712d
--- /dev/null
+++ b/src/boost/libs/variant2/test/Jamfile
@@ -0,0 +1,105 @@
+# Boost.Variant2 Library Test Jamfile
+#
+# Copyright 2015-2019 Peter Dimov
+#
+# 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
+
+import testing ;
+import ../../config/checks/config : requires ;
+
+project
+ : default-build
+
+ <warnings>all
+
+ : requirements
+
+ [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr ]
+
+ <toolset>msvc:<warnings-as-errors>on
+ <toolset>gcc:<warnings-as-errors>on
+ <toolset>clang:<warnings-as-errors>on
+ ;
+
+run variant_size.cpp ;
+run variant_alternative.cpp ;
+
+run variant_holds_alternative.cpp ;
+compile variant_holds_alternative_cx.cpp ;
+
+run variant_get_by_index.cpp ;
+compile variant_get_by_index_cx.cpp ;
+
+run variant_get_by_type.cpp ;
+compile variant_get_by_type_cx.cpp ;
+
+run variant_default_construct.cpp ;
+compile variant_default_construct_cx.cpp ;
+
+run variant_copy_construct.cpp ;
+compile variant_copy_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_move_construct.cpp ;
+compile variant_move_construct_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_value_construct.cpp ;
+compile variant_value_construct_cx.cpp ;
+
+run variant_in_place_index_construct.cpp ;
+compile variant_in_place_index_construct_cx.cpp ;
+
+run variant_in_place_type_construct.cpp ;
+compile variant_in_place_type_construct_cx.cpp ;
+
+run variant_copy_assign.cpp ;
+compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_move_assign.cpp ;
+compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_value_assign.cpp ;
+compile variant_value_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_emplace_index.cpp ;
+compile variant_emplace_index_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_emplace_type.cpp ;
+compile variant_emplace_type_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_swap.cpp ;
+
+run variant_eq_ne.cpp ;
+compile variant_eq_ne_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_lt_gt.cpp ;
+compile variant_lt_gt_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_destroy.cpp ;
+run variant_visit.cpp ;
+
+run variant_convert_construct.cpp ;
+run variant_subset.cpp ;
+run variant_valueless.cpp ;
+
+run variant_copy_construct_throw.cpp ;
+run variant_move_construct_throw.cpp ;
+run variant_convert_construct_throw.cpp ;
+
+run variant_copy_assign_throw.cpp ;
+run variant_move_assign_throw.cpp ;
+
+local NX =
+ <exception-handling>off
+ <toolset>msvc:<cxxflags>/wd4530
+ <toolset>msvc:<cxxflags>/wd4577
+ ;
+
+run variant_get_by_index.cpp throw_exception.cpp : : : $(NX) : variant_get_by_index_nx ;
+compile variant_get_by_index_cx.cpp : $(NX) : variant_get_by_index_cx_nx ;
+
+run variant_get_by_type.cpp throw_exception.cpp : : : $(NX) : variant_get_by_type_nx ;
+compile variant_get_by_type_cx.cpp : $(NX) : variant_get_by_type_cx_nx ;
+
+run variant_subset.cpp throw_exception.cpp : : : $(NX) : variant_subset_nx ;
diff --git a/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt b/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt
new file mode 100644
index 00000000..90fd0144
--- /dev/null
+++ b/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright 2018, 2019 Peter Dimov
+# 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
+
+cmake_minimum_required(VERSION 3.5)
+
+project(cmake_subdir_test LANGUAGES CXX)
+
+add_subdirectory(../.. boostorg/variant2)
+add_subdirectory(../../../config boostorg/config)
+add_subdirectory(../../../mp11 boostorg/mp11)
+
+add_executable(quick quick.cpp)
+target_link_libraries(quick Boost::variant2)
+
+enable_testing()
+add_test(quick quick)
+
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
diff --git a/src/boost/libs/variant2/test/cmake_subdir_test/quick.cpp b/src/boost/libs/variant2/test/cmake_subdir_test/quick.cpp
new file mode 100644
index 00000000..789d0e70
--- /dev/null
+++ b/src/boost/libs/variant2/test/cmake_subdir_test/quick.cpp
@@ -0,0 +1,15 @@
+
+// Copyright 2019 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+int main()
+{
+ variant<float, int> v( 2 );
+ return get<1>( v ) == 2? 0: 1;
+}
diff --git a/src/boost/libs/variant2/test/throw_exception.cpp b/src/boost/libs/variant2/test/throw_exception.cpp
new file mode 100644
index 00000000..9eaccc11
--- /dev/null
+++ b/src/boost/libs/variant2/test/throw_exception.cpp
@@ -0,0 +1,20 @@
+
+// Copyright 2019 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <exception>
+#include <cstdio>
+
+namespace boost
+{
+
+void throw_exception( std::exception const & e )
+{
+ std::fprintf( stderr, "Exception: %s\n", e.what() );
+ std::terminate();
+}
+
+} // namespace boost
diff --git a/src/boost/libs/variant2/test/variant_alternative.cpp b/src/boost/libs/variant2/test/variant_alternative.cpp
new file mode 100644
index 00000000..600c26c9
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_alternative.cpp
@@ -0,0 +1,154 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <cstddef>
+
+using namespace boost::variant2;
+using namespace boost::mp11;
+
+template<class I, class T> using var_alt_t = variant_alternative_t<I::value, T>;
+
+int main()
+{
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>>, int>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const>, int const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> volatile>, int volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const volatile>, int const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>&>, int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const&>, int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>&&>, int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const&&>, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>>, int>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const>, int const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> volatile>, int volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const volatile>, int const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>&>, int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const&>, int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>&&>, int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const&&>, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>>, float>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const>, float const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> volatile>, float volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const volatile>, float const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>&>, float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const&>, float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>&&>, float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const&&>, float const&&>));
+
+ variant_alternative<0, void>();
+ variant_alternative<0, void const>();
+ variant_alternative<0, void volatile>();
+ variant_alternative<0, void const volatile>();
+
+ variant_alternative<0, int&>();
+ variant_alternative<0, int const&>();
+ variant_alternative<0, int&&>();
+ variant_alternative<0, int const&&>();
+
+ variant_alternative<0, variant<>>();
+ variant_alternative<0, variant<> const>();
+ variant_alternative<0, variant<> volatile>();
+ variant_alternative<0, variant<> const volatile>();
+
+ variant_alternative<0, variant<>&>();
+ variant_alternative<0, variant<> const&>();
+ variant_alternative<0, variant<>&&>();
+ variant_alternative<0, variant<> const&&>();
+
+ variant_alternative<1, variant<int>>();
+ variant_alternative<1, variant<int> const>();
+ variant_alternative<1, variant<int> volatile>();
+ variant_alternative<1, variant<int> const volatile>();
+
+ variant_alternative<1, variant<int>&>();
+ variant_alternative<1, variant<int> const&>();
+ variant_alternative<1, variant<int>&&>();
+ variant_alternative<1, variant<int> const&&>();
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int const&&>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> volatile>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>&&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const&&>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const&&>));
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_convert_construct.cpp b/src/boost/libs/variant2/test/variant_convert_construct.cpp
new file mode 100644
index 00000000..dbf61d90
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_convert_construct.cpp
@@ -0,0 +1,175 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int const> v( 1 );
+
+ variant<int const, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int const>( v2 ) );
+ BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
+
+ variant<int const, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int const>( v3 ) );
+ BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
+ }
+
+ {
+ variant<int const> const v( 1 );
+
+ variant<int const, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int const>( v2 ) );
+ BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
+
+ variant<int const, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int const>( v3 ) );
+ BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
+ }
+
+ {
+ variant<float> v( 3.14f );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<float>( v2 ) );
+ BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<float>( v3 ) );
+ BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
+ }
+
+ {
+ variant<float> v( 3.15f );
+
+ variant<int, int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<float>( v2 ) );
+ BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
+
+ variant<int, int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<float>( v3 ) );
+ BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
+ }
+
+ {
+ variant<float, std::string> v( "s1" );
+
+ variant<int, int, float, std::string> v2( v );
+
+ BOOST_TEST( holds_alternative<std::string>( v2 ) );
+ BOOST_TEST_EQ( get<std::string>( v ), get<std::string>( v2 ) );
+
+ variant<int, int, float, std::string> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<std::string>( v3 ) );
+ BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
+ }
+
+ {
+ variant<X1, X2> v{ X1{1} };
+
+ variant<int, int, float, float, X1, X2> v2( v );
+
+ BOOST_TEST( holds_alternative<X1>( v2 ) );
+ BOOST_TEST_EQ( get<X1>( v ).v, get<X1>( v2 ).v );
+
+ variant<int, int, float, float, X1, X2> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<X1>( v3 ) );
+ BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp b/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp
new file mode 100644
index 00000000..bb53d7ce
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp
@@ -0,0 +1,95 @@
+
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test_copy()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X, int, float> v2( v1 );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+void test_move()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X, int, float> v2( std::move( v1 ) );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test_copy();
+ test_move();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign.cpp b/src/boost/libs/variant2/test/variant_copy_assign.cpp
new file mode 100644
index 00000000..c8ed44f7
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y
+{
+ Y& operator=( Y const& ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int> const v3( 2 );
+
+ v = v3;
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int, float> v3( 3.14f );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ variant<int, float> const v4( 3.15f );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ variant<int, int, float, std::string> const v4( 3.15f );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = v5;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ variant<int, int, float, std::string> const v6( "s2" );
+
+ v = v6;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ variant<X1, X2> const v4( in_place_index_t<1>{}, 3 );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ variant<X1, X2> const v5( in_place_index_t<0>{}, 4 );
+
+ v = v5;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_copy_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_assignable<variant<int const>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_assignable<variant<int, float, Y>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp b/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp
new file mode 100644
index 00000000..8be25794
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp
@@ -0,0 +1,116 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr T test( A const& a )
+{
+ V v;
+
+ v = a;
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+ constexpr auto w = test<variant<int>, int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<X> v( 1 );
+ constexpr auto w = test<variant<X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<Y> v( 1 );
+ constexpr auto w = test<variant<Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr variant<int, float> v( 1 );
+ constexpr auto w = test<variant<int, float>, int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.0f );
+ constexpr auto w = test<variant<int, float>, float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.0f );
+ constexpr auto w = test<variant<int, int, float>, float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<E, E, X> v( 1 );
+ constexpr auto w = test<variant<E, E, X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( X(1) );
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<E, E, Y> v( 1 );
+ constexpr auto w = test<variant<E, E, Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, Y> v( Y(1) );
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp b/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp
new file mode 100644
index 00000000..a13dccbe
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp
@@ -0,0 +1,55 @@
+
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct Y1
+{
+ Y1() noexcept {} // =default fails on msvc-14.0
+
+ Y1(Y1 const&)
+ {
+ throw std::runtime_error( "Y1(Y1 const&)" );
+ }
+
+ Y1& operator=(Y1 const&) = default;
+};
+
+struct Y2
+{
+ Y2() noexcept {}
+
+ Y2(Y2 const&)
+ {
+ throw std::runtime_error( "Y2(Y2 const&)" );
+ }
+
+ Y2& operator=(Y2 const&) = default;
+};
+
+void test()
+{
+ variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
+ variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
+
+ BOOST_TEST_THROWS( v1 = v2, std::runtime_error )
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct.cpp b/src/boost/libs/variant2/test/variant_copy_construct.cpp
new file mode 100644
index 00000000..63b88a7e
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct.cpp
@@ -0,0 +1,145 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ X1() {}
+ X1(X1 const&) {}
+ X1(X1&&) {}
+};
+
+inline bool operator==( X1, X1 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+
+struct X2
+{
+ X2() {}
+ X2(X2 const&) {}
+ X2(X2&&) {}
+};
+
+inline bool operator==( X2, X2 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+
+struct Y
+{
+ Y( Y const& ) = delete;
+};
+
+template<class V> static void test( V const & v )
+{
+ V v2( v );
+
+ BOOST_TEST_EQ( v.index(), v2.index() );
+ BOOST_TEST( v == v2 );
+}
+
+int main()
+{
+ test( variant<int>() );
+ test( variant<int>(1) );
+
+ test( variant<int const>() );
+ test( variant<int const>(1) );
+
+ test( variant<int, float>() );
+ test( variant<int, float>(1) );
+ test( variant<int, float>(3.14f) );
+
+ test( variant<int const, float const>() );
+ test( variant<int const, float const>(1) );
+ test( variant<int const, float const>(3.14f) );
+
+ test( variant<std::string>() );
+ test( variant<std::string>("test") );
+
+ test( variant<std::string const>() );
+ test( variant<std::string const>("test") );
+
+ test( variant<int, float, std::string>() );
+ test( variant<int, float, std::string>(1) );
+ test( variant<int, float, std::string>(3.14f) );
+ test( variant<int, float, std::string>("test") );
+
+ test( variant<int, int>() );
+
+ test( variant<int, int, float>() );
+ test( variant<int, int, float>(3.14f) );
+
+ test( variant<int, int, float, float>() );
+
+ test( variant<int, int, float, float, std::string>("test") );
+
+ test( variant<std::string, std::string, float>() );
+
+ test( variant<X1 const>() );
+
+ test( variant<X1, X2>() );
+ test( variant<X1, X2, int>() );
+ test( variant<X1, X2, X2>() );
+ test( variant<X1, X1, X2, X2>() );
+
+ {
+ variant<X1, X2> v;
+ v.emplace<X2>();
+
+ test( v );
+ }
+
+ {
+ variant<X1, X1, X2> v;
+ v.emplace<X2>();
+
+ test( v );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<variant<X1, X2>>));
+
+#if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
+
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_constructible<variant<int, float, Y>>));
+
+#endif
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp b/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp
new file mode 100644
index 00000000..cd3a7c2b
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp
@@ -0,0 +1,112 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class T, class V> constexpr T test( V const v )
+{
+ return get<T>( v );
+}
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+ constexpr auto w = test<int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<X> v( 1 );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<Y> v( 1 );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr variant<int, float> v( 1 );
+ constexpr auto w = test<int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.0f );
+ constexpr auto w = test<float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.0f );
+ constexpr auto w = test<float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<E, E, X> v( 1 );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( X(1) );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<E, E, Y> v( 1 );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, Y> v( Y(1) );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp b/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp
new file mode 100644
index 00000000..81b44d9f
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp
@@ -0,0 +1,69 @@
+
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X> v2( v1 );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_default_construct.cpp b/src/boost/libs/variant2/test/variant_default_construct.cpp
new file mode 100644
index 00000000..894934cb
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_default_construct.cpp
@@ -0,0 +1,103 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X();
+};
+
+struct Y
+{
+ Y() = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string const> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string, int, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string, std::string, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, float, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, int, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, X, X>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X, int, float>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<variant<int, Y>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<variant<Y, int>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_default_construct_cx.cpp b/src/boost/libs/variant2/test/variant_default_construct_cx.cpp
new file mode 100644
index 00000000..d3325c6b
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_default_construct_cx.cpp
@@ -0,0 +1,51 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int const> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, int, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_destroy.cpp b/src/boost/libs/variant2/test/variant_destroy.cpp
new file mode 100644
index 00000000..392a2d7d
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_destroy.cpp
@@ -0,0 +1,205 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X1
+{
+ static int instances;
+
+ int v;
+
+ X1(): v(0) { ++instances; }
+ explicit X1(int v): v(v) { ++instances; }
+ X1(X1 const& r): v(r.v) { ++instances; }
+ X1(X1&& r): v(r.v) { ++instances; }
+
+ ~X1() noexcept { --instances; }
+
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+int X1::instances = 0;
+
+struct X2
+{
+ static int instances;
+
+ int v;
+
+ X2(): v(0) { ++instances; }
+ explicit X2(int v): v(v) { ++instances; }
+ X2(X2 const& r): v(r.v) { ++instances; }
+ X2(X2&& r): v(r.v) { ++instances; }
+
+ ~X2() noexcept { --instances; }
+
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+int X2::instances = 0;
+
+struct Y1
+{
+ static int instances;
+
+ int v;
+
+ Y1() noexcept: v(0) { ++instances; }
+ explicit Y1(int v) noexcept: v(v) { ++instances; }
+ Y1(Y1 const& r) noexcept: v(r.v) { ++instances; }
+ Y1(Y1&& r) noexcept: v(r.v) { ++instances; }
+
+ ~Y1() noexcept { --instances; }
+
+ Y1& operator=( Y1 const& r ) noexcept { v = r.v; return *this; }
+ Y1& operator=( Y1&& r ) noexcept { v = r.v; return *this; }
+};
+
+int Y1::instances = 0;
+
+struct Y2
+{
+ static int instances;
+
+ int v;
+
+ Y2() noexcept: v(0) { ++instances; }
+ explicit Y2(int v) noexcept: v(v) { ++instances; }
+ Y2(Y2 const& r) noexcept: v(r.v) { ++instances; }
+ Y2(Y2&& r) noexcept: v(r.v) { ++instances; }
+
+ ~Y2() noexcept { --instances; }
+
+ Y2& operator=( Y2 const& r ) noexcept { v = r.v; return *this; }
+ Y2& operator=( Y2&& r ) noexcept { v = r.v; return *this; }
+};
+
+int Y2::instances = 0;
+
+int main()
+{
+ BOOST_TEST_EQ( Y1::instances, 0 );
+
+ {
+ variant<Y1> v;
+ BOOST_TEST_EQ( Y1::instances, 1 );
+
+ {
+ variant<Y1> v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+
+ v = Y1{1};
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ {
+ variant<Y1, Y2> v;
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ {
+ variant<Y1, Y2> v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v2 = Y2{1};
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+
+ v.emplace<0>();
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v.emplace<Y2>();
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ {
+ variant<X1, X2> v;
+
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ {
+ variant<X1, X2> v2;
+ BOOST_TEST_EQ( X1::instances, 2 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v = v2;
+ BOOST_TEST_EQ( X1::instances, 2 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v2 = X2{1};
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+
+ v.emplace<0>();
+
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v.emplace<X2>();
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_index.cpp b/src/boost/libs/variant2/test/variant_emplace_index.cpp
new file mode 100644
index 00000000..7fa30b7f
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_index.cpp
@@ -0,0 +1,181 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<1>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ v.emplace<1>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<1>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<1>( 1 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ v.emplace<2>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ v.emplace<2>();
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 0 );
+
+ v.emplace<3>( "s1" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ v.emplace<3>( "s2" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v.emplace<3>();
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string() );
+
+ v.emplace<3>( { 'a', 'b' } );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'a', 'b'}) );
+
+ v.emplace<3>( { 'c', 'd' }, std::allocator<char>() );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'c', 'd'}) );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v.emplace<1>( 2 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<0>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ v.emplace<1>();
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 0 );
+
+ v.emplace<1>( 6 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v.emplace<0>( 3 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v.emplace<0>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp b/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp
new file mode 100644
index 00000000..f66f99fc
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp
@@ -0,0 +1,136 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr explicit X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr explicit Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, std::size_t I, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v.template emplace<I>( a );
+
+ return get<I>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, 1>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 1>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 2>( 2.0f );
+ STATIC_ASSERT( w == 2.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 3>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 4>( 4 );
+ STATIC_ASSERT( w == 4 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 5>( 5 );
+ STATIC_ASSERT( w == 5 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 1>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 2>( 2.0f );
+ STATIC_ASSERT( w == 2.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 3>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 4>( 4 );
+ STATIC_ASSERT( w == 4 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 5>( 5 );
+ STATIC_ASSERT( w == 5 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_type.cpp b/src/boost/libs/variant2/test/variant_emplace_type.cpp
new file mode 100644
index 00000000..df8b364a
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_type.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y1
+{
+};
+
+struct Y2
+{
+ ~Y2() {}
+};
+
+struct Guard
+{
+ explicit Guard(int) {}
+ Guard(Guard&&) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<int>( 1 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<int>();
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<int>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<float>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ v.emplace<float>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<int>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<float>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ v.emplace<float>();
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 0 );
+
+ v.emplace<std::string>( "s1" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ v.emplace<std::string>( "s2" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v.emplace<std::string>();
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string() );
+
+ v.emplace<std::string>( { 'a', 'b' } );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'a', 'b' }) );
+
+ v.emplace<std::string>( { 'c', 'd' }, std::allocator<char>() );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'c', 'd' }) );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<X1>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v.emplace<X2>( 2 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ v.emplace<X1>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<X1>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ v.emplace<X2>();
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 0 );
+
+ v.emplace<X2>( 6 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v.emplace<X1>( 3 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v.emplace<X1>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ variant<Y1, Guard> v;
+ v.emplace<Guard>( 1 );
+ }
+
+ {
+ variant<Y2, Guard> v;
+ v.emplace<Guard>( 1 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp b/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp
new file mode 100644
index 00000000..2449b12b
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp
@@ -0,0 +1,91 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr explicit X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr explicit Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v.template emplace<T>( a );
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_eq_ne.cpp b/src/boost/libs/variant2/test/variant_eq_ne.cpp
new file mode 100644
index 00000000..b2fc19dc
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_eq_ne.cpp
@@ -0,0 +1,92 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+};
+
+inline bool operator==( X const&, X const& ) { return false; }
+inline bool operator!=( X const&, X const& ) { return false; }
+
+int main()
+{
+ {
+ variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+ }
+
+ {
+ variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+
+ BOOST_TEST( v1 != v5 );
+ BOOST_TEST_NOT( v1 == v5 );
+
+ BOOST_TEST( v3 != v5 );
+ BOOST_TEST_NOT( v3 == v5 );
+
+ BOOST_TEST( v5 == v6 );
+ BOOST_TEST_NOT( v5 != v6 );
+ }
+
+ {
+ variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+
+ BOOST_TEST( v1 != v5 );
+ BOOST_TEST_NOT( v1 == v5 );
+
+ BOOST_TEST( v3 != v5 );
+ BOOST_TEST_NOT( v3 == v5 );
+
+ BOOST_TEST( v5 == v6 );
+ BOOST_TEST_NOT( v5 != v6 );
+ }
+
+ {
+ variant<X> v1, v2;
+
+ BOOST_TEST_NOT( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp b/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp
new file mode 100644
index 00000000..9ebb751c
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp
@@ -0,0 +1,98 @@
+
+// Copyright 2017, 2019 Peter Dimov
+//
+// 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/variant2/variant.hpp>
+using namespace boost::variant2;
+
+#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
+
+#include <boost/config/pragma_message.hpp>
+
+BOOST_PRAGMA_MESSAGE("Skipping constexpr op==, op!= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
+
+int main() {}
+
+#else
+
+struct X
+{
+};
+
+inline constexpr bool operator==( X const&, X const& ) { return false; }
+inline constexpr bool operator!=( X const&, X const& ) { return false; }
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+ }
+
+ {
+ constexpr variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+
+ STATIC_ASSERT( v1 != v5 );
+ STATIC_ASSERT( !(v1 == v5) );
+
+ STATIC_ASSERT( v3 != v5 );
+ STATIC_ASSERT( !(v3 == v5) );
+
+ STATIC_ASSERT( v5 == v6 );
+ STATIC_ASSERT( !(v5 != v6) );
+ }
+
+ {
+ constexpr variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+
+ STATIC_ASSERT( v1 != v5 );
+ STATIC_ASSERT( !(v1 == v5) );
+
+ STATIC_ASSERT( v3 != v5 );
+ STATIC_ASSERT( !(v3 == v5) );
+
+ STATIC_ASSERT( v5 == v6 );
+ STATIC_ASSERT( !(v5 != v6) );
+ }
+
+ {
+ constexpr variant<X> v1, v2;
+
+ STATIC_ASSERT( !(v1 == v2) );
+ STATIC_ASSERT( !(v1 != v2) );
+ }
+}
+
+#endif
diff --git a/src/boost/libs/variant2/test/variant_get_by_index.cpp b/src/boost/libs/variant2/test/variant_get_by_index.cpp
new file mode 100644
index 00000000..2728196e
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_index.cpp
@@ -0,0 +1,349 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int*>));
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+ }
+
+ {
+ variant<int volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const volatile*>));
+ }
+
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float*>));
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float const*>));
+ }
+
+ {
+ variant<int const, float volatile> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float volatile*>));
+ }
+
+ {
+ variant<int const, float volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float const volatile*>));
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<1>(&v), &get<1>(v) );
+
+ BOOST_TEST_EQ( get<1>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<1>(&v), &get<1>(v) );
+
+ BOOST_TEST_EQ( get<1>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float, float> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<2>(&v), &get<2>(v) );
+
+ BOOST_TEST_EQ( get<2>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<2>(&v), &get<2>(v) );
+
+ BOOST_TEST_EQ( get<2>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, float> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const, float volatile> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const, float volatile> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float, float> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp b/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp
new file mode 100644
index 00000000..026b9d3c
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp
@@ -0,0 +1,96 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/config.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#if BOOST_WORKAROUND(BOOST_GCC, < 50000)
+# define STATIC_ASSERT_IF(...)
+#else
+# define STATIC_ASSERT_IF(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+#endif
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ }
+
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<1>(&v) == &get<1>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float, float> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == &get<2>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_type.cpp b/src/boost/libs/variant2/test/variant_get_by_type.cpp
new file mode 100644
index 00000000..47daa94c
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_type.cpp
@@ -0,0 +1,307 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int*>));
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int const*>));
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+ }
+
+ {
+ variant<int volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int volatile>(v)), int const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int volatile>(std::move(v))), int const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int volatile>(&v)), int const volatile*>));
+ }
+
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(v)), float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(std::move(v))), float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float>(&v)), float*>));
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(v)), float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(std::move(v))), float const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float>(&v)), float const*>));
+ }
+
+ {
+ variant<int const, float volatile> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(v)), float volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(std::move(v))), float volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float volatile>(&v)), float volatile*>));
+ }
+
+ {
+ variant<int const, float volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(v)), float const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(std::move(v))), float const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float volatile>(&v)), float const volatile*>));
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<int>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<int>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float, float> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, int, float> const v( 3.14f );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int> * p = 0;
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ }
+
+ {
+ variant<int const> * p = 0;
+ BOOST_TEST_EQ( get_if<int const>(p), nullptr );
+ }
+
+ {
+ variant<int> const * p = 0;
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ }
+
+ {
+ variant<int const> const * p = 0;
+ BOOST_TEST_EQ( get_if<int const>(p), nullptr );
+ }
+
+ {
+ variant<int, float> * p = 0;
+
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, float> const * p = 0;
+
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float> * p = 0;
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp b/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp
new file mode 100644
index 00000000..0f9a40c5
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp
@@ -0,0 +1,90 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/config.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#if BOOST_WORKAROUND(BOOST_GCC, < 50000)
+# define STATIC_ASSERT_IF(...)
+#else
+# define STATIC_ASSERT_IF(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+#endif
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<float>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<float>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_holds_alternative.cpp b/src/boost/libs/variant2/test/variant_holds_alternative.cpp
new file mode 100644
index 00000000..4931f40f
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_holds_alternative.cpp
@@ -0,0 +1,78 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float, float> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v( 3.14f );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v( "text" );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( 3.14f );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( "text" );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( holds_alternative<std::string>( v ) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp b/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp
new file mode 100644
index 00000000..c2bdc0a6
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp
@@ -0,0 +1,43 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ STATIC_ASSERT( !holds_alternative<float>( v ) );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+ STATIC_ASSERT( !holds_alternative<int>( v ) );
+ STATIC_ASSERT( holds_alternative<float>( v ) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+ STATIC_ASSERT( holds_alternative<float>( v ) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp b/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp
new file mode 100644
index 00000000..75821d32
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp
@@ -0,0 +1,138 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X() = default;
+ X( in_place_index_t<0> ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<X> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+
+ {
+ variant<int> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<1>{} );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<1>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<1>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<2>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<3>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<4>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, 4, 'a' );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), std::string( 4, 'a' ) );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<4>{}, { 'a', 'b', 'c' } );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, { 'a', 'b', 'c' }, std::allocator<char>() );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), (std::string{ 'a', 'b', 'c' }) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp b/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp
new file mode 100644
index 00000000..80a6934e
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp
@@ -0,0 +1,116 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr X() = default;
+ constexpr explicit X(int, int) {}
+ X( in_place_index_t<0> ) = delete;
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<X> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ }
+
+ {
+ constexpr variant<int> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<1>{} );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<1>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<1>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<2>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<3>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 3 );
+ STATIC_ASSERT( get<3>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<4>{} );
+
+ STATIC_ASSERT( v.index() == 4 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<5>{}, 0, 0 );
+
+ STATIC_ASSERT( v.index() == 5 );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp b/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp
new file mode 100644
index 00000000..3c8265ac
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp
@@ -0,0 +1,134 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X() = default;
+ template<class T> X( in_place_type_t<T> ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v( in_place_type_t<int>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<X> v( in_place_type_t<X>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ BOOST_TEST( holds_alternative<X>(v) );
+ }
+
+ {
+ variant<int> v( in_place_type_t<int>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<int>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<int>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<float>{} );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<float>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( in_place_type_t<float>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string("text") );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, 4, 'a' );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string( 4, 'a' ) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, { 'a', 'b', 'c' } );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, { 'a', 'b', 'c' }, std::allocator<char>() );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp b/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp
new file mode 100644
index 00000000..a64c3470
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp
@@ -0,0 +1,110 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr X() = default;
+ constexpr explicit X(int, int) {}
+ template<class T> X( in_place_type_t<T> ) = delete;
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( in_place_type_t<int>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<X> v( in_place_type_t<X>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int> v( in_place_type_t<int>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<int>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<int>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<float>{} );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<float>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( in_place_type_t<float>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{} );
+
+ STATIC_ASSERT( v.index() == 4 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{}, 0, 0 );
+
+ STATIC_ASSERT( v.index() == 4 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_lt_gt.cpp b/src/boost/libs/variant2/test/variant_lt_gt.cpp
new file mode 100644
index 00000000..688209f8
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_lt_gt.cpp
@@ -0,0 +1,85 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+};
+
+inline bool operator<( X const&, X const& ) { return false; }
+inline bool operator>( X const&, X const& ) { return false; }
+inline bool operator<=( X const&, X const& ) { return false; }
+inline bool operator>=( X const&, X const& ) { return false; }
+
+#define TEST_EQ( v1, v2 ) \
+ BOOST_TEST_NOT( v1 < v2 ); \
+ BOOST_TEST_NOT( v1 > v2 ); \
+ BOOST_TEST( v1 <= v2 ); \
+ BOOST_TEST( v1 >= v2 );
+
+#define TEST_LE( v1, v3 ) \
+ BOOST_TEST( v1 < v3 ); \
+ BOOST_TEST( v3 > v1 ); \
+ BOOST_TEST_NOT( v1 > v3 ); \
+ BOOST_TEST_NOT( v3 < v1 ); \
+ BOOST_TEST( v1 <= v3 ); \
+ BOOST_TEST( v3 >= v1 ); \
+ BOOST_TEST_NOT( v1 >= v3 ); \
+ BOOST_TEST_NOT( v3 <= v1 );
+
+int main()
+{
+ {
+ variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ }
+
+ {
+ variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ variant<X> v1, v2;
+
+ BOOST_TEST_NOT( v1 < v2 );
+ BOOST_TEST_NOT( v1 > v2 );
+ BOOST_TEST_NOT( v1 <= v2 );
+ BOOST_TEST_NOT( v1 >= v2 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp b/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp
new file mode 100644
index 00000000..b5708464
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp
@@ -0,0 +1,91 @@
+
+// Copyright 2017, 2019 Peter Dimov
+//
+// 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/variant2/variant.hpp>
+using namespace boost::variant2;
+
+#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
+
+#include <boost/config/pragma_message.hpp>
+
+BOOST_PRAGMA_MESSAGE("Skipping constexpr op<, op<= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
+
+int main() {}
+
+#else
+
+struct X
+{
+};
+
+inline constexpr bool operator<( X const&, X const& ) { return false; }
+inline constexpr bool operator>( X const&, X const& ) { return false; }
+inline constexpr bool operator<=( X const&, X const& ) { return false; }
+inline constexpr bool operator>=( X const&, X const& ) { return false; }
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#define TEST_EQ( v1, v2 ) \
+ STATIC_ASSERT( !(v1 < v2) ); \
+ STATIC_ASSERT( !(v1 > v2) ); \
+ STATIC_ASSERT( v1 <= v2 ); \
+ STATIC_ASSERT( v1 >= v2 );
+
+#define TEST_LE( v1, v3 ) \
+ STATIC_ASSERT( v1 < v3 ); \
+ STATIC_ASSERT( v3 > v1 ); \
+ STATIC_ASSERT( !(v1 > v3) ); \
+ STATIC_ASSERT( !(v3 < v1) ); \
+ STATIC_ASSERT( v1 <= v3 ); \
+ STATIC_ASSERT( v3 >= v1 ); \
+ STATIC_ASSERT( !(v1 >= v3) ); \
+ STATIC_ASSERT( !(v3 <= v1) );
+
+int main()
+{
+ {
+ constexpr variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ }
+
+ {
+ constexpr variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ constexpr variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ constexpr variant<X> v1, v2;
+
+ STATIC_ASSERT( !(v1 < v2) );
+ STATIC_ASSERT( !(v1 > v2) );
+ STATIC_ASSERT( !(v1 <= v2) );
+ STATIC_ASSERT( !(v1 >= v2) );
+ }
+}
+
+#endif
diff --git a/src/boost/libs/variant2/test/variant_move_assign.cpp b/src/boost/libs/variant2/test/variant_move_assign.cpp
new file mode 100644
index 00000000..632f0681
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y
+{
+ Y& operator=( Y&& ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int> v3( 2 );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int, float> v3( 3.14f );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ variant<int, float> v4( 3.15f );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ variant<int, int, float, std::string> v4( 3.15f );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = std::move(v5);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ variant<int, int, float, std::string> v6( "s2" );
+
+ v = std::move(v6);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ variant<X1, X2> v4( in_place_index_t<1>{}, 3 );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ variant<X1, X2> v5( in_place_index_t<0>{}, 4 );
+
+ v = std::move(v5);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_move_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_move_assignable<variant<int const>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_move_assignable<variant<int, float, Y>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_assign_cx.cpp b/src/boost/libs/variant2/test/variant_move_assign_cx.cpp
new file mode 100644
index 00000000..d7ab65fa
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign_cx.cpp
@@ -0,0 +1,107 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <utility>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr T test( A&& a )
+{
+ V v;
+
+ v = std::forward<A>(a);
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( variant<int>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( variant<X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( variant<Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( variant<int, float>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( variant<int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( variant<int, int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<E, E, X>, X>( variant<E, E, X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( variant<int, int, float, float, X>( X(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<E, E, Y>, Y>( variant<E, E, Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( variant<int, int, float, float, Y>( Y(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_move_assign_throw.cpp b/src/boost/libs/variant2/test/variant_move_assign_throw.cpp
new file mode 100644
index 00000000..c1df5944
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign_throw.cpp
@@ -0,0 +1,55 @@
+
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct Y1
+{
+ Y1() noexcept {} // =default fails on msvc-14.0
+
+ Y1(Y1&&)
+ {
+ throw std::runtime_error( "Y1(Y1&&)" );
+ }
+
+ Y1& operator=(Y1&&) = default;
+};
+
+struct Y2
+{
+ Y2() noexcept {}
+
+ Y2(Y2&&)
+ {
+ throw std::runtime_error( "Y2(Y2&&)" );
+ }
+
+ Y2& operator=(Y2&&) = default;
+};
+
+void test()
+{
+ variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
+ variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
+
+ BOOST_TEST_THROWS( v1 = std::move( v2 ), std::runtime_error )
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct.cpp b/src/boost/libs/variant2/test/variant_move_construct.cpp
new file mode 100644
index 00000000..dd83c8c1
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct.cpp
@@ -0,0 +1,146 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ X1() {}
+ X1(X1 const&) {}
+ X1(X1&&) {}
+};
+
+inline bool operator==( X1, X1 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+
+struct X2
+{
+ X2() {}
+ X2(X2 const&) {}
+ X2(X2&&) {}
+};
+
+inline bool operator==( X2, X2 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+
+struct Y
+{
+ Y( Y&& ) = delete;
+};
+
+template<class V> static void test( V&& v )
+{
+ V v2( v );
+ V v3( std::move(v) );
+
+ BOOST_TEST_EQ( v2.index(), v3.index() );
+ BOOST_TEST( v2 == v3 );
+}
+
+int main()
+{
+ test( variant<int>() );
+ test( variant<int>(1) );
+
+ test( variant<int const>() );
+ test( variant<int const>(1) );
+
+ test( variant<int, float>() );
+ test( variant<int, float>(1) );
+ test( variant<int, float>(3.14f) );
+
+ test( variant<int const, float const>() );
+ test( variant<int const, float const>(1) );
+ test( variant<int const, float const>(3.14f) );
+
+ test( variant<std::string>() );
+ test( variant<std::string>("test") );
+
+ test( variant<std::string const>() );
+ test( variant<std::string const>("test") );
+
+ test( variant<int, float, std::string>() );
+ test( variant<int, float, std::string>(1) );
+ test( variant<int, float, std::string>(3.14f) );
+ test( variant<int, float, std::string>("test") );
+
+ test( variant<int, int>() );
+
+ test( variant<int, int, float>() );
+ test( variant<int, int, float>(3.14f) );
+
+ test( variant<int, int, float, float>() );
+
+ test( variant<int, int, float, float, std::string>("test") );
+
+ test( variant<std::string, std::string, float>() );
+
+ test( variant<X1 const>() );
+
+ test( variant<X1, X2>() );
+ test( variant<X1, X2, int>() );
+ test( variant<X1, X2, X2>() );
+ test( variant<X1, X1, X2, X2>() );
+
+ {
+ variant<X1, X2> v;
+ v.emplace<X2>();
+
+ test( std::move(v) );
+ }
+
+ {
+ variant<X1, X1, X2> v;
+ v.emplace<X2>();
+
+ test( std::move(v) );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_move_constructible<variant<X1, X2>>));
+
+#if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
+
+ BOOST_TEST_TRAIT_FALSE((std::is_move_constructible<variant<int, float, Y>>));
+
+#endif
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct_cx.cpp b/src/boost/libs/variant2/test/variant_move_construct_cx.cpp
new file mode 100644
index 00000000..1e49b7f8
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct_cx.cpp
@@ -0,0 +1,104 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <utility>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class T, class V> constexpr T test( V&& v )
+{
+ V v2( std::forward<V>(v) );
+ return get<T>( v2 );
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<int>( variant<int>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<Y>( variant<Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<int>( variant<int, float>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<float>( variant<int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<float>( variant<int, int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<E, E, X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<int, int, float, float, X>( X(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<Y>( variant<E, E, Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<Y>( variant<int, int, float, float, Y>( Y(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct_throw.cpp b/src/boost/libs/variant2/test/variant_move_construct_throw.cpp
new file mode 100644
index 00000000..aabf7d26
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct_throw.cpp
@@ -0,0 +1,69 @@
+
+// Copyright 2019 Peter Dimov
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X> v2( std::move( v1 ) );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_size.cpp b/src/boost/libs/variant2/test/variant_size.cpp
new file mode 100644
index 00000000..81e63ac1
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_size.cpp
@@ -0,0 +1,104 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <cstddef>
+
+using namespace boost::variant2;
+using namespace boost::mp11;
+
+template<class T> using var_size_t = mp_size_t<variant_size<T>::value>;
+
+int main()
+{
+ BOOST_TEST_EQ( (variant_size<variant<>>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> volatile>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const volatile>::value), 0 );
+
+ BOOST_TEST_EQ( (variant_size<variant<>&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<>&&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const&&>::value), 0 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void>>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> volatile>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const volatile>::value), 1 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void>&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void>&&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const&&>::value), 1 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void>>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> volatile>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const volatile>::value), 2 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void>&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void>&&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const&&>::value), 2 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> volatile>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const volatile>::value), 3 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>&&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const&&>::value), 3 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> volatile>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const volatile>::value), 4 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>&&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const&&>::value), 4 );
+
+ variant_size<void>();
+ variant_size<void const>();
+ variant_size<void volatile>();
+ variant_size<void const volatile>();
+
+ variant_size<int&>();
+ variant_size<int const&>();
+ variant_size<int&&>();
+ variant_size<int const&&>();
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> volatile>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>&&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const&&>));
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_subset.cpp b/src/boost/libs/variant2/test/variant_subset.cpp
new file mode 100644
index 00000000..90c9bc21
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_subset.cpp
@@ -0,0 +1,159 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int, float> v1( 1 );
+
+ variant<int> v2 = v1.subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
+
+ variant<int> v3 = std::move(v1).subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+
+ BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
+ }
+
+ {
+ variant<int, float> const v1( 1 );
+
+ variant<int> v2 = v1.subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
+
+ variant<int> v3 = std::move(v1).subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+
+ BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+
+ variant<int, float> v2 = v1.subset<int, float>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ variant<int, float> v3 = std::move(v1).subset<int, float>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+
+ variant<float, int> v2 = v1.subset<float, int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ variant<float, int> v3 = std::move(v1).subset<float, int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int, float, std::string> v1( "s1" );
+
+ variant<int, std::string> v2 = v1.subset<int, std::string>();
+
+ BOOST_TEST( holds_alternative<std::string>( v2 ) );
+ BOOST_TEST_EQ( get<std::string>( v1 ), get<std::string>( v2 ) );
+
+ variant<float, std::string> v3 = std::move(v1).subset<float, std::string>();
+
+ BOOST_TEST( holds_alternative<std::string>( v3 ) );
+ BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
+ }
+
+ {
+ variant<int, int, float, float, X1, X2> v1{ X1{1} };
+
+ variant<X1, X2> v2 = v1.subset<X1, X2>();
+
+ BOOST_TEST( holds_alternative<X1>( v2 ) );
+ BOOST_TEST_EQ( get<X1>( v1 ).v, get<X1>( v2 ).v );
+
+ variant<X1, X2> v3 = std::move( v1 ).subset<X1, X2>();
+
+ BOOST_TEST( holds_alternative<X1>( v3 ) );
+ BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_swap.cpp b/src/boost/libs/variant2/test/variant_swap.cpp
new file mode 100644
index 00000000..3e80f0f2
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_swap.cpp
@@ -0,0 +1,259 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+ BOOST_TEST_EQ( get<0>(v2), 1 );
+
+ swap( v, v2 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int> v3( 2 );
+ BOOST_TEST_EQ( get<0>(v3), 2 );
+
+ swap( v, v3 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ BOOST_TEST_EQ( get<0>(v3), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int, float> v3( 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3), 3.14f );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v3), 1 );
+
+ variant<int, float> v4( 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4), 3.15f );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4), 3.14f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ BOOST_TEST_EQ( v2.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v2), 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v3), 3.14f );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3), 1 );
+
+ variant<int, int, float, std::string> v4( 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v4), 3.15f );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v4), 3.14f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ BOOST_TEST_EQ( v5.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v5), std::string("s1") );
+
+ swap( v, v5 );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ BOOST_TEST_EQ( v5.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v5), 3.15f );
+
+ variant<int, int, float, std::string> v6( "s2" );
+
+ BOOST_TEST_EQ( v6.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v6), std::string("s2") );
+
+ swap( v, v6 );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ BOOST_TEST_EQ( v6.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v6), std::string("s1") );
+ }
+
+ {
+ variant<X1, X2> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2).v, 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2).v, 0 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3).v, 2 );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ BOOST_TEST_EQ( v3.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v3).v, 1 );
+
+ variant<X1, X2> v4( in_place_index_t<1>{}, 3 );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4).v, 3 );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4).v, 2 );
+
+ variant<X1, X2> v5( in_place_index_t<0>{}, 4 );
+
+ BOOST_TEST_EQ( v5.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v5).v, 4 );
+
+ swap( v, v5 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ BOOST_TEST_EQ( v5.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v5).v, 3 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_assign.cpp b/src/boost/libs/variant2/test/variant_value_assign.cpp
new file mode 100644
index 00000000..2519adc0
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_assign.cpp
@@ -0,0 +1,206 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 1;
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v = 2;
+ BOOST_TEST_EQ( get<0>(v), 2 );
+
+ int w1 = 3;
+
+ v = w1;
+ BOOST_TEST_EQ( get<0>(v), 3 );
+
+ int const w2 = 4;
+
+ v = w2;
+ BOOST_TEST_EQ( get<0>(v), 4 );
+
+ v = std::move( w1 );
+ BOOST_TEST_EQ( get<0>(v), 3 );
+
+ v = std::move( w2 );
+ BOOST_TEST_EQ( get<0>(v), 4 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 1;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v = 3.14f;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ float w1 = 3.15f;
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ int const w2 = 2;
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 3.14f;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ float const w1 = 3.15f;
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = "s1";
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ std::string w2( "s2" );
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v = X1{1};
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v = X2{2};
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ X1 w1{3};
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ X1 const w2{4};
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ X2 w3{5};
+
+ v = w3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 5 );
+
+ X2 const w4{6};
+
+ v = w4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_assign_cx.cpp b/src/boost/libs/variant2/test/variant_value_assign_cx.cpp
new file mode 100644
index 00000000..0a29a0af
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_assign_cx.cpp
@@ -0,0 +1,106 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v = a;
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<E, E, X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( X(1) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<E, E, Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( Y(1) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_value_construct.cpp b/src/boost/libs/variant2/test/variant_value_construct.cpp
new file mode 100644
index 00000000..56df8967
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_construct.cpp
@@ -0,0 +1,124 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ operator int() const { return 2; }
+};
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int const> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int const> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int const> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float, std::string> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float, std::string> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int, float, std::string> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float, std::string> v( 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST( holds_alternative<float>(v) );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ }
+
+ {
+ variant<int, float, std::string> v( "text" );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ BOOST_TEST_EQ( get<2>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, std::string> v( 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST( holds_alternative<float>(v) );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, std::string> v( "text" );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ BOOST_TEST_EQ( get<3>(v), std::string("text") );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_construct_cx.cpp b/src/boost/libs/variant2/test/variant_value_construct_cx.cpp
new file mode 100644
index 00000000..5ffad252
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_construct_cx.cpp
@@ -0,0 +1,109 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr operator int() const { return 2; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int> v( X{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 2 );
+ }
+
+ {
+ constexpr variant<int const> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int const> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int const> v( X{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 2 );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, float, X> v( X{} );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( X{} );
+
+ STATIC_ASSERT( v.index() == 3 );
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_valueless.cpp b/src/boost/libs/variant2/test/variant_valueless.cpp
new file mode 100644
index 00000000..d5d18d77
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_valueless.cpp
@@ -0,0 +1,260 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+#include <stdexcept>
+
+using namespace boost::variant2;
+namespace v2d = boost::variant2::detail;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+//
+
+enum E1 { e1 };
+enum E1x { e1x };
+
+struct X1
+{
+ X1() = default;
+
+ X1( E1 ) noexcept {}
+ X1( E1x ) { throw std::runtime_error( "X1(E1x)" ); }
+};
+
+STATIC_ASSERT( std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( std::is_trivially_destructible<X1>::value );
+STATIC_ASSERT( v2d::is_trivially_move_assignable<X1>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X1, E1>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X1, E1x>::value );
+
+enum E2 { e2 };
+enum E2x { e2x };
+
+struct X2
+{
+ X2();
+ ~X2();
+
+ X2( E2 ) noexcept {}
+ X2( E2x ) { throw std::runtime_error( "X2(E2x)" ); }
+};
+
+X2::X2() {}
+X2::~X2() {}
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_trivially_destructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X2, E2>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X2, E2x>::value );
+
+enum E3 { e3 };
+enum E3x { e3x };
+
+struct X3
+{
+ X3();
+
+ X3( X3 const& ) {}
+ X3( X3&& ) {}
+
+ X3( E3 ) noexcept {}
+ X3( E3x ) { throw std::runtime_error( "X3(E3x)" ); }
+
+ X3& operator=( X3 const& ) = default;
+ X3& operator=( X3&& ) = default;
+};
+
+X3::X3() {}
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X3>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X3>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X3>::value );
+STATIC_ASSERT( std::is_trivially_destructible<X3>::value );
+//STATIC_ASSERT( v2d::is_trivially_move_assignable<X3>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X3, E3>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X3, E3x>::value );
+
+//
+
+STATIC_ASSERT( std::is_nothrow_default_constructible<monostate>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<monostate>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<monostate>::value );
+STATIC_ASSERT( std::is_trivially_destructible<monostate>::value );
+
+//
+
+int main()
+{
+ {
+ variant<X2, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X1, X2> v( e2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 1 );
+ }
+ }
+
+ {
+ variant<X2, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X1, X2, monostate> v( e2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 1 );
+ }
+ }
+
+ {
+ variant<X2, X3, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X2, X3, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X2, X3> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // double buffered, no change
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X3, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X3, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_visit.cpp b/src/boost/libs/variant2/test/variant_visit.cpp
new file mode 100644
index 00000000..ed7943ef
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_visit.cpp
@@ -0,0 +1,126 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// 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
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4244 ) // conversion from float to int, possible loss of data
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/config.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+#include <cstdio>
+
+using namespace boost::variant2;
+using boost::mp11::mp_size_t;
+
+struct X
+{
+};
+
+struct F
+{
+ mp_size_t<1> operator()( X& ) const;
+ mp_size_t<2> operator()( X const& ) const;
+ mp_size_t<3> operator()( X&& ) const;
+ mp_size_t<4> operator()( X const&& ) const;
+};
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 1 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, std::move(v) );
+ }
+
+ {
+ variant<int> const v( 2 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 2 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, std::move(v) );
+ }
+
+ {
+ variant<int const> v( 3 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 3 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, std::move(v) );
+ }
+
+ {
+ variant<int const> const v( 4 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 4 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, std::move(v) );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+ variant<int, float> const v2( 3.14f );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2 ){ return (int)(x1 * 1000) + (int)(x2 * 100); }, v1, v2 )), 1314 );
+
+ visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, v1, v2 );
+ visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, std::move(v1), std::move(v2) );
+ }
+
+ {
+ variant<int, float, double> v1( 1 );
+ variant<int, float, double> const v2( 3.14f );
+ variant<int, float, double> v3( 6.28 );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3 ){ return (int)(x1 * 100) * 1000000 + (int)(x2 * 100) * 1000 + (int)(x3 * 100); }, v1, v2, v3 )), 100314628 );
+
+ visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, v1, v2, v3 );
+ visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, std::move(v1), std::move(v2), std::move(v3) );
+ }
+
+ {
+ variant<int, float, double, char> v1( 1 );
+ variant<int, float, double, char> const v2( 3.14f );
+ variant<int, float, double, char> v3( 6.28 );
+ variant<int, float, double, char> const v4( 'A' );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3, char x4 ){ return (long long)(x1 * 100) * 100000000 + (long long)(x2 * 100) * 100000 + (long long)(x3 * 10000) + (int)x4; }, v1, v2, v3, v4 )), 10031462800 + 'A' );
+
+ visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, v1, v2, v3, v4 );
+ visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, std::move(v1), std::move(v2), std::move(v3), std::move(v4) );
+ }
+
+ {
+ variant<X> v;
+ variant<X> const cv;
+
+ BOOST_TEST_EQ( decltype(visit(F{}, v))::value, 1 );
+ BOOST_TEST_EQ( decltype(visit(F{}, cv))::value, 2 );
+ BOOST_TEST_EQ( decltype(visit(F{}, std::move(v)))::value, 3 );
+
+#if !BOOST_WORKAROUND(BOOST_GCC, < 40900)
+
+ // g++ 4.8 doesn't handle const&& particularly well
+ BOOST_TEST_EQ( decltype(visit(F{}, std::move(cv)))::value, 4 );
+
+#endif
+ }
+
+ return boost::report_errors();
+}