EnTT 3.14.0
Loading...
Searching...
No Matches
table.hpp
1#ifndef ENTT_CONTAINER_TABLE_HPP
2#define ENTT_CONTAINER_TABLE_HPP
3
4#include <cstddef>
5#include <iterator>
6#include <tuple>
7#include <type_traits>
8#include <utility>
9#include "../config/config.h"
10#include "../core/iterator.hpp"
11#include "fwd.hpp"
12
13namespace entt {
14
16namespace internal {
17
18template<typename... It>
19class table_iterator {
20 template<typename...>
21 friend class table_iterator;
22
23public:
24 using value_type = decltype(std::forward_as_tuple(*std::declval<It>()...));
25 using pointer = input_iterator_pointer<value_type>;
26 using reference = value_type;
27 using difference_type = std::ptrdiff_t;
28 using iterator_category = std::input_iterator_tag;
29 using iterator_concept = std::random_access_iterator_tag;
30
31 constexpr table_iterator() noexcept
32 : it{} {}
33
34 constexpr table_iterator(It... from) noexcept
35 : it{from...} {}
36
37 template<typename... Other, typename = std::enable_if_t<(std::is_constructible_v<It, Other> && ...)>>
38 constexpr table_iterator(const table_iterator<Other...> &other) noexcept
39 : table_iterator{std::get<Other>(other.it)...} {}
40
41 constexpr table_iterator &operator++() noexcept {
42 return (++std::get<It>(it), ...), *this;
43 }
44
45 constexpr table_iterator operator++(int) noexcept {
46 table_iterator orig = *this;
47 return ++(*this), orig;
48 }
49
50 constexpr table_iterator &operator--() noexcept {
51 return (--std::get<It>(it), ...), *this;
52 }
53
54 constexpr table_iterator operator--(int) noexcept {
55 table_iterator orig = *this;
56 return operator--(), orig;
57 }
58
59 constexpr table_iterator &operator+=(const difference_type value) noexcept {
60 return ((std::get<It>(it) += value), ...), *this;
61 }
62
63 constexpr table_iterator operator+(const difference_type value) const noexcept {
64 table_iterator copy = *this;
65 return (copy += value);
66 }
67
68 constexpr table_iterator &operator-=(const difference_type value) noexcept {
69 return (*this += -value);
70 }
71
72 constexpr table_iterator operator-(const difference_type value) const noexcept {
73 return (*this + -value);
74 }
75
76 [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
77 return std::forward_as_tuple(std::get<It>(it)[value]...);
78 }
79
80 [[nodiscard]] constexpr pointer operator->() const noexcept {
81 return {operator[](0)};
82 }
83
84 [[nodiscard]] constexpr reference operator*() const noexcept {
85 return operator[](0);
86 }
87
88 template<typename... Lhs, typename... Rhs>
89 friend constexpr std::ptrdiff_t operator-(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
90
91 template<typename... Lhs, typename... Rhs>
92 friend constexpr bool operator==(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
93
94 template<typename... Lhs, typename... Rhs>
95 friend constexpr bool operator<(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
96
97private:
98 std::tuple<It...> it;
99};
100
101template<typename... Lhs, typename... Rhs>
102[[nodiscard]] constexpr std::ptrdiff_t operator-(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
103 return std::get<0>(lhs.it) - std::get<0>(rhs.it);
104}
105
106template<typename... Lhs, typename... Rhs>
107[[nodiscard]] constexpr bool operator==(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
108 return std::get<0>(lhs.it) == std::get<0>(rhs.it);
109}
110
111template<typename... Lhs, typename... Rhs>
112[[nodiscard]] constexpr bool operator!=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
113 return !(lhs == rhs);
114}
115
116template<typename... Lhs, typename... Rhs>
117[[nodiscard]] constexpr bool operator<(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
118 return std::get<0>(lhs.it) < std::get<0>(rhs.it);
119}
120
121template<typename... Lhs, typename... Rhs>
122[[nodiscard]] constexpr bool operator>(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
123 return rhs < lhs;
124}
125
126template<typename... Lhs, typename... Rhs>
127[[nodiscard]] constexpr bool operator<=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
128 return !(lhs > rhs);
129}
130
131template<typename... Lhs, typename... Rhs>
132[[nodiscard]] constexpr bool operator>=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
133 return !(lhs < rhs);
134}
135
136} // namespace internal
148template<typename... Container>
150 using container_type = std::tuple<Container...>;
151
152public:
154 using size_type = std::size_t;
156 using iterator = internal::table_iterator<typename Container::iterator...>;
158 using const_iterator = internal::table_iterator<typename Container::const_iterator...>;
160 using reverse_iterator = internal::table_iterator<typename Container::reverse_iterator...>;
162 using const_reverse_iterator = internal::table_iterator<typename Container::const_reverse_iterator...>;
163
166 : payload{} {
167 }
168
174 : payload{container...} {
175 ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
176 }
177
183 : payload{std::move(container)...} {
184 ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
185 }
186
188 basic_table(const basic_table &) = delete;
189
195 : payload{std::move(other.payload)} {}
196
202 template<typename Allocator>
203 explicit basic_table(const Allocator &allocator)
204 : payload{Container{allocator}...} {}
205
212 template<class Allocator>
213 basic_table(const Container &...container, const Allocator &allocator) noexcept
214 : payload{Container{container, allocator}...} {
215 ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
216 }
217
224 template<class Allocator>
226 : payload{Container{std::move(container), allocator}...} {
227 ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
228 }
229
236 template<class Allocator>
238 : payload{Container{std::move(std::get<Container>(other.payload)), allocator}...} {}
239
241 ~basic_table() = default;
242
248
255 swap(other);
256 return *this;
257 }
258
263 void swap(basic_table &other) noexcept {
264 using std::swap;
265 swap(payload, other.payload);
266 }
267
276 void reserve(const size_type cap) {
277 (std::get<Container>(payload).reserve(cap), ...);
278 }
279
286 return std::get<0>(payload).capacity();
287 }
288
291 (std::get<Container>(payload).shrink_to_fit(), ...);
292 }
293
299 return std::get<0>(payload).size();
300 }
301
307 return std::get<0>(payload).empty();
308 }
309
318 return {std::get<Container>(payload).cbegin()...};
319 }
320
323 return cbegin();
324 }
325
328 return {std::get<Container>(payload).begin()...};
329 }
330
336 return {std::get<Container>(payload).cend()...};
337 }
338
341 return cend();
342 }
343
346 return {std::get<Container>(payload).end()...};
347 }
348
357 return {std::get<Container>(payload).crbegin()...};
358 }
359
364
367 return {std::get<Container>(payload).rbegin()...};
368 }
369
376 return {std::get<Container>(payload).crend()...};
377 }
378
383
386 return {std::get<Container>(payload).rend()...};
387 }
388
395 template<typename... Args>
396 std::tuple<typename Container::value_type &...> emplace(Args &&...args) {
397 if constexpr(sizeof...(Args) == 0u) {
398 return std::forward_as_tuple(std::get<Container>(payload).emplace_back()...);
399 } else {
400 return std::forward_as_tuple(std::get<Container>(payload).emplace_back(std::forward<Args>(args))...);
401 }
402 }
403
410 const auto diff = pos - begin();
411 return {std::get<Container>(payload).erase(std::get<Container>(payload).begin() + diff)...};
412 }
413
418 void erase(const size_type pos) {
419 ENTT_ASSERT(pos < size(), "Index out of bounds");
420 erase(begin() + static_cast<typename const_iterator::difference_type>(pos));
421 }
422
428 [[nodiscard]] std::tuple<const typename Container::value_type &...> operator[](const size_type pos) const {
429 ENTT_ASSERT(pos < size(), "Index out of bounds");
430 return std::forward_as_tuple(std::get<Container>(payload)[pos]...);
431 }
432
434 [[nodiscard]] std::tuple<typename Container::value_type &...> operator[](const size_type pos) {
435 ENTT_ASSERT(pos < size(), "Index out of bounds");
436 return std::forward_as_tuple(std::get<Container>(payload)[pos]...);
437 }
438
440 void clear() {
441 (std::get<Container>(payload).clear(), ...);
442 }
443
444private:
445 container_type payload;
446};
447
448} // namespace entt
449
451namespace std {
452
453template<typename... Container, typename Allocator>
454struct uses_allocator<entt::basic_table<Container...>, Allocator>
455 : std::bool_constant<(std::uses_allocator_v<Container, Allocator> && ...)> {};
456
457} // namespace std
460#endif
Basic table implementation.
Definition table.hpp:149
std::size_t size_type
Unsigned integer type.
Definition table.hpp:154
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition table.hpp:380
size_type capacity() const noexcept
Returns the number of rows that a table has currently allocated space for.
Definition table.hpp:285
basic_table(basic_table &&other, const Allocator &allocator)
Allocator-extended move constructor.
Definition table.hpp:237
size_type size() const noexcept
Returns the number of rows in a table.
Definition table.hpp:298
basic_table & operator=(const basic_table &)=delete
Default copy assignment operator, deleted on purpose.
std::tuple< const typename Container::value_type &... > operator[](const size_type pos) const
Returns the row data at specified location.
Definition table.hpp:428
const_iterator end() const noexcept
Returns an iterator to the end.
Definition table.hpp:340
iterator end() noexcept
Returns an iterator to the end.
Definition table.hpp:345
reverse_iterator rend() noexcept
Returns a reverse iterator to the end.
Definition table.hpp:385
void swap(basic_table &other) noexcept
Exchanges the contents with those of a given table.
Definition table.hpp:263
const_iterator begin() const noexcept
Returns an iterator to the beginning.
Definition table.hpp:322
internal::table_iterator< typename Container::iterator... > iterator
Input iterator type.
Definition table.hpp:156
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the beginning.
Definition table.hpp:366
~basic_table()=default
Default destructor.
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the end.
Definition table.hpp:375
bool empty() const noexcept
Checks whether a table is empty.
Definition table.hpp:306
basic_table()
Default constructor.
Definition table.hpp:165
iterator erase(const_iterator pos)
Removes a row from a table.
Definition table.hpp:409
void shrink_to_fit()
Requests the removal of unused capacity.
Definition table.hpp:290
basic_table(const Container &...container, const Allocator &allocator) noexcept
Copy constructs the underlying containers using a given allocator.
Definition table.hpp:213
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition table.hpp:361
basic_table & operator=(basic_table &&other) noexcept
Move assignment operator.
Definition table.hpp:254
void clear()
Clears a table.
Definition table.hpp:440
basic_table(Container &&...container, const Allocator &allocator) noexcept
Move constructs the underlying containers using a given allocator.
Definition table.hpp:225
void erase(const size_type pos)
Removes a row from a table.
Definition table.hpp:418
basic_table(const basic_table &)=delete
Default copy constructor, deleted on purpose.
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition table.hpp:356
internal::table_iterator< typename Container::reverse_iterator... > reverse_iterator
Reverse iterator type.
Definition table.hpp:160
void reserve(const size_type cap)
Increases the capacity of a table.
Definition table.hpp:276
iterator begin() noexcept
Returns an iterator to the beginning.
Definition table.hpp:327
basic_table(basic_table &&other) noexcept
Move constructor.
Definition table.hpp:194
basic_table(const Container &...container) noexcept
Copy constructs the underlying containers.
Definition table.hpp:173
basic_table(const Allocator &allocator)
Constructs the underlying containers using a given allocator.
Definition table.hpp:203
basic_table(Container &&...container) noexcept
Move constructs the underlying containers.
Definition table.hpp:182
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition table.hpp:317
std::tuple< typename Container::value_type &... > operator[](const size_type pos)
Returns the row data at specified location.
Definition table.hpp:434
internal::table_iterator< typename Container::const_iterator... > const_iterator
Constant input iterator type.
Definition table.hpp:158
const_iterator cend() const noexcept
Returns an iterator to the end.
Definition table.hpp:335
std::tuple< typename Container::value_type &... > emplace(Args &&...args)
Appends a row to the end of a table.
Definition table.hpp:396
internal::table_iterator< typename Container::const_reverse_iterator... > const_reverse_iterator
Constant reverse iterator type.
Definition table.hpp:162
EnTT default namespace.
Definition dense_map.hpp:22
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
Definition memory.hpp:219
constexpr get_t< Type... > get
Variable template for lists of observed elements.
Definition fwd.hpp:168
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.