mirror of
https://github.com/boostorg/variant2.git
synced 2025-07-29 11:47:36 +02:00
Add test/variant_copy_construct, variant_move_construct
This commit is contained in:
@ -642,8 +642,13 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
template<class U> constexpr variant( U&& u )
|
||||
noexcept( std::is_nothrow_constructible< variant2::detail::resolve_overload_type<U&&, T...>, U >::value )
|
||||
template<class U,
|
||||
class E1 = std::enable_if_t<!std::is_same<std::decay_t<U>, variant>::value>,
|
||||
class V = variant2::detail::resolve_overload_type<U&&, T...>,
|
||||
class E2 = std::enable_if_t<std::is_constructible<V, U>::value>
|
||||
>
|
||||
constexpr variant( U&& u )
|
||||
noexcept( std::is_nothrow_constructible<V, U>::value )
|
||||
: variant_base( variant2::detail::resolve_overload_index<U&&, T...>(), std::forward<U>(u) )
|
||||
{
|
||||
}
|
||||
@ -714,9 +719,9 @@ public:
|
||||
template<class U,
|
||||
class E1 = std::enable_if_t<!std::is_same<std::decay_t<U>, variant>::value>,
|
||||
class V = variant2::detail::resolve_overload_type<U, T...>,
|
||||
class E2 = std::enable_if_t<std::is_assignable<V&, U>::value && std::is_constructible<V&, U>::value>
|
||||
class E2 = std::enable_if_t<std::is_assignable<V&, U>::value && std::is_constructible<V, U>::value>
|
||||
>
|
||||
variant& operator=( U&& u ) // noexcept(see below );
|
||||
variant& operator=( U&& u ) noexcept( std::is_nothrow_assignable<V&, U>::value && std::is_nothrow_constructible<V, U>::value )
|
||||
{
|
||||
std::size_t const I = variant2::detail::resolve_overload_index<U, T...>::value;
|
||||
|
||||
@ -733,7 +738,6 @@ public:
|
||||
}
|
||||
|
||||
// modifiers
|
||||
// using variant_base::emplace;
|
||||
|
||||
template<class U, class... A, class I = mp_find<variant<T...>, U>> U& emplace( A&&... a )
|
||||
{
|
||||
@ -777,28 +781,30 @@ template<class... T> constexpr bool operator==( variant<T...> const & v, variant
|
||||
{
|
||||
if( v.index() != w.index() ) return false;
|
||||
|
||||
bool r = false;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) == get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) == get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class... T> constexpr bool operator!=( variant<T...> const & v, variant<T...> const & w )
|
||||
{
|
||||
if( v.index() != w.index() ) return true;
|
||||
|
||||
bool r = true;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) != get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) != get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return true;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class... T> constexpr bool operator<( variant<T...> const & v, variant<T...> const & w )
|
||||
@ -806,14 +812,15 @@ template<class... T> constexpr bool operator<( variant<T...> const & v, variant<
|
||||
if( v.index() < w.index() ) return true;
|
||||
if( v.index() > w.index() ) return false;
|
||||
|
||||
bool r = false;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) < get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) < get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class... T> constexpr bool operator>( variant<T...> const & v, variant<T...> const & w )
|
||||
@ -821,14 +828,15 @@ template<class... T> constexpr bool operator>( variant<T...> const & v, variant
|
||||
if( v.index() > w.index() ) return true;
|
||||
if( v.index() < w.index() ) return false;
|
||||
|
||||
bool r = false;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) > get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) > get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class... T> constexpr bool operator<=( variant<T...> const & v, variant<T...> const & w )
|
||||
@ -836,14 +844,15 @@ template<class... T> constexpr bool operator<=( variant<T...> const & v, variant
|
||||
if( v.index() < w.index() ) return true;
|
||||
if( v.index() > w.index() ) return false;
|
||||
|
||||
bool r = false;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) <= get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) <= get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class... T> constexpr bool operator>=( variant<T...> const & v, variant<T...> const & w )
|
||||
@ -851,14 +860,15 @@ template<class... T> constexpr bool operator>=( variant<T...> const & v, variant
|
||||
if( v.index() > w.index() ) return true;
|
||||
if( v.index() < w.index() ) return false;
|
||||
|
||||
bool r = false;
|
||||
|
||||
mp_for_each<mp_iota_c<sizeof...(T)>>([&]( auto I ){
|
||||
|
||||
if( I == v.index() ) return get<I>(v) >= get<I>(w);
|
||||
if( I == v.index() ) r = get<I>(v) >= get<I>(w);
|
||||
|
||||
});
|
||||
|
||||
assert( false );
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
|
||||
// visitation
|
||||
|
@ -21,3 +21,5 @@ run get_by_type.cpp : : : $(REQ) ;
|
||||
compile get_by_type_cx.cpp : : : $(REQ) ;
|
||||
run variant_default_construct.cpp : : : $(REQ) ;
|
||||
compile variant_default_construct_cx.cpp : : : $(REQ) ;
|
||||
run variant_copy_construct.cpp : : : $(REQ) ;
|
||||
run variant_move_construct.cpp : : : $(REQ) ;
|
||||
|
120
test/variant_copy_construct.cpp
Normal file
120
test/variant_copy_construct.cpp
Normal 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/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 );
|
||||
|
||||
template<class V> static void test( V const & v )
|
||||
{
|
||||
V v2( v );
|
||||
|
||||
BOOST_TEST_EQ( v.index(), v2.index() );
|
||||
BOOST_TEST( v == v2 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test( variant<int>() );
|
||||
test( variant<int>(1) );
|
||||
|
||||
test( variant<int const>() );
|
||||
test( variant<int const>(1) );
|
||||
|
||||
test( variant<int, float>() );
|
||||
test( variant<int, float>(1) );
|
||||
test( variant<int, float>(3.14f) );
|
||||
|
||||
test( variant<int, 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, X2>() );
|
||||
test( variant<X1, X2, int>() );
|
||||
test( variant<X1, X2, X2>() );
|
||||
test( variant<X1, X1, X2, X2>() );
|
||||
|
||||
{
|
||||
variant<X1, X2> v;
|
||||
v.emplace<X2>();
|
||||
|
||||
test( v );
|
||||
}
|
||||
|
||||
{
|
||||
variant<X1, X1, X2> v;
|
||||
v.emplace<X2>();
|
||||
|
||||
test( v );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, float>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int, float, float>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int, float>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, X1>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, int, X1>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2, int, int>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
121
test/variant_move_construct.cpp
Normal file
121
test/variant_move_construct.cpp
Normal 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/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 );
|
||||
|
||||
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, 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, 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>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user