mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
fix variant
add test variant
This commit is contained in:
parent
cb803dbd14
commit
c5d82f6a99
5 changed files with 249 additions and 5 deletions
213
libs/variant/test/variant.cpp
Normal file
213
libs/variant/test/variant.cpp
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
#ifndef SPROUT_LIBS_VARIANT_TEST_VARIANT_CPP
|
||||||
|
#define SPROUT_LIBS_VARIANT_TEST_VARIANT_CPP
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <sprout/variant.hpp>
|
||||||
|
#include <testspr/tools.hpp>
|
||||||
|
|
||||||
|
namespace testspr {
|
||||||
|
static void variant_test() {
|
||||||
|
using namespace sprout;
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto var1 = sprout::variant<int, double>(1.0);
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto var2 = sprout::variant<int, double>();
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto var3 = sprout::variant<int, double>();
|
||||||
|
TESTSPR_BOTH_ASSERT(var3.which() == 0);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto var3 = sprout::variant<int, double>(var1);
|
||||||
|
TESTSPR_BOTH_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::get<double>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto var3 = sprout::variant<int, double>(1.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::get<double>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
auto var4 = var2;
|
||||||
|
var3.swap(var4);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 0);
|
||||||
|
TESTSPR_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
TESTSPR_ASSERT(var4.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var4) == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
auto var4 = var2;
|
||||||
|
swap(var3, var4);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 0);
|
||||||
|
TESTSPR_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
TESTSPR_ASSERT(var4.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var4) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// operator=
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
var3 = sprout::variant<int, double>(1.0);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
var3 = 1.0;
|
||||||
|
TESTSPR_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// which
|
||||||
|
TESTSPR_BOTH_ASSERT(var1.which() == 1);
|
||||||
|
TESTSPR_BOTH_ASSERT(var2.which() == 0);
|
||||||
|
|
||||||
|
// empty
|
||||||
|
TESTSPR_BOTH_ASSERT(!var1.empty());
|
||||||
|
TESTSPR_BOTH_ASSERT(!var2.empty());
|
||||||
|
|
||||||
|
// operator==
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 == var2));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 == sprout::variant<int, double>(1.0)));
|
||||||
|
|
||||||
|
// operator!=
|
||||||
|
TESTSPR_BOTH_ASSERT(var1 != var2);
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 != sprout::variant<int, double>(1.0)));
|
||||||
|
|
||||||
|
// operator<
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < var2));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < sprout::variant<int, double>(0.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < sprout::variant<int, double>(1.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 < sprout::variant<int, double>(2.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < sprout::variant<int, double>(0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < sprout::variant<int, double>(1)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 < sprout::variant<int, double>(2)));
|
||||||
|
|
||||||
|
// operator>
|
||||||
|
TESTSPR_BOTH_ASSERT(var1 > var2);
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 > sprout::variant<int, double>(0.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 > sprout::variant<int, double>(1.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 > sprout::variant<int, double>(2.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 > sprout::variant<int, double>(0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 > sprout::variant<int, double>(1)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 > sprout::variant<int, double>(2)));
|
||||||
|
|
||||||
|
// operator<=
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 <= var2));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 <= sprout::variant<int, double>(0.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 <= sprout::variant<int, double>(1.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 <= sprout::variant<int, double>(2.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 <= sprout::variant<int, double>(0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 <= sprout::variant<int, double>(1)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 <= sprout::variant<int, double>(2)));
|
||||||
|
|
||||||
|
// operator>=
|
||||||
|
TESTSPR_BOTH_ASSERT(var1 >= var2);
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 >= sprout::variant<int, double>(0.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 >= sprout::variant<int, double>(1.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT(!(var1 >= sprout::variant<int, double>(2.0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 >= sprout::variant<int, double>(0)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 >= sprout::variant<int, double>(1)));
|
||||||
|
TESTSPR_BOTH_ASSERT((var1 >= sprout::variant<int, double>(2)));
|
||||||
|
|
||||||
|
// get_at
|
||||||
|
TESTSPR_BOTH_ASSERT(var1.get_at<1>() == 1.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(var2.get_at<0>() == 0);
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
TESTSPR_ASSERT(var3.get_at<1>() == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
TESTSPR_ASSERT(var3.get_at<0>() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::get<double>(var1) == 1.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::get<int>(var2) == 0);
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
TESTSPR_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply_visitor
|
||||||
|
TESTSPR_BOTH_ASSERT(var1.apply_visitor(testspr::x2_visitor<double>()) == 2.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(var2.apply_visitor(testspr::x2_visitor<double>()) == 0.0);
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
TESTSPR_ASSERT(var3.apply_visitor(testspr::x2_assign_visitor<double>()) == 2.0);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var3) == 2.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
TESTSPR_ASSERT(var3.apply_visitor(testspr::x2_assign_visitor<double>()) == 0.0);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 0);
|
||||||
|
TESTSPR_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply_visitor
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::apply_visitor(testspr::x2_visitor<double>(), var1) == 2.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::apply_visitor(testspr::x2_visitor<double>(), var2) == 0.0);
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
TESTSPR_ASSERT(sprout::apply_visitor(testspr::x2_assign_visitor<double>(), var3) == 2.0);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 1);
|
||||||
|
TESTSPR_ASSERT(sprout::get<double>(var3) == 2.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
TESTSPR_ASSERT(sprout::apply_visitor(testspr::x2_assign_visitor<double>(), var3) == 0.0);
|
||||||
|
TESTSPR_ASSERT(var3.which() == 0);
|
||||||
|
TESTSPR_ASSERT(sprout::get<int>(var3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// operator<<
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << var1;
|
||||||
|
TESTSPR_ASSERT(os.str() == "1");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << var2;
|
||||||
|
TESTSPR_ASSERT(os.str() == "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// tuples::get
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(var1) == 1.0);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(var2) == 0);
|
||||||
|
{
|
||||||
|
auto var3 = var1;
|
||||||
|
TESTSPR_ASSERT(sprout::tuples::get<1>(var3) == 1.0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto var3 = var2;
|
||||||
|
TESTSPR_ASSERT(sprout::tuples::get<0>(var3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tuple_size
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::tuples::tuple_size<decltype(var1)>::value == 2);
|
||||||
|
|
||||||
|
// tuple_element
|
||||||
|
TESTSPR_BOTH_ASSERT((std::is_same<sprout::tuples::tuple_element<0, decltype(var1)>::type, int const>::value));
|
||||||
|
TESTSPR_BOTH_ASSERT((std::is_same<sprout::tuples::tuple_element<1, decltype(var1)>::type, double const>::value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace testspr
|
||||||
|
|
||||||
|
#ifndef TESTSPR_CPP_INCLUDE
|
||||||
|
# define TESTSPR_TEST_FUNCTION testspr::variant_test
|
||||||
|
# include <testspr/include_main.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_LIBS_VARIANT_TEST_VARIANT_CPP
|
|
@ -16,9 +16,14 @@
|
||||||
#include <sprout/type/algorithm/find_index.hpp>
|
#include <sprout/type/algorithm/find_index.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
template<typename... Types>
|
||||||
|
class variant;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
class variant_impl {
|
class variant_impl {
|
||||||
|
template<typename...>
|
||||||
|
friend class variant;
|
||||||
protected:
|
protected:
|
||||||
typedef sprout::tuples::tuple<Types...> tuple_type;
|
typedef sprout::tuples::tuple<Types...> tuple_type;
|
||||||
typedef sprout::types::type_tuple<typename std::decay<Types>::type...> uncvref_tuple_type;
|
typedef sprout::types::type_tuple<typename std::decay<Types>::type...> uncvref_tuple_type;
|
||||||
|
@ -45,6 +50,7 @@ namespace sprout {
|
||||||
{
|
{
|
||||||
static_assert(Index::value < sizeof...(Types), "variant<>: invalid operand");
|
static_assert(Index::value < sizeof...(Types), "variant<>: invalid operand");
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
void swap(variant_impl& other)
|
void swap(variant_impl& other)
|
||||||
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(tuple_, other.tuple_)))
|
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(tuple_, other.tuple_)))
|
||||||
{
|
{
|
||||||
|
@ -154,7 +160,7 @@ namespace sprout {
|
||||||
{}
|
{}
|
||||||
// modifiers
|
// modifiers
|
||||||
void swap(variant& other)
|
void swap(variant& other)
|
||||||
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(impl_type::swap(other)))
|
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::declval<impl_type&>().swap(other)))
|
||||||
{
|
{
|
||||||
impl_type::swap(other);
|
impl_type::swap(other);
|
||||||
}
|
}
|
||||||
|
@ -244,11 +250,11 @@ namespace sprout {
|
||||||
// visitation support
|
// visitation support
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
SPROUT_CONSTEXPR typename Visitor::result_type apply_visitor(Visitor&& visitor) const {
|
SPROUT_CONSTEXPR typename Visitor::result_type apply_visitor(Visitor&& visitor) const {
|
||||||
return visit(tuple_, sprout::forward<Visitor>(visitor), which_);
|
return visit<0>(tuple_, sprout::forward<Visitor>(visitor), which_);
|
||||||
}
|
}
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
typename Visitor::result_type apply_visitor(Visitor&& visitor) {
|
typename Visitor::result_type apply_visitor(Visitor&& visitor) {
|
||||||
return visit(tuple_, sprout::forward<Visitor>(visitor), which_);
|
return visit<0>(tuple_, sprout::forward<Visitor>(visitor), which_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../libs/bitset/test/bitset.cpp"
|
#include "../libs/bitset/test/bitset.cpp"
|
||||||
#include "../libs/tuple/test/tuple.cpp"
|
#include "../libs/tuple/test/tuple.cpp"
|
||||||
#include "../libs/optional/test/optional.cpp"
|
#include "../libs/optional/test/optional.cpp"
|
||||||
|
#include "../libs/variant/test/variant.cpp"
|
||||||
#include "../libs/algorithm/test/algorithm.cpp"
|
#include "../libs/algorithm/test/algorithm.cpp"
|
||||||
#include "../libs/random/test/random.cpp"
|
#include "../libs/random/test/random.cpp"
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ namespace testspr {
|
||||||
testspr::bitset_test();
|
testspr::bitset_test();
|
||||||
testspr::tuple_test();
|
testspr::tuple_test();
|
||||||
testspr::optional_test();
|
testspr::optional_test();
|
||||||
|
testspr::variant_test();
|
||||||
testspr::algorithm_test();
|
testspr::algorithm_test();
|
||||||
testspr::random_test();
|
testspr::random_test();
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,29 @@ namespace testspr {
|
||||||
SPROUT_CONSTEXPR result operator()(T const& val) const { return result{val}; }
|
SPROUT_CONSTEXPR result operator()(T const& val) const { return result{val}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// x2_visitor
|
||||||
|
//
|
||||||
|
template<typename R = void>
|
||||||
|
class x2_visitor {
|
||||||
|
public:
|
||||||
|
typedef R result_type;
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
SPROUT_CONSTEXPR result_type operator()(T const& t) const { return static_cast<result_type>(t + t); }
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// x2_assign_visitor
|
||||||
|
//
|
||||||
|
template<typename R = void>
|
||||||
|
class x2_assign_visitor {
|
||||||
|
public:
|
||||||
|
typedef R result_type;
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
SPROUT_CONSTEXPR result_type operator()(T& t) const { return static_cast<result_type>(t += t); }
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// distance
|
// distance
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue