early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -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()

View File

@@ -0,0 +1,128 @@
# 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 ;
run variant_visit_derived.cpp ;
run variant_many_types.cpp ;
run variant_visit_r.cpp : : :
<toolset>gcc,<target-os>windows:<variant>release
<toolset>gcc,<target-os>cygwin:<variant>release
;
compile variant_derived_construct.cpp ;
run variant_visit_by_index.cpp ;
run variant_ostream_insert.cpp ;
run is_output_streamable.cpp ;

View File

@@ -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>)

View File

@@ -0,0 +1,21 @@
# 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(../../../assert boostorg/assert)
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>)

View File

@@ -0,0 +1,41 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <ostream>
#include <string>
struct X
{
};
struct Y
{
};
std::ostream& operator<<( std::ostream& os, Y const& /*y*/ )
{
os << "Y()";
return os;
}
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, int>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, float>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, std::string>));
BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable<std::ostream, void>));
BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable<std::ostream, X>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, Y>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, boost::variant2::monostate>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, boost::variant2::variant<int, float, std::string>>));
BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable<std::ostream, boost::variant2::variant<int, float, X>>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, boost::variant2::variant<int, float, Y>>));
BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable<std::ostream, boost::variant2::variant<boost::variant2::monostate, int, float>>));
return boost::report_errors();
}

View File

@@ -0,0 +1,13 @@
// Copyright 2019 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2.hpp>
using namespace boost::variant2;
int main()
{
variant<float, int> v( 2 );
return get<1>( v ) == 2? 0: 1;
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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 );
}
}

View File

@@ -0,0 +1,33 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
using namespace boost::variant2;
template<class... T> class X: variant<T...>
{
using base = variant<T...>;
using base::base;
};
struct Y
{
Y( Y const& rhs ) = default;
template<class T> Y( T const& t )
{
t.bar();
}
};
int main()
{
using W = X<int, double, Y>;
W a( 1 );
W b( a );
(void)b;
}

View File

@@ -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();
}

View File

@@ -0,0 +1,292 @@
// 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
{
int v = 1;
Y1() = default;
Y1(Y1 const&) = delete;
Y1(Y1&&) = delete;
};
STATIC_ASSERT( !std::is_copy_constructible<Y1>::value );
STATIC_ASSERT( !std::is_move_constructible<Y1>::value );
struct Y2
{
int v = 2;
Y2() = default;
Y2(Y2 const&) = delete;
Y2(Y2&&) = delete;
};
STATIC_ASSERT( !std::is_copy_constructible<Y2>::value );
STATIC_ASSERT( !std::is_move_constructible<Y2>::value );
struct Z1
{
static int instances;
int v = 1;
Z1() { ++instances; }
~Z1() { --instances; }
Z1(Z1 const&) = delete;
Z1(Z1&&) = delete;
};
int Z1::instances = 0;
struct Z2
{
static int instances;
int v = 2;
Z2() { ++instances; }
~Z2() { --instances; }
Z2(Z2 const&) = delete;
Z2(Z2&&) = delete;
};
int Z2::instances = 0;
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 );
}
{
variant<Y1, Y2> v;
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v).v, 1 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v).v, 1 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
BOOST_TEST_EQ( get<1>(v).v, 2 );
v.emplace<1>();
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, 1 );
}
{
variant<Z1, Z2> v;
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v).v, 1 );
BOOST_TEST_EQ( Z1::instances, 1 );
BOOST_TEST_EQ( Z2::instances, 0 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v).v, 1 );
BOOST_TEST_EQ( Z1::instances, 1 );
BOOST_TEST_EQ( Z2::instances, 0 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
BOOST_TEST_EQ( get<1>(v).v, 2 );
BOOST_TEST_EQ( Z1::instances, 0 );
BOOST_TEST_EQ( Z2::instances, 1 );
v.emplace<1>();
BOOST_TEST_EQ( v.index(), 1 );
BOOST_TEST_EQ( get<1>(v).v, 2 );
BOOST_TEST_EQ( Z1::instances, 0 );
BOOST_TEST_EQ( Z2::instances, 1 );
v.emplace<0>();
BOOST_TEST_EQ( v.index(), 0 );
BOOST_TEST_EQ( get<0>(v).v, 1 );
BOOST_TEST_EQ( Z1::instances, 1 );
BOOST_TEST_EQ( Z2::instances, 0 );
}
BOOST_TEST_EQ( Z1::instances, 0 );
BOOST_TEST_EQ( Z2::instances, 0 );
return boost::report_errors();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -0,0 +1,99 @@
// 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 );
}
{
variant<monostate> v1, v2;
BOOST_TEST( v1 == v2 );
BOOST_TEST_NOT( v1 != v2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,105 @@
// 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) );
}
{
constexpr variant<monostate> v1, v2;
STATIC_ASSERT( v1 == v2 );
STATIC_ASSERT( !(v1 != v2) );
}
}
#endif

