Bump mapbox/variant to version 1.2.0 (#6898)

This commit is contained in:
Siarhei Fedartsou
2024-05-24 20:39:45 +02:00
committed by GitHub
parent babdced52f
commit 8b48e2ccc6
26 changed files with 10327 additions and 9617 deletions
+2 -2
View File
@@ -160,8 +160,8 @@ struct swap_visitor
{
using T = typename std::common_type<A, B>::type;
T tmp = a;
a = b;
b = tmp;
a = static_cast<A>(b);
b = static_cast<B>(tmp);
}
};
+1 -3
View File
@@ -46,9 +46,7 @@ TEST_CASE("set() works cleanly even if the constructor throws ", "[variant]")
variant_type v = obj;
REQUIRE(v.is<t1>());
REQUIRE(v.get<t1>().value == 42);
REQUIRE_THROWS({
v.set<t2>(13);
});
REQUIRE_THROWS(v.set<t2>(13));
}
REQUIRE(count == 0);
}
+66
View File
@@ -0,0 +1,66 @@
#include <typeinfo>
#include <utility>
#include <mapbox/variant.hpp>
using namespace mapbox;
namespace test {
struct t_noexcept_true_1 {
t_noexcept_true_1(t_noexcept_true_1&&) noexcept = default;
t_noexcept_true_1& operator=(t_noexcept_true_1&&) noexcept = default;
};
struct t_noexcept_true_2 {
t_noexcept_true_2(t_noexcept_true_2&&) noexcept = default;
t_noexcept_true_2& operator=(t_noexcept_true_2&&) noexcept = default;
};
struct t_noexcept_false_1 {
t_noexcept_false_1(t_noexcept_false_1&&) noexcept(false) {}
t_noexcept_false_1& operator=(t_noexcept_false_1&&) noexcept(false) { return *this; }
};
using should_be_no_throw_copyable = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(std::is_nothrow_move_assignable<should_be_no_throw_copyable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_be_no_throw_assignable = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(std::is_nothrow_move_constructible<should_be_no_throw_assignable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_not_be_no_throw_copyable = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
static_assert(not std::is_nothrow_move_assignable<should_not_be_no_throw_copyable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_not_be_no_throw_assignable = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
static_assert(not std::is_nothrow_move_constructible<should_not_be_no_throw_assignable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
// this type cannot be nothrow converted from either of its types, even the nothrow moveable one,
// because the conversion operator moves the whole variant.
using convertable_test_type = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
// this type can be nothrow converted from either of its types.
using convertable_test_type_2 = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(not std::is_nothrow_assignable<convertable_test_type, t_noexcept_true_1>::value,
"variants with noexcept(true) move constructible types should be nothrow-convertible "
"from those types only IF the variant itself is nothrow_move_assignable");
static_assert(not std::is_nothrow_assignable<convertable_test_type, t_noexcept_false_1>::value,
"variants with noexcept(false) move constructible types should not be nothrow-convertible "
"from those types");
static_assert(std::is_nothrow_assignable<convertable_test_type_2, t_noexcept_true_2>::value,
"variants with noexcept(true) move constructible types should be nothrow-convertible "
"from those types only IF the variant itself is nothrow_move_assignable");
} // namespace test
+2 -1
View File
@@ -1,4 +1,3 @@
#include "catch.hpp"
#include <mapbox/optional.hpp>
@@ -97,6 +96,8 @@ TEST_CASE("self assignment", "[optional]")
a = 1;
REQUIRE(a.get() == 1);
#if !defined(__clang__)
a = a;
REQUIRE(a.get() == 1);
#endif
}
+29 -2
View File
@@ -1,6 +1,6 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/recursive_wrapper.hpp>
#include <type_traits>
@@ -153,6 +153,33 @@ TEST_CASE("recursive wrapper of pair<int, int>")
b = std::move(c);
REQUIRE(b.get().first == 5);
REQUIRE(b.get().second == 6);
// REQUIRE(c.get_pointer() == nullptr);
//REQUIRE(c.get_pointer() == nullptr);
}
SECTION("Multiple recurssive wrappers of polymorphic types")
{
// https://github.com/mapbox/variant/issues/146
// (Visual Studio 2015 update 3)
using namespace mapbox::util;
struct Base;
struct Derived;
using Variant = variant<recursive_wrapper<Base>, recursive_wrapper<Derived>>;
struct Base { };
struct Derived : public Base { };
{
Base base;
Derived derived;
Variant v;
v = base;
v = derived; // compile error prior https://github.com/mapbox/variant/pull/147
CHECK(v.is<Derived>());
}
{
Derived derived;
Variant v(derived); // compile error prior https://github.com/mapbox/variant/pull/147
CHECK(v.is<Derived>());
}
}
}
+1 -2
View File
@@ -1,4 +1,3 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -15,7 +14,7 @@ struct some_struct
std::string c;
};
using variant_internal_index_type = size_t;
using variant_internal_index_type = mapbox::util::type_index_t;
TEST_CASE("size of variants")
{
+21 -63
View File
@@ -208,9 +208,7 @@ TEST_CASE("get with wrong type (here: double) should throw", "[variant]")
REQUIRE(var.is<int>());
REQUIRE_FALSE(var.is<double>());
REQUIRE(var.get<int>() == 5);
REQUIRE_THROWS_AS({
var.get<double>();
},
REQUIRE_THROWS_AS(var.get<double>(),
mapbox::util::bad_variant_access&);
}
@@ -222,13 +220,9 @@ TEST_CASE("get with wrong type (here: int) should throw", "[variant]")
REQUIRE_FALSE(var.is<int>());
REQUIRE(var.get<double>() == 5.0);
REQUIRE(mapbox::util::get<double>(var) == 5.0);
REQUIRE_THROWS_AS({
var.get<int>();
},
REQUIRE_THROWS_AS(var.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<int>(var);
},
REQUIRE_THROWS_AS(mapbox::util::get<int>(var),
mapbox::util::bad_variant_access&);
}
@@ -240,26 +234,18 @@ TEST_CASE("get on const varint with wrong type (here: int) should throw", "[vari
REQUIRE_FALSE(var.is<int>());
REQUIRE(var.get<double>() == 5.0);
REQUIRE(mapbox::util::get<double>(var) == 5.0);
REQUIRE_THROWS_AS({
var.get<int>();
},
REQUIRE_THROWS_AS(var.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<int>(var);
},
REQUIRE_THROWS_AS(mapbox::util::get<int>(var),
mapbox::util::bad_variant_access&);
}
TEST_CASE("get with any type should throw if not initialized", "[variant]")
{
mapbox::util::variant<int, double> var{mapbox::util::no_init()};
REQUIRE_THROWS_AS({
var.get<int>();
},
REQUIRE_THROWS_AS(var.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
var.get<double>();
},
REQUIRE_THROWS_AS(var.get<double>(),
mapbox::util::bad_variant_access&);
}
@@ -273,16 +259,12 @@ TEST_CASE("no_init variant can be copied and moved from", "[variant]")
REQUIRE(v2.get<int>() == 42);
v2 = v1;
REQUIRE_THROWS_AS({
v2.get<int>();
},
REQUIRE_THROWS_AS(v2.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE(v3.get<int>() == 23);
v3 = std::move(v1);
REQUIRE_THROWS_AS({
v3.get<int>();
},
REQUIRE_THROWS_AS(v3.get<int>(),
mapbox::util::bad_variant_access&);
}
@@ -294,9 +276,7 @@ TEST_CASE("no_init variant can be copied and moved to", "[variant]")
variant_type v2{mapbox::util::no_init()};
variant_type v3{mapbox::util::no_init()};
REQUIRE_THROWS_AS({
v2.get<int>();
},
REQUIRE_THROWS_AS(v2.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE(v1.get<int>() == 42);
@@ -304,9 +284,7 @@ TEST_CASE("no_init variant can be copied and moved to", "[variant]")
REQUIRE(v2.get<int>() == 42);
REQUIRE(v1.get<int>() == 42);
REQUIRE_THROWS_AS({
v3.get<int>();
},
REQUIRE_THROWS_AS(v3.get<int>(),
mapbox::util::bad_variant_access&);
v3 = std::move(v1);
@@ -327,9 +305,7 @@ TEST_CASE("implicit conversion to first type in variant type list", "[variant][i
using variant_type = mapbox::util::variant<long, char>;
variant_type var = 5l; // converted to long
REQUIRE(var.get<long>() == 5);
REQUIRE_THROWS_AS({
var.get<char>();
},
REQUIRE_THROWS_AS(var.get<char>(),
mapbox::util::bad_variant_access&);
}
@@ -498,13 +474,9 @@ TEST_CASE("storing reference wrappers works")
variant_type v{std::ref(a)};
REQUIRE(v.get<int>() == 1);
REQUIRE(mapbox::util::get<int>(v) == 1);
REQUIRE_THROWS_AS({
v.get<double>();
},
REQUIRE_THROWS_AS(v.get<double>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<double>(v);
},
REQUIRE_THROWS_AS(mapbox::util::get<double>(v),
mapbox::util::bad_variant_access&);
a = 2;
REQUIRE(v.get<int>() == 2);
@@ -515,13 +487,9 @@ TEST_CASE("storing reference wrappers works")
v = std::ref(b);
REQUIRE(v.get<double>() == Approx(3.141));
REQUIRE(mapbox::util::get<double>(v) == Approx(3.141));
REQUIRE_THROWS_AS({
v.get<int>();
},
REQUIRE_THROWS_AS(v.get<int>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<int>(v);
},
REQUIRE_THROWS_AS(mapbox::util::get<int>(v),
mapbox::util::bad_variant_access&);
b = 2.718;
REQUIRE(v.get<double>() == Approx(2.718));
@@ -530,9 +498,7 @@ TEST_CASE("storing reference wrappers works")
v.get<double>() = 4.1;
REQUIRE(b == Approx(4.1));
REQUIRE_THROWS_AS({
v.get<int>() = 4;
},
REQUIRE_THROWS_AS(v.get<int>() = 4,
mapbox::util::bad_variant_access&);
}
@@ -546,26 +512,18 @@ TEST_CASE("storing reference wrappers to consts works")
REQUIRE(v.get<int>() == 1);
REQUIRE(mapbox::util::get<int const>(v) == 1);
REQUIRE(mapbox::util::get<int>(v) == 1);
REQUIRE_THROWS_AS({
v.get<double const>();
},
REQUIRE_THROWS_AS(v.get<double const>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<double const>(v);
},
REQUIRE_THROWS_AS(mapbox::util::get<double const>(v),
mapbox::util::bad_variant_access&);
double b = 3.141;
v = std::cref(b);
REQUIRE(v.get<double const>() == Approx(3.141));
REQUIRE(mapbox::util::get<double const>(v) == Approx(3.141));
REQUIRE_THROWS_AS({
v.get<int const>();
},
REQUIRE_THROWS_AS(v.get<int const>(),
mapbox::util::bad_variant_access&);
REQUIRE_THROWS_AS({
mapbox::util::get<int const>(v);
},
REQUIRE_THROWS_AS(mapbox::util::get<int const>(v),
mapbox::util::bad_variant_access&);
}
+31
View File
@@ -0,0 +1,31 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <string>
TEST_CASE("variant_alternative", "[types]")
{
using variant_type = mapbox::util::variant<int, double, std::string>;
using type_0 = mapbox::util::variant_alternative<0, variant_type>::type;
using type_1 = mapbox::util::variant_alternative<1, variant_type>::type;
using type_2 = mapbox::util::variant_alternative<2, variant_type>::type;
//using type_3 = mapbox::util::variant_alternative<3, variant_type>::type; // compile error
constexpr bool check_0 = std::is_same<int, type_0>::value;
constexpr bool check_1 = std::is_same<double, type_1>::value;
constexpr bool check_2 = std::is_same<std::string, type_2>::value;
CHECK(check_0);
CHECK(check_1);
CHECK(check_2);
}
TEST_CASE("variant_size", "[types]")
{
constexpr auto value_0 = mapbox::util::variant_size<mapbox::util::variant<>>::value;
constexpr auto value_1 = mapbox::util::variant_size<mapbox::util::variant<int>>::value;
constexpr auto value_2 = mapbox::util::variant_size<mapbox::util::variant<int, std::string>>::value;
CHECK(value_0 == 0);
CHECK(value_1 == 1);
CHECK(value_2 == 2);
}
+52
View File
@@ -0,0 +1,52 @@
#include <mapbox/variant.hpp>
using namespace mapbox::util;
namespace {
template <typename... T>
struct tag {};
struct deduced_result_visitor
{
template <typename T>
tag<T> operator() (T);
template <typename T>
tag<T const> operator() (T) const;
template <typename T, typename U>
tag<T, U> operator() (T, U);
template <typename T, typename U>
tag<T, U const> operator() (T, U) const;
};
struct explicit_result_visitor : deduced_result_visitor
{
using result_type = tag<float>;
};
// Doing this compile-time test via assignment to typed tag objects gives
// more useful error messages when something goes wrong, than std::is_same
// in a static_assert would. Here if result_of_unary_visit returns anything
// other than the expected type on the left hand side, the conversion error
// message will tell you exactly what it was.
#ifdef __clang__
# pragma clang diagnostic ignored "-Wunused-variable"
#endif
tag<int> d1m = detail::result_of_unary_visit<deduced_result_visitor, int>{};
tag<int const> d1c = detail::result_of_unary_visit<deduced_result_visitor const, int>{};
tag<float> e1m = detail::result_of_unary_visit<explicit_result_visitor, int>{};
tag<float> e1c = detail::result_of_unary_visit<explicit_result_visitor const, int>{};
tag<int, int> d2m = detail::result_of_binary_visit<deduced_result_visitor, int>{};
tag<int, int const> d2c = detail::result_of_binary_visit<deduced_result_visitor const, int>{};
tag<float> e2m = detail::result_of_binary_visit<explicit_result_visitor, int>{};
tag<float> e2c = detail::result_of_binary_visit<explicit_result_visitor const, int>{};
} // namespace