diff options
Diffstat (limited to '')
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(); +} |