View File

@@ -0,0 +1,355 @@
// 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( __clang__ ) && defined( __has_warning )
# if __has_warning( "-Wdeprecated-volatile" )
# pragma clang diagnostic ignored "-Wdeprecated-volatile"
# endif
#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;
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();
}

View File

@@ -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) );
}
}

View File

@@ -0,0 +1,313 @@
// 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( __clang__ ) && defined( __has_warning )
# if __has_warning( "-Wdeprecated-volatile" )
# pragma clang diagnostic ignored "-Wdeprecated-volatile"
# endif
#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;
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();
}

View File

@@ -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) );
}
}

View File

@@ -0,0 +1,86 @@
// 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>
#include <vector>
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 m = 0;
};
std::size_t hash_value( X const& x )
{
return boost::hash<int>()( x.m );
}
struct Y {}; // no hash support
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>();
test<boost::hash, monostate, X, std::vector<X>>();
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<Y> ));
#endif
return boost::report_errors();
}

View File

@@ -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();
}

View File

@@ -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 ) );
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,121 @@
// 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>
#include <boost/config/workaround.hpp>
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 );
}
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 120000)
// no idea why this fails on g++ 10/11
#else
{
constexpr variant<int, int, float, float, X, X> v( in_place_index_t<5>{}, 0, 0 );
STATIC_ASSERT( v.index() == 5 );
}
#endif
}

View File

@@ -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();
}

View File

@@ -0,0 +1,120 @@
// 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>
#include <boost/config/workaround.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) );
}
#if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 120000)
// no idea why this fails on g++ 10/11
#else
{
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) );
}
#endif
}

View File

@@ -0,0 +1,94 @@
// 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 );
}
{
variant<monostate> v1, v2;
BOOST_TEST_NOT( v1 < v2 );
BOOST_TEST_NOT( v1 > v2 );
BOOST_TEST( v1 <= v2 );
BOOST_TEST( v1 >= v2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,100 @@
// 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) );
}
{
constexpr variant<monostate> v1, v2;
STATIC_ASSERT( !(v1 < v2) );
STATIC_ASSERT( !(v1 > v2) );
STATIC_ASSERT( v1 <= v2 );
STATIC_ASSERT( v1 >= v2 );
}
}
#endif

View File

