Squashed 'external/entt/entt/' content from commit fef92113
git-subtree-dir: external/entt/entt git-subtree-split: fef921132cae7588213d0f9bcd2fb9c8ffd8b7fc
This commit is contained in:
98
test/entt/core/algorithm.cpp
Normal file
98
test/entt/core/algorithm.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/algorithm.hpp>
|
||||
|
||||
struct boxed_int {
|
||||
int value;
|
||||
};
|
||||
|
||||
TEST(Algorithm, StdSort) {
|
||||
// well, I'm pretty sure it works, it's std::sort!!
|
||||
std::array<int, 5> arr{{4, 1, 3, 2, 0}};
|
||||
entt::std_sort sort;
|
||||
|
||||
sort(arr.begin(), arr.end());
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i + 1u]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, StdSortBoxedInt) {
|
||||
// well, I'm pretty sure it works, it's std::sort!!
|
||||
std::array<boxed_int, 6> arr{{{4}, {1}, {3}, {2}, {0}, {6}}};
|
||||
entt::std_sort sort;
|
||||
|
||||
sort(arr.begin(), arr.end(), [](const auto &lhs, const auto &rhs) {
|
||||
return lhs.value > rhs.value;
|
||||
});
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_GT(arr[i].value, arr[i + 1u].value);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, InsertionSort) {
|
||||
std::array<int, 5> arr{{4, 1, 3, 2, 0}};
|
||||
entt::insertion_sort sort;
|
||||
|
||||
sort(arr.begin(), arr.end());
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i + 1u]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, InsertionSortBoxedInt) {
|
||||
std::array<boxed_int, 6> arr{{{4}, {1}, {3}, {2}, {0}, {6}}};
|
||||
entt::insertion_sort sort;
|
||||
|
||||
sort(arr.begin(), arr.end(), [](const auto &lhs, const auto &rhs) {
|
||||
return lhs.value > rhs.value;
|
||||
});
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_GT(arr[i].value, arr[i + 1u].value);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, InsertionSortEmptyContainer) {
|
||||
std::vector<int> vec{};
|
||||
entt::insertion_sort sort;
|
||||
// this should crash with asan enabled if we break the constraint
|
||||
sort(vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
TEST(Algorithm, RadixSort) {
|
||||
std::array<uint32_t, 5> arr{{4, 1, 3, 2, 0}};
|
||||
entt::radix_sort<8, 32> sort;
|
||||
|
||||
sort(arr.begin(), arr.end(), [](const auto &value) {
|
||||
return value;
|
||||
});
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_LT(arr[i], arr[i + 1u]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, RadixSortBoxedInt) {
|
||||
std::array<boxed_int, 6> arr{{{4}, {1}, {3}, {2}, {0}, {6}}};
|
||||
entt::radix_sort<2, 6> sort;
|
||||
|
||||
sort(arr.rbegin(), arr.rend(), [](const auto &instance) {
|
||||
return instance.value;
|
||||
});
|
||||
|
||||
for(auto i = 0u; i < (arr.size() - 1u); ++i) {
|
||||
ASSERT_GT(arr[i].value, arr[i + 1u].value);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Algorithm, RadixSortEmptyContainer) {
|
||||
std::vector<int> vec{};
|
||||
entt::radix_sort<8, 32> sort;
|
||||
// this should crash with asan enabled if we break the constraint
|
||||
sort(vec.begin(), vec.end());
|
||||
}
|
1466
test/entt/core/any.cpp
Normal file
1466
test/entt/core/any.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
test/entt/core/compressed_pair.cpp
Normal file
182
test/entt/core/compressed_pair.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/compressed_pair.hpp>
|
||||
|
||||
struct empty_type {};
|
||||
|
||||
struct move_only_type {
|
||||
move_only_type()
|
||||
: value{new int{99}} {}
|
||||
|
||||
move_only_type(int v)
|
||||
: value{new int{v}} {}
|
||||
|
||||
~move_only_type() {
|
||||
delete value;
|
||||
}
|
||||
|
||||
move_only_type(const move_only_type &) = delete;
|
||||
move_only_type &operator=(const move_only_type &) = delete;
|
||||
|
||||
move_only_type(move_only_type &&other) noexcept
|
||||
: value{std::exchange(other.value, nullptr)} {}
|
||||
|
||||
move_only_type &operator=(move_only_type &&other) noexcept {
|
||||
delete value;
|
||||
value = std::exchange(other.value, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int *value;
|
||||
};
|
||||
|
||||
struct non_default_constructible {
|
||||
non_default_constructible(int v)
|
||||
: value{v} {}
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
TEST(CompressedPair, Size) {
|
||||
struct local {
|
||||
int value;
|
||||
empty_type empty;
|
||||
};
|
||||
|
||||
static_assert(sizeof(entt::compressed_pair<int, int>) == sizeof(int[2u]));
|
||||
static_assert(sizeof(entt::compressed_pair<empty_type, int>) == sizeof(int));
|
||||
static_assert(sizeof(entt::compressed_pair<int, empty_type>) == sizeof(int));
|
||||
static_assert(sizeof(entt::compressed_pair<int, empty_type>) < sizeof(local));
|
||||
static_assert(sizeof(entt::compressed_pair<int, empty_type>) < sizeof(std::pair<int, empty_type>));
|
||||
}
|
||||
|
||||
TEST(CompressedPair, ConstructCopyMove) {
|
||||
static_assert(!std::is_default_constructible_v<entt::compressed_pair<non_default_constructible, empty_type>>);
|
||||
static_assert(std::is_default_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
|
||||
|
||||
static_assert(std::is_copy_constructible_v<entt::compressed_pair<non_default_constructible, empty_type>>);
|
||||
static_assert(!std::is_copy_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
|
||||
static_assert(std::is_copy_assignable_v<entt::compressed_pair<non_default_constructible, empty_type>>);
|
||||
static_assert(!std::is_copy_assignable_v<entt::compressed_pair<move_only_type, empty_type>>);
|
||||
|
||||
static_assert(std::is_move_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
|
||||
static_assert(std::is_move_assignable_v<entt::compressed_pair<move_only_type, empty_type>>);
|
||||
|
||||
entt::compressed_pair copyable{non_default_constructible{42}, empty_type{}};
|
||||
auto by_copy{copyable};
|
||||
|
||||
ASSERT_EQ(by_copy.first().value, 42);
|
||||
|
||||
by_copy.first().value = 3;
|
||||
copyable = by_copy;
|
||||
|
||||
ASSERT_EQ(copyable.first().value, 3);
|
||||
|
||||
entt::compressed_pair<empty_type, move_only_type> movable{};
|
||||
auto by_move{std::move(movable)};
|
||||
|
||||
ASSERT_EQ(*by_move.second().value, 99);
|
||||
ASSERT_EQ(movable.second().value, nullptr);
|
||||
|
||||
*by_move.second().value = 3;
|
||||
movable = std::move(by_move);
|
||||
|
||||
ASSERT_EQ(*movable.second().value, 3);
|
||||
ASSERT_EQ(by_move.second().value, nullptr);
|
||||
}
|
||||
|
||||
TEST(CompressedPair, PiecewiseConstruct) {
|
||||
std::vector<int> vec{42};
|
||||
entt::compressed_pair<empty_type, empty_type> empty{std::piecewise_construct, std::make_tuple(), std::make_tuple()};
|
||||
entt::compressed_pair<std::vector<int>, std::size_t> pair{std::piecewise_construct, std::forward_as_tuple(std::move(vec)), std::make_tuple(sizeof(empty))};
|
||||
|
||||
ASSERT_EQ(pair.first().size(), 1u);
|
||||
ASSERT_EQ(pair.second(), sizeof(empty));
|
||||
ASSERT_EQ(vec.size(), 0u);
|
||||
}
|
||||
|
||||
TEST(CompressedPair, DeductionGuide) {
|
||||
int value = 42;
|
||||
empty_type empty{};
|
||||
entt::compressed_pair pair{value, 3};
|
||||
|
||||
static_assert(std::is_same_v<decltype(entt::compressed_pair{empty_type{}, empty}), entt::compressed_pair<empty_type, empty_type>>);
|
||||
|
||||
ASSERT_TRUE((std::is_same_v<decltype(pair), entt::compressed_pair<int, int>>));
|
||||
ASSERT_EQ(pair.first(), 42);
|
||||
ASSERT_EQ(pair.second(), 3);
|
||||
}
|
||||
|
||||
TEST(CompressedPair, Getters) {
|
||||
entt::compressed_pair pair{3, empty_type{}};
|
||||
const auto &cpair = pair;
|
||||
|
||||
static_assert(std::is_same_v<decltype(pair.first()), int &>);
|
||||
static_assert(std::is_same_v<decltype(pair.second()), empty_type &>);
|
||||
|
||||
static_assert(std::is_same_v<decltype(cpair.first()), const int &>);
|
||||
static_assert(std::is_same_v<decltype(cpair.second()), const empty_type &>);
|
||||
|
||||
ASSERT_EQ(pair.first(), cpair.first());
|
||||
ASSERT_EQ(&pair.second(), &cpair.second());
|
||||
}
|
||||
|
||||
TEST(CompressedPair, Swap) {
|
||||
entt::compressed_pair pair{1, 2};
|
||||
entt::compressed_pair other{3, 4};
|
||||
|
||||
swap(pair, other);
|
||||
|
||||
ASSERT_EQ(pair.first(), 3);
|
||||
ASSERT_EQ(pair.second(), 4);
|
||||
ASSERT_EQ(other.first(), 1);
|
||||
ASSERT_EQ(other.second(), 2);
|
||||
|
||||
pair.swap(other);
|
||||
|
||||
ASSERT_EQ(pair.first(), 1);
|
||||
ASSERT_EQ(pair.second(), 2);
|
||||
ASSERT_EQ(other.first(), 3);
|
||||
ASSERT_EQ(other.second(), 4);
|
||||
}
|
||||
|
||||
TEST(CompressedPair, Get) {
|
||||
entt::compressed_pair pair{1, 2};
|
||||
|
||||
ASSERT_EQ(pair.get<0>(), 1);
|
||||
ASSERT_EQ(pair.get<1>(), 2);
|
||||
|
||||
ASSERT_EQ(&pair.get<0>(), &pair.first());
|
||||
ASSERT_EQ(&pair.get<1>(), &pair.second());
|
||||
|
||||
auto &&[first, second] = pair;
|
||||
|
||||
ASSERT_EQ(first, 1);
|
||||
ASSERT_EQ(second, 2);
|
||||
|
||||
first = 3;
|
||||
second = 4;
|
||||
|
||||
ASSERT_EQ(pair.first(), 3);
|
||||
ASSERT_EQ(pair.second(), 4);
|
||||
|
||||
auto &[cfirst, csecond] = std::as_const(pair);
|
||||
|
||||
ASSERT_EQ(cfirst, 3);
|
||||
ASSERT_EQ(csecond, 4);
|
||||
|
||||
static_assert(std::is_same_v<decltype(cfirst), const int>);
|
||||
static_assert(std::is_same_v<decltype(csecond), const int>);
|
||||
|
||||
auto [tfirst, tsecond] = entt::compressed_pair{9, 99};
|
||||
|
||||
ASSERT_EQ(tfirst, 9);
|
||||
ASSERT_EQ(tsecond, 99);
|
||||
|
||||
static_assert(std::is_same_v<decltype(cfirst), const int>);
|
||||
static_assert(std::is_same_v<decltype(csecond), const int>);
|
||||
}
|
72
test/entt/core/enum.cpp
Normal file
72
test/entt/core/enum.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/enum.hpp>
|
||||
|
||||
enum class detected {
|
||||
foo = 0x01,
|
||||
bar = 0x02,
|
||||
quux = 0x04,
|
||||
_entt_enum_as_bitmask
|
||||
};
|
||||
|
||||
// small type on purpose
|
||||
enum class registered : std::uint8_t {
|
||||
foo = 0x01,
|
||||
bar = 0x02,
|
||||
quux = 0x04
|
||||
};
|
||||
|
||||
template<>
|
||||
struct entt::enum_as_bitmask<registered>
|
||||
: std::true_type {};
|
||||
|
||||
template<typename Type>
|
||||
struct Enum: testing::Test {
|
||||
using type = Type;
|
||||
};
|
||||
|
||||
using EnumTypes = ::testing::Types<detected, registered>;
|
||||
|
||||
TYPED_TEST_SUITE(Enum, EnumTypes, );
|
||||
|
||||
TYPED_TEST(Enum, Functionalities) {
|
||||
using enum_type = typename TestFixture::type;
|
||||
|
||||
ASSERT_TRUE(!!((enum_type::foo | enum_type::bar) & enum_type::foo));
|
||||
ASSERT_TRUE(!!((enum_type::foo | enum_type::bar) & enum_type::bar));
|
||||
ASSERT_TRUE(!((enum_type::foo | enum_type::bar) & enum_type::quux));
|
||||
|
||||
ASSERT_TRUE(!!((enum_type::foo ^ enum_type::bar) & enum_type::foo));
|
||||
ASSERT_TRUE(!((enum_type::foo ^ enum_type::foo) & enum_type::foo));
|
||||
|
||||
ASSERT_TRUE(!(~enum_type::foo & enum_type::foo));
|
||||
ASSERT_TRUE(!!(~enum_type::foo & enum_type::bar));
|
||||
|
||||
ASSERT_TRUE(enum_type::foo == enum_type::foo);
|
||||
ASSERT_TRUE(enum_type::foo != enum_type::bar);
|
||||
|
||||
enum_type value = enum_type::foo;
|
||||
|
||||
ASSERT_TRUE(!!(value & enum_type::foo));
|
||||
ASSERT_TRUE(!(value & enum_type::bar));
|
||||
ASSERT_TRUE(!(value & enum_type::quux));
|
||||
|
||||
value |= (enum_type::bar | enum_type::quux);
|
||||
|
||||
ASSERT_TRUE(!!(value & enum_type::foo));
|
||||
ASSERT_TRUE(!!(value & enum_type::bar));
|
||||
ASSERT_TRUE(!!(value & enum_type::quux));
|
||||
|
||||
value &= (enum_type::bar | enum_type::quux);
|
||||
|
||||
ASSERT_TRUE(!(value & enum_type::foo));
|
||||
ASSERT_TRUE(!!(value & enum_type::bar));
|
||||
ASSERT_TRUE(!!(value & enum_type::quux));
|
||||
|
||||
value ^= enum_type::bar;
|
||||
|
||||
ASSERT_TRUE(!(value & enum_type::foo));
|
||||
ASSERT_TRUE(!(value & enum_type::bar));
|
||||
ASSERT_TRUE(!!(value & enum_type::quux));
|
||||
}
|
22
test/entt/core/family.cpp
Normal file
22
test/entt/core/family.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/family.hpp>
|
||||
|
||||
using a_family = entt::family<struct a_family_type>;
|
||||
using another_family = entt::family<struct another_family_type>;
|
||||
|
||||
TEST(Family, Functionalities) {
|
||||
auto t1 = a_family::value<int>;
|
||||
auto t2 = a_family::value<int>;
|
||||
auto t3 = a_family::value<char>;
|
||||
auto t4 = another_family::value<double>;
|
||||
|
||||
ASSERT_EQ(t1, t2);
|
||||
ASSERT_NE(t1, t3);
|
||||
ASSERT_EQ(t1, t4);
|
||||
}
|
||||
|
||||
TEST(Family, Uniqueness) {
|
||||
ASSERT_NE(a_family::value<int>, a_family::value<int &>);
|
||||
ASSERT_NE(a_family::value<int>, a_family::value<int &&>);
|
||||
ASSERT_NE(a_family::value<int>, a_family::value<const int &>);
|
||||
}
|
224
test/entt/core/hashed_string.cpp
Normal file
224
test/entt/core/hashed_string.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
|
||||
template<typename>
|
||||
struct foobar_t;
|
||||
|
||||
template<>
|
||||
struct foobar_t<std::uint32_t> {
|
||||
static constexpr auto value = 0xbf9cf968;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct foobar_t<std::uint64_t> {
|
||||
static constexpr auto value = 0x85944171f73967e8;
|
||||
};
|
||||
|
||||
inline constexpr auto foobar_v = foobar_t<entt::id_type>::value;
|
||||
|
||||
TEST(BasicHashedString, DeductionGuide) {
|
||||
static_assert(std::is_same_v<decltype(entt::basic_hashed_string{"foo"}), entt::hashed_string>);
|
||||
static_assert(std::is_same_v<decltype(entt::basic_hashed_string{L"foo"}), entt::hashed_wstring>);
|
||||
}
|
||||
|
||||
TEST(HashedString, Functionalities) {
|
||||
using namespace entt::literals;
|
||||
using hash_type = entt::hashed_string::hash_type;
|
||||
|
||||
const char *bar = "bar";
|
||||
|
||||
auto foo_hs = entt::hashed_string{"foo"};
|
||||
auto bar_hs = entt::hashed_string{bar};
|
||||
|
||||
ASSERT_NE(static_cast<hash_type>(foo_hs), static_cast<hash_type>(bar_hs));
|
||||
ASSERT_STREQ(static_cast<const char *>(foo_hs), "foo");
|
||||
ASSERT_STREQ(static_cast<const char *>(bar_hs), bar);
|
||||
ASSERT_STREQ(foo_hs.data(), "foo");
|
||||
ASSERT_STREQ(bar_hs.data(), bar);
|
||||
ASSERT_EQ(foo_hs.size(), 3u);
|
||||
ASSERT_EQ(bar_hs.size(), 3u);
|
||||
|
||||
ASSERT_EQ(foo_hs, foo_hs);
|
||||
ASSERT_NE(foo_hs, bar_hs);
|
||||
|
||||
entt::hashed_string hs{"foobar"};
|
||||
|
||||
ASSERT_EQ(static_cast<hash_type>(hs), foobar_v);
|
||||
ASSERT_EQ(hs.value(), foobar_v);
|
||||
|
||||
ASSERT_EQ(foo_hs, "foo"_hs);
|
||||
ASSERT_NE(bar_hs, "foo"_hs);
|
||||
|
||||
entt::hashed_string empty_hs{};
|
||||
|
||||
ASSERT_EQ(empty_hs, entt::hashed_string{});
|
||||
ASSERT_NE(empty_hs, foo_hs);
|
||||
|
||||
empty_hs = foo_hs;
|
||||
|
||||
ASSERT_NE(empty_hs, entt::hashed_string{});
|
||||
ASSERT_EQ(empty_hs, foo_hs);
|
||||
}
|
||||
|
||||
TEST(HashedString, Empty) {
|
||||
using hash_type = entt::hashed_string::hash_type;
|
||||
|
||||
entt::hashed_string hs{};
|
||||
|
||||
ASSERT_EQ(hs.size(), 0u);
|
||||
ASSERT_EQ(static_cast<hash_type>(hs), hash_type{});
|
||||
ASSERT_EQ(static_cast<const char *>(hs), nullptr);
|
||||
}
|
||||
|
||||
TEST(HashedString, Correctness) {
|
||||
const char *foobar = "foobar";
|
||||
std::string_view view{"foobar__", 6};
|
||||
|
||||
ASSERT_EQ(entt::hashed_string{foobar}, foobar_v);
|
||||
ASSERT_EQ((entt::hashed_string{view.data(), view.size()}), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_string{"foobar"}, foobar_v);
|
||||
|
||||
ASSERT_EQ(entt::hashed_string::value(foobar), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_string::value(view.data(), view.size()), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_string::value("foobar"), foobar_v);
|
||||
|
||||
ASSERT_EQ(entt::hashed_string{foobar}.size(), 6u);
|
||||
ASSERT_EQ((entt::hashed_string{view.data(), view.size()}).size(), 6u);
|
||||
ASSERT_EQ(entt::hashed_string{"foobar"}.size(), 6u);
|
||||
}
|
||||
|
||||
TEST(HashedString, Order) {
|
||||
using namespace entt::literals;
|
||||
const entt::hashed_string lhs = "foo"_hs;
|
||||
const entt::hashed_string rhs = "bar"_hs;
|
||||
|
||||
ASSERT_FALSE(lhs < lhs);
|
||||
ASSERT_FALSE(rhs < rhs);
|
||||
|
||||
ASSERT_LT(rhs, lhs);
|
||||
ASSERT_LE(rhs, lhs);
|
||||
|
||||
ASSERT_GT(lhs, rhs);
|
||||
ASSERT_GE(lhs, rhs);
|
||||
}
|
||||
|
||||
TEST(HashedString, Constexprness) {
|
||||
using namespace entt::literals;
|
||||
constexpr std::string_view view{"foobar__", 6};
|
||||
|
||||
static_assert(entt::hashed_string{"quux"} == "quux"_hs);
|
||||
static_assert(entt::hashed_string{"foobar"} == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_string::value("quux") == "quux"_hs);
|
||||
static_assert(entt::hashed_string::value("foobar") == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_string{"quux", 4} == "quux"_hs);
|
||||
static_assert(entt::hashed_string{view.data(), view.size()} == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_string::value("quux", 4) == "quux"_hs);
|
||||
static_assert(entt::hashed_string::value(view.data(), view.size()) == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_string{"bar"} < "foo"_hs);
|
||||
static_assert(entt::hashed_string{"bar"} <= "bar"_hs);
|
||||
|
||||
static_assert(entt::hashed_string{"foo"} > "bar"_hs);
|
||||
static_assert(entt::hashed_string{"foo"} >= "foo"_hs);
|
||||
}
|
||||
|
||||
TEST(HashedWString, Functionalities) {
|
||||
using namespace entt::literals;
|
||||
using hash_type = entt::hashed_wstring::hash_type;
|
||||
|
||||
const wchar_t *bar = L"bar";
|
||||
|
||||
auto foo_hws = entt::hashed_wstring{L"foo"};
|
||||
auto bar_hws = entt::hashed_wstring{bar};
|
||||
|
||||
ASSERT_NE(static_cast<hash_type>(foo_hws), static_cast<hash_type>(bar_hws));
|
||||
ASSERT_STREQ(static_cast<const wchar_t *>(foo_hws), L"foo");
|
||||
ASSERT_STREQ(static_cast<const wchar_t *>(bar_hws), bar);
|
||||
ASSERT_STREQ(foo_hws.data(), L"foo");
|
||||
ASSERT_STREQ(bar_hws.data(), bar);
|
||||
ASSERT_EQ(foo_hws.size(), 3u);
|
||||
ASSERT_EQ(bar_hws.size(), 3u);
|
||||
|
||||
ASSERT_EQ(foo_hws, foo_hws);
|
||||
ASSERT_NE(foo_hws, bar_hws);
|
||||
|
||||
entt::hashed_wstring hws{L"foobar"};
|
||||
|
||||
ASSERT_EQ(static_cast<hash_type>(hws), foobar_v);
|
||||
ASSERT_EQ(hws.value(), foobar_v);
|
||||
|
||||
ASSERT_EQ(foo_hws, L"foo"_hws);
|
||||
ASSERT_NE(bar_hws, L"foo"_hws);
|
||||
}
|
||||
|
||||
TEST(HashedWString, Empty) {
|
||||
using hash_type = entt::hashed_wstring::hash_type;
|
||||
|
||||
entt::hashed_wstring hws{};
|
||||
|
||||
ASSERT_EQ(hws.size(), 0u);
|
||||
ASSERT_EQ(static_cast<hash_type>(hws), hash_type{});
|
||||
ASSERT_EQ(static_cast<const wchar_t *>(hws), nullptr);
|
||||
}
|
||||
|
||||
TEST(HashedWString, Correctness) {
|
||||
const wchar_t *foobar = L"foobar";
|
||||
std::wstring_view view{L"foobar__", 6};
|
||||
|
||||
ASSERT_EQ(entt::hashed_wstring{foobar}, foobar_v);
|
||||
ASSERT_EQ((entt::hashed_wstring{view.data(), view.size()}), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_wstring{L"foobar"}, foobar_v);
|
||||
|
||||
ASSERT_EQ(entt::hashed_wstring::value(foobar), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_wstring::value(view.data(), view.size()), foobar_v);
|
||||
ASSERT_EQ(entt::hashed_wstring::value(L"foobar"), foobar_v);
|
||||
|
||||
ASSERT_EQ(entt::hashed_wstring{foobar}.size(), 6u);
|
||||
ASSERT_EQ((entt::hashed_wstring{view.data(), view.size()}).size(), 6u);
|
||||
ASSERT_EQ(entt::hashed_wstring{L"foobar"}.size(), 6u);
|
||||
}
|
||||
|
||||
TEST(HashedWString, Order) {
|
||||
using namespace entt::literals;
|
||||
const entt::hashed_wstring lhs = L"foo"_hws;
|
||||
const entt::hashed_wstring rhs = L"bar"_hws;
|
||||
|
||||
ASSERT_FALSE(lhs < lhs);
|
||||
ASSERT_FALSE(rhs < rhs);
|
||||
|
||||
ASSERT_LT(rhs, lhs);
|
||||
ASSERT_LE(rhs, lhs);
|
||||
|
||||
ASSERT_GT(lhs, rhs);
|
||||
ASSERT_GE(lhs, rhs);
|
||||
}
|
||||
|
||||
TEST(HashedWString, Constexprness) {
|
||||
using namespace entt::literals;
|
||||
constexpr std::wstring_view view{L"foobar__", 6};
|
||||
|
||||
static_assert(entt::hashed_wstring{L"quux"} == L"quux"_hws);
|
||||
static_assert(entt::hashed_wstring{L"foobar"} == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_wstring::value(L"quux") == L"quux"_hws);
|
||||
static_assert(entt::hashed_wstring::value(L"foobar") == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_wstring{L"quux", 4} == L"quux"_hws);
|
||||
static_assert(entt::hashed_wstring{view.data(), view.size()} == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_wstring::value(L"quux", 4) == L"quux"_hws);
|
||||
static_assert(entt::hashed_wstring::value(view.data(), view.size()) == foobar_v);
|
||||
|
||||
static_assert(entt::hashed_wstring{L"bar"} < L"foo"_hws);
|
||||
static_assert(entt::hashed_wstring{L"bar"} <= L"bar"_hws);
|
||||
|
||||
static_assert(entt::hashed_wstring{L"foo"} > L"bar"_hws);
|
||||
static_assert(entt::hashed_wstring{L"foo"} >= L"foo"_hws);
|
||||
}
|
31
test/entt/core/ident.cpp
Normal file
31
test/entt/core/ident.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include <type_traits>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/ident.hpp>
|
||||
|
||||
struct a_type {};
|
||||
struct another_type {};
|
||||
|
||||
TEST(Ident, Uniqueness) {
|
||||
using id = entt::ident<a_type, another_type>;
|
||||
constexpr a_type an_instance;
|
||||
constexpr another_type another_instance;
|
||||
|
||||
ASSERT_NE(id::value<a_type>, id::value<another_type>);
|
||||
ASSERT_EQ(id::value<a_type>, id::value<decltype(an_instance)>);
|
||||
ASSERT_NE(id::value<a_type>, id::value<decltype(another_instance)>);
|
||||
ASSERT_EQ(id::value<a_type>, id::value<a_type>);
|
||||
ASSERT_EQ(id::value<another_type>, id::value<another_type>);
|
||||
|
||||
// test uses in constant expressions
|
||||
switch(id::value<another_type>) {
|
||||
case id::value<a_type>:
|
||||
FAIL();
|
||||
case id::value<another_type>:
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Identifier, SingleType) {
|
||||
using id = entt::ident<a_type>;
|
||||
[[maybe_unused]] std::integral_constant<id::value_type, id::value<a_type>> ic;
|
||||
}
|
55
test/entt/core/iterator.cpp
Normal file
55
test/entt/core/iterator.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/iterator.hpp>
|
||||
|
||||
struct clazz {
|
||||
int value{0};
|
||||
};
|
||||
|
||||
TEST(InputIteratorPointer, Functionalities) {
|
||||
clazz instance{};
|
||||
entt::input_iterator_pointer ptr{std::move(instance)};
|
||||
ptr->value = 42;
|
||||
|
||||
ASSERT_EQ(instance.value, 0);
|
||||
ASSERT_EQ(ptr->value, 42);
|
||||
ASSERT_EQ(ptr->value, (*ptr).value);
|
||||
ASSERT_EQ(ptr.operator->(), &ptr.operator*());
|
||||
}
|
||||
|
||||
TEST(IotaIterator, Functionalities) {
|
||||
entt::iota_iterator<std::size_t> first{};
|
||||
const entt::iota_iterator<std::size_t> last{2u};
|
||||
|
||||
ASSERT_NE(first, last);
|
||||
ASSERT_FALSE(first == last);
|
||||
ASSERT_TRUE(first != last);
|
||||
|
||||
ASSERT_EQ(*first++, 0u);
|
||||
ASSERT_EQ(*first, 1u);
|
||||
ASSERT_EQ(*++first, *last);
|
||||
ASSERT_EQ(*first, 2u);
|
||||
}
|
||||
|
||||
TEST(IterableAdaptor, Functionalities) {
|
||||
std::vector<int> vec{1, 2};
|
||||
entt::iterable_adaptor iterable{vec.begin(), vec.end()};
|
||||
decltype(iterable) other{};
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(other = iterable);
|
||||
ASSERT_NO_FATAL_FAILURE(std::swap(other, iterable));
|
||||
|
||||
ASSERT_EQ(iterable.begin(), vec.begin());
|
||||
ASSERT_EQ(iterable.end(), vec.end());
|
||||
|
||||
ASSERT_EQ(*iterable.cbegin(), 1);
|
||||
ASSERT_EQ(*++iterable.cbegin(), 2);
|
||||
ASSERT_EQ(++iterable.cbegin(), --iterable.end());
|
||||
|
||||
for(auto value: entt::iterable_adaptor<const int *, const void *>{vec.data(), vec.data() + 1u}) {
|
||||
ASSERT_EQ(value, 1);
|
||||
}
|
||||
}
|
241
test/entt/core/memory.cpp
Normal file
241
test/entt/core/memory.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/memory.hpp>
|
||||
#include "../common/basic_test_allocator.hpp"
|
||||
#include "../common/config.h"
|
||||
#include "../common/throwing_allocator.hpp"
|
||||
#include "../common/throwing_type.hpp"
|
||||
#include "../common/tracked_memory_resource.hpp"
|
||||
|
||||
TEST(ToAddress, Functionalities) {
|
||||
std::shared_ptr<int> shared = std::make_shared<int>();
|
||||
auto *plain = std::addressof(*shared);
|
||||
|
||||
ASSERT_EQ(entt::to_address(shared), plain);
|
||||
ASSERT_EQ(entt::to_address(plain), plain);
|
||||
}
|
||||
|
||||
TEST(PoccaPocmaAndPocs, Functionalities) {
|
||||
test::basic_test_allocator<int> lhs, rhs;
|
||||
// honestly, I don't even know how one is supposed to test such a thing :)
|
||||
entt::propagate_on_container_copy_assignment(lhs, rhs);
|
||||
entt::propagate_on_container_move_assignment(lhs, rhs);
|
||||
entt::propagate_on_container_swap(lhs, rhs);
|
||||
}
|
||||
|
||||
ENTT_DEBUG_TEST(PoccaPocmaAndPocsDeathTest, Functionalities) {
|
||||
using pocs = std::false_type;
|
||||
test::basic_test_allocator<int, pocs> lhs, rhs;
|
||||
ASSERT_DEATH(entt::propagate_on_container_swap(lhs, rhs), "");
|
||||
}
|
||||
|
||||
TEST(IsPowerOfTwo, Functionalities) {
|
||||
// constexpr-ness guaranteed
|
||||
constexpr auto zero_is_power_of_two = entt::is_power_of_two(0u);
|
||||
|
||||
ASSERT_FALSE(zero_is_power_of_two);
|
||||
ASSERT_TRUE(entt::is_power_of_two(1u));
|
||||
ASSERT_TRUE(entt::is_power_of_two(2u));
|
||||
ASSERT_TRUE(entt::is_power_of_two(4u));
|
||||
ASSERT_FALSE(entt::is_power_of_two(7u));
|
||||
ASSERT_TRUE(entt::is_power_of_two(128u));
|
||||
ASSERT_FALSE(entt::is_power_of_two(200u));
|
||||
}
|
||||
|
||||
TEST(NextPowerOfTwo, Functionalities) {
|
||||
// constexpr-ness guaranteed
|
||||
constexpr auto next_power_of_two_of_zero = entt::next_power_of_two(0u);
|
||||
|
||||
ASSERT_EQ(next_power_of_two_of_zero, 1u);
|
||||
ASSERT_EQ(entt::next_power_of_two(1u), 1u);
|
||||
ASSERT_EQ(entt::next_power_of_two(2u), 2u);
|
||||
ASSERT_EQ(entt::next_power_of_two(3u), 4u);
|
||||
ASSERT_EQ(entt::next_power_of_two(17u), 32u);
|
||||
ASSERT_EQ(entt::next_power_of_two(32u), 32u);
|
||||
ASSERT_EQ(entt::next_power_of_two(33u), 64u);
|
||||
ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16)), std::pow(2, 16));
|
||||
ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16) + 1u), std::pow(2, 17));
|
||||
}
|
||||
|
||||
ENTT_DEBUG_TEST(NextPowerOfTwoDeathTest, Functionalities) {
|
||||
ASSERT_DEATH(static_cast<void>(entt::next_power_of_two((std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)) + 1)), "");
|
||||
}
|
||||
|
||||
TEST(FastMod, Functionalities) {
|
||||
// constexpr-ness guaranteed
|
||||
constexpr auto fast_mod_of_zero = entt::fast_mod(0u, 8u);
|
||||
|
||||
ASSERT_EQ(fast_mod_of_zero, 0u);
|
||||
ASSERT_EQ(entt::fast_mod(7u, 8u), 7u);
|
||||
ASSERT_EQ(entt::fast_mod(8u, 8u), 0u);
|
||||
}
|
||||
|
||||
TEST(AllocateUnique, Functionalities) {
|
||||
test::throwing_allocator<test::throwing_type> allocator{};
|
||||
test::throwing_allocator<test::throwing_type>::trigger_on_allocate = true;
|
||||
test::throwing_type::trigger_on_value = 0;
|
||||
|
||||
ASSERT_THROW((entt::allocate_unique<test::throwing_type>(allocator, 0)), test::throwing_allocator<test::throwing_type>::exception_type);
|
||||
ASSERT_THROW((entt::allocate_unique<test::throwing_type>(allocator, test::throwing_type{0})), test::throwing_type::exception_type);
|
||||
|
||||
std::unique_ptr<test::throwing_type, entt::allocation_deleter<test::throwing_allocator<test::throwing_type>>> ptr = entt::allocate_unique<test::throwing_type>(allocator, 42);
|
||||
|
||||
ASSERT_TRUE(ptr);
|
||||
ASSERT_EQ(*ptr, 42);
|
||||
|
||||
ptr.reset();
|
||||
|
||||
ASSERT_FALSE(ptr);
|
||||
}
|
||||
|
||||
#if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)
|
||||
|
||||
TEST(AllocateUnique, NoUsesAllocatorConstruction) {
|
||||
test::tracked_memory_resource memory_resource{};
|
||||
std::pmr::polymorphic_allocator<int> allocator{&memory_resource};
|
||||
|
||||
using type = std::unique_ptr<int, entt::allocation_deleter<std::pmr::polymorphic_allocator<int>>>;
|
||||
type ptr = entt::allocate_unique<int>(allocator, 0);
|
||||
|
||||
ASSERT_EQ(memory_resource.do_allocate_counter(), 1u);
|
||||
ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
|
||||
}
|
||||
|
||||
TEST(AllocateUnique, UsesAllocatorConstruction) {
|
||||
using string_type = typename test::tracked_memory_resource::string_type;
|
||||
|
||||
test::tracked_memory_resource memory_resource{};
|
||||
std::pmr::polymorphic_allocator<string_type> allocator{&memory_resource};
|
||||
|
||||
using type = std::unique_ptr<string_type, entt::allocation_deleter<std::pmr::polymorphic_allocator<string_type>>>;
|
||||
type ptr = entt::allocate_unique<string_type>(allocator, test::tracked_memory_resource::default_value);
|
||||
|
||||
ASSERT_GT(memory_resource.do_allocate_counter(), 1u);
|
||||
ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, NoUsesAllocatorConstruction) {
|
||||
const auto value = 42;
|
||||
const auto args = entt::uses_allocator_construction_args<int>(std::allocator<int>{}, value);
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 1u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<const int &>>);
|
||||
|
||||
ASSERT_EQ(std::get<0>(args), value);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, LeadingAllocatorConvention) {
|
||||
const auto value = 42;
|
||||
const auto args = entt::uses_allocator_construction_args<std::tuple<int, char>>(std::allocator<int>{}, value, 'c');
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 4u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::allocator_arg_t, const std::allocator<int> &, const int &, char &&>>);
|
||||
|
||||
ASSERT_EQ(std::get<2>(args), value);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, TrailingAllocatorConvention) {
|
||||
const auto size = 42u;
|
||||
const auto args = entt::uses_allocator_construction_args<std::vector<int>>(std::allocator<int>{}, size);
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 2u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<const unsigned int &, const std::allocator<int> &>>);
|
||||
|
||||
ASSERT_EQ(std::get<0>(args), size);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, PairPiecewiseConstruct) {
|
||||
const auto size = 42u;
|
||||
const auto tup = std::make_tuple(size);
|
||||
const auto args = entt::uses_allocator_construction_args<std::pair<int, std::vector<int>>>(std::allocator<int>{}, std::piecewise_construct, std::make_tuple(3), tup);
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 3u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::piecewise_construct_t, std::tuple<int &&>, std::tuple<const unsigned int &, const std::allocator<int> &>>>);
|
||||
|
||||
ASSERT_EQ(std::get<0>(std::get<2>(args)), size);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, PairNoArgs) {
|
||||
[[maybe_unused]] const auto args = entt::uses_allocator_construction_args<std::pair<int, std::vector<int>>>(std::allocator<int>{});
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 3u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<int> &>>>);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, PairValues) {
|
||||
const auto size = 42u;
|
||||
const auto args = entt::uses_allocator_construction_args<std::pair<int, std::vector<int>>>(std::allocator<int>{}, 3, size);
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 3u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::piecewise_construct_t, std::tuple<int &&>, std::tuple<const unsigned int &, const std::allocator<int> &>>>);
|
||||
|
||||
ASSERT_EQ(std::get<0>(std::get<2>(args)), size);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, PairConstLValueReference) {
|
||||
const auto value = std::make_pair(3, 42u);
|
||||
const auto args = entt::uses_allocator_construction_args<std::pair<int, std::vector<int>>>(std::allocator<int>{}, value);
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 3u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::piecewise_construct_t, std::tuple<const int &>, std::tuple<const unsigned int &, const std::allocator<int> &>>>);
|
||||
|
||||
ASSERT_EQ(std::get<0>(std::get<1>(args)), 3);
|
||||
ASSERT_EQ(std::get<0>(std::get<2>(args)), 42u);
|
||||
}
|
||||
|
||||
TEST(UsesAllocatorConstructionArgs, PairRValueReference) {
|
||||
[[maybe_unused]] const auto args = entt::uses_allocator_construction_args<std::pair<int, std::vector<int>>>(std::allocator<int>{}, std::make_pair(3, 42u));
|
||||
|
||||
static_assert(std::tuple_size_v<decltype(args)> == 3u);
|
||||
static_assert(std::is_same_v<decltype(args), const std::tuple<std::piecewise_construct_t, std::tuple<int &&>, std::tuple<unsigned int &&, const std::allocator<int> &>>>);
|
||||
}
|
||||
|
||||
TEST(MakeObjUsingAllocator, Functionalities) {
|
||||
const auto size = 42u;
|
||||
test::throwing_allocator<int>::trigger_on_allocate = true;
|
||||
|
||||
ASSERT_THROW((entt::make_obj_using_allocator<std::vector<int, test::throwing_allocator<int>>>(test::throwing_allocator<int>{}, size)), test::throwing_allocator<int>::exception_type);
|
||||
|
||||
const auto vec = entt::make_obj_using_allocator<std::vector<int>>(std::allocator<int>{}, size);
|
||||
|
||||
ASSERT_FALSE(vec.empty());
|
||||
ASSERT_EQ(vec.size(), size);
|
||||
}
|
||||
|
||||
TEST(UninitializedConstructUsingAllocator, NoUsesAllocatorConstruction) {
|
||||
alignas(int) std::byte storage[sizeof(int)];
|
||||
std::allocator<int> allocator{};
|
||||
|
||||
int *value = entt::uninitialized_construct_using_allocator(reinterpret_cast<int *>(&storage), allocator, 42);
|
||||
|
||||
ASSERT_EQ(*value, 42);
|
||||
}
|
||||
|
||||
#if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)
|
||||
|
||||
TEST(UninitializedConstructUsingAllocator, UsesAllocatorConstruction) {
|
||||
using string_type = typename test::tracked_memory_resource::string_type;
|
||||
|
||||
test::tracked_memory_resource memory_resource{};
|
||||
std::pmr::polymorphic_allocator<string_type> allocator{&memory_resource};
|
||||
alignas(string_type) std::byte storage[sizeof(string_type)];
|
||||
|
||||
string_type *value = entt::uninitialized_construct_using_allocator(reinterpret_cast<string_type *>(&storage), allocator, test::tracked_memory_resource::default_value);
|
||||
|
||||
ASSERT_GT(memory_resource.do_allocate_counter(), 0u);
|
||||
ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
|
||||
ASSERT_EQ(*value, test::tracked_memory_resource::default_value);
|
||||
|
||||
value->~string_type();
|
||||
}
|
||||
|
||||
#endif
|
22
test/entt/core/monostate.cpp
Normal file
22
test/entt/core/monostate.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
#include <entt/core/monostate.hpp>
|
||||
|
||||
TEST(Monostate, Functionalities) {
|
||||
using namespace entt::literals;
|
||||
|
||||
const bool b_pre = entt::monostate<entt::hashed_string{"foobar"}>{};
|
||||
const int i_pre = entt::monostate<"foobar"_hs>{};
|
||||
|
||||
ASSERT_FALSE(b_pre);
|
||||
ASSERT_EQ(i_pre, int{});
|
||||
|
||||
entt::monostate<"foobar"_hs>{} = true;
|
||||
entt::monostate_v<"foobar"_hs> = 42;
|
||||
|
||||
const bool &b_post = entt::monostate<"foobar"_hs>{};
|
||||
const int &i_post = entt::monostate_v<entt::hashed_string{"foobar"}>;
|
||||
|
||||
ASSERT_TRUE(b_post);
|
||||
ASSERT_EQ(i_post, 42);
|
||||
}
|
38
test/entt/core/tuple.cpp
Normal file
38
test/entt/core/tuple.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <tuple>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/tuple.hpp>
|
||||
|
||||
TEST(Tuple, IsTuple) {
|
||||
static_assert(!entt::is_tuple_v<int>);
|
||||
static_assert(entt::is_tuple_v<std::tuple<>>);
|
||||
static_assert(entt::is_tuple_v<std::tuple<int>>);
|
||||
static_assert(entt::is_tuple_v<std::tuple<int, char>>);
|
||||
}
|
||||
|
||||
TEST(Tuple, UnwrapTuple) {
|
||||
auto single = std::make_tuple(42);
|
||||
auto multi = std::make_tuple(42, 'c');
|
||||
auto ref = std::forward_as_tuple(std::get<0>(single));
|
||||
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(single)), int &>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(multi)), std::tuple<int, char> &>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(ref)), int &>));
|
||||
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::move(single))), int &&>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::move(multi))), std::tuple<int, char> &&>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::move(ref))), int &>));
|
||||
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::as_const(single))), const int &>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::as_const(multi))), const std::tuple<int, char> &>));
|
||||
ASSERT_TRUE((std::is_same_v<decltype(entt::unwrap_tuple(std::as_const(ref))), int &>));
|
||||
|
||||
ASSERT_EQ(entt::unwrap_tuple(single), 42);
|
||||
ASSERT_EQ(entt::unwrap_tuple(multi), multi);
|
||||
ASSERT_EQ(entt::unwrap_tuple(std::move(ref)), 42);
|
||||
}
|
||||
|
||||
TEST(Tuple, ForwardApply) {
|
||||
ASSERT_EQ(entt::forward_apply{[](auto &&...args) { return sizeof...(args); }}(std::make_tuple()), 0u);
|
||||
ASSERT_EQ(entt::forward_apply{[](int i) { return i; }}(std::make_tuple(42)), 42);
|
||||
ASSERT_EQ(entt::forward_apply{[](auto... args) { return (args + ...); }}(std::make_tuple('a', 1u)), 'b');
|
||||
}
|
116
test/entt/core/type_info.cpp
Normal file
116
test/entt/core/type_info.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/type_info.hpp>
|
||||
#include <entt/core/type_traits.hpp>
|
||||
|
||||
template<>
|
||||
struct entt::type_name<float> final {
|
||||
[[nodiscard]] static constexpr std::string_view value() noexcept {
|
||||
return std::string_view{""};
|
||||
}
|
||||
};
|
||||
|
||||
TEST(TypeIndex, Functionalities) {
|
||||
ASSERT_EQ(entt::type_index<int>::value(), entt::type_index<int>::value());
|
||||
ASSERT_NE(entt::type_index<int>::value(), entt::type_index<char>::value());
|
||||
ASSERT_NE(entt::type_index<int>::value(), entt::type_index<int &&>::value());
|
||||
ASSERT_NE(entt::type_index<int &>::value(), entt::type_index<const int &>::value());
|
||||
ASSERT_EQ(static_cast<entt::id_type>(entt::type_index<int>{}), entt::type_index<int>::value());
|
||||
}
|
||||
|
||||
TEST(TypeHash, Functionalities) {
|
||||
ASSERT_NE(entt::type_hash<int>::value(), entt::type_hash<const int>::value());
|
||||
ASSERT_NE(entt::type_hash<int>::value(), entt::type_hash<char>::value());
|
||||
ASSERT_EQ(entt::type_hash<int>::value(), entt::type_hash<int>::value());
|
||||
ASSERT_EQ(static_cast<entt::id_type>(entt::type_hash<int>{}), entt::type_hash<int>::value());
|
||||
}
|
||||
|
||||
TEST(TypeName, Functionalities) {
|
||||
ASSERT_EQ(entt::type_name<int>::value(), std::string_view{"int"});
|
||||
ASSERT_EQ(entt::type_name<float>{}.value(), std::string_view{""});
|
||||
|
||||
ASSERT_TRUE((entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"std::integral_constant<int, 3>"})
|
||||
|| (entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"std::__1::integral_constant<int, 3>"})
|
||||
|| (entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"struct std::integral_constant<int,3>"}));
|
||||
|
||||
ASSERT_TRUE(((entt::type_name<entt::type_list<entt::type_list<int, char>, double>>::value()) == std::string_view{"entt::type_list<entt::type_list<int, char>, double>"})
|
||||
|| ((entt::type_name<entt::type_list<entt::type_list<int, char>, double>>::value()) == std::string_view{"struct entt::type_list<struct entt::type_list<int,char>,double>"}));
|
||||
|
||||
ASSERT_EQ(static_cast<std::string_view>(entt::type_name<int>{}), entt::type_name<int>::value());
|
||||
}
|
||||
|
||||
TEST(TypeInfo, Functionalities) {
|
||||
static_assert(std::is_copy_constructible_v<entt::type_info>);
|
||||
static_assert(std::is_move_constructible_v<entt::type_info>);
|
||||
static_assert(std::is_copy_assignable_v<entt::type_info>);
|
||||
static_assert(std::is_move_assignable_v<entt::type_info>);
|
||||
|
||||
entt::type_info info{std::in_place_type<int>};
|
||||
entt::type_info other{std::in_place_type<void>};
|
||||
|
||||
ASSERT_EQ(info, entt::type_info{std::in_place_type<int &>});
|
||||
ASSERT_EQ(info, entt::type_info{std::in_place_type<int &&>});
|
||||
ASSERT_EQ(info, entt::type_info{std::in_place_type<const int &>});
|
||||
|
||||
ASSERT_NE(info, other);
|
||||
ASSERT_TRUE(info == info);
|
||||
ASSERT_FALSE(info != info);
|
||||
|
||||
ASSERT_EQ(info.index(), entt::type_index<int>::value());
|
||||
ASSERT_EQ(info.hash(), entt::type_hash<int>::value());
|
||||
ASSERT_EQ(info.name(), entt::type_name<int>::value());
|
||||
|
||||
other = info;
|
||||
|
||||
ASSERT_EQ(other.index(), entt::type_index<int>::value());
|
||||
ASSERT_EQ(other.hash(), entt::type_hash<int>::value());
|
||||
ASSERT_EQ(other.name(), entt::type_name<int>::value());
|
||||
|
||||
ASSERT_EQ(other.index(), info.index());
|
||||
ASSERT_EQ(other.hash(), info.hash());
|
||||
ASSERT_EQ(other.name(), info.name());
|
||||
|
||||
other = std::move(info);
|
||||
|
||||
ASSERT_EQ(other.index(), entt::type_index<int>::value());
|
||||
ASSERT_EQ(other.hash(), entt::type_hash<int>::value());
|
||||
ASSERT_EQ(other.name(), entt::type_name<int>::value());
|
||||
|
||||
ASSERT_EQ(other.index(), info.index());
|
||||
ASSERT_EQ(other.hash(), info.hash());
|
||||
ASSERT_EQ(other.name(), info.name());
|
||||
}
|
||||
|
||||
TEST(TypeInfo, Order) {
|
||||
entt::type_info rhs = entt::type_id<int>();
|
||||
entt::type_info lhs = entt::type_id<char>();
|
||||
|
||||
// let's adjust the two objects since values are generated at runtime
|
||||
rhs < lhs ? void() : std::swap(lhs, rhs);
|
||||
|
||||
ASSERT_FALSE(lhs < lhs);
|
||||
ASSERT_FALSE(rhs < rhs);
|
||||
|
||||
ASSERT_LT(rhs, lhs);
|
||||
ASSERT_LE(rhs, lhs);
|
||||
|
||||
ASSERT_GT(lhs, rhs);
|
||||
ASSERT_GE(lhs, rhs);
|
||||
}
|
||||
|
||||
TEST(TypeId, Functionalities) {
|
||||
const int value = 42;
|
||||
|
||||
ASSERT_EQ(entt::type_id(value), entt::type_id<int>());
|
||||
ASSERT_EQ(entt::type_id(42), entt::type_id<int>());
|
||||
|
||||
ASSERT_EQ(entt::type_id<int>(), entt::type_id<int>());
|
||||
ASSERT_EQ(entt::type_id<int &>(), entt::type_id<int &&>());
|
||||
ASSERT_EQ(entt::type_id<int &>(), entt::type_id<int>());
|
||||
ASSERT_NE(entt::type_id<int>(), entt::type_id<char>());
|
||||
|
||||
ASSERT_EQ(&entt::type_id<int>(), &entt::type_id<int>());
|
||||
ASSERT_NE(&entt::type_id<int>(), &entt::type_id<void>());
|
||||
}
|
224
test/entt/core/type_traits.cpp
Normal file
224
test/entt/core/type_traits.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
#include <entt/core/type_traits.hpp>
|
||||
|
||||
struct not_comparable {
|
||||
bool operator==(const not_comparable &) const = delete;
|
||||
};
|
||||
|
||||
struct nlohmann_json_like final {
|
||||
using value_type = nlohmann_json_like;
|
||||
|
||||
bool operator==(const nlohmann_json_like &) const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct clazz {
|
||||
char foo(int) {
|
||||
return {};
|
||||
}
|
||||
|
||||
int bar(double, float) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool quux;
|
||||
};
|
||||
|
||||
int free_function(int, const double &) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
template<typename, typename Type = void>
|
||||
struct multi_argument_operation {
|
||||
using type = Type;
|
||||
};
|
||||
|
||||
TEST(SizeOf, Functionalities) {
|
||||
static_assert(entt::size_of_v<void> == 0u);
|
||||
static_assert(entt::size_of_v<char> == sizeof(char));
|
||||
static_assert(entt::size_of_v<int[]> == 0u);
|
||||
static_assert(entt::size_of_v<int[3]> == sizeof(int[3]));
|
||||
}
|
||||
|
||||
TEST(UnpackAsType, Functionalities) {
|
||||
auto test = [](auto &&...args) {
|
||||
return [](entt::unpack_as_type<int, decltype(args)>... value) {
|
||||
return (value + ... + 0);
|
||||
};
|
||||
};
|
||||
|
||||
ASSERT_EQ(test('c', 42., true)(1, 2, 3), 6);
|
||||
}
|
||||
|
||||
TEST(UnpackAsValue, Functionalities) {
|
||||
auto test = [](auto &&...args) {
|
||||
return (entt::unpack_as_value<2, decltype(args)> + ... + 0);
|
||||
};
|
||||
|
||||
ASSERT_EQ(test('c', 42., true), 6);
|
||||
}
|
||||
|
||||
TEST(IntegralConstant, Functionalities) {
|
||||
entt::integral_constant<3> constant{};
|
||||
|
||||
static_assert(std::is_same_v<typename entt::integral_constant<3>::value_type, int>);
|
||||
static_assert(constant.value == 3);
|
||||
}
|
||||
|
||||
TEST(Choice, Functionalities) {
|
||||
static_assert(std::is_base_of_v<entt::choice_t<0>, entt::choice_t<1>>);
|
||||
static_assert(!std::is_base_of_v<entt::choice_t<1>, entt::choice_t<0>>);
|
||||
}
|
||||
|
||||
TEST(TypeList, Functionalities) {
|
||||
using type = entt::type_list<int, char>;
|
||||
using other = entt::type_list<double>;
|
||||
|
||||
static_assert(type::size == 2u);
|
||||
static_assert(other::size == 1u);
|
||||
|
||||
static_assert(std::is_same_v<decltype(type{} + other{}), entt::type_list<int, char, double>>);
|
||||
static_assert(std::is_same_v<entt::type_list_cat_t<type, other, type, other>, entt::type_list<int, char, double, int, char, double>>);
|
||||
static_assert(std::is_same_v<entt::type_list_cat_t<type, other>, entt::type_list<int, char, double>>);
|
||||
static_assert(std::is_same_v<entt::type_list_cat_t<type, type>, entt::type_list<int, char, int, char>>);
|
||||
static_assert(std::is_same_v<entt::type_list_unique_t<entt::type_list_cat_t<type, type>>, entt::type_list<int, char>>);
|
||||
|
||||
static_assert(entt::type_list_contains_v<type, int>);
|
||||
static_assert(entt::type_list_contains_v<type, char>);
|
||||
static_assert(!entt::type_list_contains_v<type, double>);
|
||||
|
||||
static_assert(std::is_same_v<entt::type_list_element_t<0u, type>, int>);
|
||||
static_assert(std::is_same_v<entt::type_list_element_t<1u, type>, char>);
|
||||
static_assert(std::is_same_v<entt::type_list_element_t<0u, other>, double>);
|
||||
|
||||
static_assert(entt::type_list_index_v<int, type> == 0u);
|
||||
static_assert(entt::type_list_index_v<char, type> == 1u);
|
||||
static_assert(entt::type_list_index_v<double, other> == 0u);
|
||||
|
||||
static_assert(std::is_same_v<entt::type_list_diff_t<entt::type_list<int, char, double>, entt::type_list<float, bool>>, entt::type_list<int, char, double>>);
|
||||
static_assert(std::is_same_v<entt::type_list_diff_t<entt::type_list<int, char, double>, entt::type_list<int, char, double>>, entt::type_list<>>);
|
||||
static_assert(std::is_same_v<entt::type_list_diff_t<entt::type_list<int, char, double>, entt::type_list<int, char>>, entt::type_list<double>>);
|
||||
static_assert(std::is_same_v<entt::type_list_diff_t<entt::type_list<int, char, double>, entt::type_list<char, double>>, entt::type_list<int>>);
|
||||
static_assert(std::is_same_v<entt::type_list_diff_t<entt::type_list<int, char, double>, entt::type_list<char>>, entt::type_list<int, double>>);
|
||||
|
||||
static_assert(std::is_same_v<entt::type_list_transform_t<entt::type_list<int, char>, entt::type_identity>, entt::type_list<int, char>>);
|
||||
static_assert(std::is_same_v<entt::type_list_transform_t<entt::type_list<int, char>, std::add_const>, entt::type_list<const int, const char>>);
|
||||
static_assert(std::is_same_v<entt::type_list_transform_t<entt::type_list<int, char>, multi_argument_operation>, entt::type_list<void, void>>);
|
||||
}
|
||||
|
||||
TEST(ValueList, Functionalities) {
|
||||
using value = entt::value_list<0, 2>;
|
||||
using other = entt::value_list<1>;
|
||||
|
||||
static_assert(value::size == 2u);
|
||||
static_assert(other::size == 1u);
|
||||
|
||||
static_assert(std::is_same_v<decltype(value{} + other{}), entt::value_list<0, 2, 1>>);
|
||||
static_assert(std::is_same_v<entt::value_list_cat_t<value, other, value, other>, entt::value_list<0, 2, 1, 0, 2, 1>>);
|
||||
static_assert(std::is_same_v<entt::value_list_cat_t<value, other>, entt::value_list<0, 2, 1>>);
|
||||
static_assert(std::is_same_v<entt::value_list_cat_t<value, value>, entt::value_list<0, 2, 0, 2>>);
|
||||
|
||||
static_assert(entt::value_list_element_v<0u, value> == 0);
|
||||
static_assert(entt::value_list_element_v<1u, value> == 2);
|
||||
static_assert(entt::value_list_element_v<0u, other> == 1);
|
||||
}
|
||||
|
||||
TEST(IsApplicable, Functionalities) {
|
||||
static_assert(entt::is_applicable_v<void(int, char), std::tuple<double, char>>);
|
||||
static_assert(!entt::is_applicable_v<void(int, char), std::tuple<int>>);
|
||||
|
||||
static_assert(entt::is_applicable_r_v<float, int(int, char), std::tuple<double, char>>);
|
||||
static_assert(!entt::is_applicable_r_v<float, void(int, char), std::tuple<double, char>>);
|
||||
static_assert(!entt::is_applicable_r_v<int, int(int, char), std::tuple<void>>);
|
||||
}
|
||||
|
||||
TEST(IsComplete, Functionalities) {
|
||||
static_assert(!entt::is_complete_v<void>);
|
||||
static_assert(entt::is_complete_v<int>);
|
||||
}
|
||||
|
||||
TEST(IsIterator, Functionalities) {
|
||||
static_assert(!entt::is_iterator_v<void>);
|
||||
static_assert(!entt::is_iterator_v<int>);
|
||||
|
||||
static_assert(!entt::is_iterator_v<void *>);
|
||||
static_assert(entt::is_iterator_v<int *>);
|
||||
|
||||
static_assert(entt::is_iterator_v<std::vector<int>::iterator>);
|
||||
static_assert(entt::is_iterator_v<std::vector<int>::const_iterator>);
|
||||
static_assert(entt::is_iterator_v<std::vector<int>::reverse_iterator>);
|
||||
}
|
||||
|
||||
TEST(IsEBCOEligible, Functionalities) {
|
||||
static_assert(entt::is_ebco_eligible_v<not_comparable>);
|
||||
static_assert(!entt::is_ebco_eligible_v<nlohmann_json_like>);
|
||||
static_assert(!entt::is_ebco_eligible_v<double>);
|
||||
static_assert(!entt::is_ebco_eligible_v<void>);
|
||||
}
|
||||
|
||||
TEST(IsTransparent, Functionalities) {
|
||||
static_assert(!entt::is_transparent_v<std::less<int>>);
|
||||
static_assert(entt::is_transparent_v<std::less<void>>);
|
||||
static_assert(!entt::is_transparent_v<std::logical_not<double>>);
|
||||
static_assert(entt::is_transparent_v<std::logical_not<void>>);
|
||||
}
|
||||
|
||||
TEST(IsEqualityComparable, Functionalities) {
|
||||
static_assert(entt::is_equality_comparable_v<int>);
|
||||
static_assert(entt::is_equality_comparable_v<const int>);
|
||||
static_assert(entt::is_equality_comparable_v<std::vector<int>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::vector<std::vector<int>>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::unordered_map<int, int>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::unordered_map<int, std::unordered_map<int, char>>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::pair<const int, int>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::pair<const int, std::unordered_map<int, char>>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::vector<not_comparable>::iterator>);
|
||||
static_assert(entt::is_equality_comparable_v<nlohmann_json_like>);
|
||||
|
||||
static_assert(!entt::is_equality_comparable_v<not_comparable>);
|
||||
static_assert(!entt::is_equality_comparable_v<const not_comparable>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::vector<not_comparable>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::vector<std::vector<not_comparable>>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::unordered_map<int, not_comparable>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::unordered_map<int, std::unordered_map<int, not_comparable>>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::pair<const int, not_comparable>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::pair<const int, std::unordered_map<int, not_comparable>>>);
|
||||
static_assert(!entt::is_equality_comparable_v<void>);
|
||||
}
|
||||
|
||||
TEST(ConstnessAs, Functionalities) {
|
||||
static_assert(std::is_same_v<entt::constness_as_t<int, char>, int>);
|
||||
static_assert(std::is_same_v<entt::constness_as_t<const int, char>, int>);
|
||||
static_assert(std::is_same_v<entt::constness_as_t<int, const char>, const int>);
|
||||
static_assert(std::is_same_v<entt::constness_as_t<const int, const char>, const int>);
|
||||
}
|
||||
|
||||
TEST(MemberClass, Functionalities) {
|
||||
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::foo)>>);
|
||||
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::bar)>>);
|
||||
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::quux)>>);
|
||||
}
|
||||
|
||||
TEST(NthArgument, Functionalities) {
|
||||
static_assert(std::is_same_v<entt::nth_argument_t<0u, &free_function>, int>);
|
||||
static_assert(std::is_same_v<entt::nth_argument_t<1u, &free_function>, const double &>);
|
||||
static_assert(std::is_same_v<entt::nth_argument_t<0u, &clazz::bar>, double>);
|
||||
static_assert(std::is_same_v<entt::nth_argument_t<1u, &clazz::bar>, float>);
|
||||
static_assert(std::is_same_v<entt::nth_argument_t<0u, &clazz::quux>, bool>);
|
||||
|
||||
ASSERT_EQ(free_function(entt::nth_argument_t<0u, &free_function>{}, entt::nth_argument_t<1u, &free_function>{}), 42);
|
||||
}
|
||||
|
||||
TEST(Tag, Functionalities) {
|
||||
using namespace entt::literals;
|
||||
static_assert(entt::tag<"foobar"_hs>::value == entt::hashed_string::value("foobar"));
|
||||
static_assert(std::is_same_v<typename entt::tag<"foobar"_hs>::value_type, entt::id_type>);
|
||||
}
|
61
test/entt/core/utility.cpp
Normal file
61
test/entt/core/utility.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <utility>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/type_traits.hpp>
|
||||
#include <entt/core/utility.hpp>
|
||||
|
||||
struct functions {
|
||||
static void foo(int) {}
|
||||
static void foo() {}
|
||||
|
||||
void bar(int) {}
|
||||
void bar() {}
|
||||
};
|
||||
|
||||
TEST(Identity, Functionalities) {
|
||||
entt::identity identity;
|
||||
int value = 42;
|
||||
|
||||
ASSERT_TRUE(entt::is_transparent_v<entt::identity>);
|
||||
ASSERT_EQ(identity(value), value);
|
||||
ASSERT_EQ(&identity(value), &value);
|
||||
}
|
||||
|
||||
TEST(Overload, Functionalities) {
|
||||
ASSERT_EQ(entt::overload<void(int)>(&functions::foo), static_cast<void (*)(int)>(&functions::foo));
|
||||
ASSERT_EQ(entt::overload<void()>(&functions::foo), static_cast<void (*)()>(&functions::foo));
|
||||
|
||||
ASSERT_EQ(entt::overload<void(int)>(&functions::bar), static_cast<void (functions::*)(int)>(&functions::bar));
|
||||
ASSERT_EQ(entt::overload<void()>(&functions::bar), static_cast<void (functions::*)()>(&functions::bar));
|
||||
|
||||
functions instance;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(entt::overload<void(int)>(&functions::foo)(0));
|
||||
ASSERT_NO_FATAL_FAILURE(entt::overload<void()>(&functions::foo)());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE((instance.*entt::overload<void(int)>(&functions::bar))(0));
|
||||
ASSERT_NO_FATAL_FAILURE((instance.*entt::overload<void()>(&functions::bar))());
|
||||
}
|
||||
|
||||
TEST(Overloaded, Functionalities) {
|
||||
int iv = 0;
|
||||
char cv = '\0';
|
||||
|
||||
entt::overloaded func{
|
||||
[&iv](int value) { iv = value; },
|
||||
[&cv](char value) { cv = value; }};
|
||||
|
||||
func(42);
|
||||
func('c');
|
||||
|
||||
ASSERT_EQ(iv, 42);
|
||||
ASSERT_EQ(cv, 'c');
|
||||
}
|
||||
|
||||
TEST(YCombinator, Functionalities) {
|
||||
entt::y_combinator gauss([](const auto &self, auto value) -> unsigned int {
|
||||
return value ? (value + self(value - 1u)) : 0;
|
||||
});
|
||||
|
||||
ASSERT_EQ(gauss(3u), 3u * 4u / 2u);
|
||||
ASSERT_EQ(std::as_const(gauss)(7u), 7u * 8u / 2u);
|
||||
}
|
Reference in New Issue
Block a user