1#ifndef ENTT_CONTAINER_TABLE_HPP
2#define ENTT_CONTAINER_TABLE_HPP
9#include "../config/config.h"
10#include "../core/iterator.hpp"
18template<
typename... It>
21 friend class table_iterator;
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;
31 constexpr table_iterator() noexcept
34 constexpr table_iterator(It... from) noexcept
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)...} {}
41 constexpr table_iterator &operator++() noexcept {
42 return (++std::get<It>(it), ...), *
this;
45 constexpr table_iterator operator++(
int)
noexcept {
46 table_iterator orig = *
this;
47 return ++(*this), orig;
50 constexpr table_iterator &operator--() noexcept {
51 return (--std::get<It>(it), ...), *
this;
54 constexpr table_iterator operator--(
int)
noexcept {
55 table_iterator orig = *
this;
56 return operator--(), orig;
59 constexpr table_iterator &operator+=(
const difference_type value)
noexcept {
60 return ((std::get<It>(it) += value), ...), *
this;
63 constexpr table_iterator
operator+(
const difference_type value)
const noexcept {
64 table_iterator copy = *
this;
65 return (copy += value);
68 constexpr table_iterator &operator-=(
const difference_type value)
noexcept {
69 return (*
this += -value);
72 constexpr table_iterator operator-(
const difference_type value)
const noexcept {
73 return (*
this + -value);
76 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
77 return std::forward_as_tuple(std::get<It>(it)[value]...);
80 [[nodiscard]]
constexpr pointer operator->() const noexcept {
81 return {operator[](0)};
84 [[nodiscard]]
constexpr reference operator*() const noexcept {
88 template<
typename... Lhs,
typename... Rhs>
89 friend constexpr std::ptrdiff_t operator-(
const table_iterator<Lhs...> &,
const table_iterator<Rhs...> &)
noexcept;
91 template<
typename... Lhs,
typename... Rhs>
92 friend constexpr bool operator==(
const table_iterator<Lhs...> &,
const table_iterator<Rhs...> &)
noexcept;
94 template<
typename... Lhs,
typename... Rhs>
95 friend constexpr bool operator<(
const table_iterator<Lhs...> &,
const table_iterator<Rhs...> &)
noexcept;
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);
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);
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);
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);
121template<
typename... Lhs,
typename... Rhs>
122[[nodiscard]]
constexpr bool operator>(
const table_iterator<Lhs...> &lhs,
const table_iterator<Rhs...> &rhs)
noexcept {
126template<
typename... Lhs,
typename... Rhs>
127[[nodiscard]]
constexpr bool operator<=(
const table_iterator<Lhs...> &lhs,
const table_iterator<Rhs...> &rhs)
noexcept {
131template<
typename... Lhs,
typename... Rhs>
132[[nodiscard]]
constexpr bool operator>=(
const table_iterator<Lhs...> &lhs,
const table_iterator<Rhs...> &rhs)
noexcept {
150 using container_type = std::tuple<
Container...>;
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...>;
175 ENTT_ASSERT((((std::get<Container>(payload).
size() *
sizeof...(
Container)) == (std::get<Container>(payload).
size() + ...)) && ...),
"Unexpected container size");
184 ENTT_ASSERT((((std::get<Container>(payload).
size() *
sizeof...(
Container)) == (std::get<Container>(payload).
size() + ...)) && ...),
"Unexpected container size");
195 : payload{std::move(
other.payload)} {}
202 template<
typename Allocator>
212 template<
class Allocator>
215 ENTT_ASSERT((((std::get<Container>(payload).
size() *
sizeof...(
Container)) == (std::get<Container>(payload).
size() + ...)) && ...),
"Unexpected container size");
224 template<
class Allocator>
227 ENTT_ASSERT((((std::get<Container>(payload).
size() *
sizeof...(
Container)) == (std::get<Container>(payload).
size() + ...)) && ...),
"Unexpected container size");
236 template<
class Allocator>
277 (std::get<Container>(payload).reserve(
cap), ...);
286 return std::get<0>(payload).capacity();
291 (std::get<Container>(payload).shrink_to_fit(), ...);
299 return std::get<0>(payload).size();
307 return std::get<0>(payload).empty();
318 return {std::get<Container>(payload).cbegin()...};
328 return {std::get<Container>(payload).begin()...};
336 return {std::get<Container>(payload).cend()...};
346 return {std::get<Container>(payload).end()...};
357 return {std::get<Container>(payload).crbegin()...};
367 return {std::get<Container>(payload).rbegin()...};
376 return {std::get<Container>(payload).crend()...};
386 return {std::get<Container>(payload).rend()...};
395 template<
typename...
Args>
397 if constexpr(
sizeof...(Args) == 0
u) {
398 return std::forward_as_tuple(std::get<Container>(payload).
emplace_back()...);
400 return std::forward_as_tuple(std::get<Container>(payload).
emplace_back(std::forward<Args>(
args))...);
411 return {std::get<Container>(payload).erase(std::get<Container>(payload).
begin() +
diff)...};
419 ENTT_ASSERT(
pos <
size(),
"Index out of bounds");
429 ENTT_ASSERT(
pos <
size(),
"Index out of bounds");
430 return std::forward_as_tuple(std::get<Container>(payload)[
pos]...);
435 ENTT_ASSERT(
pos <
size(),
"Index out of bounds");
436 return std::forward_as_tuple(std::get<Container>(payload)[
pos]...);
441 (std::get<Container>(payload).clear(), ...);
445 container_type payload;
453template<
typename... Container,
typename Allocator>
454struct uses_allocator<
entt::basic_table<Container...>, Allocator>
455 : std::bool_constant<(std::uses_allocator_v<Container, Allocator> && ...)> {};
Basic table implementation.
std::size_t size_type
Unsigned integer type.
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
size_type capacity() const noexcept
Returns the number of rows that a table has currently allocated space for.
basic_table(basic_table &&other, const Allocator &allocator)
Allocator-extended move constructor.
size_type size() const noexcept
Returns the number of rows in a table.
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.
const_iterator end() const noexcept
Returns an iterator to the end.
iterator end() noexcept
Returns an iterator to the end.
reverse_iterator rend() noexcept
Returns a reverse iterator to the end.
void swap(basic_table &other) noexcept
Exchanges the contents with those of a given table.
const_iterator begin() const noexcept
Returns an iterator to the beginning.
internal::table_iterator< typename Container::iterator... > iterator
Input iterator type.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the beginning.
~basic_table()=default
Default destructor.
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the end.
bool empty() const noexcept
Checks whether a table is empty.
basic_table()
Default constructor.
iterator erase(const_iterator pos)
Removes a row from a table.
void shrink_to_fit()
Requests the removal of unused capacity.
basic_table(const Container &...container, const Allocator &allocator) noexcept
Copy constructs the underlying containers using a given allocator.
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
basic_table & operator=(basic_table &&other) noexcept
Move assignment operator.
void clear()
Clears a table.
basic_table(Container &&...container, const Allocator &allocator) noexcept
Move constructs the underlying containers using a given allocator.
void erase(const size_type pos)
Removes a row from a table.
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.
internal::table_iterator< typename Container::reverse_iterator... > reverse_iterator
Reverse iterator type.
void reserve(const size_type cap)
Increases the capacity of a table.
iterator begin() noexcept
Returns an iterator to the beginning.
basic_table(basic_table &&other) noexcept
Move constructor.
basic_table(const Container &...container) noexcept
Copy constructs the underlying containers.
basic_table(const Allocator &allocator)
Constructs the underlying containers using a given allocator.
basic_table(Container &&...container) noexcept
Move constructs the underlying containers.
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
std::tuple< typename Container::value_type &... > operator[](const size_type pos)
Returns the row data at specified location.
internal::table_iterator< typename Container::const_iterator... > const_iterator
Constant input iterator type.
const_iterator cend() const noexcept
Returns an iterator to the end.
std::tuple< typename Container::value_type &... > emplace(Args &&...args)
Appends a row to the end of a table.
internal::table_iterator< typename Container::const_reverse_iterator... > const_reverse_iterator
Constant reverse iterator type.
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
constexpr get_t< Type... > get
Variable template for lists of observed elements.
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.