summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/variant
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/variant')
-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.cpp77
-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
41 files changed, 5766 insertions, 0 deletions
diff --git a/src/boost/libs/variant/CMakeLists.txt b/src/boost/libs/variant/CMakeLists.txt
new file mode 100644
index 000000000..1984c195d
--- /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 000000000..f66db24a0
--- /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 000000000..17fc68c63
--- /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 000000000..e0b9a5981
--- /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 000000000..302f2ef25
--- /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 000000000..efdd31d00
--- /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 000000000..7ff043f8d
--- /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-2020 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 000000000..bfe505b74
--- /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-2020 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 000000000..7cb1ff81c
--- /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 000000000..097c2c402
--- /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 000000000..72afff9e2
--- /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 000000000..c6d5ef301
--- /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 000000000..87f1f694c
--- /dev/null
+++ b/src/boost/libs/variant/test/hash_variant_test.cpp
@@ -0,0 +1,54 @@
+// Copyright (c) 2011-2020 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 000000000..3b47abb6e
--- /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-2020 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 000000000..c106ceead
--- /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-2020 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 000000000..9b965554a
--- /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 000000000..77edbd550
--- /dev/null
+++ b/src/boost/libs/variant/test/no_rvalue_to_nonconst_visitation.cpp
@@ -0,0 +1,32 @@
+// Copyright (c) 2017-2020 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 000000000..e00487ca6
--- /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-2020 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 000000000..d327bfb4c
--- /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-2020 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 000000000..7bb5b4cf0
--- /dev/null
+++ b/src/boost/libs/variant/test/recursive_wrapper_move_test.cpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2017
+// Mikhail Maximov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/config.hpp"
+#include "boost/core/lightweight_test.hpp"
+
+#ifdef __cpp_inheriting_constructors
+// Test is based on reported issue:
+// https://svn.boost.org/trac/boost/ticket/12680
+// GCC 6 crashed, trying to determine is boost::recursive_wrapper<Node>
+// is_noexcept_move_constructible
+
+#include <string>
+
+#include <boost/variant.hpp>
+#include <boost/array.hpp>
+
+struct Leaf { };
+struct Node;
+
+typedef boost::variant<Leaf, boost::recursive_wrapper<Node>> TreeBase;
+
+struct Tree : TreeBase {
+ using TreeBase::TreeBase;
+
+ template <typename Iter>
+ static Tree Create(Iter /*first*/, Iter /*last*/) { return Leaf{}; }
+};
+
+struct Node {
+ Tree left, right;
+};
+
+
+// Test from https://svn.boost.org/trac/boost/ticket/7120
+template<class Node>
+struct node1_type;
+
+struct var_type;
+
+using var_base = boost::variant<int,
+ boost::recursive_wrapper<node1_type<var_type>>
+>;
+
+template<class Node>
+struct node1_type {
+ boost::array<Node, 1> children;
+};
+
+struct var_type : var_base {
+ using var_base::var_base;
+};
+
+void run() {
+ std::string input{"abracadabra"};
+ const Tree root = Tree::Create(input.begin(), input.end());
+ (void)root; // prevents unused variable warning
+
+ var_type v1 = 1;
+ (void)v1;
+}
+
+#else // #!ifdef __cpp_inheriting_constructors
+// if compiler does not support inheriting constructors - does nothing
+void run() {}
+#endif
+
+int main()
+{
+ run();
+ return boost::report_errors();
+}
+
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 000000000..884435d34
--- /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-2020 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 000000000..b7b9494c4
--- /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 000000000..12e318360
--- /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 000000000..27f0f5892
--- /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 000000000..bef83b361
--- /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 000000000..5de06c8c4
--- /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 000000000..6a0c75d6b
--- /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 000000000..1acec31e0
--- /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 000000000..94ef65ab5
--- /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 000000000..08f5267df
--- /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-2020 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 000000000..156f3f56e
--- /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-2020 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 000000000..e99f3ff99
--- /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-2020 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 000000000..069452398
--- /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-2020 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 000000000..49173c4e3
--- /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-2020 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 000000000..c57302cbe
--- /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 000000000..25642b313
--- /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-2020 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 000000000..3f7f58125
--- /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 000000000..674412c8a
--- /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 000000000..9aa971c0b
--- /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-2020 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 000000000..81afb8e53
--- /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 000000000..c3d0ddc20
--- /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* = BOOST_VARIANT_NULL)
+{
+ 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* = BOOST_VARIANT_NULL)
+{
+ 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();
+}