Compare commits

...

13 Commits

Author SHA1 Message Date
Michele Caini
dd6863f71d update single include file 2021-07-28 09:58:14 +02:00
Michele Caini
dc7c976518 Ready to cut v3.8.1 2021-07-28 09:56:40 +02:00
Michele Caini
3408556eea sparse_set: fix an issue with assuring pages properly on emplace (close #746) 2021-07-27 18:53:30 +02:00
Michele Caini
f94b9773da build system: test id type std::uint64_t on the CI, all platforms 2021-07-26 23:37:55 +02:00
Michele Caini
e0b3786d97 test: make tests for entity traits work when id_type is std::uint64_t 2021-07-26 23:37:50 +02:00
Michele Caini
4047cb01a8 test: make tests for hashed string work when id_type is std::uint64_t 2021-07-26 23:37:46 +02:00
Michele Caini
8cfd08b137 sparse set: make vs2017 work (more or less) fine when id_type is std::uint64_t 2021-07-26 23:37:42 +02:00
Michele Caini
311011672c entity: avoid UBs when id type is std::uint64_t (close #745) 2021-07-26 23:37:39 +02:00
Hussein Taher
6df19c833d snapshot: fix warning for discarding a nodiscard (#728) 2021-07-26 23:37:36 +02:00
Michele Caini
78d9e71888 test: get rid of inconsistent line (close #741) 2021-07-26 23:37:32 +02:00
Michele Caini
94131648dd type_traits: try to also please gcc :) 2021-07-26 23:37:12 +02:00
Michele Caini
151f180199 core: make is_equality_comparable[_v] work with iterators (close #739) 2021-07-26 23:37:02 +02:00
Michele Caini
bb8bfaf262 meta_any: avoid risky fallthrough in the vtable (close #736) 2021-07-26 23:36:51 +02:00
16 changed files with 7930 additions and 3969 deletions

View File

@@ -9,46 +9,42 @@ jobs:
strategy: strategy:
matrix: matrix:
compiler: [ compiler:
g++-7, g++-8, g++-9, g++, - pkg: g++-7
clang++-8, clang++-9, clang++-10, clang++ exe: g++-7
] - pkg: g++-8
exe: g++-8
- pkg: g++-9
exe: g++-9
- pkg: g++
exe: g++
- pkg: clang-8
exe: clang++-8
- pkg: clang-9
exe: clang++-9
- pkg: clang-10
exe: clang++-10
- pkg: clang
exe: clang++
id_type: [uint32, uint64]
include:
- id_type: uint64
id_type_option: -DENTT_BUILD_UINT64=ON
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install g++-7 - name: Install compiler
if: ${{ matrix.compiler == 'g++-7' }}
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install g++-7 -y sudo apt-get install ${{ matrix.compiler.pkg }} -y
- name: Install g++-8
if: ${{ matrix.compiler == 'g++-8' }}
run: |
sudo apt-get update
sudo apt-get install g++-8 -y
- name: Install clang-8
if: ${{ matrix.compiler == 'clang++-8' }}
run: |
sudo apt-get update
sudo apt-get install clang-8 -y
- name: Install clang-9
if: ${{ matrix.compiler == 'clang++-9' }}
run: |
sudo apt-get update
sudo apt-get install clang-9 -y
- name: Install clang-10
if: ${{ matrix.compiler == 'clang++-10' }}
run: |
sudo apt-get update
sudo apt-get install clang-10 -y
- name: Compile tests - name: Compile tests
working-directory: build working-directory: build
env: env:
CXX: ${{ matrix.compiler }} CXX: ${{ matrix.compiler.exe }}
run: | run: |
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON .. cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.id_type_option }} ..
make -j4 make -j4
- name: Run tests - name: Run tests
working-directory: build working-directory: build
@@ -63,11 +59,14 @@ jobs:
matrix: matrix:
os: [windows-latest, windows-2016] os: [windows-latest, windows-2016]
toolset: [clang-cl, default, v141] toolset: [clang-cl, default, v141]
id_type: [uint32, uint64]
include: include:
- toolset: clang-cl - toolset: clang-cl
toolset_option: -T"ClangCl" toolset_option: -T"ClangCl"
- toolset: v141 - toolset: v141
toolset_option: -T"v141" toolset_option: -T"v141"
- id_type: uint64
id_type_option: -DENTT_BUILD_UINT64=ON
exclude: exclude:
- os: windows-2016 - os: windows-2016
toolset: clang-cl toolset: clang-cl
@@ -81,7 +80,7 @@ jobs:
- name: Compile tests - name: Compile tests
working-directory: build working-directory: build
run: | run: |
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.toolset_option }} .. cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.id_type_option }} ${{ matrix.toolset_option }} ..
cmake --build . -j 4 cmake --build . -j 4
- name: Run tests - name: Run tests
working-directory: build working-directory: build
@@ -91,6 +90,14 @@ jobs:
macos: macos:
timeout-minutes: 10 timeout-minutes: 10
strategy:
matrix:
id_type: [uint32, uint64]
include:
- id_type: uint64
id_type_option: -DENTT_BUILD_UINT64=ON
runs-on: macOS-latest runs-on: macOS-latest
steps: steps:
@@ -98,7 +105,7 @@ jobs:
- name: Compile tests - name: Compile tests
working-directory: build working-directory: build
run: | run: |
cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON .. cmake -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.id_type_option }} ..
make -j4 make -j4
- name: Run tests - name: Run tests
working-directory: build working-directory: build