@@ -0,0 +1,109 @@
// 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)
# pragma warning( disable: 4503 ) // decorated name length exceeded
#endif
#include <boost/variant2/variant.hpp>
#include <boost/mp11.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::mp11;
template<class I> struct X
{
static int const value = I::value;
int v_;
};
template<class I> int const X<I>::value;
template<class I> struct Y
{
static int const value = I::value;
int v_;
Y() = default;
Y( Y const& ) = default;
explicit Y( int v ): v_( v ) {}
Y& operator=( Y const& ) noexcept = default;
Y& operator=( Y&& r ) noexcept
{
v_ = r.v_;
return *this;
}
};
template<class I> int const Y<I>::value;
template<class I> struct Z
{
static int const value = I::value;
int v_;
~Z() {}
};
template<class I> int const Z<I>::value;
template<class V> struct F1
{
template<class T> void operator()( T ) const
{
int const i = T::value;
T t{ i * 2 };
using boost::variant2::get;
{
V v( t );
BOOST_TEST_EQ( v.index(), i );
BOOST_TEST_EQ( get<i>( v ).v_, t.v_ );
BOOST_TEST_EQ( get<T>( v ).v_, t.v_ );
}
{
V const v( t );
BOOST_TEST_EQ( v.index(), i );
BOOST_TEST_EQ( get<i>( v ).v_, t.v_ );
BOOST_TEST_EQ( get<T>( v ).v_, t.v_ );
}
{
V v;
v = t;
BOOST_TEST_EQ( v.index(), i );
BOOST_TEST_EQ( get<i>( v ).v_, t.v_ );
BOOST_TEST_EQ( get<T>( v ).v_, t.v_ );
}
}
};
template<class V> void test()
{
mp_for_each<V>( F1<V>() );
}
int main()
{
int const N = 32;
using V = mp_rename<mp_iota_c<N>, boost::variant2::variant>;
test< mp_transform<X, V> >();
test< mp_transform<Y, V> >();
test< mp_transform<Z, V> >();
return boost::report_errors();
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -0,0 +1,43 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
using namespace boost::variant2;
template<class T> std::string to_string( T const& t )
{
std::ostringstream os;
os << t;
return os.str();
}
int main()
{
{
BOOST_TEST_EQ( to_string( monostate() ), "monostate" );
}
{
variant<monostate, int, float, std::string> v;
BOOST_TEST_EQ( to_string( v ), to_string( monostate() ) );
v = 1;
BOOST_TEST_EQ( to_string( v ), to_string( 1 ) );
v = 3.14f;
BOOST_TEST_EQ( to_string( v ), to_string( 3.14f ) );
v = "test";
BOOST_TEST_EQ( to_string( v ), to_string( "test" ) );
}
return boost::report_errors();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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) );
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,130 @@
// 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()
{
{
BOOST_TEST_EQ( (visit( []{ return 5; } )), 5 );
}
{
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();
}

View File

@@ -0,0 +1,126 @@
// Copyright 2017, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://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/mp11.hpp>
#include <boost/config.hpp>
using namespace boost::variant2;
using boost::mp11::mp_int;
struct X
{
};
struct F1
{
int operator()( X& ) const { return 1; }
int operator()( X const& ) const { return 2; }
int operator()( X&& ) const { return 3; }
int operator()( X const&& ) const { return 4; }
};
struct F2
{
mp_int<1> operator()( X& ) const { return {}; }
mp_int<2> operator()( X const& ) const { return {}; }
mp_int<3> operator()( X&& ) const { return {}; }
mp_int<4> operator()( X const&& ) const { return {}; }
};
int main()
{
{
variant<int, int, float> v;
visit_by_index( v,
[]( int& x ){ BOOST_TEST_EQ( x, 0 ); },
[]( int& ){ BOOST_ERROR( "incorrect alternative" ); },
[]( float& ){ BOOST_ERROR( "incorrect alternative" ); } );
}
{
variant<int const, int, float const> v( in_place_index_t<0>(), 1 );
visit_by_index( v,
[]( int const& x ){ BOOST_TEST_EQ( x, 1 ); },
[]( int& ){ BOOST_ERROR( "incorrect alternative" ); },
[]( float const& ){ BOOST_ERROR( "incorrect alternative" ); } );
}
{
variant<int, int, float> const v( in_place_index_t<1>(), 2 );
visit_by_index( v,
[]( int const& ){ BOOST_ERROR( "incorrect alternative" ); },
[]( int const& x ){ BOOST_TEST_EQ( x, 2 ); },
[]( float const& ){ BOOST_ERROR( "incorrect alternative" ); } );
}
{
variant<int const, int, float const> const v( 3.14f );
visit_by_index( v,
[]( int const& ){ BOOST_ERROR( "incorrect alternative" ); },
[]( int const& ){ BOOST_ERROR( "incorrect alternative" ); },
[]( float const& x ){ BOOST_TEST_EQ( x, 3.14f ); } );
}
{
variant<int, float> const v( 7 );
auto r = visit_by_index( v,
[]( int const& x ) -> double { return x; },
[]( float const& x ) -> double { return x; } );
BOOST_TEST_TRAIT_SAME( decltype(r), double );
BOOST_TEST_EQ( r, 7.0 );
}
{
variant<int, float> const v( 2.0f );
auto r = visit_by_index( v,
[]( int const& x ) { return x + 0.0; },
[]( float const& x ) { return x + 0.0; } );
BOOST_TEST_TRAIT_SAME( decltype(r), double );
BOOST_TEST_EQ( r, 2.0 );
}
{
variant<int, float, double> const v( 3.0 );
auto r = visit_by_index<double>( v,
[]( int const& x ) { return x; },
[]( float const& x ) { return x; },
[]( double const& x ) { return x; } );
BOOST_TEST_TRAIT_SAME( decltype(r), double );
BOOST_TEST_EQ( r, 3.0 );
}
{
variant<X> v;
variant<X> const cv;
F1 f1;
BOOST_TEST_EQ( visit_by_index( v, f1 ), 1 );
BOOST_TEST_EQ( visit_by_index( cv, f1 ), 2 );
BOOST_TEST_EQ( visit_by_index( std::move( v ), f1 ), 3 );
BOOST_TEST_EQ( visit_by_index( std::move( cv ), f1 ), 4 );
F2 f2;
BOOST_TEST_EQ( visit_by_index<int>( v, f2 ), 1 );
BOOST_TEST_EQ( visit_by_index<int>( cv, f2 ), 2 );
BOOST_TEST_EQ( visit_by_index<int>( std::move( v ), f2 ), 3 );
BOOST_TEST_EQ( visit_by_index<int>( std::move( cv ), f2 ), 4 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,56 @@
// Copyright 2017, 2020 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://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/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <utility>
struct X: boost::variant2::variant<int, float>
{
#if BOOST_WORKAROUND( BOOST_MSVC, < 1940 )
template<class T> explicit X( T&& t ): variant( std::forward<T>( t ) ) {};
#else
using variant::variant;
#endif
};
template<class... T> struct Y: boost::variant2::variant<T...>
{
using boost::variant2::variant<T...>::variant;
};
int main()
{
{
X v1( 1 );
X 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) );
}
{
Y<int, float> v1( 1 );
Y<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) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,98 @@
// 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/core/lightweight_test.hpp>
using namespace boost::variant2;
struct F1
{
template<class T1> T1 operator()( T1 t1 ) const
{
return t1;
}
};
struct F2
{
template<class T1, class T2> auto operator()( T1 t1, T2 t2 ) const -> decltype( t1 + t2 )
{
return t1 + t2;
}
};
struct F3
{
template<class T1, class T2, class T3> auto operator()( T1 t1, T2 t2, T3 t3 ) const -> decltype( t1 + t2 + t3 )
{
return t1 + t2 + t3;
}
};
struct F4
{
template<class T1, class T2, class T3, class T4> auto operator()( T1 t1, T2 t2, T3 t3, T4 t4 ) const -> decltype( t1 + t2 + t3 + t4 )
{
return t1 + t2 + t3 + t4;
}
};
int main()
{
{
BOOST_TEST_EQ( (visit<int>( []{ return 3.14f; } )), 3 );
}
{
variant<int, float> v( 1 );
BOOST_TEST_EQ( visit<int>( F1(), v ), 1 );
BOOST_TEST_EQ( visit<float>( F1(), v ), 1.0f );
}
{
variant<int, float> const v( 3.14f );
BOOST_TEST_EQ( visit<int>( F1(), v ), 3 );
BOOST_TEST_EQ( visit<float>( F1(), v ), 3.14f );
}
{
variant<int, float> v1( 1 );
variant<int, float> const v2( 3.14f );
BOOST_TEST_EQ( visit<int>( F2(), v1, v2 ), 4 );
BOOST_TEST_EQ( visit<float>( F2(), v1, v2 ), 1 + 3.14f );
}
{
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>( F3(), v1, v2, v3 ), 10 );
BOOST_TEST_EQ( visit<float>( F3(), v1, v2, v3 ), static_cast<float>( 1 + 3.14f + 6.28 ) );
}
{
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>( F4(), v1, v2, v3, v4 ), 10 + 'A' );
BOOST_TEST_EQ( visit<float>( F4(), v1, v2, v3, v4 ), static_cast<float>( 1 + 3.14f + 6.28 + 'A' ) );
}
return boost::report_errors();
}