operator== instead equals function for value

This commit is contained in:
BlackMATov
2021-08-16 16:28:23 +07:00
parent f6fe32e7eb
commit f11452ba10
6 changed files with 143 additions and 121 deletions

View File

@@ -42,10 +42,6 @@ namespace meta_hpp
const void* data() const noexcept;
const void* cdata() const noexcept;
template < typename T >
bool equals(const T& other) const;
bool equals(const value& other) const;
template < typename T, typename Tp = std::decay_t<T> >
Tp& cast() &;
@@ -64,6 +60,12 @@ namespace meta_hpp
template < typename T, typename Tp = std::decay_t<T> >
const Tp* try_cast() const noexcept;
template < typename T >
friend bool operator==(const value& l, const T& r);
template < typename T >
friend bool operator==(const T& l, const value& r);
friend bool operator==(const value& l, const value& r);
friend std::istream& operator>>(std::istream& os, value& v);
friend std::ostream& operator<<(std::ostream& os, const value& v);
private:
@@ -95,17 +97,14 @@ namespace meta_hpp::detail
has_value_type_equality_operator_v<T>
, int> = 0 >
bool value_equals_function(const value& l, const value& r) {
return l.type() == r.type()
&& l.cast<T>() == r.cast<T>();
assert(l.type() == r.type());
return l.cast<T>() == r.cast<T>();
}
template < typename T, std::enable_if_t<
!has_value_type_equality_operator_v<T>
, int> = 0 >
bool value_equals_function(const value& l, const value& r) {
if ( l.type() != r.type() ) {
return false;
}
bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) {
throw std::logic_error("value type doesn't have equality operator");
}
}
@@ -303,16 +302,6 @@ namespace meta_hpp
return traits_->cdata(*this);
}
template < typename T >
bool value::equals(const T& other) const {
return type() == type_db::get<T>()
&& std::equal_to<>{}(cast<T>(), other);
}
inline bool value::equals(const value& other) const {
return traits_->equals(*this, other);
}
template < typename T, typename Tp >
Tp& value::cast() & {
if ( type() != type_db::get<Tp>() ) {
@@ -358,6 +347,23 @@ namespace meta_hpp
namespace meta_hpp
{
template < typename T >
bool operator==(const value& l, const T& r) {
return l.type() == type_db::get<T>()
&& std::equal_to<>{}(l.cast<T>(), r);
}
template < typename T >
bool operator==(const T& l, const value& r) {
return type_db::get<T>() == r.type()
&& std::equal_to<>{}(l, r.cast<T>());
}
inline bool operator==(const value& l, const value& r) {
return l.type() == r.type()
&& l.traits_->equals(l, r);
}
inline std::istream& operator>>(std::istream& is, value& v) {
v.traits_->istream(is, v);
return is;

View File

@@ -51,7 +51,7 @@ TEST_CASE("features/infos/ctor") {
REQUIRE(ci);
REQUIRE(ci.get_data_by_name("info"));
CHECK(ci.get_data_by_name("info").value().equals("void ctor"s));
CHECK(ci.get_data_by_name("info").value() == "void ctor"s);
{
const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array<any_type, 0>{});
@@ -74,7 +74,7 @@ TEST_CASE("features/infos/ctor") {
}
{
CHECK(ci.invoke().equals(ivec2{}));
CHECK(ci.invoke() == ivec2{});
CHECK_THROWS(ci.invoke(42));
}
}
@@ -84,7 +84,7 @@ TEST_CASE("features/infos/ctor") {
REQUIRE(ci);
REQUIRE(ci.get_data_by_name("info"));
CHECK(ci.get_data_by_name("info").value().equals("int ctor"s));
CHECK(ci.get_data_by_name("info").value() == "int ctor"s);
{
const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array<any_type, 1>{
@@ -110,7 +110,7 @@ TEST_CASE("features/infos/ctor") {
{
CHECK_THROWS(ci.invoke());
CHECK(ci.invoke(42).equals(ivec2{42}));
CHECK(ci.invoke(42) == ivec2{42});
}
}
@@ -119,7 +119,7 @@ TEST_CASE("features/infos/ctor") {
REQUIRE(ci);
REQUIRE(ci.get_data_by_name("info"));
CHECK(ci.get_data_by_name("info").value().equals("copy ctor"s));
CHECK(ci.get_data_by_name("info").value() == "copy ctor"s);
{
const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array<any_type, 1>{
@@ -152,7 +152,7 @@ TEST_CASE("features/infos/ctor") {
{
CHECK_THROWS(ci.invoke());
CHECK_THROWS(ci.invoke(42));
CHECK(ci.invoke(ivec2{21,42}).equals(ivec2{21,42}));
CHECK(ci.invoke(ivec2{21,42}) == ivec2{21,42});
}
}
@@ -161,7 +161,7 @@ TEST_CASE("features/infos/ctor") {
REQUIRE(ci);
REQUIRE(ci.get_data_by_name("info"));
CHECK(ci.get_data_by_name("info").value().equals("int,int ctor"s));
CHECK(ci.get_data_by_name("info").value() == "int,int ctor"s);
{
const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array<any_type, 2>{
@@ -195,7 +195,7 @@ TEST_CASE("features/infos/ctor") {
CHECK_THROWS(ci.invoke());
CHECK_THROWS(ci.invoke(42));
CHECK_THROWS(ci.invoke(ivec2{21,42}));
CHECK(ci.invoke(21,42).equals(ivec2{21,42}));
CHECK(ci.invoke(21,42) == ivec2{21,42});
}
}
}

View File

@@ -53,7 +53,7 @@ TEST_CASE("features/infos/function") {
REQUIRE(fi);
REQUIRE(fi.get_data_by_name("info"));
CHECK(fi.get_data_by_name("info").value().equals("iadd function"s));
CHECK(fi.get_data_by_name("info").value() == "iadd function"s);
CHECK_FALSE(fi.is_invocable_with());
CHECK_FALSE(fi.is_invocable_with<int>());
@@ -68,7 +68,7 @@ TEST_CASE("features/infos/function") {
CHECK_THROWS(fi.invoke(ivec2{}, 42));
CHECK(fi.invoke(ivec2{1,2},ivec2{3,4}));
CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})->equals(ivec2{4,6}));
CHECK(fi.invoke(ivec2{1,2},ivec2{3,4}).value() == ivec2{4,6});
}
SUBCASE("ilength2") {
@@ -76,7 +76,7 @@ TEST_CASE("features/infos/function") {
REQUIRE(fi);
REQUIRE(fi.get_data_by_name("info"));
CHECK(fi.get_data_by_name("info").value().equals("ilength2 function"s));
CHECK(fi.get_data_by_name("info").value() == "ilength2 function"s);
CHECK_FALSE(fi.is_invocable_with());
CHECK_FALSE(fi.is_invocable_with<int>());
@@ -90,6 +90,6 @@ TEST_CASE("features/infos/function") {
CHECK_THROWS(fi.invoke(ivec2{}, 42));
CHECK(fi.invoke(ivec2{2,3}));
CHECK(fi.invoke(ivec2{2,3})->equals(13));
CHECK(fi.invoke(ivec2{2,3}).value() == 13);
}
}

View File

@@ -76,15 +76,15 @@ TEST_CASE("features/infos/member") {
{
ivec2 v{1,2};
CHECK(x_mi.get(v).equals(1));
CHECK(x_mi.get(std::as_const(v)).equals(1));
CHECK(x_mi.get(std::move(v)).equals(1));
CHECK(x_mi.get(std::move(std::as_const(v))).equals(1));
CHECK(x_mi.get(v) == 1);
CHECK(x_mi.get(std::as_const(v)) == 1);
CHECK(x_mi.get(std::move(v)) == 1);
CHECK(x_mi.get(std::move(std::as_const(v))) == 1);
CHECK(y_mi.get(v).equals(2));
CHECK(y_mi.get(std::as_const(v)).equals(2));
CHECK(y_mi.get(std::move(v)).equals(2));
CHECK(y_mi.get(std::move(std::as_const(v))).equals(2));
CHECK(y_mi.get(v) == 2);
CHECK(y_mi.get(std::as_const(v)) == 2);
CHECK(y_mi.get(std::move(v)) == 2);
CHECK(y_mi.get(std::move(std::as_const(v))) == 2);
static_assert(std::is_invocable_v<decltype(&ivec2::x), ivec2&>);
static_assert(std::is_invocable_v<decltype(&ivec2::x), const ivec2&>);
@@ -128,15 +128,15 @@ TEST_CASE("features/infos/member") {
{
ipnt2 v{1,2};
CHECK(x_mi.get(v).equals(1));
CHECK(x_mi.get(std::as_const(v)).equals(1));
CHECK(x_mi.get(std::move(v)).equals(1));
CHECK(x_mi.get(std::move(std::as_const(v))).equals(1));
CHECK(x_mi.get(v) == 1);
CHECK(x_mi.get(std::as_const(v)) == 1);
CHECK(x_mi.get(std::move(v)) == 1);
CHECK(x_mi.get(std::move(std::as_const(v))) == 1);
CHECK(y_mi.get(v).equals(2));
CHECK(y_mi.get(std::as_const(v)).equals(2));
CHECK(y_mi.get(std::move(v)).equals(2));
CHECK(y_mi.get(std::move(std::as_const(v))).equals(2));
CHECK(y_mi.get(v) == 2);
CHECK(y_mi.get(std::as_const(v)) == 2);
CHECK(y_mi.get(std::move(v)) == 2);
CHECK(y_mi.get(std::move(std::as_const(v))) == 2);
static_assert(std::is_invocable_v<decltype(&ipnt2::x), ipnt2&>);
static_assert(std::is_invocable_v<decltype(&ipnt2::x), const ipnt2&>);

View File

@@ -146,14 +146,14 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(1));
CHECK(mi.invoke(cl).value() == 1);
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(1));
CHECK(mi.invoke(std::move(cl)).value() == 1);
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(1));
CHECK(mi2.invoke(cl).value() == 1);
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(1));
CHECK(mi2.invoke(std::move(cl)).value() == 1);
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -202,14 +202,14 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(2));
CHECK(mi.invoke(cl).value() == 2);
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(2));
CHECK(mi.invoke(std::move(cl)).value() == 2);
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(2));
CHECK(mi2.invoke(cl).value() == 2);
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(2));
CHECK(mi2.invoke(std::move(cl)).value() == 2);
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -258,15 +258,15 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(3));
CHECK(mi.invoke(std::as_const(cl))->equals(3));
CHECK(mi.invoke(std::move(cl))->equals(3));
CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(3));
CHECK(mi.invoke(cl).value() == 3);
CHECK(mi.invoke(std::as_const(cl)).value() == 3);
CHECK(mi.invoke(std::move(cl)).value() == 3);
CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3);
CHECK(mi2.invoke(cl)->equals(3));
CHECK(mi2.invoke(std::as_const(cl))->equals(3));
CHECK(mi2.invoke(std::move(cl))->equals(3));
CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(3));
CHECK(mi2.invoke(cl).value() == 3);
CHECK(mi2.invoke(std::as_const(cl)).value() == 3);
CHECK(mi2.invoke(std::move(cl)).value() == 3);
CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 3);
}
static_assert(std::is_invocable_v<decltype(&clazz::const_method), clazz&>);
@@ -314,15 +314,15 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(4));
CHECK(mi.invoke(std::as_const(cl))->equals(4));
CHECK(mi.invoke(std::move(cl))->equals(4));
CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(4));
CHECK(mi.invoke(cl).value() == 4);
CHECK(mi.invoke(std::as_const(cl)).value() == 4);
CHECK(mi.invoke(std::move(cl)).value() == 4);
CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4);
CHECK(mi2.invoke(cl)->equals(4));
CHECK(mi2.invoke(std::as_const(cl))->equals(4));
CHECK(mi2.invoke(std::move(cl))->equals(4));
CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(4));
CHECK(mi2.invoke(cl).value() == 4);
CHECK(mi2.invoke(std::as_const(cl)).value() == 4);
CHECK(mi2.invoke(std::move(cl)).value() == 4);
CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 4);
}
static_assert(std::is_invocable_v<decltype(&clazz::const_method_noexcept), clazz&>);
@@ -370,12 +370,12 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(5));
CHECK(mi.invoke(cl).value() == 5);
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK_THROWS(mi.invoke(std::move(cl)));
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(5));
CHECK(mi2.invoke(cl).value() == 5);
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK_THROWS(mi2.invoke(std::move(cl)));
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
@@ -426,12 +426,12 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(6));
CHECK(mi.invoke(cl).value() == 6);
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK_THROWS(mi.invoke(std::move(cl)));
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(6));
CHECK(mi2.invoke(cl).value() == 6);
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK_THROWS(mi2.invoke(std::move(cl)));
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
@@ -482,13 +482,13 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(7));
CHECK(mi.invoke(std::as_const(cl))->equals(7));
CHECK(mi.invoke(cl).value() == 7);
CHECK(mi.invoke(std::as_const(cl)).value() == 7);
CHECK_THROWS(mi.invoke(std::move(cl)));
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(7));
CHECK(mi2.invoke(std::as_const(cl))->equals(7));
CHECK(mi2.invoke(cl).value() == 7);
CHECK(mi2.invoke(std::as_const(cl)).value() == 7);
CHECK_THROWS(mi2.invoke(std::move(cl)));
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -538,13 +538,13 @@ TEST_CASE("features/infos/method") {
{
clazz cl;
CHECK(mi.invoke(cl)->equals(8));
CHECK(mi.invoke(std::as_const(cl))->equals(8));
CHECK(mi.invoke(cl).value() == 8);
CHECK(mi.invoke(std::as_const(cl)).value() == 8);
CHECK_THROWS(mi.invoke(std::move(cl)));
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK(mi2.invoke(cl)->equals(8));
CHECK(mi2.invoke(std::as_const(cl))->equals(8));
CHECK(mi2.invoke(cl).value() == 8);
CHECK(mi2.invoke(std::as_const(cl)).value() == 8);
CHECK_THROWS(mi2.invoke(std::move(cl)));
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -596,12 +596,12 @@ TEST_CASE("features/infos/method") {
CHECK_THROWS(mi.invoke(cl));
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(9));
CHECK(mi.invoke(std::move(cl)).value() == 9);
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK_THROWS(mi2.invoke(cl));
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(9));
CHECK(mi2.invoke(std::move(cl)).value() == 9);
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -652,12 +652,12 @@ TEST_CASE("features/infos/method") {
CHECK_THROWS(mi.invoke(cl));
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(10));
CHECK(mi.invoke(std::move(cl)).value() == 10);
CHECK_THROWS(mi.invoke(std::move(std::as_const(cl))));
CHECK_THROWS(mi2.invoke(cl));
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(10));
CHECK(mi2.invoke(std::move(cl)).value() == 10);
CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl))));
}
@@ -708,13 +708,13 @@ TEST_CASE("features/infos/method") {
CHECK_THROWS(mi.invoke(cl));
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(11));
CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(11));
CHECK(mi.invoke(std::move(cl)).value() == 11);
CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11);
CHECK_THROWS(mi2.invoke(cl));
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(11));
CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(11));
CHECK(mi2.invoke(std::move(cl)).value() == 11);
CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 11);
}
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_rref), clazz&>);
@@ -764,13 +764,13 @@ TEST_CASE("features/infos/method") {
CHECK_THROWS(mi.invoke(cl));
CHECK_THROWS(mi.invoke(std::as_const(cl)));
CHECK(mi.invoke(std::move(cl))->equals(12));
CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(12));
CHECK(mi.invoke(std::move(cl)).value() == 12);
CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12);
CHECK_THROWS(mi2.invoke(cl));
CHECK_THROWS(mi2.invoke(std::as_const(cl)));
CHECK(mi2.invoke(std::move(cl))->equals(12));
CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(12));
CHECK(mi2.invoke(std::move(cl)).value() == 12);
CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 12);
}
static_assert(!std::is_invocable_v<decltype(&clazz::const_method_noexcept_rref), clazz&>);

