summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/variant2
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boost/libs/variant2/CMakeLists.txt31
-rw-r--r--src/boost/libs/variant2/README.md21
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark1.cpp168
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark1.md267
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark2.cpp149
-rw-r--r--src/boost/libs/variant2/benchmark/benchmark2.md207
-rw-r--r--src/boost/libs/variant2/index.html15
-rw-r--r--src/boost/libs/variant2/meta/libraries.json14
-rw-r--r--src/boost/libs/variant2/test/CMakeLists.txt11
-rw-r--r--src/boost/libs/variant2/test/Jamfile112
-rw-r--r--src/boost/libs/variant2/test/cmake_install_test/CMakeLists.txt17
-rw-r--r--src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt19
-rw-r--r--src/boost/libs/variant2/test/quick.cpp15
-rw-r--r--src/boost/libs/variant2/test/throw_exception.cpp20
-rw-r--r--src/boost/libs/variant2/test/variant_alternative.cpp154
-rw-r--r--src/boost/libs/variant2/test/variant_convert_construct.cpp175
-rw-r--r--src/boost/libs/variant2/test/variant_convert_construct_throw.cpp95
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign_cx.cpp116
-rw-r--r--src/boost/libs/variant2/test/variant_copy_assign_throw.cpp55
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct.cpp162
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct_cx.cpp112
-rw-r--r--src/boost/libs/variant2/test/variant_copy_construct_throw.cpp69
-rw-r--r--src/boost/libs/variant2/test/variant_default_construct.cpp103
-rw-r--r--src/boost/libs/variant2/test/variant_default_construct_cx.cpp51
-rw-r--r--src/boost/libs/variant2/test/variant_destroy.cpp205
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_index.cpp181
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_index_cx.cpp136
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_type.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_emplace_type_cx.cpp91
-rw-r--r--src/boost/libs/variant2/test/variant_eq_ne.cpp92
-rw-r--r--src/boost/libs/variant2/test/variant_eq_ne_cx.cpp98
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_index.cpp349
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_index_cx.cpp96
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_type.cpp307
-rw-r--r--src/boost/libs/variant2/test/variant_get_by_type_cx.cpp90
-rw-r--r--src/boost/libs/variant2/test/variant_hash.cpp73
-rw-r--r--src/boost/libs/variant2/test/variant_holds_alternative.cpp78
-rw-r--r--src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp43
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_index_construct.cpp138
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp116
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_type_construct.cpp134
-rw-r--r--src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp110
-rw-r--r--src/boost/libs/variant2/test/variant_lt_gt.cpp85
-rw-r--r--src/boost/libs/variant2/test/variant_lt_gt_cx.cpp91
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign.cpp194
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign_cx.cpp107
-rw-r--r--src/boost/libs/variant2/test/variant_move_assign_throw.cpp55
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct.cpp146
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct_cx.cpp104
-rw-r--r--src/boost/libs/variant2/test/variant_move_construct_throw.cpp69
-rw-r--r--src/boost/libs/variant2/test/variant_size.cpp104
-rw-r--r--src/boost/libs/variant2/test/variant_special.cpp103
-rw-r--r--src/boost/libs/variant2/test/variant_subset.cpp159
-rw-r--r--src/boost/libs/variant2/test/variant_swap.cpp259
-rw-r--r--src/boost/libs/variant2/test/variant_trivial.cpp95
-rw-r--r--src/boost/libs/variant2/test/variant_value_assign.cpp206
-rw-r--r--src/boost/libs/variant2/test/variant_value_assign_cx.cpp106
-rw-r--r--src/boost/libs/variant2/test/variant_value_construct.cpp124
-rw-r--r--src/boost/libs/variant2/test/variant_value_construct_cx.cpp109
-rw-r--r--src/boost/libs/variant2/test/variant_valueless.cpp260
-rw-r--r--src/boost/libs/variant2/test/variant_visit.cpp126
62 files changed, 7385 insertions, 0 deletions
diff --git a/src/boost/libs/variant2/CMakeLists.txt b/src/boost/libs/variant2/CMakeLists.txt
new file mode 100644
index 000000000..9d509eee0
--- /dev/null
+++ b/src/boost/libs/variant2/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright 2018, 2019 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# http://www.boost.org/LICENSE_1_0.txt
+
+cmake_minimum_required(VERSION 3.5...3.16)
+
+project(boost_variant2 VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
+
+add_library(boost_variant2 INTERFACE)
+add_library(Boost::variant2 ALIAS boost_variant2)
+
+target_include_directories(boost_variant2 INTERFACE include)
+
+target_link_libraries(boost_variant2
+ INTERFACE
+ Boost::config
+ Boost::mp11
+)
+
+if(BOOST_SUPERPROJECT_VERSION)
+
+ include(BoostInstall)
+ boost_install(TARGETS boost_variant2 HEADER_DIRECTORY include/)
+
+endif()
+
+if(BUILD_TESTING)
+
+ add_subdirectory(test)
+
+endif()
diff --git a/src/boost/libs/variant2/README.md b/src/boost/libs/variant2/README.md
new file mode 100644
index 000000000..83a32fe27
--- /dev/null
+++ b/src/boost/libs/variant2/README.md
@@ -0,0 +1,21 @@
+# variant2
+
+This repository contains a never-valueless, strong guarantee, C++11/14/17
+implementation of [std::variant](http://en.cppreference.com/w/cpp/utility/variant).
+See [the documentation](https://www.boost.org/libs/variant2)
+for more information.
+
+The code requires [Boost.Mp11](https://github.com/boostorg/mp11) and
+Boost.Config.
+
+The library is part of Boost, starting from release 1.71, but the header
+`variant.hpp` will also work [standalone](https://godbolt.org/z/nVUNKX).
+
+Supported compilers:
+
+* g++ 4.8 or later with `-std=c++11` or above
+* clang++ 3.5 or later with `-std=c++11` or above
+* Visual Studio 2015, 2017, 2019
+
+Tested on [Travis](https://travis-ci.org/boostorg/variant2/) and
+[Appveyor](https://ci.appveyor.com/project/pdimov/variant2-fkab9).
diff --git a/src/boost/libs/variant2/benchmark/benchmark1.cpp b/src/boost/libs/variant2/benchmark/benchmark1.cpp
new file mode 100644
index 000000000..703f89114
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark1.cpp
@@ -0,0 +1,168 @@
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(ONLY_V2)
+# define NO_BV
+# define NO_SV
+#endif
+
+#if defined(ONLY_BV)
+# define NO_V2
+# define NO_SV
+#endif
+
+#if defined(ONLY_SV)
+# define NO_V2
+# define NO_BV
+#endif
+
+#if !defined(NO_V2)
+#include <boost/variant2/variant.hpp>
+#endif
+
+#if !defined(NO_BV)
+#include <boost/variant.hpp>
+#endif
+
+#if !defined(NO_SV)
+#include <variant>
+#endif
+
+#include <type_traits>
+#include <chrono>
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <map>
+#include <string>
+#include <stdexcept>
+
+template<class T> struct is_numeric: std::integral_constant<bool, std::is_integral<T>::value || std::is_floating_point<T>::value>
+{
+};
+
+template<class T, class U> struct have_addition: std::integral_constant<bool, is_numeric<T>::value && is_numeric<U>::value>
+{
+};
+
+template<class T, class U, class E = std::enable_if_t<have_addition<T, U>::value>> auto add( T const& t, U const& u )
+{
+ return t + u;
+}
+
+template<class T, class U, class E = std::enable_if_t<!have_addition<T, U>::value>> double add( T const& /*t*/, U const& /*u*/ )
+{
+ throw std::logic_error( "Invalid addition" );
+}
+
+inline double to_double( double const& v )
+{
+ return v;
+}
+
+#if !defined(NO_V2)
+
+template<class... T> boost::variant2::variant<T...> operator+( boost::variant2::variant<T...> const& v1, boost::variant2::variant<T...> const& v2 )
+{
+ return visit( [&]( auto const& x1, auto const & x2 ) -> boost::variant2::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( boost::variant2::variant<T...> const& v )
+{
+ return boost::variant2::get<double>( v );
+}
+
+#endif
+
+#if !defined(NO_BV)
+
+template<class... T> boost::variant<T...> operator+( boost::variant<T...> const& v1, boost::variant<T...> const& v2 )
+{
+ return boost::apply_visitor( [&]( auto const& x1, auto const & x2 ) -> boost::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( boost::variant<T...> const& v )
+{
+ return boost::get<double>( v );
+}
+
+#endif
+
+#if !defined(NO_SV)
+
+template<class... T> std::variant<T...> operator+( std::variant<T...> const& v1, std::variant<T...> const& v2 )
+{
+ return visit( [&]( auto const& x1, auto const & x2 ) -> std::variant<T...> { return add( x1, x2 ); }, v1, v2 );
+}
+
+template<class... T> double to_double( std::variant<T...> const& v )
+{
+ return std::get<double>( v );
+}
+
+#endif
+
+template<class V> void test_( long long N )
+{
+ std::vector<V> w;
+ // lack of reserve is deliberate
+
+ auto tp1 = std::chrono::high_resolution_clock::now();
+
+ for( long long i = 0; i < N; ++i )
+ {
+ V v;
+
+ if( i % 7 == 0 )
+ {
+ v = i / 7;
+ }
+ else
+ {
+ v = i / 7.0;
+ }
+
+ w.push_back( v );
+ }
+
+ V s = 0.0;
+
+ for( long long i = 0; i < N; ++i )
+ {
+ s = s + w[ i ];
+ }
+
+ auto tp2 = std::chrono::high_resolution_clock::now();
+
+ std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << to_double( s ) << "\n";
+}
+
+template<class... T> void test( long long N )
+{
+ std::cout << "N=" << N << ":\n";
+
+ std::cout << " double: "; test_<double>( N );
+#if !defined(NO_V2)
+ std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
+#endif
+#if !defined(NO_BV)
+ std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
+#endif
+#if !defined(NO_SV)
+ std::cout << " std::variant: "; test_<std::variant<T...>>( N );
+#endif
+
+ std::cout << '\n';
+}
+
+int main()
+{
+ long long const N = 100'000'000LL;
+
+ test<long long, double>( N );
+ test<std::nullptr_t, long long, double, std::string, std::vector<std::string>, std::map<std::string, std::string>>( N );
+}
diff --git a/src/boost/libs/variant2/benchmark/benchmark1.md b/src/boost/libs/variant2/benchmark/benchmark1.md
new file mode 100644
index 000000000..aa3bb933a
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark1.md
@@ -0,0 +1,267 @@
+# benchmark1.cpp results
+
+## VS 2017 15.9.7 64 bit (cl.exe 19.16, /EHsc /std:c++17)
+
+### /Od
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1837 ms
+boost::variant (-DONLY_BV): 2627 ms
+ std::variant (-DONLY_SV): 1425 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 9041 ms; S=7.14286e+14
+ variant2: 48367 ms; S=7.14286e+14
+boost::variant: 102776 ms; S=7.14286e+14
+ std::variant: 40590 ms; S=7.14286e+14
+
+N=100000000:
+ double: 9029 ms; S=7.14286e+14
+ variant2: 92962 ms; S=7.14286e+14
+boost::variant: 110441 ms; S=7.14286e+14
+ std::variant: 92974 ms; S=7.14286e+14
+```
+
+### /O2 /DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2571 ms
+boost::variant (-DONLY_BV): 3335 ms
+ std::variant (-DONLY_SV): 1903 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1949 ms; S=7.14286e+14
+ variant2: 4176 ms; S=7.14286e+14
+boost::variant: 11312 ms; S=7.14286e+14
+ std::variant: 4617 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1949 ms; S=7.14286e+14
+ variant2: 11807 ms; S=7.14286e+14
+boost::variant: 15632 ms; S=7.14286e+14
+ std::variant: 10725 ms; S=7.14286e+14
+```
+
+## g++ 7.4.0 -std=c++17 (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2734 ms
+boost::variant (-DONLY_BV): 4308 ms
+ std::variant (-DONLY_SV): 2298 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 3620 ms; S=7.14286e+14
+ variant2: 29214 ms; S=7.14286e+14
+boost::variant: 88492 ms; S=7.14286e+14
+ std::variant: 39510 ms; S=7.14286e+14
+
+N=100000000:
+ double: 3642 ms; S=7.14286e+14
+ variant2: 75822 ms; S=7.14286e+14
+boost::variant: 96680 ms; S=7.14286e+14
+ std::variant: 66411 ms; S=7.14286e+14
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2103 ms
+boost::variant (-DONLY_BV): 3398 ms
+ std::variant (-DONLY_SV): 1841 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1576 ms; S=7.14286e+14
+ variant2: 3424 ms; S=7.14286e+14
+boost::variant: 4356 ms; S=7.14286e+14
+ std::variant: 3764 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1582 ms; S=7.14286e+14
+ variant2: 9062 ms; S=7.14286e+14
+boost::variant: 9603 ms; S=7.14286e+14
+ std::variant: 8825 ms; S=7.14286e+14
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2276 ms
+boost::variant (-DONLY_BV): 3647 ms
+ std::variant (-DONLY_SV): 2111 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1643 ms; S=7.14286e+14
+ variant2: 3070 ms; S=7.14286e+14
+boost::variant: 3385 ms; S=7.14286e+14
+ std::variant: 3880 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1622 ms; S=7.14286e+14
+ variant2: 8101 ms; S=7.14286e+14
+boost::variant: 8611 ms; S=7.14286e+14
+ std::variant: 8694 ms; S=7.14286e+14
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2390 ms
+boost::variant (-DONLY_BV): 3768 ms
+ std::variant (-DONLY_SV): 2094 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1611 ms; S=7.14286e+14
+ variant2: 2975 ms; S=7.14286e+14
+boost::variant: 3232 ms; S=7.14286e+14
+ std::variant: 3726 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1603 ms; S=7.14286e+14
+ variant2: 8157 ms; S=7.14286e+14
+boost::variant: 8419 ms; S=7.14286e+14
+ std::variant: 8659 ms; S=7.14286e+14
+```
+
+## clang++ 5.0.1 -std=c++17 -stdlib=libc++ (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2190 ms
+boost::variant (-DONLY_BV): 3537 ms
+ std::variant (-DONLY_SV): 2151 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 6063 ms; S=7.14286e+14
+ variant2: 23616 ms; S=7.14286e+14
+boost::variant: 92730 ms; S=7.14286e+14
+ std::variant: 23160 ms; S=7.14286e+14
+
+N=100000000:
+ double: 6054 ms; S=7.14286e+14
+ variant2: 52738 ms; S=7.14286e+14
+boost::variant: 96896 ms; S=7.14286e+14
+ std::variant: 72595 ms; S=7.14286e+14
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2722 ms
+boost::variant (-DONLY_BV): 4337 ms
+ std::variant (-DONLY_SV): 2697 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 2171 ms; S=7.14286e+14
+ variant2: 9280 ms; S=7.14286e+14
+boost::variant: 51478 ms; S=7.14286e+14
+ std::variant: 5642 ms; S=7.14286e+14
+
+N=100000000:
+ double: 2171 ms; S=7.14286e+14
+ variant2: 22166 ms; S=7.14286e+14
+boost::variant: 54084 ms; S=7.14286e+14
+ std::variant: 14330 ms; S=7.14286e+14
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2499 ms
+boost::variant (-DONLY_BV): 3826 ms
+ std::variant (-DONLY_SV): 2645 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1604 ms; S=7.14286e+14
+ variant2: 2726 ms; S=7.14286e+14
+boost::variant: 6662 ms; S=7.14286e+14
+ std::variant: 3869 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1598 ms; S=7.14286e+14
+ variant2: 8136 ms; S=7.14286e+14
+boost::variant: 9236 ms; S=7.14286e+14
+ std::variant: 6279 ms; S=7.14286e+14
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 2509 ms
+boost::variant (-DONLY_BV): 3845 ms
+ std::variant (-DONLY_SV): 2638 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ double: 1592 ms; S=7.14286e+14
+ variant2: 2697 ms; S=7.14286e+14
+boost::variant: 6648 ms; S=7.14286e+14
+ std::variant: 3826 ms; S=7.14286e+14
+
+N=100000000:
+ double: 1614 ms; S=7.14286e+14
+ variant2: 8035 ms; S=7.14286e+14
+boost::variant: 9221 ms; S=7.14286e+14
+ std::variant: 6319 ms; S=7.14286e+14
+```
diff --git a/src/boost/libs/variant2/benchmark/benchmark2.cpp b/src/boost/libs/variant2/benchmark/benchmark2.cpp
new file mode 100644
index 000000000..bea5f3a95
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark2.cpp
@@ -0,0 +1,149 @@
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(ONLY_V2)
+# define NO_BV
+# define NO_SV
+#endif
+
+#if defined(ONLY_BV)
+# define NO_V2
+# define NO_SV
+#endif
+
+#if defined(ONLY_SV)
+# define NO_V2
+# define NO_BV
+#endif
+
+#if !defined(NO_V2)
+#include <boost/variant2/variant.hpp>
+#endif
+
+#if !defined(NO_BV)
+#include <boost/variant.hpp>
+#endif
+
+#if !defined(NO_SV)
+#include <variant>
+#endif
+
+#include <type_traits>
+#include <chrono>
+#include <iostream>
+#include <iomanip>
+#include <vector>
+
+struct prefix
+{
+ int v_;
+};
+
+struct X1: prefix {};
+struct X2: prefix {};
+struct X3: prefix {};
+struct X4: prefix {};
+struct X5: prefix {};
+struct X6: prefix {};
+struct X7: prefix {};
+struct X8: prefix {};
+struct X9: prefix {};
+struct X10: prefix {};
+struct X11: prefix {};
+struct X12: prefix {};
+
+inline int get_value( prefix const& v )
+{
+ return v.v_;
+}
+
+#if !defined(NO_V2)
+
+template<class... T> int get_value( boost::variant2::variant<T...> const& v )
+{
+ return visit( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+#if !defined(NO_BV)
+
+template<class... T> int get_value( boost::variant<T...> const& v )
+{
+ return boost::apply_visitor( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+#if !defined(NO_SV)
+
+template<class... T> int get_value( std::variant<T...> const& v )
+{
+ return visit( []( prefix const& x ) { return x.v_; }, v );
+}
+
+#endif
+
+template<class V> void test_( int N )
+{
+ std::vector<V> w;
+ // lack of reserve is deliberate
+
+ auto tp1 = std::chrono::high_resolution_clock::now();
+
+ for( int i = 0; i < N / 12; ++i )
+ {
+ w.push_back( X1{ i } );
+ w.push_back( X2{ i } );
+ w.push_back( X3{ i } );
+ w.push_back( X4{ i } );
+ w.push_back( X5{ i } );
+ w.push_back( X6{ i } );
+ w.push_back( X7{ i } );
+ w.push_back( X8{ i } );
+ w.push_back( X9{ i } );
+ w.push_back( X10{ i } );
+ w.push_back( X11{ i } );
+ w.push_back( X12{ i } );
+ }
+
+ unsigned long long s = 0;
+
+ for( std::size_t i = 0, n = w.size(); i < n; ++i )
+ {
+ s = s + get_value( w[ i ] );
+ }
+
+ auto tp2 = std::chrono::high_resolution_clock::now();
+
+ std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << s << "\n";
+}
+
+template<class... T> void test( int N )
+{
+ std::cout << "N=" << N << ":\n";
+
+ std::cout << " prefix: "; test_<prefix>( N );
+#if !defined(NO_V2)
+ std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
+#endif
+#if !defined(NO_BV)
+ std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
+#endif
+#if !defined(NO_SV)
+ std::cout << " std::variant: "; test_<std::variant<T...>>( N );
+#endif
+
+ std::cout << '\n';
+}
+
+int main()
+{
+ int const N = 100'000'000;
+
+ test<X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12>( N );
+}
diff --git a/src/boost/libs/variant2/benchmark/benchmark2.md b/src/boost/libs/variant2/benchmark/benchmark2.md
new file mode 100644
index 000000000..9aad6488a
--- /dev/null
+++ b/src/boost/libs/variant2/benchmark/benchmark2.md
@@ -0,0 +1,207 @@
+# benchmark2.cpp results
+
+## VS 2017 15.9.7 64 bit (cl.exe 19.16, /EHsc /std:c++17)
+
+### /Od
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1403 ms
+boost::variant (-DONLY_BV): 2972 ms
+ std::variant (-DONLY_SV): 1057 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 7016 ms; S=416666583333336
+ variant2: 24723 ms; S=416666583333336
+boost::variant: 60438 ms; S=416666583333336
+ std::variant: 20707 ms; S=416666583333336
+```
+
+### /O2 /DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1778 ms
+boost::variant (-DONLY_BV): 3252 ms
+ std::variant (-DONLY_SV): 1372 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 803 ms; S=416666583333336
+ variant2: 2124 ms; S=416666583333336
+boost::variant: 6191 ms; S=416666583333336
+ std::variant: 2193 ms; S=416666583333336
+```
+
+## g++ 7.4.0 -std=c++17 (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1739 ms
+boost::variant (-DONLY_BV): 3113 ms
+ std::variant (-DONLY_SV): 1719 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 5163 ms; S=416666583333336
+ variant2: 20628 ms; S=416666583333336
+boost::variant: 43308 ms; S=416666583333336
+ std::variant: 42375 ms; S=416666583333336
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1484 ms
+boost::variant (-DONLY_BV): 2947 ms
+ std::variant (-DONLY_SV): 1448 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 781 ms; S=416666583333336
+ variant2: 1992 ms; S=416666583333336
+boost::variant: 2249 ms; S=416666583333336
+ std::variant: 4843 ms; S=416666583333336
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1547 ms
+boost::variant (-DONLY_BV): 2999 ms
+ std::variant (-DONLY_SV): 1528 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 793 ms; S=416666583333336
+ variant2: 1686 ms; S=416666583333336
+boost::variant: 1833 ms; S=416666583333336
+ std::variant: 4340 ms; S=416666583333336
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1595 ms
+boost::variant (-DONLY_BV): 3084 ms
+ std::variant (-DONLY_SV): 1620 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 853 ms; S=416666583333336
+ variant2: 1681 ms; S=416666583333336
+boost::variant: 1773 ms; S=416666583333336
+ std::variant: 3989 ms; S=416666583333336
+```
+
+## clang++ 5.0.1 -std=c++17 -stdlib=libc++ (Cygwin 64 bit)
+
+### -O0
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1578 ms
+boost::variant (-DONLY_BV): 2623 ms
+ std::variant (-DONLY_SV): 1508 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 4447 ms; S=416666583333336
+ variant2: 16016 ms; S=416666583333336
+boost::variant: 42365 ms; S=416666583333336
+ std::variant: 17817 ms; S=416666583333336
+```
+
+### -O1
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1841 ms
+boost::variant (-DONLY_BV): 2919 ms
+ std::variant (-DONLY_SV): 1776 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 1390 ms; S=416666583333336
+ variant2: 5397 ms; S=416666583333336
+boost::variant: 23234 ms; S=416666583333336
+ std::variant: 2807 ms; S=416666583333336
+```
+
+### -O2 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1766 ms
+boost::variant (-DONLY_BV): 2817 ms
+ std::variant (-DONLY_SV): 1718 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 604 ms; S=416666583333336
+ variant2: 1625 ms; S=416666583333336
+boost::variant: 2735 ms; S=416666583333336
+ std::variant: 2664 ms; S=416666583333336
+```
+
+### -O3 -DNDEBUG
+
+#### Compile time
+
+```
+ variant2 (-DONLY_V2): 1720 ms
+boost::variant (-DONLY_BV): 2806 ms
+ std::variant (-DONLY_SV): 1737 ms
+```
+
+#### Run time
+
+```
+N=100000000:
+ prefix: 603 ms; S=416666583333336
+ variant2: 1608 ms; S=416666583333336
+boost::variant: 2696 ms; S=416666583333336
+ std::variant: 2668 ms; S=416666583333336
+```
diff --git a/src/boost/libs/variant2/index.html b/src/boost/libs/variant2/index.html
new file mode 100644
index 000000000..ce8b2263a
--- /dev/null
+++ b/src/boost/libs/variant2/index.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/variant2.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/variant2.html">doc/html/variant2.html</a>.
+</body>
+</html>
+<!--
+ Copyright Beman Dawes, 2001
+ Distributed under the Boost Software License, Version 1.0.
+ See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt
+-->
diff --git a/src/boost/libs/variant2/meta/libraries.json b/src/boost/libs/variant2/meta/libraries.json
new file mode 100644
index 000000000..7d9337ec7
--- /dev/null
+++ b/src/boost/libs/variant2/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "key": "variant2",
+ "name": "Variant2",
+ "authors": [
+ "Peter Dimov"
+ ],
+ "maintainers": [
+ "Peter Dimov <pdimov -at- pdimov.com>"
+ ],
+ "description": "A never-valueless, strong guarantee implementation of std::variant.",
+ "category": [
+ "Containers", "Data"
+ ]
+}
diff --git a/src/boost/libs/variant2/test/CMakeLists.txt b/src/boost/libs/variant2/test/CMakeLists.txt
new file mode 100644
index 000000000..0c317a246
--- /dev/null
+++ b/src/boost/libs/variant2/test/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright 2018, 2019 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
+
+if(HAVE_BOOST_TEST)
+
+boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::variant2 Boost::core Boost::container_hash)
+
+endif()
diff --git a/src/boost/libs/variant2/test/Jamfile b/src/boost/libs/variant2/test/Jamfile
new file mode 100644
index 000000000..93bbb6757
--- /dev/null
+++ b/src/boost/libs/variant2/test/Jamfile
@@ -0,0 +1,112 @@
+# Boost.Variant2 Library Test Jamfile
+#
+# Copyright 2015-2019 Peter Dimov
+#
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt
+
+import testing ;
+import ../../config/checks/config : requires ;
+
+project
+ : default-build
+
+ <warnings>extra
+
+ : requirements
+
+ [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr ]
+
+ <toolset>msvc:<warnings-as-errors>on
+ <toolset>gcc:<warnings-as-errors>on
+ <toolset>clang:<warnings-as-errors>on
+ ;
+
+run quick.cpp ;
+
+run variant_size.cpp ;
+run variant_alternative.cpp ;
+
+run variant_holds_alternative.cpp ;
+compile variant_holds_alternative_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_get_by_index.cpp ;
+compile variant_get_by_index_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_get_by_type.cpp ;
+compile variant_get_by_type_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_default_construct.cpp ;
+compile variant_default_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_copy_construct.cpp ;
+compile variant_copy_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_move_construct.cpp ;
+compile variant_move_construct_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_value_construct.cpp ;
+compile variant_value_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_in_place_index_construct.cpp ;
+compile variant_in_place_index_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_in_place_type_construct.cpp ;
+compile variant_in_place_type_construct_cx.cpp : <toolset>msvc-14.0:<build>no ;
+
+run variant_copy_assign.cpp ;
+compile variant_copy_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_move_assign.cpp ;
+compile variant_move_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_value_assign.cpp ;
+compile variant_value_assign_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_emplace_index.cpp ;
+compile variant_emplace_index_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_emplace_type.cpp ;
+compile variant_emplace_type_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_swap.cpp ;
+
+run variant_eq_ne.cpp ;
+compile variant_eq_ne_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_lt_gt.cpp ;
+compile variant_lt_gt_cx.cpp : [ requires cxx14_constexpr ] ;
+
+run variant_destroy.cpp ;
+run variant_visit.cpp ;
+
+run variant_convert_construct.cpp ;
+run variant_subset.cpp ;
+run variant_valueless.cpp ;
+
+run variant_copy_construct_throw.cpp ;
+run variant_move_construct_throw.cpp ;
+run variant_convert_construct_throw.cpp ;
+
+run variant_copy_assign_throw.cpp ;
+run variant_move_assign_throw.cpp ;
+
+local NX =
+ <exception-handling>off
+ <toolset>msvc:<cxxflags>/wd4530
+ <toolset>msvc:<cxxflags>/wd4577
+ ;
+
+run variant_get_by_index.cpp throw_exception.cpp : : : $(NX) : variant_get_by_index_nx ;
+compile variant_get_by_index_cx.cpp : $(NX) <toolset>msvc-14.0:<build>no : variant_get_by_index_cx_nx ;
+
+run variant_get_by_type.cpp throw_exception.cpp : : : $(NX) : variant_get_by_type_nx ;
+compile variant_get_by_type_cx.cpp : $(NX) <toolset>msvc-14.0:<build>no : variant_get_by_type_cx_nx ;
+
+run variant_subset.cpp throw_exception.cpp : : : $(NX) : variant_subset_nx ;
+
+run variant_hash.cpp ;
+
+run variant_trivial.cpp ;
+run variant_special.cpp ;
diff --git a/src/boost/libs/variant2/test/cmake_install_test/CMakeLists.txt b/src/boost/libs/variant2/test/cmake_install_test/CMakeLists.txt
new file mode 100644
index 000000000..62a1176e8
--- /dev/null
+++ b/src/boost/libs/variant2/test/cmake_install_test/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright 2018, 2019 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+cmake_minimum_required(VERSION 3.5...3.16)
+
+project(cmake_install_test LANGUAGES CXX)
+
+find_package(boost_variant2 REQUIRED)
+
+add_executable(quick ../quick.cpp)
+target_link_libraries(quick Boost::variant2)
+
+enable_testing()
+add_test(quick quick)
+
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
diff --git a/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt b/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt
new file mode 100644
index 000000000..91ad66312
--- /dev/null
+++ b/src/boost/libs/variant2/test/cmake_subdir_test/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright 2018, 2019 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+cmake_minimum_required(VERSION 3.5...3.16)
+
+project(cmake_subdir_test LANGUAGES CXX)
+
+add_subdirectory(../.. boostorg/variant2)
+add_subdirectory(../../../config boostorg/config)
+add_subdirectory(../../../mp11 boostorg/mp11)
+
+add_executable(quick ../quick.cpp)
+target_link_libraries(quick Boost::variant2)
+
+enable_testing()
+add_test(quick quick)
+
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
diff --git a/src/boost/libs/variant2/test/quick.cpp b/src/boost/libs/variant2/test/quick.cpp
new file mode 100644
index 000000000..789d0e707
--- /dev/null
+++ b/src/boost/libs/variant2/test/quick.cpp
@@ -0,0 +1,15 @@
+
+// Copyright 2019 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+int main()
+{
+ variant<float, int> v( 2 );
+ return get<1>( v ) == 2? 0: 1;
+}
diff --git a/src/boost/libs/variant2/test/throw_exception.cpp b/src/boost/libs/variant2/test/throw_exception.cpp
new file mode 100644
index 000000000..9eaccc119
--- /dev/null
+++ b/src/boost/libs/variant2/test/throw_exception.cpp
@@ -0,0 +1,20 @@
+
+// Copyright 2019 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <exception>
+#include <cstdio>
+
+namespace boost
+{
+
+void throw_exception( std::exception const & e )
+{
+ std::fprintf( stderr, "Exception: %s\n", e.what() );
+ std::terminate();
+}
+
+} // namespace boost
diff --git a/src/boost/libs/variant2/test/variant_alternative.cpp b/src/boost/libs/variant2/test/variant_alternative.cpp
new file mode 100644
index 000000000..600c26c99
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_alternative.cpp
@@ -0,0 +1,154 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <cstddef>
+
+using namespace boost::variant2;
+using namespace boost::mp11;
+
+template<class I, class T> using var_alt_t = variant_alternative_t<I::value, T>;
+
+int main()
+{
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>>, int>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const>, int const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> volatile>, int volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const volatile>, int const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>&>, int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const&>, int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int>&&>, int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int> const&&>, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float>>, void>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> const>, void const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> volatile>, void volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<void, int, float> const volatile>, void const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float>&>, char&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float> const&>, char const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float>&&>, char&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<0, variant<char, int, float> const&&>, char const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>>, int>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const>, int const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> volatile>, int volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const volatile>, int const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>&>, int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const&>, int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float>&&>, int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<1, variant<void, int, float> const&&>, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>>, float>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const>, float const>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> volatile>, float volatile>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const volatile>, float const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>&>, float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const&>, float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float>&&>, float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<variant_alternative_t<2, variant<void, int, float> const&&>, float const&&>));
+
+ variant_alternative<0, void>();
+ variant_alternative<0, void const>();
+ variant_alternative<0, void volatile>();
+ variant_alternative<0, void const volatile>();
+
+ variant_alternative<0, int&>();
+ variant_alternative<0, int const&>();
+ variant_alternative<0, int&&>();
+ variant_alternative<0, int const&&>();
+
+ variant_alternative<0, variant<>>();
+ variant_alternative<0, variant<> const>();
+ variant_alternative<0, variant<> volatile>();
+ variant_alternative<0, variant<> const volatile>();
+
+ variant_alternative<0, variant<>&>();
+ variant_alternative<0, variant<> const&>();
+ variant_alternative<0, variant<>&&>();
+ variant_alternative<0, variant<> const&&>();
+
+ variant_alternative<1, variant<int>>();
+ variant_alternative<1, variant<int> const>();
+ variant_alternative<1, variant<int> volatile>();
+ variant_alternative<1, variant<int> const volatile>();
+
+ variant_alternative<1, variant<int>&>();
+ variant_alternative<1, variant<int> const&>();
+ variant_alternative<1, variant<int>&&>();
+ variant_alternative<1, variant<int> const&&>();
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, void const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, int const&&>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<>&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<0>, variant<> const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> volatile>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int>&&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_alt_t, mp_size_t<0>, variant<int> const&&>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int>&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_alt_t, mp_size_t<1>, variant<int> const&&>));
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_convert_construct.cpp b/src/boost/libs/variant2/test/variant_convert_construct.cpp
new file mode 100644
index 000000000..dbf61d907
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_convert_construct.cpp
@@ -0,0 +1,175 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int const> v( 1 );
+
+ variant<int const, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int const>( v2 ) );
+ BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
+
+ variant<int const, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int const>( v3 ) );
+ BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
+ }
+
+ {
+ variant<int const> const v( 1 );
+
+ variant<int const, float> v2( v );
+
+ BOOST_TEST( holds_alternative<int const>( v2 ) );
+ BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
+
+ variant<int const, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<int const>( v3 ) );
+ BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
+ }
+
+ {
+ variant<float> v( 3.14f );
+
+ variant<int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<float>( v2 ) );
+ BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
+
+ variant<int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<float>( v3 ) );
+ BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
+ }
+
+ {
+ variant<float> v( 3.15f );
+
+ variant<int, int, float> v2( v );
+
+ BOOST_TEST( holds_alternative<float>( v2 ) );
+ BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
+
+ variant<int, int, float> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<float>( v3 ) );
+ BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
+ }
+
+ {
+ variant<float, std::string> v( "s1" );
+
+ variant<int, int, float, std::string> v2( v );
+
+ BOOST_TEST( holds_alternative<std::string>( v2 ) );
+ BOOST_TEST_EQ( get<std::string>( v ), get<std::string>( v2 ) );
+
+ variant<int, int, float, std::string> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<std::string>( v3 ) );
+ BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
+ }
+
+ {
+ variant<X1, X2> v{ X1{1} };
+
+ variant<int, int, float, float, X1, X2> v2( v );
+
+ BOOST_TEST( holds_alternative<X1>( v2 ) );
+ BOOST_TEST_EQ( get<X1>( v ).v, get<X1>( v2 ).v );
+
+ variant<int, int, float, float, X1, X2> v3( std::move(v) );
+
+ BOOST_TEST( holds_alternative<X1>( v3 ) );
+ BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp b/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp
new file mode 100644
index 000000000..bb53d7ce5
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_convert_construct_throw.cpp
@@ -0,0 +1,95 @@
+
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test_copy()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X, int, float> v2( v1 );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+void test_move()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X, int, float> v2( std::move( v1 ) );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test_copy();
+ test_move();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign.cpp b/src/boost/libs/variant2/test/variant_copy_assign.cpp
new file mode 100644
index 000000000..c8ed44f75
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y
+{
+ Y& operator=( Y const& ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int> const v3( 2 );
+
+ v = v3;
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int, float> v3( 3.14f );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ variant<int, float> const v4( 3.15f );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ variant<int, int, float, std::string> const v4( 3.15f );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = v5;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ variant<int, int, float, std::string> const v6( "s2" );
+
+ v = v6;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ v = v2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ v = v3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ variant<X1, X2> const v4( in_place_index_t<1>{}, 3 );
+
+ v = v4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ variant<X1, X2> const v5( in_place_index_t<0>{}, 4 );
+
+ v = v5;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_assignable<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_assignable<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_copy_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_assignable<variant<int const>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_assignable<variant<int, float, Y>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp b/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp
new file mode 100644
index 000000000..8be25794a
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign_cx.cpp
@@ -0,0 +1,116 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr T test( A const& a )
+{
+ V v;
+
+ v = a;
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+ constexpr auto w = test<variant<int>, int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<X> v( 1 );
+ constexpr auto w = test<variant<X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<Y> v( 1 );
+ constexpr auto w = test<variant<Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr variant<int, float> v( 1 );
+ constexpr auto w = test<variant<int, float>, int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.0f );
+ constexpr auto w = test<variant<int, float>, float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.0f );
+ constexpr auto w = test<variant<int, int, float>, float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<E, E, X> v( 1 );
+ constexpr auto w = test<variant<E, E, X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( X(1) );
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<E, E, Y> v( 1 );
+ constexpr auto w = test<variant<E, E, Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, Y> v( Y(1) );
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp b/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp
new file mode 100644
index 000000000..a13dccbec
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_assign_throw.cpp
@@ -0,0 +1,55 @@
+
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct Y1
+{
+ Y1() noexcept {} // =default fails on msvc-14.0
+
+ Y1(Y1 const&)
+ {
+ throw std::runtime_error( "Y1(Y1 const&)" );
+ }
+
+ Y1& operator=(Y1 const&) = default;
+};
+
+struct Y2
+{
+ Y2() noexcept {}
+
+ Y2(Y2 const&)
+ {
+ throw std::runtime_error( "Y2(Y2 const&)" );
+ }
+
+ Y2& operator=(Y2 const&) = default;
+};
+
+void test()
+{
+ variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
+ variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
+
+ BOOST_TEST_THROWS( v1 = v2, std::runtime_error )
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct.cpp b/src/boost/libs/variant2/test/variant_copy_construct.cpp
new file mode 100644
index 000000000..169a2faf0
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct.cpp
@@ -0,0 +1,162 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/config.hpp>
+#include <boost/config/workaround.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ X1() {}
+ X1(X1 const&) {}
+ X1(X1&&) {}
+};
+
+inline bool operator==( X1, X1 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+
+struct X2
+{
+ X2() {}
+ X2(X2 const&) {}
+ X2(X2&&) {}
+};
+
+inline bool operator==( X2, X2 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+
+struct Y
+{
+ Y( Y const& ) = delete;
+};
+
+struct D
+{
+ ~D() {}
+};
+
+inline bool operator==( D, D ) { return true; }
+
+template<class V> static void test( V const & v )
+{
+ V v2( v );
+
+ BOOST_TEST_EQ( v.index(), v2.index() );
+ BOOST_TEST( v == v2 );
+
+ BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<V>));
+}
+
+int main()
+{
+ test( variant<int>() );
+ test( variant<int>(1) );
+
+ test( variant<int const>() );
+ test( variant<int const>(1) );
+
+ test( variant<int, float>() );
+ test( variant<int, float>(1) );
+ test( variant<int, float>(3.14f) );
+
+ test( variant<int const, float const>() );
+ test( variant<int const, float const>(1) );
+ test( variant<int const, float const>(3.14f) );
+
+ test( variant<std::string>() );
+ test( variant<std::string>("test") );
+
+ test( variant<std::string const>() );
+ test( variant<std::string const>("test") );
+
+ test( variant<int, float, std::string>() );
+ test( variant<int, float, std::string>(1) );
+ test( variant<int, float, std::string>(3.14f) );
+ test( variant<int, float, std::string>("test") );
+
+ test( variant<int, int>() );
+
+ test( variant<int, int, float>() );
+ test( variant<int, int, float>(3.14f) );
+
+ test( variant<int, int, float, float>() );
+
+ test( variant<int, int, float, float, std::string>("test") );
+
+ test( variant<std::string, std::string, float>() );
+
+ test( variant<X1 const>() );
+
+ test( variant<X1, X2>() );
+ test( variant<X1, X2, int>() );
+ test( variant<X1, X2, X2>() );
+ test( variant<X1, X1, X2, X2>() );
+
+ {
+ variant<X1, X2> v;
+ v.emplace<X2>();
+
+ test( v );
+ }
+
+ {
+ variant<X1, X1, X2> v;
+ v.emplace<X2>();
+
+ test( v );
+ }
+
+#if !BOOST_WORKAROUND( __GNUC__, < 5 )
+
+ test( variant<D>() );
+
+#endif
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<variant<X1, X2>>));
+
+#if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
+
+ BOOST_TEST_TRAIT_FALSE((std::is_copy_constructible<variant<int, float, Y>>));
+
+#endif
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp b/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp
new file mode 100644
index 000000000..cd3a7c2b0
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct_cx.cpp
@@ -0,0 +1,112 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class T, class V> constexpr T test( V const v )
+{
+ return get<T>( v );
+}
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+ constexpr auto w = test<int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<X> v( 1 );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<Y> v( 1 );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr variant<int, float> v( 1 );
+ constexpr auto w = test<int>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.0f );
+ constexpr auto w = test<float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.0f );
+ constexpr auto w = test<float>( v );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr variant<E, E, X> v( 1 );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( X(1) );
+ constexpr auto w = test<X>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr variant<E, E, Y> v( 1 );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, Y> v( Y(1) );
+ constexpr auto w = test<Y>( v );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp b/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp
new file mode 100644
index 000000000..81b44d9f4
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_copy_construct_throw.cpp
@@ -0,0 +1,69 @@
+
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X> v2( v1 );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_default_construct.cpp b/src/boost/libs/variant2/test/variant_default_construct.cpp
new file mode 100644
index 000000000..894934cb9
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_default_construct.cpp
@@ -0,0 +1,103 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X();
+};
+
+struct Y
+{
+ Y() = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string const> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string, int, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ variant<std::string, std::string, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), std::string() );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, float, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, int, X>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_default_constructible<variant<int, X, X>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_default_constructible<variant<X, int, float>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<variant<int, Y>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<variant<Y, int>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_default_construct_cx.cpp b/src/boost/libs/variant2/test/variant_default_construct_cx.cpp
new file mode 100644
index 000000000..d3325c6b1
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_default_construct_cx.cpp
@@ -0,0 +1,51 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int const> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, int, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_destroy.cpp b/src/boost/libs/variant2/test/variant_destroy.cpp
new file mode 100644
index 000000000..392a2d7dc
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_destroy.cpp
@@ -0,0 +1,205 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X1
+{
+ static int instances;
+
+ int v;
+
+ X1(): v(0) { ++instances; }
+ explicit X1(int v): v(v) { ++instances; }
+ X1(X1 const& r): v(r.v) { ++instances; }
+ X1(X1&& r): v(r.v) { ++instances; }
+
+ ~X1() noexcept { --instances; }
+
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+int X1::instances = 0;
+
+struct X2
+{
+ static int instances;
+
+ int v;
+
+ X2(): v(0) { ++instances; }
+ explicit X2(int v): v(v) { ++instances; }
+ X2(X2 const& r): v(r.v) { ++instances; }
+ X2(X2&& r): v(r.v) { ++instances; }
+
+ ~X2() noexcept { --instances; }
+
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+int X2::instances = 0;
+
+struct Y1
+{
+ static int instances;
+
+ int v;
+
+ Y1() noexcept: v(0) { ++instances; }
+ explicit Y1(int v) noexcept: v(v) { ++instances; }
+ Y1(Y1 const& r) noexcept: v(r.v) { ++instances; }
+ Y1(Y1&& r) noexcept: v(r.v) { ++instances; }
+
+ ~Y1() noexcept { --instances; }
+
+ Y1& operator=( Y1 const& r ) noexcept { v = r.v; return *this; }
+ Y1& operator=( Y1&& r ) noexcept { v = r.v; return *this; }
+};
+
+int Y1::instances = 0;
+
+struct Y2
+{
+ static int instances;
+
+ int v;
+
+ Y2() noexcept: v(0) { ++instances; }
+ explicit Y2(int v) noexcept: v(v) { ++instances; }
+ Y2(Y2 const& r) noexcept: v(r.v) { ++instances; }
+ Y2(Y2&& r) noexcept: v(r.v) { ++instances; }
+
+ ~Y2() noexcept { --instances; }
+
+ Y2& operator=( Y2 const& r ) noexcept { v = r.v; return *this; }
+ Y2& operator=( Y2&& r ) noexcept { v = r.v; return *this; }
+};
+
+int Y2::instances = 0;
+
+int main()
+{
+ BOOST_TEST_EQ( Y1::instances, 0 );
+
+ {
+ variant<Y1> v;
+ BOOST_TEST_EQ( Y1::instances, 1 );
+
+ {
+ variant<Y1> v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+
+ v = Y1{1};
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ {
+ variant<Y1, Y2> v;
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ {
+ variant<Y1, Y2> v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 2 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v2 = Y2{1};
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+
+ v.emplace<0>();
+
+ BOOST_TEST_EQ( Y1::instances, 1 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ v.emplace<Y2>();
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( Y1::instances, 0 );
+ BOOST_TEST_EQ( Y2::instances, 0 );
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ {
+ variant<X1, X2> v;
+
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ {
+ variant<X1, X2> v2;
+ BOOST_TEST_EQ( X1::instances, 2 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v = v2;
+ BOOST_TEST_EQ( X1::instances, 2 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v2 = X2{1};
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+
+ v = v2;
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 2 );
+ }
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+
+ v.emplace<0>();
+
+ BOOST_TEST_EQ( X1::instances, 1 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ v.emplace<X2>();
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X1::instances, 0 );
+ BOOST_TEST_EQ( X2::instances, 0 );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_index.cpp b/src/boost/libs/variant2/test/variant_emplace_index.cpp
new file mode 100644
index 000000000..7fa30b7f8
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_index.cpp
@@ -0,0 +1,181 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<1>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ v.emplace<1>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<1>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<1>( 1 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ v.emplace<2>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ v.emplace<2>();
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 0 );
+
+ v.emplace<3>( "s1" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ v.emplace<3>( "s2" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v.emplace<3>();
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string() );
+
+ v.emplace<3>( { 'a', 'b' } );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'a', 'b'}) );
+
+ v.emplace<3>( { 'c', 'd' }, std::allocator<char>() );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'c', 'd'}) );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<0>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v.emplace<1>( 2 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ v.emplace<0>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<0>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ v.emplace<1>();
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 0 );
+
+ v.emplace<1>( 6 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v.emplace<0>( 3 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v.emplace<0>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp b/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp
new file mode 100644
index 000000000..f66f99fc1
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_index_cx.cpp
@@ -0,0 +1,136 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr explicit X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr explicit Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, std::size_t I, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v.template emplace<I>( a );
+
+ return get<I>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, 1>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 1>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 2>( 2.0f );
+ STATIC_ASSERT( w == 2.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 3>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 4>( 4 );
+ STATIC_ASSERT( w == 4 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X, X>, 5>( 5 );
+ STATIC_ASSERT( w == 5 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 0>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 1>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 2>( 2.0f );
+ STATIC_ASSERT( w == 2.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 3>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 4>( 4 );
+ STATIC_ASSERT( w == 4 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y, Y>, 5>( 5 );
+ STATIC_ASSERT( w == 5 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_type.cpp b/src/boost/libs/variant2/test/variant_emplace_type.cpp
new file mode 100644
index 000000000..df8b364a1
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_type.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y1
+{
+};
+
+struct Y2
+{
+ ~Y2() {}
+};
+
+struct Guard
+{
+ explicit Guard(int) {}
+ Guard(Guard&&) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<int>( 1 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<int>();
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<int>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v.emplace<float>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ v.emplace<float>();
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ v.emplace<int>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v.emplace<float>( 3.14f );
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ v.emplace<float>();
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 0 );
+
+ v.emplace<std::string>( "s1" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ v.emplace<std::string>( "s2" );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v.emplace<std::string>();
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string() );
+
+ v.emplace<std::string>( { 'a', 'b' } );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'a', 'b' }) );
+
+ v.emplace<std::string>( { 'c', 'd' }, std::allocator<char>() );
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), (std::string{ 'c', 'd' }) );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<X1>( 1 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v.emplace<X2>( 2 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ v.emplace<X1>();
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v.emplace<X1>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ v.emplace<X2>();
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 0 );
+
+ v.emplace<X2>( 6 );
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v.emplace<X1>( 3 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v.emplace<X1>( 4 );
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ variant<Y1, Guard> v;
+ v.emplace<Guard>( 1 );
+ }
+
+ {
+ variant<Y2, Guard> v;
+ v.emplace<Guard>( 1 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp b/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp
new file mode 100644
index 000000000..2449b12ba
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_emplace_type_cx.cpp
@@ -0,0 +1,91 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr explicit X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr explicit Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v.template emplace<T>( a );
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_eq_ne.cpp b/src/boost/libs/variant2/test/variant_eq_ne.cpp
new file mode 100644
index 000000000..b2fc19dc0
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_eq_ne.cpp
@@ -0,0 +1,92 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+};
+
+inline bool operator==( X const&, X const& ) { return false; }
+inline bool operator!=( X const&, X const& ) { return false; }
+
+int main()
+{
+ {
+ variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+ }
+
+ {
+ variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+
+ BOOST_TEST( v1 != v5 );
+ BOOST_TEST_NOT( v1 == v5 );
+
+ BOOST_TEST( v3 != v5 );
+ BOOST_TEST_NOT( v3 == v5 );
+
+ BOOST_TEST( v5 == v6 );
+ BOOST_TEST_NOT( v5 != v6 );
+ }
+
+ {
+ variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ BOOST_TEST( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+
+ BOOST_TEST( v1 != v3 );
+ BOOST_TEST_NOT( v1 == v3 );
+
+ BOOST_TEST( v3 == v4 );
+ BOOST_TEST_NOT( v3 != v4 );
+
+ BOOST_TEST( v1 != v5 );
+ BOOST_TEST_NOT( v1 == v5 );
+
+ BOOST_TEST( v3 != v5 );
+ BOOST_TEST_NOT( v3 == v5 );
+
+ BOOST_TEST( v5 == v6 );
+ BOOST_TEST_NOT( v5 != v6 );
+ }
+
+ {
+ variant<X> v1, v2;
+
+ BOOST_TEST_NOT( v1 == v2 );
+ BOOST_TEST_NOT( v1 != v2 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp b/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp
new file mode 100644
index 000000000..9ebb751c5
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_eq_ne_cx.cpp
@@ -0,0 +1,98 @@
+
+// Copyright 2017, 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+using namespace boost::variant2;
+
+#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
+
+#include <boost/config/pragma_message.hpp>
+
+BOOST_PRAGMA_MESSAGE("Skipping constexpr op==, op!= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
+
+int main() {}
+
+#else
+
+struct X
+{
+};
+
+inline constexpr bool operator==( X const&, X const& ) { return false; }
+inline constexpr bool operator!=( X const&, X const& ) { return false; }
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+ }
+
+ {
+ constexpr variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+
+ STATIC_ASSERT( v1 != v5 );
+ STATIC_ASSERT( !(v1 == v5) );
+
+ STATIC_ASSERT( v3 != v5 );
+ STATIC_ASSERT( !(v3 == v5) );
+
+ STATIC_ASSERT( v5 == v6 );
+ STATIC_ASSERT( !(v5 != v6) );
+ }
+
+ {
+ constexpr variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ STATIC_ASSERT( v1 == v2 );
+ STATIC_ASSERT( !(v1 != v2) );
+
+ STATIC_ASSERT( v1 != v3 );
+ STATIC_ASSERT( !(v1 == v3) );
+
+ STATIC_ASSERT( v3 == v4 );
+ STATIC_ASSERT( !(v3 != v4) );
+
+ STATIC_ASSERT( v1 != v5 );
+ STATIC_ASSERT( !(v1 == v5) );
+
+ STATIC_ASSERT( v3 != v5 );
+ STATIC_ASSERT( !(v3 == v5) );
+
+ STATIC_ASSERT( v5 == v6 );
+ STATIC_ASSERT( !(v5 != v6) );
+ }
+
+ {
+ constexpr variant<X> v1, v2;
+
+ STATIC_ASSERT( !(v1 == v2) );
+ STATIC_ASSERT( !(v1 != v2) );
+ }
+}
+
+#endif
diff --git a/src/boost/libs/variant2/test/variant_get_by_index.cpp b/src/boost/libs/variant2/test/variant_get_by_index.cpp
new file mode 100644
index 000000000..2728196e0
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_index.cpp
@@ -0,0 +1,349 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int*>));
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+ }
+
+ {
+ variant<int volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const volatile*>));
+ }
+
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float*>));
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float const*>));
+ }
+
+ {
+ variant<int const, float volatile> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float volatile*>));
+ }
+
+ {
+ variant<int const, float volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<0>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<0>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(v)), float const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<1>(std::move(v))), float const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<1>(&v)), float const volatile*>));
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<1>(&v), &get<1>(v) );
+
+ BOOST_TEST_EQ( get<1>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<1>(&v), &get<1>(v) );
+
+ BOOST_TEST_EQ( get<1>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float, float> v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> const v;
+
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get_if<0>(&v), &get<0>(v) );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<2>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<2>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<0>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<2>(&v), &get<2>(v) );
+
+ BOOST_TEST_EQ( get<2>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<0>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<0>(&v), nullptr );
+
+ BOOST_TEST_THROWS( get<1>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<1>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<2>(&v), &get<2>(v) );
+
+ BOOST_TEST_EQ( get<2>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, float> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const, float volatile> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int const, float volatile> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float, float> * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<0>(p), nullptr );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp b/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp
new file mode 100644
index 000000000..026b9d3c8
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_index_cx.cpp
@@ -0,0 +1,96 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/config.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#if BOOST_WORKAROUND(BOOST_GCC, < 50000)
+# define STATIC_ASSERT_IF(...)
+#else
+# define STATIC_ASSERT_IF(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+#endif
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ }
+
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<1>(&v) == &get<1>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float, float> v( 1 );
+
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == &get<0>(v) );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<0>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<1>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<2>(&v) == &get<2>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_type.cpp b/src/boost/libs/variant2/test/variant_get_by_type.cpp
new file mode 100644
index 000000000..47daa94c2
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_type.cpp
@@ -0,0 +1,307 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int*>));
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int const*>));
+ }
+
+ {
+ variant<int const> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+ }
+
+ {
+ variant<int volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int volatile>(v)), int const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int volatile>(std::move(v))), int const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int volatile>(&v)), int const volatile*>));
+ }
+
+ {
+ variant<int> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(v)), float&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(std::move(v))), float&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float>(&v)), float*>));
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(v)), float const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float>(std::move(v))), float const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float>(&v)), float const*>));
+ }
+
+ {
+ variant<int const, float volatile> v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(v)), float volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(std::move(v))), float volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float volatile>(&v)), float volatile*>));
+ }
+
+ {
+ variant<int const, float volatile> const v;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(v)), int const&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<int const>(std::move(v))), int const&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<int const>(&v)), int const*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(v)), float const volatile&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get<float volatile>(std::move(v))), float const volatile&&>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(get_if<float volatile>(&v)), float const volatile*>));
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_THROWS( get<float>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<float>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+
+ BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<int>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float> const v( 3.14f );
+
+ BOOST_TEST_THROWS( get<int>(v), bad_variant_access );
+ BOOST_TEST_EQ( get_if<int>(&v), nullptr );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, float, float> v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> const v;
+
+ BOOST_TEST_EQ( get<int>(v), 0 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 0 );
+ }
+
+ {
+ variant<int, float, float> v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, float, float> const v( 1 );
+
+ BOOST_TEST_EQ( get<int>(v), 1 );
+ BOOST_TEST_EQ( get_if<int>(&v), &get<int>(v) );
+
+ BOOST_TEST_EQ( get<int>(std::move(v)), 1 );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int, int, float> const v( 3.14f );
+
+ BOOST_TEST_EQ( get<float>(v), 3.14f );
+ BOOST_TEST_EQ( get_if<float>(&v), &get<float>(v) );
+
+ BOOST_TEST_EQ( get<float>(std::move(v)), 3.14f );
+ }
+
+ {
+ variant<int> * p = 0;
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ }
+
+ {
+ variant<int const> * p = 0;
+ BOOST_TEST_EQ( get_if<int const>(p), nullptr );
+ }
+
+ {
+ variant<int> const * p = 0;
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ }
+
+ {
+ variant<int const> const * p = 0;
+ BOOST_TEST_EQ( get_if<int const>(p), nullptr );
+ }
+
+ {
+ variant<int, float> * p = 0;
+
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, float> const * p = 0;
+
+ BOOST_TEST_EQ( get_if<int>(p), nullptr );
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float> * p = 0;
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ {
+ variant<int, int, float> const * p = 0;
+ BOOST_TEST_EQ( get_if<float>(p), nullptr );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp b/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp
new file mode 100644
index 000000000..0f9a40c51
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_get_by_type_cx.cpp
@@ -0,0 +1,90 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/config.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#if BOOST_WORKAROUND(BOOST_GCC, < 50000)
+# define STATIC_ASSERT_IF(...)
+#else
+# define STATIC_ASSERT_IF(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+#endif
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ STATIC_ASSERT_IF( get_if<float>(&v) == nullptr );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<float>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == nullptr );
+ STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+
+ STATIC_ASSERT( get<int>(v) == 0 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float, float> v( 1 );
+
+ STATIC_ASSERT( get<int>(v) == 1 );
+
+ STATIC_ASSERT_IF( get_if<int>(&v) == &get<int>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+
+ STATIC_ASSERT( get<float>(v) == 3.14f );
+
+ STATIC_ASSERT_IF( get_if<float>(&v) == &get<float>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_hash.cpp b/src/boost/libs/variant2/test/variant_hash.cpp
new file mode 100644
index 000000000..ecff65635
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_hash.cpp
@@ -0,0 +1,73 @@
+
+// Copyright 2020 Peter Dimov.
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4244 ) // conversion from int to float, possible loss of data
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/container_hash/hash.hpp>
+#include <boost/config/workaround.hpp>
+
+using namespace boost::variant2;
+
+template<template<class...> class Hash, class T1, class T2, class T3> void test()
+{
+ variant<T1, T2, T3> v1( in_place_index_t<0>{} );
+ std::size_t h1 = Hash<decltype(v1)>()( v1 );
+
+ variant<T1, T2, T3> v2( in_place_index_t<1>{} );
+ std::size_t h2 = Hash<decltype(v2)>()( v2 );
+
+ variant<T1, T2, T3> v3( in_place_index_t<2>{} );
+ std::size_t h3 = Hash<decltype(v3)>()( v3 );
+
+ BOOST_TEST_NE( h1, h2 );
+ BOOST_TEST_NE( h1, h3 );
+ BOOST_TEST_NE( h2, h3 );
+}
+
+template<template<class...> class Hash, class T> void test2()
+{
+ variant<T> v1( 0 );
+ std::size_t h1 = Hash<decltype(v1)>()( v1 );
+
+ variant<T> v2( 1 );
+ std::size_t h2 = Hash<decltype(v2)>()( v2 );
+
+ variant<T> v3( 2 );
+ std::size_t h3 = Hash<decltype(v3)>()( v3 );
+
+ BOOST_TEST_NE( h1, h2 );
+ BOOST_TEST_NE( h1, h3 );
+ BOOST_TEST_NE( h2, h3 );
+}
+
+struct X {};
+
+int main()
+{
+ test<std::hash, monostate, monostate, monostate>();
+ test<std::hash, int, int, float>();
+
+ test<boost::hash, monostate, monostate, monostate>();
+ test<boost::hash, int, int, float>();
+
+ test2<std::hash, int>();
+ test2<std::hash, float>();
+
+ test2<boost::hash, int>();
+ test2<boost::hash, float>();
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) && ( !defined(_LIBCPP_STD_VER) || _LIBCPP_STD_VER > 11 )
+
+ BOOST_TEST_TRAIT_FALSE(( detail::is_hash_enabled<X> ));
+
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_holds_alternative.cpp b/src/boost/libs/variant2/test/variant_holds_alternative.cpp
new file mode 100644
index 000000000..4931f40fe
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_holds_alternative.cpp
@@ -0,0 +1,78 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <string>
+
+using namespace boost::variant2;
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float> v( 3.14f );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float, float> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ }
+
+ {
+ variant<int, int, float> v( 3.14f );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v;
+ BOOST_TEST( holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v( 3.14f );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, float, std::string> v( "text" );
+ BOOST_TEST( !holds_alternative<int>( v ) );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( 3.14f );
+ BOOST_TEST( holds_alternative<float>( v ) );
+ BOOST_TEST( !holds_alternative<std::string>( v ) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( "text" );
+ BOOST_TEST( !holds_alternative<float>( v ) );
+ BOOST_TEST( holds_alternative<std::string>( v ) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp b/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp
new file mode 100644
index 000000000..c2bdc0a61
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_holds_alternative_cx.cpp
@@ -0,0 +1,43 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ }
+
+ {
+ constexpr variant<int, float> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ STATIC_ASSERT( !holds_alternative<float>( v ) );
+ }
+
+ {
+ constexpr variant<int, float> v( 3.14f );
+ STATIC_ASSERT( !holds_alternative<int>( v ) );
+ STATIC_ASSERT( holds_alternative<float>( v ) );
+ }
+
+ {
+ constexpr variant<int, float, float> v;
+ STATIC_ASSERT( holds_alternative<int>( v ) );
+ }
+
+ {
+ constexpr variant<int, int, float> v( 3.14f );
+ STATIC_ASSERT( holds_alternative<float>( v ) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp b/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp
new file mode 100644
index 000000000..75821d328
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_index_construct.cpp
@@ -0,0 +1,138 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X() = default;
+ X( in_place_index_t<0> ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<X> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+
+ {
+ variant<int> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<0>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<1>{} );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+ }
+
+ {
+ variant<int, float> v( in_place_index_t<1>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<0>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<1>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<2>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<3>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<4>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, 4, 'a' );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), std::string( 4, 'a' ) );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<4>{}, { 'a', 'b', 'c' } );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+ }
+
+ {
+ variant<int, int, float, float, std::string, std::string> v( in_place_index_t<5>{}, { 'a', 'b', 'c' }, std::allocator<char>() );
+
+ BOOST_TEST_EQ( v.index(), 5 );
+ BOOST_TEST_EQ( get<5>(v), (std::string{ 'a', 'b', 'c' }) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp b/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp
new file mode 100644
index 000000000..80a6934ec
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_index_construct_cx.cpp
@@ -0,0 +1,116 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr X() = default;
+ constexpr explicit X(int, int) {}
+ X( in_place_index_t<0> ) = delete;
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<X> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ }
+
+ {
+ constexpr variant<int> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<0>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<1>{} );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 0 );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_index_t<1>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<0>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<1>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<2>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<3>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 3 );
+ STATIC_ASSERT( get<3>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<4>{} );
+
+ STATIC_ASSERT( v.index() == 4 );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X, X> v( in_place_index_t<5>{}, 0, 0 );
+
+ STATIC_ASSERT( v.index() == 5 );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp b/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp
new file mode 100644
index 000000000..3c8265acc
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_type_construct.cpp
@@ -0,0 +1,134 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ X() = default;
+ template<class T> X( in_place_type_t<T> ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v( in_place_type_t<int>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<X> v( in_place_type_t<X>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ BOOST_TEST( holds_alternative<X>(v) );
+ }
+
+ {
+ variant<int> v( in_place_type_t<int>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<int>{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<int>{}, 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST( holds_alternative<int>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<float>{} );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 0 );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, float> v( in_place_type_t<float>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, int, float, std::string> v( in_place_type_t<float>{}, 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ BOOST_TEST( holds_alternative<float>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, "text" );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string("text") );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, 4, 'a' );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), std::string( 4, 'a' ) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, { 'a', 'b', 'c' } );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ {
+ variant<int, int, float, float, std::string> v( in_place_type_t<std::string>{}, { 'a', 'b', 'c' }, std::allocator<char>() );
+
+ BOOST_TEST_EQ( v.index(), 4 );
+ BOOST_TEST_EQ( get<4>(v), (std::string{ 'a', 'b', 'c' }) );
+
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp b/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp
new file mode 100644
index 000000000..a64c34700
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_in_place_type_construct_cx.cpp
@@ -0,0 +1,110 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr X() = default;
+ constexpr explicit X(int, int) {}
+ template<class T> X( in_place_type_t<T> ) = delete;
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( in_place_type_t<int>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<X> v( in_place_type_t<X>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int> v( in_place_type_t<int>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<int>{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<int>{}, 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<float>{} );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 0 );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, float> v( in_place_type_t<float>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( in_place_type_t<float>{}, 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{} );
+
+ STATIC_ASSERT( v.index() == 4 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{}, 0, 0 );
+
+ STATIC_ASSERT( v.index() == 4 );
+
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_lt_gt.cpp b/src/boost/libs/variant2/test/variant_lt_gt.cpp
new file mode 100644
index 000000000..688209f8c
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_lt_gt.cpp
@@ -0,0 +1,85 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+};
+
+inline bool operator<( X const&, X const& ) { return false; }
+inline bool operator>( X const&, X const& ) { return false; }
+inline bool operator<=( X const&, X const& ) { return false; }
+inline bool operator>=( X const&, X const& ) { return false; }
+
+#define TEST_EQ( v1, v2 ) \
+ BOOST_TEST_NOT( v1 < v2 ); \
+ BOOST_TEST_NOT( v1 > v2 ); \
+ BOOST_TEST( v1 <= v2 ); \
+ BOOST_TEST( v1 >= v2 );
+
+#define TEST_LE( v1, v3 ) \
+ BOOST_TEST( v1 < v3 ); \
+ BOOST_TEST( v3 > v1 ); \
+ BOOST_TEST_NOT( v1 > v3 ); \
+ BOOST_TEST_NOT( v3 < v1 ); \
+ BOOST_TEST( v1 <= v3 ); \
+ BOOST_TEST( v3 >= v1 ); \
+ BOOST_TEST_NOT( v1 >= v3 ); \
+ BOOST_TEST_NOT( v3 <= v1 );
+
+int main()
+{
+ {
+ variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ }
+
+ {
+ variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ variant<X> v1, v2;
+
+ BOOST_TEST_NOT( v1 < v2 );
+ BOOST_TEST_NOT( v1 > v2 );
+ BOOST_TEST_NOT( v1 <= v2 );
+ BOOST_TEST_NOT( v1 >= v2 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp b/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp
new file mode 100644
index 000000000..b5708464f
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_lt_gt_cx.cpp
@@ -0,0 +1,91 @@
+
+// Copyright 2017, 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+using namespace boost::variant2;
+
+#if !defined(BOOST_MP11_HAS_CXX14_CONSTEXPR)
+
+#include <boost/config/pragma_message.hpp>
+
+BOOST_PRAGMA_MESSAGE("Skipping constexpr op<, op<= test because BOOST_MP11_HAS_CXX14_CONSTEXPR is not defined")
+
+int main() {}
+
+#else
+
+struct X
+{
+};
+
+inline constexpr bool operator<( X const&, X const& ) { return false; }
+inline constexpr bool operator>( X const&, X const& ) { return false; }
+inline constexpr bool operator<=( X const&, X const& ) { return false; }
+inline constexpr bool operator>=( X const&, X const& ) { return false; }
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+#define TEST_EQ( v1, v2 ) \
+ STATIC_ASSERT( !(v1 < v2) ); \
+ STATIC_ASSERT( !(v1 > v2) ); \
+ STATIC_ASSERT( v1 <= v2 ); \
+ STATIC_ASSERT( v1 >= v2 );
+
+#define TEST_LE( v1, v3 ) \
+ STATIC_ASSERT( v1 < v3 ); \
+ STATIC_ASSERT( v3 > v1 ); \
+ STATIC_ASSERT( !(v1 > v3) ); \
+ STATIC_ASSERT( !(v3 < v1) ); \
+ STATIC_ASSERT( v1 <= v3 ); \
+ STATIC_ASSERT( v3 >= v1 ); \
+ STATIC_ASSERT( !(v1 >= v3) ); \
+ STATIC_ASSERT( !(v3 <= v1) );
+
+int main()
+{
+ {
+ constexpr variant<int> v1, v2, v3( 1 ), v4( 1 );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ }
+
+ {
+ constexpr variant<int, float> v1, v2, v3( 1 ), v4( 1 ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ constexpr variant<int, int, float> v1, v2, v3( in_place_index_t<1>{} ), v4( in_place_index_t<1>{} ), v5( 3.14f ), v6( 3.14f );
+
+ TEST_EQ( v1, v2 )
+ TEST_LE( v1, v3 )
+ TEST_EQ( v3, v4 )
+ TEST_LE( v1, v5 )
+ TEST_LE( v3, v5 )
+ TEST_EQ( v5, v6 )
+ }
+
+ {
+ constexpr variant<X> v1, v2;
+
+ STATIC_ASSERT( !(v1 < v2) );
+ STATIC_ASSERT( !(v1 > v2) );
+ STATIC_ASSERT( !(v1 <= v2) );
+ STATIC_ASSERT( !(v1 >= v2) );
+ }
+}
+
+#endif
diff --git a/src/boost/libs/variant2/test/variant_move_assign.cpp b/src/boost/libs/variant2/test/variant_move_assign.cpp
new file mode 100644
index 000000000..632f06812
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign.cpp
@@ -0,0 +1,194 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+struct Y
+{
+ Y& operator=( Y&& ) = delete;
+};
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int> v3( 2 );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ variant<int, float> v3( 3.14f );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ variant<int, float> v4( 3.15f );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ variant<int, int, float, std::string> v4( 3.15f );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = std::move(v5);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ variant<int, int, float, std::string> v6( "s2" );
+
+ v = std::move(v6);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ v = std::move(v2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ v = std::move(v3);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ variant<X1, X2> v4( in_place_index_t<1>{}, 3 );
+
+ v = std::move(v4);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ variant<X1, X2> v5( in_place_index_t<0>{}, 4 );
+
+ v = std::move(v5);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_assignable<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_assignable<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_move_assignable<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_move_assignable<variant<int const>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_move_assignable<variant<int, float, Y>>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_assign_cx.cpp b/src/boost/libs/variant2/test/variant_move_assign_cx.cpp
new file mode 100644
index 000000000..d7ab65fa7
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign_cx.cpp
@@ -0,0 +1,107 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <utility>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr T test( A&& a )
+{
+ V v;
+
+ v = std::forward<A>(a);
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( variant<int>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( variant<X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( variant<Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( variant<int, float>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( variant<int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( variant<int, int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<E, E, X>, X>( variant<E, E, X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( variant<int, int, float, float, X>( X(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<E, E, Y>, Y>( variant<E, E, Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( variant<int, int, float, float, Y>( Y(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_move_assign_throw.cpp b/src/boost/libs/variant2/test/variant_move_assign_throw.cpp
new file mode 100644
index 000000000..c1df59442
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_assign_throw.cpp
@@ -0,0 +1,55 @@
+
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct Y1
+{
+ Y1() noexcept {} // =default fails on msvc-14.0
+
+ Y1(Y1&&)
+ {
+ throw std::runtime_error( "Y1(Y1&&)" );
+ }
+
+ Y1& operator=(Y1&&) = default;
+};
+
+struct Y2
+{
+ Y2() noexcept {}
+
+ Y2(Y2&&)
+ {
+ throw std::runtime_error( "Y2(Y2&&)" );
+ }
+
+ Y2& operator=(Y2&&) = default;
+};
+
+void test()
+{
+ variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
+ variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
+
+ BOOST_TEST_THROWS( v1 = std::move( v2 ), std::runtime_error )
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct.cpp b/src/boost/libs/variant2/test/variant_move_construct.cpp
new file mode 100644
index 000000000..dd83c8c18
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct.cpp
@@ -0,0 +1,146 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ X1() {}
+ X1(X1 const&) {}
+ X1(X1&&) {}
+};
+
+inline bool operator==( X1, X1 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+
+struct X2
+{
+ X2() {}
+ X2(X2 const&) {}
+ X2(X2&&) {}
+};
+
+inline bool operator==( X2, X2 ) { return true; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+
+struct Y
+{
+ Y( Y&& ) = delete;
+};
+
+template<class V> static void test( V&& v )
+{
+ V v2( v );
+ V v3( std::move(v) );
+
+ BOOST_TEST_EQ( v2.index(), v3.index() );
+ BOOST_TEST( v2 == v3 );
+}
+
+int main()
+{
+ test( variant<int>() );
+ test( variant<int>(1) );
+
+ test( variant<int const>() );
+ test( variant<int const>(1) );
+
+ test( variant<int, float>() );
+ test( variant<int, float>(1) );
+ test( variant<int, float>(3.14f) );
+
+ test( variant<int const, float const>() );
+ test( variant<int const, float const>(1) );
+ test( variant<int const, float const>(3.14f) );
+
+ test( variant<std::string>() );
+ test( variant<std::string>("test") );
+
+ test( variant<std::string const>() );
+ test( variant<std::string const>("test") );
+
+ test( variant<int, float, std::string>() );
+ test( variant<int, float, std::string>(1) );
+ test( variant<int, float, std::string>(3.14f) );
+ test( variant<int, float, std::string>("test") );
+
+ test( variant<int, int>() );
+
+ test( variant<int, int, float>() );
+ test( variant<int, int, float>(3.14f) );
+
+ test( variant<int, int, float, float>() );
+
+ test( variant<int, int, float, float, std::string>("test") );
+
+ test( variant<std::string, std::string, float>() );
+
+ test( variant<X1 const>() );
+
+ test( variant<X1, X2>() );
+ test( variant<X1, X2, int>() );
+ test( variant<X1, X2, X2>() );
+ test( variant<X1, X1, X2, X2>() );
+
+ {
+ variant<X1, X2> v;
+ v.emplace<X2>();
+
+ test( std::move(v) );
+ }
+
+ {
+ variant<X1, X1, X2> v;
+ v.emplace<X2>();
+
+ test( std::move(v) );
+ }
+
+ {
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int const>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, float>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_nothrow_move_constructible<variant<int, int, float, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, int, float>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, X1>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<int, int, X1>>));
+
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2>>));
+ BOOST_TEST_TRAIT_FALSE((std::is_nothrow_move_constructible<variant<X1, X2, int, int>>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_move_constructible<variant<X1, X2>>));
+
+#if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
+
+ BOOST_TEST_TRAIT_FALSE((std::is_move_constructible<variant<int, float, Y>>));
+
+#endif
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct_cx.cpp b/src/boost/libs/variant2/test/variant_move_construct_cx.cpp
new file mode 100644
index 000000000..1e49b7f88
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct_cx.cpp
@@ -0,0 +1,104 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <utility>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class T, class V> constexpr T test( V&& v )
+{
+ V v2( std::forward<V>(v) );
+ return get<T>( v2 );
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<int>( variant<int>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<Y>( variant<Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<int>( variant<int, float>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<float>( variant<int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<float>( variant<int, int, float>( 3.0f ) );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<E, E, X>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<X>( variant<int, int, float, float, X>( X(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<Y>( variant<E, E, Y>( 1 ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<Y>( variant<int, int, float, float, Y>( Y(1) ) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_move_construct_throw.cpp b/src/boost/libs/variant2/test/variant_move_construct_throw.cpp
new file mode 100644
index 000000000..aabf7d268
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_move_construct_throw.cpp
@@ -0,0 +1,69 @@
+
+// Copyright 2019 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <stdexcept>
+
+using namespace boost::variant2;
+
+struct X
+{
+ static int instances;
+
+ X()
+ {
+ ++instances;
+ }
+
+ X( X const& )
+ {
+ throw std::runtime_error( "X(X const&)" );
+ }
+
+ ~X()
+ {
+ --instances;
+ }
+};
+
+int X::instances = 0;
+
+void test()
+{
+ X::instances = 0;
+
+ {
+ variant<X> v1;
+
+ BOOST_TEST_EQ( X::instances, 1 );
+
+ try
+ {
+ variant<X> v2( std::move( v1 ) );
+ BOOST_TEST_EQ( X::instances, 2 );
+ }
+ catch( std::exception const& )
+ {
+ }
+
+ BOOST_TEST_EQ( X::instances, 1 );
+ }
+
+ BOOST_TEST_EQ( X::instances, 0 );
+}
+
+int main()
+{
+ test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_size.cpp b/src/boost/libs/variant2/test/variant_size.cpp
new file mode 100644
index 000000000..81e63ac18
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_size.cpp
@@ -0,0 +1,104 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <cstddef>
+
+using namespace boost::variant2;
+using namespace boost::mp11;
+
+template<class T> using var_size_t = mp_size_t<variant_size<T>::value>;
+
+int main()
+{
+ BOOST_TEST_EQ( (variant_size<variant<>>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> volatile>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const volatile>::value), 0 );
+
+ BOOST_TEST_EQ( (variant_size<variant<>&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<>&&>::value), 0 );
+ BOOST_TEST_EQ( (variant_size<variant<> const&&>::value), 0 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void>>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> volatile>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const volatile>::value), 1 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void>&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void>&&>::value), 1 );
+ BOOST_TEST_EQ( (variant_size<variant<void> const&&>::value), 1 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void>>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> volatile>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const volatile>::value), 2 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void>&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void>&&>::value), 2 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void> const&&>::value), 2 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> volatile>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const volatile>::value), 3 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void>&&>::value), 3 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void> const&&>::value), 3 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> volatile>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const volatile>::value), 4 );
+
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void>&&>::value), 4 );
+ BOOST_TEST_EQ( (variant_size<variant<void, void, void, void> const&&>::value), 4 );
+
+ variant_size<void>();
+ variant_size<void const>();
+ variant_size<void volatile>();
+ variant_size<void const volatile>();
+
+ variant_size<int&>();
+ variant_size<int const&>();
+ variant_size<int&&>();
+ variant_size<int const&&>();
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void const>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void volatile>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, void const volatile>));
+
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int const&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int&&>));
+ BOOST_TEST_TRAIT_FALSE((mp_valid<var_size_t, int const&&>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> volatile>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const volatile>));
+
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<>&&>));
+ BOOST_TEST_TRAIT_TRUE((mp_valid<var_size_t, variant<> const&&>));
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_special.cpp b/src/boost/libs/variant2/test/variant_special.cpp
new file mode 100644
index 000000000..956d927b3
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_special.cpp
@@ -0,0 +1,103 @@
+// Copyright 2020 Peter Dimov.
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER) && _MSC_VER < 1910
+# pragma warning(disable: 4503) // decorated name length exceeded
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/config.hpp>
+#include <boost/config/workaround.hpp>
+
+#include <boost/mp11.hpp>
+using namespace boost::mp11;
+
+//
+
+using namespace boost::variant2;
+
+struct D
+{
+ ~D() noexcept {}
+};
+
+struct CC1
+{
+ CC1( CC1 const& ) {}
+};
+
+struct CC2
+{
+ CC2( CC2 const& ) = delete;
+};
+
+struct MC1
+{
+ MC1( MC1 && ) {}
+};
+
+struct MC2
+{
+ MC2( MC2 && ) = delete;
+};
+
+struct CA1
+{
+ CA1& operator=( CA1 const& ) { return *this; }
+};
+
+struct CA2
+{
+ CA2& operator=( CA2 const& ) = delete;
+};
+
+struct MA1
+{
+ MA1& operator=( MA1 && ) { return *this; }
+};
+
+struct MA2
+{
+ MA2& operator=( MA2 && ) = delete;
+};
+
+struct test
+{
+ template<class... T> void operator()( mp_list<T...> ) const noexcept
+ {
+ using U = mp_inherit<T...>;
+
+#if !BOOST_WORKAROUND( __GNUC__, < 5 )
+
+ BOOST_TEST_EQ( std::is_copy_constructible<variant<U>>::value, std::is_copy_constructible<U>::value );
+ BOOST_TEST_EQ( std::is_nothrow_copy_constructible<variant<U>>::value, std::is_nothrow_copy_constructible<U>::value );
+
+#endif
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
+
+ BOOST_TEST_EQ( std::is_move_constructible<variant<U>>::value, std::is_move_constructible<U>::value );
+
+#else
+
+ BOOST_TEST_GE( std::is_move_constructible<variant<U>>::value, std::is_move_constructible<U>::value );
+
+#endif
+
+ BOOST_TEST_EQ( std::is_nothrow_move_constructible<variant<U>>::value, std::is_nothrow_move_constructible<U>::value );
+
+ BOOST_TEST_EQ( std::is_copy_assignable<variant<U>>::value, std::is_copy_constructible<U>::value && std::is_copy_assignable<U>::value );
+ BOOST_TEST_EQ( std::is_nothrow_copy_assignable<variant<U>>::value, std::is_nothrow_copy_constructible<U>::value && std::is_copy_assignable<U>::value );
+
+ BOOST_TEST_EQ( std::is_move_assignable<variant<U>>::value, std::is_move_constructible<U>::value && std::is_move_assignable<U>::value );
+ BOOST_TEST_EQ( std::is_nothrow_move_assignable<variant<U>>::value, std::is_nothrow_move_constructible<U>::value && std::is_move_assignable<U>::value );
+ }
+};
+
+int main()
+{
+ mp_for_each< mp_power_set< mp_list<D, CC1, CC2, MC1, MC2, CA1, CA2, MA1, MA2> > >( test() );
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_subset.cpp b/src/boost/libs/variant2/test/variant_subset.cpp
new file mode 100644
index 000000000..90c9bc211
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_subset.cpp
@@ -0,0 +1,159 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int, float> v1( 1 );
+
+ variant<int> v2 = v1.subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
+
+ variant<int> v3 = std::move(v1).subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+
+ BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
+ }
+
+ {
+ variant<int, float> const v1( 1 );
+
+ variant<int> v2 = v1.subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
+
+ variant<int> v3 = std::move(v1).subset<int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+
+ BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+
+ variant<int, float> v2 = v1.subset<int, float>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ variant<int, float> v3 = std::move(v1).subset<int, float>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+
+ variant<float, int> v2 = v1.subset<float, int>();
+
+ BOOST_TEST( holds_alternative<int>( v2 ) );
+ BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
+
+ variant<float, int> v3 = std::move(v1).subset<float, int>();
+
+ BOOST_TEST( holds_alternative<int>( v3 ) );
+ BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
+ }
+
+ {
+ variant<int, float, std::string> v1( "s1" );
+
+ variant<int, std::string> v2 = v1.subset<int, std::string>();
+
+ BOOST_TEST( holds_alternative<std::string>( v2 ) );
+ BOOST_TEST_EQ( get<std::string>( v1 ), get<std::string>( v2 ) );
+
+ variant<float, std::string> v3 = std::move(v1).subset<float, std::string>();
+
+ BOOST_TEST( holds_alternative<std::string>( v3 ) );
+ BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
+ }
+
+ {
+ variant<int, int, float, float, X1, X2> v1{ X1{1} };
+
+ variant<X1, X2> v2 = v1.subset<X1, X2>();
+
+ BOOST_TEST( holds_alternative<X1>( v2 ) );
+ BOOST_TEST_EQ( get<X1>( v1 ).v, get<X1>( v2 ).v );
+
+ variant<X1, X2> v3 = std::move( v1 ).subset<X1, X2>();
+
+ BOOST_TEST( holds_alternative<X1>( v3 ) );
+ BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_swap.cpp b/src/boost/libs/variant2/test/variant_swap.cpp
new file mode 100644
index 000000000..3e80f0f2a
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_swap.cpp
@@ -0,0 +1,259 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int> v2( 1 );
+ BOOST_TEST_EQ( get<0>(v2), 1 );
+
+ swap( v, v2 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int> v3( 2 );
+ BOOST_TEST_EQ( get<0>(v3), 2 );
+
+ swap( v, v3 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ BOOST_TEST_EQ( get<0>(v3), 1 );
+ }
+
+ {
+ variant<int, float> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, float> v2( 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int, float> v3( 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3), 3.14f );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v3), 1 );
+
+ variant<int, float> v4( 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4), 3.15f );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4), 3.14f );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ variant<int, int, float, std::string> v2( in_place_index_t<1>{}, 1 );
+
+ BOOST_TEST_EQ( v2.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v2), 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2), 0 );
+
+ variant<int, int, float, std::string> v3( 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v3), 3.14f );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3), 1 );
+
+ variant<int, int, float, std::string> v4( 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v4), 3.15f );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ BOOST_TEST_EQ( v4.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v4), 3.14f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ BOOST_TEST_EQ( v5.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v5), std::string("s1") );
+
+ swap( v, v5 );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ BOOST_TEST_EQ( v5.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v5), 3.15f );
+
+ variant<int, int, float, std::string> v6( "s2" );
+
+ BOOST_TEST_EQ( v6.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v6), std::string("s2") );
+
+ swap( v, v6 );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ BOOST_TEST_EQ( v6.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v6), std::string("s1") );
+ }
+
+ {
+ variant<X1, X2> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ variant<X1, X2> v2( X1{1} );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2).v, 1 );
+
+ swap( v, v2 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ BOOST_TEST_EQ( v2.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v2).v, 0 );
+
+ variant<X1, X2> v3( in_place_index_t<1>{}, 2 );
+
+ BOOST_TEST_EQ( v3.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v3).v, 2 );
+
+ swap( v, v3 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ BOOST_TEST_EQ( v3.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v3).v, 1 );
+
+ variant<X1, X2> v4( in_place_index_t<1>{}, 3 );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4).v, 3 );
+
+ swap( v, v4 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 3 );
+
+ BOOST_TEST_EQ( v4.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v4).v, 2 );
+
+ variant<X1, X2> v5( in_place_index_t<0>{}, 4 );
+
+ BOOST_TEST_EQ( v5.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v5).v, 4 );
+
+ swap( v, v5 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ BOOST_TEST_EQ( v5.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v5).v, 3 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_trivial.cpp b/src/boost/libs/variant2/test/variant_trivial.cpp
new file mode 100644
index 000000000..c8137842a
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_trivial.cpp
@@ -0,0 +1,95 @@
+// Copyright 2020 Peter Dimov.
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER) && _MSC_VER < 1910
+# pragma warning(disable: 4503) // decorated name length exceeded
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/config.hpp>
+#include <boost/config/workaround.hpp>
+
+#include <boost/mp11.hpp>
+using namespace boost::mp11;
+
+//
+
+struct D
+{
+ ~D() noexcept {}
+};
+
+struct CC1
+{
+ CC1( CC1 const& ) noexcept {}
+};
+
+struct CC2
+{
+ CC2( CC2 const& ) = delete;
+};
+
+struct MC1
+{
+ MC1( MC1 && ) noexcept {}
+};
+
+struct MC2
+{
+ MC2( MC2 && ) = delete;
+};
+
+struct CA1
+{
+ CA1& operator=( CA1 const& ) noexcept { return *this; }
+};
+
+struct CA2
+{
+ CA2& operator=( CA2 const& ) = delete;
+};
+
+struct MA1
+{
+ MA1& operator=( MA1 && ) noexcept { return *this; }
+};
+
+struct MA2
+{
+ MA2& operator=( MA2 && ) = delete;
+};
+
+using namespace boost::variant2;
+namespace v2d = boost::variant2::detail;
+
+struct test
+{
+ template<class... T> void operator()( mp_list<T...> ) const noexcept
+ {
+ using U = mp_inherit<T...>;
+
+#if !BOOST_WORKAROUND( __GNUC__, < 5 )
+
+ BOOST_TEST_EQ( v2d::is_trivially_copy_constructible<variant<U>>::value, v2d::is_trivially_copy_constructible<U>::value );
+ BOOST_TEST_EQ( v2d::is_trivially_copy_assignable<variant<U>>::value, std::is_trivially_destructible<U>::value && v2d::is_trivially_copy_constructible<U>::value && v2d::is_trivially_copy_assignable<U>::value );
+
+#endif
+
+ BOOST_TEST_EQ( std::is_trivially_destructible<variant<U>>::value, std::is_trivially_destructible<U>::value );
+
+#if !BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000)
+
+ BOOST_TEST_EQ( v2d::is_trivially_move_constructible<variant<U>>::value, v2d::is_trivially_move_constructible<U>::value );
+ BOOST_TEST_EQ( v2d::is_trivially_move_assignable<variant<U>>::value, std::is_trivially_destructible<U>::value && v2d::is_trivially_move_constructible<U>::value && v2d::is_trivially_move_assignable<U>::value );
+
+#endif
+ }
+};
+
+int main()
+{
+ mp_for_each< mp_power_set< mp_list<D, CC1, CC2, MC1, MC2, CA1, CA2, MA1, MA2> > >( test() );
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_assign.cpp b/src/boost/libs/variant2/test/variant_value_assign.cpp
new file mode 100644
index 000000000..2519adc08
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_assign.cpp
@@ -0,0 +1,206 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+struct X1
+{
+ int v;
+
+ X1(): v(0) {}
+ explicit X1(int v): v(v) {}
+ X1(X1 const& r): v(r.v) {}
+ X1(X1&& r): v(r.v) {}
+ X1& operator=( X1 const& r ) { v = r.v; return *this; }
+ X1& operator=( X1&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
+
+struct X2
+{
+ int v;
+
+ X2(): v(0) {}
+ explicit X2(int v): v(v) {}
+ X2(X2 const& r): v(r.v) {}
+ X2(X2&& r): v(r.v) {}
+ X2& operator=( X2 const& r ) { v = r.v; return *this; }
+ X2& operator=( X2&& r ) { v = r.v; return *this; }
+};
+
+inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
+STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
+
+int main()
+{
+ {
+ variant<int> v;
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 1;
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v = 2;
+ BOOST_TEST_EQ( get<0>(v), 2 );
+
+ int w1 = 3;
+
+ v = w1;
+ BOOST_TEST_EQ( get<0>(v), 3 );
+
+ int const w2 = 4;
+
+ v = w2;
+ BOOST_TEST_EQ( get<0>(v), 4 );
+
+ v = std::move( w1 );
+ BOOST_TEST_EQ( get<0>(v), 3 );
+
+ v = std::move( w2 );
+ BOOST_TEST_EQ( get<0>(v), 4 );
+ }
+
+ {
+ variant<int, float> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 1;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+
+ v = 3.14f;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+
+ float w1 = 3.15f;
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ int const w2 = 2;
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v), 3.15f );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, int, float, std::string> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 0 );
+
+ v = 3.14f;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+
+ float const w1 = 3.15f;
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ variant<int, int, float, std::string> v5( "s1" );
+
+ v = "s1";
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s1") );
+
+ std::string w2( "s2" );
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST_EQ( get<2>(v), 3.15f );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST_EQ( get<3>(v), std::string("s2") );
+ }
+
+ {
+ variant<X1, X2> v;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 0 );
+
+ v = X1{1};
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 1 );
+
+ v = X2{2};
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 2 );
+
+ X1 w1{3};
+
+ v = w1;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ X1 const w2{4};
+
+ v = w2;
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+
+ X2 w3{5};
+
+ v = w3;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 5 );
+
+ X2 const w4{6};
+
+ v = w4;
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST_EQ( get<1>(v).v, 6 );
+
+ v = std::move(w1);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 3 );
+
+ v = std::move(w2);
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v).v, 4 );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_assign_cx.cpp b/src/boost/libs/variant2/test/variant_value_assign_cx.cpp
new file mode 100644
index 000000000..0a29a0afd
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_assign_cx.cpp
@@ -0,0 +1,106 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ int v;
+ X() = default;
+ constexpr X( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+struct Y
+{
+ int v;
+ constexpr Y(): v() {}
+ constexpr Y( int v ): v( v ) {}
+ constexpr operator int() const { return v; }
+};
+
+enum E
+{
+ v
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+template<class V, class T, class A> constexpr A test( A const& a )
+{
+ V v;
+
+ v = a;
+
+ return get<T>(v);
+}
+
+int main()
+{
+ {
+ constexpr auto w = test<variant<int>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+
+ {
+ constexpr auto w = test<variant<int, float>, int>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float>, float>( 3.0f );
+ STATIC_ASSERT( w == 3.0f );
+ }
+
+ {
+ constexpr auto w = test<variant<E, E, X>, X>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, X>, X>( X(1) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+#else
+
+ {
+ constexpr auto w = test<variant<E, E, Y>, Y>( 1 );
+ STATIC_ASSERT( w == 1 );
+ }
+
+ {
+ constexpr auto w = test<variant<int, int, float, float, Y>, Y>( Y(1) );
+ STATIC_ASSERT( w == 1 );
+ }
+
+#endif
+}
diff --git a/src/boost/libs/variant2/test/variant_value_construct.cpp b/src/boost/libs/variant2/test/variant_value_construct.cpp
new file mode 100644
index 000000000..56df89679
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_construct.cpp
@@ -0,0 +1,124 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+
+using namespace boost::variant2;
+
+struct X
+{
+ operator int() const { return 2; }
+};
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int const> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int const> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int const> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float, std::string> v( 1 );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 1 );
+ }
+
+ {
+ variant<int, float, std::string> v( 'a' );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 'a' );
+ }
+
+ {
+ variant<int, float, std::string> v( X{} );
+
+ BOOST_TEST_EQ( v.index(), 0 );
+ BOOST_TEST( holds_alternative<int>(v) );
+ BOOST_TEST_EQ( get<0>(v), 2 );
+ }
+
+ {
+ variant<int, float, std::string> v( 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+ BOOST_TEST( holds_alternative<float>(v) );
+ BOOST_TEST_EQ( get<1>(v), 3.14f );
+ }
+
+ {
+ variant<int, float, std::string> v( "text" );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ BOOST_TEST_EQ( get<2>(v), std::string("text") );
+ }
+
+ {
+ variant<int, int, float, std::string> v( 3.14f );
+
+ BOOST_TEST_EQ( v.index(), 2 );
+ BOOST_TEST( holds_alternative<float>(v) );
+ BOOST_TEST_EQ( get<2>(v), 3.14f );
+ }
+
+ {
+ variant<int, int, float, std::string> v( "text" );
+
+ BOOST_TEST_EQ( v.index(), 3 );
+ BOOST_TEST( holds_alternative<std::string>(v) );
+ BOOST_TEST_EQ( get<3>(v), std::string("text") );
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_value_construct_cx.cpp b/src/boost/libs/variant2/test/variant_value_construct_cx.cpp
new file mode 100644
index 000000000..5ffad252a
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_value_construct_cx.cpp
@@ -0,0 +1,109 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/variant2/variant.hpp>
+
+using namespace boost::variant2;
+
+struct X
+{
+ constexpr operator int() const { return 2; }
+};
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+int main()
+{
+ {
+ constexpr variant<int> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int> v( X{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 2 );
+ }
+
+ {
+ constexpr variant<int const> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int const> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int const> v( X{} );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( get<0>(v) == 2 );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 1 );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ STATIC_ASSERT( get<0>(v) == 1 );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 'a' );
+
+ STATIC_ASSERT( v.index() == 0 );
+ STATIC_ASSERT( holds_alternative<int>(v) );
+ STATIC_ASSERT( get<0>(v) == 'a' );
+ }
+
+ {
+ constexpr variant<int, float, X> v( 3.14f );
+
+ STATIC_ASSERT( v.index() == 1 );
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ STATIC_ASSERT( get<1>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, float, X> v( X{} );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( 3.14f );
+
+ STATIC_ASSERT( v.index() == 2 );
+ STATIC_ASSERT( holds_alternative<float>(v) );
+ STATIC_ASSERT( get<2>(v) == 3.14f );
+ }
+
+ {
+ constexpr variant<int, int, float, X> v( X{} );
+
+ STATIC_ASSERT( v.index() == 3 );
+ STATIC_ASSERT( holds_alternative<X>(v) );
+ }
+}
diff --git a/src/boost/libs/variant2/test/variant_valueless.cpp b/src/boost/libs/variant2/test/variant_valueless.cpp
new file mode 100644
index 000000000..d5d18d776
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_valueless.cpp
@@ -0,0 +1,260 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4702 ) // unreachable code
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+#include <stdexcept>
+
+using namespace boost::variant2;
+namespace v2d = boost::variant2::detail;
+
+#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
+
+//
+
+enum E1 { e1 };
+enum E1x { e1x };
+
+struct X1
+{
+ X1() = default;
+
+ X1( E1 ) noexcept {}
+ X1( E1x ) { throw std::runtime_error( "X1(E1x)" ); }
+};
+
+STATIC_ASSERT( std::is_nothrow_default_constructible<X1>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<X1>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<X1>::value );
+STATIC_ASSERT( std::is_trivially_destructible<X1>::value );
+STATIC_ASSERT( v2d::is_trivially_move_assignable<X1>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X1, E1>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X1, E1x>::value );
+
+enum E2 { e2 };
+enum E2x { e2x };
+
+struct X2
+{
+ X2();
+ ~X2();
+
+ X2( E2 ) noexcept {}
+ X2( E2x ) { throw std::runtime_error( "X2(E2x)" ); }
+};
+
+X2::X2() {}
+X2::~X2() {}
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<X2>::value );
+STATIC_ASSERT( !std::is_trivially_destructible<X2>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X2, E2>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X2, E2x>::value );
+
+enum E3 { e3 };
+enum E3x { e3x };
+
+struct X3
+{
+ X3();
+
+ X3( X3 const& ) {}
+ X3( X3&& ) {}
+
+ X3( E3 ) noexcept {}
+ X3( E3x ) { throw std::runtime_error( "X3(E3x)" ); }
+
+ X3& operator=( X3 const& ) = default;
+ X3& operator=( X3&& ) = default;
+};
+
+X3::X3() {}
+
+STATIC_ASSERT( !std::is_nothrow_default_constructible<X3>::value );
+STATIC_ASSERT( !std::is_nothrow_copy_constructible<X3>::value );
+STATIC_ASSERT( !std::is_nothrow_move_constructible<X3>::value );
+STATIC_ASSERT( std::is_trivially_destructible<X3>::value );
+//STATIC_ASSERT( v2d::is_trivially_move_assignable<X3>::value );
+STATIC_ASSERT( std::is_nothrow_constructible<X3, E3>::value );
+STATIC_ASSERT( !std::is_nothrow_constructible<X3, E3x>::value );
+
+//
+
+STATIC_ASSERT( std::is_nothrow_default_constructible<monostate>::value );
+STATIC_ASSERT( std::is_nothrow_copy_constructible<monostate>::value );
+STATIC_ASSERT( std::is_nothrow_move_constructible<monostate>::value );
+STATIC_ASSERT( std::is_trivially_destructible<monostate>::value );
+
+//
+
+int main()
+{
+ {
+ variant<X2, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X1, X2> v( e2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 1 );
+ }
+ }
+
+ {
+ variant<X2, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X1, X2, monostate> v( e2 );
+
+ BOOST_TEST_EQ( v.index(), 1 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 1 );
+ }
+ }
+
+ {
+ variant<X2, X3, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X2, X3, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X2, X3> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e3x;
+ BOOST_ERROR( "`v = e3x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // double buffered, no change
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X3, X1> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ {
+ variant<X3, X1, monostate> v;
+
+ BOOST_TEST_EQ( v.index(), 0 );
+
+ try
+ {
+ v = e1x;
+ BOOST_ERROR( "`v = e1x;` failed to throw" );
+ }
+ catch( std::exception const& )
+ {
+ // strong guarantee
+ BOOST_TEST_EQ( v.index(), 0 );
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/variant2/test/variant_visit.cpp b/src/boost/libs/variant2/test/variant_visit.cpp
new file mode 100644
index 000000000..ed7943ef6
--- /dev/null
+++ b/src/boost/libs/variant2/test/variant_visit.cpp
@@ -0,0 +1,126 @@
+
+// Copyright 2017 Peter Dimov.
+//
+// Distributed under the Boost Software License, Version 1.0.
+//
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if defined(_MSC_VER)
+# pragma warning( disable: 4244 ) // conversion from float to int, possible loss of data
+#endif
+
+#include <boost/variant2/variant.hpp>
+#include <boost/mp11.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/core/lightweight_test_trait.hpp>
+#include <boost/config.hpp>
+#include <type_traits>
+#include <utility>
+#include <string>
+#include <cstdio>
+
+using namespace boost::variant2;
+using boost::mp11::mp_size_t;
+
+struct X
+{
+};
+
+struct F
+{
+ mp_size_t<1> operator()( X& ) const;
+ mp_size_t<2> operator()( X const& ) const;
+ mp_size_t<3> operator()( X&& ) const;
+ mp_size_t<4> operator()( X const&& ) const;
+};
+
+int main()
+{
+ {
+ variant<int> v( 1 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 1 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 1 ); }, std::move(v) );
+ }
+
+ {
+ variant<int> const v( 2 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 2 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 2 ); }, std::move(v) );
+ }
+
+ {
+ variant<int const> v( 3 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 3 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 3 ); }, std::move(v) );
+ }
+
+ {
+ variant<int const> const v( 4 );
+
+ BOOST_TEST_EQ( (visit( []( int x ){ return x; }, v )), 4 );
+
+ visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, v );
+ visit( []( int x ){ BOOST_TEST_EQ( x, 4 ); }, std::move(v) );
+ }
+
+ {
+ variant<int, float> v1( 1 );
+ variant<int, float> const v2( 3.14f );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2 ){ return (int)(x1 * 1000) + (int)(x2 * 100); }, v1, v2 )), 1314 );
+
+ visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, v1, v2 );
+ visit( []( int x1, float x2 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); }, std::move(v1), std::move(v2) );
+ }
+
+ {
+ variant<int, float, double> v1( 1 );
+ variant<int, float, double> const v2( 3.14f );
+ variant<int, float, double> v3( 6.28 );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3 ){ return (int)(x1 * 100) * 1000000 + (int)(x2 * 100) * 1000 + (int)(x3 * 100); }, v1, v2, v3 )), 100314628 );
+
+ visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, v1, v2, v3 );
+ visit( []( int x1, float x2, double x3 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); }, std::move(v1), std::move(v2), std::move(v3) );
+ }
+
+ {
+ variant<int, float, double, char> v1( 1 );
+ variant<int, float, double, char> const v2( 3.14f );
+ variant<int, float, double, char> v3( 6.28 );
+ variant<int, float, double, char> const v4( 'A' );
+
+ BOOST_TEST_EQ( (visit( []( int x1, float x2, double x3, char x4 ){ return (long long)(x1 * 100) * 100000000 + (long long)(x2 * 100) * 100000 + (long long)(x3 * 10000) + (int)x4; }, v1, v2, v3, v4 )), 10031462800 + 'A' );
+
+ visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, v1, v2, v3, v4 );
+ visit( []( int x1, float x2, double x3, char x4 ){ BOOST_TEST_EQ( x1, 1 ); BOOST_TEST_EQ( x2, 3.14f ); BOOST_TEST_EQ( x3, 6.28 ); BOOST_TEST_EQ( x4, 'A' ); }, std::move(v1), std::move(v2), std::move(v3), std::move(v4) );
+ }
+
+ {
+ variant<X> v;
+ variant<X> const cv;
+
+ BOOST_TEST_EQ( decltype(visit(F{}, v))::value, 1 );
+ BOOST_TEST_EQ( decltype(visit(F{}, cv))::value, 2 );
+ BOOST_TEST_EQ( decltype(visit(F{}, std::move(v)))::value, 3 );
+
+#if !BOOST_WORKAROUND(BOOST_GCC, < 40900)
+
+ // g++ 4.8 doesn't handle const&& particularly well
+ BOOST_TEST_EQ( decltype(visit(F{}, std::move(cv)))::value, 4 );
+
+#endif
+ }
+
+ return boost::report_errors();
+}