View File

@@ -10,6 +10,10 @@ jobs:
strategy: strategy:
matrix: matrix:
compiler: [clang++] compiler: [clang++]
id_type: [uint32, uint64]
include:
- id_type: uint64
id_type_option: -DENTT_BUILD_UINT64=ON
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -20,7 +24,7 @@ jobs:
env: env:
CXX: ${{ matrix.compiler }} CXX: ${{ matrix.compiler }}
run: | run: |
cmake -DENTT_USE_SANITIZER=ON -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON .. cmake -DENTT_USE_SANITIZER=ON -DENTT_BUILD_TESTING=ON -DENTT_BUILD_LIB=ON -DENTT_BUILD_EXAMPLE=ON ${{ matrix.id_type_option }} ..
make -j4 make -j4
- name: Run tests - name: Run tests
working-directory: build working-directory: build

View File

@@ -173,6 +173,7 @@ if(ENTT_BUILD_TESTING)
option(ENTT_BUILD_EXAMPLE "Build examples." OFF) option(ENTT_BUILD_EXAMPLE "Build examples." OFF)
option(ENTT_BUILD_LIB "Build lib tests." OFF) option(ENTT_BUILD_LIB "Build lib tests." OFF)
option(ENTT_BUILD_SNAPSHOT "Build snapshot test with Cereal." OFF) option(ENTT_BUILD_SNAPSHOT "Build snapshot test with Cereal." OFF)
option(ENTT_BUILD_UINT64 "Build using 64b entity identifiers" OFF)
include(CTest) include(CTest)
enable_testing() enable_testing()

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
#define ENTT_VERSION_MAJOR 3 #define ENTT_VERSION_MAJOR 3
#define ENTT_VERSION_MINOR 8 #define ENTT_VERSION_MINOR 8
#define ENTT_VERSION_PATCH 0 #define ENTT_VERSION_PATCH 1
#endif #endif

View File