View File

@@ -94,8 +94,8 @@ TEST_CASE("features/utilities/value") {
CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2)));
CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2)));
CHECK(val.equals(ivec2{1,2}));
CHECK(val.equals(value{ivec2{1,2}}));
CHECK(val == ivec2{1,2});
CHECK(val == value{ivec2{1,2}});
CHECK(val.cast<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
@@ -119,8 +119,8 @@ TEST_CASE("features/utilities/value") {
CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2)));
CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2)));
CHECK(val.equals(ivec2{1,2}));
CHECK(val.equals(value{ivec2{1,2}}));
CHECK(val == ivec2{1,2});
CHECK(val == value{ivec2{1,2}});
CHECK(val.cast<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
@@ -138,8 +138,8 @@ TEST_CASE("features/utilities/value") {
CHECK(val.type() == type_db::get<ivec2>());
CHECK(val.equals(ivec2{1,2}));
CHECK(val.equals(value{ivec2{1,2}}));
CHECK(val == ivec2{1,2});
CHECK(val == value{ivec2{1,2}});
CHECK(val.cast<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
@@ -157,8 +157,8 @@ TEST_CASE("features/utilities/value") {
CHECK(val.type() == type_db::get<ivec2>());
CHECK(val.equals(ivec2{1,2}));
CHECK(val.equals(value{ivec2{1,2}}));
CHECK(val == ivec2{1,2});
CHECK(val == value{ivec2{1,2}});
CHECK(val.cast<ivec2>() == ivec2{1,2});
CHECK(std::as_const(val).cast<ivec2>() == ivec2{1,2});
@@ -174,11 +174,11 @@ TEST_CASE("features/utilities/value") {
CHECK(ivec2::copy_ctor_counter == 0);
value val_dst{std::move(val_src)};
CHECK(val_dst.equals(ivec2{1,2}));
CHECK(val_dst == ivec2{1,2});
CHECK(ivec2::move_ctor_counter == 2);
CHECK(ivec2::copy_ctor_counter == 0);
CHECK(val_src.equals(ivec2{0,0}));
CHECK(val_src == ivec2{0,0});
CHECK(val_src.data() != val_dst.data());
}
@@ -189,11 +189,11 @@ TEST_CASE("features/utilities/value") {
CHECK(ivec2::copy_ctor_counter == 1);
value val_dst{val_src};
CHECK(val_dst.equals(ivec2{1,2}));
CHECK(val_dst == ivec2{1,2});
CHECK(ivec2::move_ctor_counter == 0);
CHECK(ivec2::copy_ctor_counter == 2);
CHECK(val_src.equals(ivec2{1,2}));
CHECK(val_src == ivec2{1,2});
CHECK(val_src.data() != val_dst.data());
}
@@ -206,16 +206,16 @@ TEST_CASE("features/utilities/value") {
value val_dst{"hello"s};
val_dst = std::move(val_src1);
CHECK(val_dst.equals("world"s));
CHECK(val_dst == "world"s);
CHECK(ivec2::move_ctor_counter == 1);
CHECK(ivec2::copy_ctor_counter == 0);
val_dst = std::move(val_src2);
CHECK(val_dst.equals(ivec2{1,2}));
CHECK(val_dst == ivec2{1,2});
CHECK(ivec2::move_ctor_counter == 2);
CHECK(ivec2::copy_ctor_counter == 0);
CHECK(val_src2.equals(ivec2{0,0}));
CHECK(val_src2 == ivec2{0,0});
CHECK(val_src2.data() != val_dst.data());
}
@@ -228,16 +228,16 @@ TEST_CASE("features/utilities/value") {
value val_dst{"hello"s};
val_dst = val_src1;
CHECK(val_dst.equals("world"s));
CHECK(val_dst == "world"s);
CHECK(ivec2::move_ctor_counter == 1);
CHECK(ivec2::copy_ctor_counter == 0);
val_dst = val_src2;
CHECK(val_dst.equals(ivec2{1,2}));
CHECK(val_dst == ivec2{1,2});
CHECK(ivec2::move_ctor_counter == 1);
CHECK(ivec2::copy_ctor_counter == 1);
CHECK(val_src2.equals(ivec2{1,2}));
CHECK(val_src2 == ivec2{1,2});
CHECK(val_src2.data() != val_dst.data());
}
@@ -248,20 +248,20 @@ TEST_CASE("features/utilities/value") {
CHECK(ivec2::copy_ctor_counter == 0);
val1.swap(val2);
CHECK(val1.equals(ivec2{1,2}));
CHECK(val2.equals("world"s));
CHECK(val1 == ivec2{1,2});
CHECK(val2 == "world"s);
CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3));
CHECK(ivec2::copy_ctor_counter == 0);
swap(val1, val2);
CHECK(val1.equals("world"s));
CHECK(val2.equals(ivec2{1,2}));
CHECK(val1 == "world"s);
CHECK(val2 == ivec2{1,2});
}
SUBCASE("ostream") {
std::stringstream str_stream;
CHECK_NOTHROW(str_stream << value{21} << " " << value{42});
CHECK_THROWS(str_stream << value{ivec2{1,2}});
CHECK_THROWS((str_stream << value{ivec2{1,2}}));
REQUIRE(str_stream.str() == "21 42");
}
@@ -273,8 +273,24 @@ TEST_CASE("features/utilities/value") {
v = value{0};
CHECK_NOTHROW(str_stream >> v);
CHECK(v.equals(21));
CHECK(v == 21);
CHECK_NOTHROW(str_stream >> v);
CHECK(v.equals(42));
CHECK(v == 42);
}
SUBCASE("operator==") {
CHECK(value{ivec2{1,2}} == ivec2{1,2});
CHECK_FALSE(value{ivec2{1,2}} == ivec2{1,3});
CHECK(ivec2{1,2} == value{ivec2{1,2}});
CHECK_FALSE(ivec2{1,3} == value{ivec2{1,2}});
CHECK(value{ivec2{1,2}} == value{ivec2{1,2}});
CHECK_FALSE(value{ivec2{1,2}} == value{ivec2{1,3}});
class empty_class1 {};
class empty_class2 {};
CHECK_FALSE(value{empty_class1{}} == value{empty_class2{}});
CHECK_THROWS(value{empty_class1{}} == value{empty_class1{}});
}
}