* more on any const and non-const reference support
* poly support for const and non-const references
* poly as_ref overloads
This commit is contained in:
Michele Caini
2020-12-17 13:04:25 +01:00
parent 3a6ecb10a7
commit 2eeb7552d6
4 changed files with 140 additions and 11 deletions

View File

@@ -263,7 +263,7 @@ public:
/*! @copydoc data */
[[nodiscard]] void * data() ENTT_NOEXCEPT {
return const_cast<void *>(std::as_const(*this).data());
return storage.data();
}
/**

View File

@@ -661,17 +661,24 @@ TEST(Any, AsRef) {
ASSERT_EQ(entt::any_cast<int>(any), 42);
ASSERT_EQ(entt::any_cast<int>(ref), 42);
ASSERT_EQ(entt::any_cast<int>(cref), 42);
ASSERT_EQ(entt::any_cast<const int>(any), 42);
ASSERT_EQ(entt::any_cast<const int>(ref), 42);
ASSERT_EQ(entt::any_cast<const int>(cref), 42);
ASSERT_EQ(entt::any_cast<int &>(any), 42);
ASSERT_EQ(entt::any_cast<const int &>(any), 42);
ASSERT_EQ(entt::any_cast<int &>(ref), 42);
ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
ASSERT_DEATH(entt::any_cast<int &>(cref), ".*");
ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
entt::any_cast<int &>(any) = 3;
ASSERT_EQ(entt::any_cast<int>(any), 3);
ASSERT_EQ(entt::any_cast<int>(ref), 3);
ASSERT_EQ(entt::any_cast<const int>(cref), 3);
ASSERT_EQ(entt::any_cast<int>(cref), 3);
std::swap(ref, cref);
@@ -683,12 +690,24 @@ TEST(Any, AsRef) {
ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
ASSERT_DEATH(entt::any_cast<int &>(ref), ".*");
ASSERT_DEATH(entt::any_cast<int &>(cref), ".*");
ASSERT_EQ(entt::any_cast<const int &>(ref), 3);
ASSERT_EQ(entt::any_cast<const int &>(cref), 3);
ref = 42;
cref = 42;
ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
ASSERT_EQ(entt::any_cast<int &>(ref), 42);
ASSERT_EQ(entt::any_cast<int &>(cref), 42);
ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
ASSERT_NE(entt::any_cast<int>(&ref), any.data());
ASSERT_NE(entt::any_cast<int>(&cref), any.data());
}

View File

@@ -11,13 +11,13 @@ struct Deduced: entt::type_list<> {
void set(int v) { entt::poly_call<1>(*this, v); }
int get() const { return entt::poly_call<2>(*this); }
void decr() { entt::poly_call<3>(*this); }
int mul(int v) { return entt::poly_call<4>(*this, v); }
int mul(int v) const { return entt::poly_call<4>(*this, v); }
};
template<typename Type>
struct members {
static void decr(Type &self) { self.set(self.get()-1); }
static double mul(Type &self, double v) { return v * self.get(); }
static double mul(const Type &self, double v) { return v * self.get(); }
};
template<typename Type>
@@ -35,7 +35,7 @@ struct impl {
void set(int v) { value = v; }
int get() const { return value; }
void decrement() { --value; }
double multiply(double v) { return v * value; }
double multiply(double v) const { return v * value; }
int value{};
};
@@ -123,7 +123,7 @@ TEST(PolyDeduced, Owned) {
ASSERT_EQ(poly->mul(3), 3);
}
TEST(PolyDeduced, Alias) {
TEST(PolyDeduced, Reference) {
impl instance{};
entt::poly<Deduced> poly{std::ref(instance)};
@@ -146,3 +146,58 @@ TEST(PolyDeduced, Alias) {
ASSERT_EQ(poly->get(), 1);
ASSERT_EQ(poly->mul(3), 3);
}
TEST(PolyDeduced, ConstReference) {
impl instance{};
entt::poly<Deduced> poly{std::cref(instance)};
ASSERT_TRUE(poly);
ASSERT_EQ(poly.data(), nullptr);
ASSERT_NE(std::as_const(poly).data(), nullptr);
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_DEATH(poly->set(1), ".*");
ASSERT_DEATH(poly->incr(), ".*");
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_EQ(poly->mul(3), 0);
ASSERT_DEATH(poly->decr(), ".*");
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_EQ(poly->mul(3), 0);
}
TEST(PolyDeduced, AsRef) {
entt::poly<Deduced> poly{impl{}};
auto ref = as_ref(poly);
auto cref = as_ref(std::as_const(poly));
ASSERT_NE(poly.data(), nullptr);
ASSERT_NE(ref.data(), nullptr);
ASSERT_EQ(cref.data(), nullptr);
ASSERT_NE(std::as_const(cref).data(), nullptr);
std::swap(ref, cref);
ASSERT_EQ(ref.data(), nullptr);
ASSERT_NE(std::as_const(ref).data(), nullptr);
ASSERT_NE(cref.data(), nullptr);
ref = as_ref(ref);
cref = as_ref(std::as_const(cref));
ASSERT_EQ(ref.data(), nullptr);
ASSERT_NE(std::as_const(ref).data(), nullptr);
ASSERT_EQ(cref.data(), nullptr);
ASSERT_NE(std::as_const(cref).data(), nullptr);
ref = impl{};
cref = impl{};
ASSERT_NE(ref.data(), nullptr);
ASSERT_NE(cref.data(), nullptr);
}

View File

@@ -9,7 +9,7 @@ struct Defined: entt::type_list<
void(int),
int() const,
void(),
int(int)
int(int) const
> {
template<typename Base>
struct type: Base {
@@ -17,13 +17,13 @@ struct Defined: entt::type_list<
void set(int v) { entt::poly_call<1>(*this, v); }
int get() const { return entt::poly_call<2>(*this); }
void decr() { entt::poly_call<3>(*this); }
int mul(int v) { return entt::poly_call<4>(*this, v); }
int mul(int v) const { return entt::poly_call<4>(*this, v); }
};
template<typename Type>
struct members {
static void decr(Type &self) { self.decrement(); }
static double mul(Type &self, double v) { return self.multiply(v); }
static double mul(const Type &self, double v) { return self.multiply(v); }
};
template<typename Type>
@@ -41,7 +41,7 @@ struct impl {
void set(int v) { value = v; }
int get() const { return value; }
void decrement() { --value; }
double multiply(double v) { return v * value; }
double multiply(double v) const { return v * value; }
int value{};
};
@@ -129,7 +129,7 @@ TEST(PolyDefined, Owned) {
ASSERT_EQ(poly->mul(3), 3);
}
TEST(PolyDefined, Alias) {
TEST(PolyDefined, Reference) {
impl instance{};
entt::poly<Defined> poly{std::ref(instance)};
@@ -152,3 +152,58 @@ TEST(PolyDefined, Alias) {
ASSERT_EQ(poly->get(), 1);
ASSERT_EQ(poly->mul(3), 3);
}
TEST(PolyDefined, ConstReference) {
impl instance{};
entt::poly<Defined> poly{std::cref(instance)};
ASSERT_TRUE(poly);
ASSERT_EQ(poly.data(), nullptr);
ASSERT_NE(std::as_const(poly).data(), nullptr);
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_DEATH(poly->set(1), ".*");
ASSERT_DEATH(poly->incr(), ".*");
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_EQ(poly->mul(3), 0);
ASSERT_DEATH(poly->decr(), ".*");
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(poly->get(), 0);
ASSERT_EQ(poly->mul(3), 0);
}
TEST(PolyDefined, AsRef) {
entt::poly<Defined> poly{impl{}};
auto ref = as_ref(poly);
auto cref = as_ref(std::as_const(poly));
ASSERT_NE(poly.data(), nullptr);
ASSERT_NE(ref.data(), nullptr);
ASSERT_EQ(cref.data(), nullptr);
ASSERT_NE(std::as_const(cref).data(), nullptr);
std::swap(ref, cref);
ASSERT_EQ(ref.data(), nullptr);
ASSERT_NE(std::as_const(ref).data(), nullptr);
ASSERT_NE(cref.data(), nullptr);
ref = as_ref(ref);
cref = as_ref(std::as_const(cref));
ASSERT_EQ(ref.data(), nullptr);
ASSERT_NE(std::as_const(ref).data(), nullptr);
ASSERT_EQ(cref.data(), nullptr);
ASSERT_NE(std::as_const(cref).data(), nullptr);
ref = impl{};
cref = impl{};
ASSERT_NE(ref.data(), nullptr);
ASSERT_NE(cref.data(), nullptr);
}