@@ -422,68 +422,6 @@ template<typename... List>
using value_list_cat_t = typename value_list_cat<List...>::type; using value_list_cat_t = typename value_list_cat<List...>::type;
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
namespace internal {
template<typename>
[[nodiscard]] constexpr bool is_equality_comparable(...) { return false; }
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<0>)
-> decltype(std::declval<Type>() == std::declval<Type>()) { return true; }
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<1>)
-> decltype(std::declval<typename Type::value_type>(), std::declval<Type>() == std::declval<Type>()) {
if constexpr(std::is_same_v<typename Type::value_type, Type>) {
return is_equality_comparable<Type>(choice<0>);
} else {
return is_equality_comparable<typename Type::value_type>(choice<2>);
}
}
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<2>)
-> decltype(std::declval<typename Type::mapped_type>(), std::declval<Type>() == std::declval<Type>()) {
return is_equality_comparable<typename Type::key_type>(choice<2>) && is_equality_comparable<typename Type::mapped_type>(choice<2>);
}
}
/**
* Internal details not to be documented.
* @endcond
*/
/**
* @brief Provides the member constant `value` to true if a given type is
* equality comparable, false otherwise.
* @tparam Type The type to test.
*/
template<typename Type, typename = void>
struct is_equality_comparable: std::bool_constant<internal::is_equality_comparable<Type>(choice<2>)> {};
/**
* @brief Helper variable template.
* @tparam Type The type to test.
*/
template<class Type>
inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
/*! @brief Same as std::is_invocable, but with tuples. */ /*! @brief Same as std::is_invocable, but with tuples. */
template<typename, typename> template<typename, typename>
struct is_applicable: std::false_type {}; struct is_applicable: std::false_type {};
@@ -624,6 +562,70 @@ template<typename Type, typename It>
inline constexpr bool is_iterator_type_v = is_iterator_type<Type, It>::value; inline constexpr bool is_iterator_type_v = is_iterator_type<Type, It>::value;
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
namespace internal {
template<typename>
[[nodiscard]] constexpr bool is_equality_comparable(...) { return false; }
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<0>)
-> decltype(std::declval<Type>() == std::declval<Type>()) { return true; }
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<1>)
-> decltype(std::declval<typename Type::value_type>(), std::declval<Type>() == std::declval<Type>()) {
if constexpr(is_iterator_v<Type>) {
return true;
} else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
return is_equality_comparable<Type>(choice<0>);
} else {
return is_equality_comparable<typename Type::value_type>(choice<2>);
}
}
template<typename Type>
[[nodiscard]] constexpr auto is_equality_comparable(choice_t<2>)
-> decltype(std::declval<typename Type::mapped_type>(), std::declval<Type>() == std::declval<Type>()) {
return is_equality_comparable<typename Type::key_type>(choice<2>) && is_equality_comparable<typename Type::mapped_type>(choice<2>);
}
}
/**
* Internal details not to be documented.
* @endcond
*/
/**
* @brief Provides the member constant `value` to true if a given type is
* equality comparable, false otherwise.
* @tparam Type The type to test.
*/
template<typename Type, typename = void>
struct is_equality_comparable: std::bool_constant<internal::is_equality_comparable<Type>(choice<2>)> {};
/**
* @brief Helper variable template.
* @tparam Type The type to test.
*/
template<class Type>
inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
/** /**
* @brief Transcribes the constness of a type to another type. * @brief Transcribes the constness of a type to another type.
* @tparam To The type to which to transcribe the constness. * @tparam To The type to which to transcribe the constness.

View File

@@ -126,7 +126,7 @@ public:
* @return A properly constructed identifier. * @return A properly constructed identifier.
*/ */
[[nodiscard]] static constexpr value_type construct(const entity_type entity = traits_type::entity_mask, const version_type version = traits_type::version_mask) ENTT_NOEXCEPT { [[nodiscard]] static constexpr value_type construct(const entity_type entity = traits_type::entity_mask, const version_type version = traits_type::version_mask) ENTT_NOEXCEPT {
return value_type{(entity & traits_type::entity_mask) | (version << traits_type::entity_shift)}; return value_type{(entity & traits_type::entity_mask) | (static_cast<entity_type>(version) << traits_type::entity_shift)};
} }
}; };

View File

@@ -55,7 +55,7 @@ class basic_snapshot {
while(begin != last) { while(begin != last) {
const auto entt = *(begin++); const auto entt = *(begin++);
((reg->template all_of<Component>(entt) ? ++size[Index] : size[Index]), ...); ((reg->template all_of<Component>(entt) ? ++size[Index] : 0u), ...);
} }
(get<Component>(archive, size[Index], first, last), ...); (get<Component>(archive, size[Index], first, last), ...);

View File

@@ -164,11 +164,11 @@ class basic_sparse_set {
}; };
[[nodiscard]] static auto page(const Entity entt) ENTT_NOEXCEPT { [[nodiscard]] static auto page(const Entity entt) ENTT_NOEXCEPT {
return size_type{traits_type::to_entity(entt) / sparse_page}; return static_cast<size_type>(traits_type::to_entity(entt) / sparse_page);
} }
[[nodiscard]] static auto offset(const Entity entt) ENTT_NOEXCEPT { [[nodiscard]] static auto offset(const Entity entt) ENTT_NOEXCEPT {
return size_type{traits_type::to_entity(entt) & (sparse_page - 1)}; return static_cast<size_type>(traits_type::to_entity(entt) & (sparse_page - 1));
} }
[[nodiscard]] auto assure_page(const std::size_t idx) { [[nodiscard]] auto assure_page(const std::size_t idx) {
@@ -246,7 +246,7 @@ protected:
*/ */
virtual void swap_and_pop(const Entity entt, [[maybe_unused]] void *ud) { virtual void swap_and_pop(const Entity entt, [[maybe_unused]] void *ud) {
auto &ref = sparse[page(entt)][offset(entt)]; auto &ref = sparse[page(entt)][offset(entt)];
const auto pos = size_type{traits_type::to_entity(ref)}; const auto pos = static_cast<size_type>(traits_type::to_entity(ref));
ENTT_ASSERT(packed[pos] == entt, "Invalid entity identifier"); ENTT_ASSERT(packed[pos] == entt, "Invalid entity identifier");
auto &last = packed[--count]; auto &last = packed[--count];
@@ -265,7 +265,7 @@ protected:
*/ */
virtual void in_place_pop(const Entity entt, [[maybe_unused]] void *ud) { virtual void in_place_pop(const Entity entt, [[maybe_unused]] void *ud) {
auto &ref = sparse[page(entt)][offset(entt)]; auto &ref = sparse[page(entt)][offset(entt)];
const auto pos = size_type{traits_type::to_entity(ref)}; const auto pos = static_cast<size_type>(traits_type::to_entity(ref));
ENTT_ASSERT(packed[pos] == entt, "Invalid entity identifier"); ENTT_ASSERT(packed[pos] == entt, "Invalid entity identifier");
packed[pos] = std::exchange(free_list, traits_type::construct(static_cast<typename traits_type::entity_type>(pos))); packed[pos] = std::exchange(free_list, traits_type::construct(static_cast<typename traits_type::entity_type>(pos)));
@@ -367,7 +367,7 @@ public:
* @return The next slot available for insertion. * @return The next slot available for insertion.
*/ */
[[nodiscard]] size_type slot() const ENTT_NOEXCEPT { [[nodiscard]] size_type slot() const ENTT_NOEXCEPT {
return free_list == null ? count : size_type{traits_type::to_entity(free_list)}; return free_list == null ? count : static_cast<size_type>(traits_type::to_entity(free_list));
} }
/** /**
@@ -533,7 +533,7 @@ public:
*/ */
[[nodiscard]] size_type index(const entity_type entt) const ENTT_NOEXCEPT { [[nodiscard]] size_type index(const entity_type entt) const ENTT_NOEXCEPT {
ENTT_ASSERT(contains(entt), "Set does not contain entity"); ENTT_ASSERT(contains(entt), "Set does not contain entity");
return size_type{traits_type::to_entity(sparse[page(entt)][offset(entt)])}; return static_cast<size_type>(traits_type::to_entity(sparse[page(entt)][offset(entt)]));
} }
/** /**
@@ -593,8 +593,8 @@ public:
return emplace_back(entt); return emplace_back(entt);
} else { } else {
ENTT_ASSERT(!contains(entt), "Set already contains entity"); ENTT_ASSERT(!contains(entt), "Set already contains entity");
const auto pos = size_type{traits_type::to_entity(free_list)}; const auto pos = static_cast<size_type>(traits_type::to_entity(free_list));
sparse[page(entt)][offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(pos)); assure_page(page(entt))[offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(pos));
free_list = std::exchange(packed[pos], entt); free_list = std::exchange(packed[pos], entt);
return pos; return pos;
} }
@@ -724,8 +724,8 @@ public:
auto &entt = sparse[page(lhs)][offset(lhs)]; auto &entt = sparse[page(lhs)][offset(lhs)];
auto &other = sparse[page(rhs)][offset(rhs)]; auto &other = sparse[page(rhs)][offset(rhs)];
const auto from = size_type{traits_type::to_entity(entt)}; const auto from = static_cast<size_type>(traits_type::to_entity(entt));
const auto to = size_type{traits_type::to_entity(other)}; const auto to = static_cast<size_type>(traits_type::to_entity(other));
// basic no-leak guarantee (with invalid state) if swapping throws // basic no-leak guarantee (with invalid state) if swapping throws
swap_at(from, to); swap_at(from, to);

View File

@@ -182,6 +182,7 @@ class meta_any {
static_cast<meta_any *>(to)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from))); static_cast<meta_any *>(to)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from)));
} }
} }
break;
case operation::SEQ: case operation::SEQ:
if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) { if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
*static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, std::move(const_cast<any &>(from)) }; *static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, std::move(const_cast<any &>(from)) };

View File

@@ -65,6 +65,14 @@ function(SETUP_TARGET TARGET_NAME)
NOMINMAX NOMINMAX
${ARGN} ${ARGN}
) )
if(ENTT_BUILD_UINT64)
target_compile_definitions(
${TARGET_NAME}
PRIVATE
ENTT_ID_TYPE=std::uint64_t
)
endif()
endfunction() endfunction()
add_library(odr OBJECT odr.cpp) add_library(odr OBJECT odr.cpp)

View File

@@ -4,6 +4,21 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <entt/core/hashed_string.hpp> #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) { 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{"foo"}), entt::hashed_string>);
static_assert(std::is_same_v<decltype(entt::basic_hashed_string{L"foo"}), entt::hashed_wstring>); static_assert(std::is_same_v<decltype(entt::basic_hashed_string{L"foo"}), entt::hashed_wstring>);
@@ -29,8 +44,8 @@ TEST(HashedString, Functionalities) {
entt::hashed_string hs{"foobar"}; entt::hashed_string hs{"foobar"};
ASSERT_EQ(static_cast<hash_type>(hs), 0xbf9cf968); ASSERT_EQ(static_cast<hash_type>(hs), foobar_v);
ASSERT_EQ(hs.value(), 0xbf9cf968); ASSERT_EQ(hs.value(), foobar_v);
ASSERT_EQ(foo_hs, "foo"_hs); ASSERT_EQ(foo_hs, "foo"_hs);
ASSERT_NE(bar_hs, "foo"_hs); ASSERT_NE(bar_hs, "foo"_hs);
@@ -59,9 +74,9 @@ TEST(HashedString, Correctness) {
const char *foobar = "foobar"; const char *foobar = "foobar";
std::string_view view{"foobar__", 6}; std::string_view view{"foobar__", 6};
ASSERT_EQ(entt::hashed_string{foobar}, 0xbf9cf968); ASSERT_EQ(entt::hashed_string{foobar}, foobar_v);
ASSERT_EQ(entt::hashed_string::value(foobar), 0xbf9cf968); ASSERT_EQ(entt::hashed_string::value(foobar), foobar_v);
ASSERT_EQ(entt::hashed_string::value(view.data(), view.size()), 0xbf9cf968); ASSERT_EQ(entt::hashed_string::value(view.data(), view.size()), foobar_v);
} }
TEST(HashedString, Constexprness) { TEST(HashedString, Constexprness) {
@@ -69,13 +84,13 @@ TEST(HashedString, Constexprness) {
constexpr std::string_view view{"foobar__", 6}; constexpr std::string_view view{"foobar__", 6};
static_assert(entt::hashed_string{"quux"} == "quux"_hs); static_assert(entt::hashed_string{"quux"} == "quux"_hs);
static_assert(entt::hashed_string{"foobar"} == 0xbf9cf968); static_assert(entt::hashed_string{"foobar"} == foobar_v);
static_assert(entt::hashed_string::value("quux") == "quux"_hs); static_assert(entt::hashed_string::value("quux") == "quux"_hs);
static_assert(entt::hashed_string::value("foobar") == 0xbf9cf968); static_assert(entt::hashed_string::value("foobar") == foobar_v);
static_assert(entt::hashed_string::value("quux", 4) == "quux"_hs); static_assert(entt::hashed_string::value("quux", 4) == "quux"_hs);
static_assert(entt::hashed_string::value(view.data(), view.size()) == 0xbf9cf968); static_assert(entt::hashed_string::value(view.data(), view.size()) == foobar_v);
} }
TEST(HashedWString, Functionalities) { TEST(HashedWString, Functionalities) {
@@ -98,8 +113,8 @@ TEST(HashedWString, Functionalities) {
entt::hashed_wstring hws{L"foobar"}; entt::hashed_wstring hws{L"foobar"};
ASSERT_EQ(static_cast<hash_type>(hws), 0xbf9cf968); ASSERT_EQ(static_cast<hash_type>(hws), foobar_v);
ASSERT_EQ(hws.value(), 0xbf9cf968); ASSERT_EQ(hws.value(), foobar_v);
ASSERT_EQ(foo_hws, L"foo"_hws); ASSERT_EQ(foo_hws, L"foo"_hws);
ASSERT_NE(bar_hws, L"foo"_hws); ASSERT_NE(bar_hws, L"foo"_hws);
@@ -118,9 +133,9 @@ TEST(HashedWString, Correctness) {
const wchar_t *foobar = L"foobar"; const wchar_t *foobar = L"foobar";
std::wstring_view view{L"foobar__", 6}; std::wstring_view view{L"foobar__", 6};
ASSERT_EQ(entt::hashed_wstring{foobar}, 0xbf9cf968); ASSERT_EQ(entt::hashed_wstring{foobar}, foobar_v);
ASSERT_EQ(entt::hashed_wstring::value(foobar), 0xbf9cf968); ASSERT_EQ(entt::hashed_wstring::value(foobar), foobar_v);
ASSERT_EQ(entt::hashed_wstring::value(view.data(), view.size()), 0xbf9cf968); ASSERT_EQ(entt::hashed_wstring::value(view.data(), view.size()), foobar_v);
} }
TEST(HashedWString, Constexprness) { TEST(HashedWString, Constexprness) {
@@ -128,11 +143,11 @@ TEST(HashedWString, Constexprness) {
constexpr std::wstring_view view{L"foobar__", 6}; constexpr std::wstring_view view{L"foobar__", 6};
static_assert(entt::hashed_wstring{L"quux"} == L"quux"_hws); static_assert(entt::hashed_wstring{L"quux"} == L"quux"_hws);
static_assert(entt::hashed_wstring{L"foobar"} == 0xbf9cf968); 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"quux") == L"quux"_hws);
static_assert(entt::hashed_wstring::value(L"foobar") == 0xbf9cf968); static_assert(entt::hashed_wstring::value(L"foobar") == foobar_v);
static_assert(entt::hashed_wstring::value(L"quux", 4) == L"quux"_hws); static_assert(entt::hashed_wstring::value(L"quux", 4) == L"quux"_hws);
static_assert(entt::hashed_wstring::value(view.data(), view.size()) == 0xbf9cf968); static_assert(entt::hashed_wstring::value(view.data(), view.size()) == foobar_v);
} }

View File

@@ -101,6 +101,7 @@ TEST(TypeTraits, IsEqualityComparable) {
static_assert(entt::is_equality_comparable_v<std::vector<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, 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::unordered_map<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<nlohmann_json_like>);
static_assert(!entt::is_equality_comparable_v<not_comparable>); static_assert(!entt::is_equality_comparable_v<not_comparable>);

View File

@@ -30,7 +30,7 @@ TEST(Entity, Traits) {
ASSERT_EQ(traits_type::construct(), static_cast<entt::entity>(entt::null)); ASSERT_EQ(traits_type::construct(), static_cast<entt::entity>(entt::null));
ASSERT_EQ(traits_type::construct(), static_cast<entt::entity>(entt::tombstone)); ASSERT_EQ(traits_type::construct(), static_cast<entt::entity>(entt::tombstone));
ASSERT_EQ(traits_type::construct(), entt::entity{0xFFFFFFFF}); ASSERT_EQ(traits_type::construct(), entt::entity{~entt::id_type{}});
} }
TEST(Entity, Null) { TEST(Entity, Null) {

View File

@@ -65,7 +65,6 @@ TEST(Helper, ToEntity) {
ASSERT_EQ(entt::to_entity(registry, registry.get<int>(next)), next); ASSERT_EQ(entt::to_entity(registry, registry.get<int>(next)), next);
ASSERT_EQ(&registry.get<int>(entity) + ENTT_PACKED_PAGE - 1u, &registry.get<int>(other)); ASSERT_EQ(&registry.get<int>(entity) + ENTT_PACKED_PAGE - 1u, &registry.get<int>(other));
ASSERT_NE(&registry.get<int>(entity) + ENTT_PACKED_PAGE, &registry.get<int>(next));
registry.destroy(other); registry.destroy(other);

View File

@@ -207,6 +207,19 @@ TEST(SparseSet, Emplace) {
ASSERT_EQ(set.index(entities[1u]), 0u); ASSERT_EQ(set.index(entities[1u]), 0u);
} }
TEST(SparseSet, EmplaceOutOfBounds) {
entt::sparse_set set{entt::deletion_policy::in_place};
entt::entity entities[2u]{entt::entity{0}, entt::entity{ENTT_SPARSE_PAGE}};
ASSERT_EQ(set.emplace(entities[0u]), 0u);
ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
set.erase(entities[0u]);
ASSERT_EQ(set.emplace(entities[1u]), 0u);
ASSERT_EQ(set.extent(), 2u * ENTT_SPARSE_PAGE);
}
TEST(SparseSet, Insert) { TEST(SparseSet, Insert) {
entt::sparse_set set{entt::deletion_policy::in_place}; entt::sparse_set set{entt::deletion_policy::in_place};
entt::entity entities[2u]; entt::entity entities[2u];