1#ifndef ENTT_META_META_HPP
2#define ENTT_META_META_HPP
9#include "../config/config.h"
10#include "../core/any.hpp"
11#include "../core/fwd.hpp"
12#include "../core/iterator.hpp"
13#include "../core/type_info.hpp"
14#include "../core/type_traits.hpp"
15#include "../core/utility.hpp"
16#include "../locator/locator.hpp"
17#include "adl_pointer.hpp"
22#include "type_traits.hpp"
55 template<
typename Type>
56 void rebind(Type &instance)
noexcept {
57 value_type_node = &internal::resolve<typename Type::value_type>;
58 const_reference_node = &internal::resolve<std::remove_const_t<std::remove_reference_t<typename Type::const_reference>>>;
67 const_only = std::is_const_v<Type>;
81 [[nodiscard]] inline explicit operator
bool() const noexcept;
85 internal::meta_type_node (*value_type_node)(
const internal::meta_context &){};
86 internal::meta_type_node (*const_reference_node)(
const internal::meta_context &){};
88 bool (*clear_fn)(
void *){};
89 bool (*reserve_fn)(
void *,
const size_type){};
90 bool (*resize_fn)(
void *,
const size_type){};
91 iterator (*begin_fn)(
const meta_ctx &,
void *,
const void *){};
92 iterator (*end_fn)(
const meta_ctx &,
void *,
const void *){};
93 iterator (*insert_fn)(
const meta_ctx &,
void *,
const void *,
const void *,
const iterator &){};
125 template<
typename Type>
127 key_type_node = &internal::resolve<typename Type::key_type>;
128 value_type_node = &internal::resolve<typename Type::value_type>;
131 mapped_type_node = &internal::resolve<typename Type::mapped_type>;
142 const_only = std::is_const_v<Type>;
146 [[nodiscard]]
inline bool key_only() const noexcept;
158 [[nodiscard]] inline explicit operator
bool() const noexcept;
162 internal::meta_type_node (*key_type_node)(
const internal::meta_context &){};
163 internal::meta_type_node (*mapped_type_node)(
const internal::meta_context &){};
164 internal::meta_type_node (*value_type_node)(
const internal::meta_context &){};
166 bool (*clear_fn)(
void *){};
167 bool (*reserve_fn)(
void *,
const size_type){};
168 iterator (*begin_fn)(
const meta_ctx &,
void *,
const void *){};
169 iterator (*end_fn)(
const meta_ctx &,
void *,
const void *){};
170 bool (*insert_fn)(
void *,
const void *,
const void *){};
171 size_type (*erase_fn)(
void *,
const void *){};
172 iterator (*find_fn)(
const meta_ctx &,
void *,
const void *,
const void *){};
182 using vtable_type = void(
const internal::meta_traits op,
const bool,
const void *,
void *);
184 template<
typename Type>
185 static std::enable_if_t<std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>> basic_vtable([[maybe_unused]]
const internal::meta_traits req, [[maybe_unused]]
const bool const_only, [[maybe_unused]]
const void *value, [[maybe_unused]]
void *other) {
186 if constexpr(is_meta_pointer_like_v<Type>) {
187 if(req == internal::meta_traits::is_meta_pointer_like) {
188 if constexpr(std::is_function_v<typename std::pointer_traits<Type>::element_type>) {
189 static_cast<meta_any *
>(other)->emplace<Type>(*
static_cast<const Type *
>(value));
190 }
else if constexpr(!std::is_void_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
193 if constexpr(std::is_constructible_v<bool, Type>) {
194 if(
const auto &pointer_like = *
static_cast<const Type *
>(value); pointer_like) {
204 if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
205 if(req == internal::meta_traits::is_meta_sequence_container) {
210 if constexpr(is_complete_v<meta_associative_container_traits<Type>>) {
211 if(req == internal::meta_traits::is_meta_associative_container) {
226 node{
storage ? other.node : internal::meta_type_node{}},
227 vtable{
storage ? other.vtable : &basic_vtable<void>} {}
242 vtable{&basic_vtable<void>} {}
250 template<
typename Type,
typename... Args>
251 explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
261 template<
typename Type,
typename... Args>
263 :
storage{std::in_place_type<Type>, std::forward<Args>(args)...},
265 node{internal::
resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx))},
266 vtable{&basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>} {}
273 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
283 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
285 :
meta_any{area, std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
295 node = node.resolve ? node.resolve(internal::meta_context::from(*ctx)) : node;
306 node = node.resolve ? node.resolve(internal::meta_context::from(*ctx)) : node;
320 :
storage{std::move(other.storage)},
322 node{std::exchange(other.node, internal::meta_type_node{})},
323 vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
340 vtable = other.vtable;
351 storage = std::move(other.storage);
353 node = std::exchange(other.node, internal::meta_type_node{});
354 vtable = std::exchange(other.vtable, &basic_vtable<void>);
364 template<
typename Type>
367 emplace<std::decay_t<Type>>(std::forward<Type>(value));
375 [[nodiscard]] const
void *
data() const noexcept {
380 [[nodiscard]]
void *
data() noexcept {
391 template<
typename... Args>
395 template<
typename... Args>
405 template<
typename Type>
423 template<
typename Type>
425 const auto other = internal::resolve<std::remove_cv_t<Type>>(internal::meta_context::from(*ctx));
426 return static_cast<const Type *
>(internal::try_cast(internal::meta_context::from(*ctx), node, other,
data()));
430 template<
typename Type>
432 if constexpr(std::is_const_v<Type>) {
433 return std::as_const(*this).try_cast<std::remove_const_t<Type>>();
435 const auto other = internal::resolve<std::remove_cv_t<Type>>(internal::meta_context::from(*ctx));
436 return static_cast<Type *
>(
const_cast<void *
>(internal::try_cast(internal::meta_context::from(*ctx), node, other,
data())));
445 template<
typename Type>
446 [[nodiscard]] Type
cast()
const {
447 auto *
const instance = try_cast<std::remove_reference_t<Type>>();
448 ENTT_ASSERT(instance,
"Invalid instance");
449 return static_cast<Type
>(*instance);
453 template<
typename Type>
456 auto *
const instance = try_cast<std::remove_reference_t<const Type>>();
457 ENTT_ASSERT(instance,
"Invalid instance");
458 return static_cast<Type
>(*instance);
475 if(
auto other = std::as_const(*this).allow_cast(
type); other) {
477 std::swap(*
this, other);
492 template<
typename Type>
494 if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
497 auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
507 template<
typename Type>
509 auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
510 return allow_cast(
meta_type{*ctx, other}) && (!(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) ||
storage.
data() !=
nullptr);
514 template<
typename Type,
typename... Args>
518 node = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
519 vtable = &basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
533 vtable = &basic_vtable<void>;
549 vtable(internal::meta_traits::is_meta_sequence_container,
true,
data(), &proxy);
559 vtable(internal::meta_traits::is_meta_associative_container,
policy() ==
meta_any_policy::cref, std::as_const(*this).data(), &proxy);
566 vtable(internal::meta_traits::is_meta_associative_container,
true,
data(), &proxy);
577 vtable(internal::meta_traits::is_meta_pointer_like,
true,
storage.
data(), &ret);
585 [[nodiscard]]
explicit operator bool() const noexcept {
586 return !(node.info ==
nullptr);
591 return (ctx == other.ctx) && ((!node.info && !other.node.info) || (node.info && other.node.info && *node.info == *other.node.info &&
storage == other.storage));
596 return !(*
this == other);
610 [[deprecated(
"use policy() and meta_any_policy instead")]] [[nodiscard]]
bool owner() const noexcept {
625 internal::meta_type_node node;
636template<
typename Type>
638 return meta_any{ctx, std::in_place_type<Type &&>, std::forward<Type>(value)};
647template<
typename Type>
690 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
692 :
any{ctx, std::in_place_type<Type &>, value} {}
699 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
717 :
any{area, std::move(other.
any)} {}
741 [[nodiscard]]
explicit operator bool() const noexcept {
742 return static_cast<bool>(
any);
747 return (
any == other.any);
752 return !(*
this == other);
793 return node->value ? node->type(internal::meta_context::from(*ctx)).from_void(*ctx,
nullptr, node->value.get()) :
meta_any{
meta_ctx_arg, *ctx};
801 return node->value ? node->type(internal::meta_context::from(*ctx)).from_void(*ctx, node->value.get(),
nullptr) :
meta_any{
meta_ctx_arg, *ctx};
808 [[nodiscard]]
explicit operator bool() const noexcept {
809 return (node !=
nullptr);
818 return (ctx == other.ctx && node == other.node);
822 const internal::meta_prop_node *node;
833 return !(lhs == rhs);
839 using size_type =
typename internal::meta_data_node::size_type;
868 return static_cast<bool>(node->traits & internal::meta_traits::is_const);
876 return static_cast<bool>(node->traits & internal::meta_traits::is_static);
889 template<typename Type>
891 return node->set && node->set(
meta_handle{*ctx, std::move(instance)},
meta_any{*ctx, std::forward<Type>(value)});
900 return node->get(*ctx,
meta_handle{*ctx, std::move(instance)});
914 [[nodiscard]]
meta_range<
meta_prop,
typename decltype(internal::meta_data_node::prop)::const_iterator>
prop()
const noexcept {
915 return {{*ctx, node->prop.cbegin()}, {*ctx, node->prop.cend()}};
924 const auto it = node->prop.find(key);
932 [[nodiscard]]
explicit operator bool() const noexcept {
933 return (node !=
nullptr);
938 return (ctx == other.ctx && node == other.node);
942 const internal::meta_data_node *node;
953 return !(lhs == rhs);
959 using size_type =
typename internal::meta_func_node::size_type;
988 return static_cast<bool>(node->traits & internal::meta_traits::is_const);
996 return static_cast<bool>(node->traits & internal::meta_traits::is_static);
1034 template<
typename... Args>
1036 meta_any arguments[
sizeof...(Args) + !
sizeof...(Args)]{{*ctx, std::forward<Args>(args)}...};
1037 return invoke(std::move(instance), arguments,
sizeof...(Args));
1042 return {{*ctx, node->prop.cbegin()}, {*ctx, node->prop.cend()}};
1051 const auto it = node->prop.find(key);
1067 [[nodiscard]]
explicit operator bool() const noexcept {
1068 return (node !=
nullptr);
1073 return (ctx == other.ctx && node == other.node);
1077 const internal::meta_func_node *node;
1088 return !(lhs == rhs);
1093 template<
typename Func>
1094 [[nodiscard]]
auto lookup(
meta_any *
const args,
const typename internal::meta_type_node::size_type sz, [[maybe_unused]]
bool constness, Func next)
const {
1095 decltype(next()) candidate =
nullptr;
1099 for(
auto curr = next(); curr; curr = next()) {
1100 if constexpr(std::is_same_v<std::decay_t<
decltype(*curr)>, internal::meta_func_node>) {
1101 if(constness && !
static_cast<bool>(curr->traits & internal::meta_traits::is_const)) {
1106 if(curr->arity == sz) {
1110 for(; pos < sz && args[pos]; ++pos) {
1111 const auto other = curr->arg(*ctx, pos);
1112 const auto type = args[pos].type();
1114 if(
const auto &
info = other.info();
info == type.info()) {
1116 }
else if(!((type.node.details && (type.node.details->base.contains(
info.
hash()) || type.node.details->conv.contains(
info.
hash()))) || (type.node.conversion_helper && other.node.conversion_helper))) {
1122 if(!candidate || match > same) {
1126 }
else if(match == same) {
1127 if constexpr(std::is_same_v<std::decay_t<
decltype(*curr)>, internal::meta_func_node>) {
1128 if(
static_cast<bool>(curr->traits & internal::meta_traits::is_const) !=
static_cast<bool>(candidate->traits & internal::meta_traits::is_const)) {
1129 candidate =
static_cast<bool>(candidate->traits & internal::meta_traits::is_const) ? curr : candidate;
1141 return ambiguous ? nullptr : candidate;
1146 using size_type =
typename internal::meta_type_node::size_type;
1168 :
meta_type{area, curr.type(internal::meta_context::from(area))} {}
1191 return node.size_of;
1200 return static_cast<bool>(node.traits & internal::meta_traits::is_arithmetic);
1208 return static_cast<bool>(node.traits & internal::meta_traits::is_integral);
1216 return static_cast<bool>(node.traits & internal::meta_traits::is_signed);
1224 return static_cast<bool>(node.traits & internal::meta_traits::is_array);
1232 return static_cast<bool>(node.traits & internal::meta_traits::is_enum);
1240 return static_cast<bool>(node.traits & internal::meta_traits::is_class);
1257 return {*ctx, node.remove_pointer(internal::meta_context::from(*ctx))};
1265 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_pointer_like);
1273 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_sequence_container);
1281 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_associative_container);
1291 return (node.templ.arity != 0u);
1299 return node.templ.arity;
1307 return node.templ.type ?
meta_type{*ctx, node.templ.type(internal::meta_context::from(*ctx))} :
meta_type{};
1326 return (internal::try_cast(internal::meta_context::from(*ctx), node, other.node,
this) !=
nullptr);
1335 return (internal::try_convert(internal::meta_context::from(*ctx), node, other.info(), other.is_arithmetic() || other.is_enum(),
nullptr, [](
const void *,
auto &&...args) { return ((static_cast<void>(args), 1) + ... + 0u); }) != 0u);
1342 [[nodiscard]]
meta_range<
meta_type,
typename decltype(internal::meta_type_descriptor::base)::const_iterator>
base()
const noexcept {
1343 using range_type =
meta_range<
meta_type,
typename decltype(internal::meta_type_descriptor::base)::const_iterator>;
1344 return node.details ? range_type{{*ctx, node.details->base.cbegin()}, {*ctx, node.details->base.cend()}} : range_type{};
1351 [[nodiscard]]
meta_range<
meta_data,
typename decltype(internal::meta_type_descriptor::data)::const_iterator>
data()
const noexcept {
1352 using range_type =
meta_range<
meta_data,
typename decltype(internal::meta_type_descriptor::data)::const_iterator>;
1353 return node.details ? range_type{{*ctx, node.details->data.cbegin()}, {*ctx, node.details->data.cend()}} : range_type{};
1362 const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), node,
id);
1370 [[nodiscard]]
meta_range<
meta_func,
typename decltype(internal::meta_type_descriptor::func)::const_iterator>
func()
const noexcept {
1371 using return_type =
meta_range<
meta_func,
typename decltype(internal::meta_type_descriptor::func)::const_iterator>;
1372 return node.details ? return_type{{*ctx, node.details->func.cbegin()}, {*ctx, node.details->func.cend()}} : return_type{};
1384 const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), node,
id);
1400 if(
const auto *candidate = lookup(args, sz,
false, [first = node.details->ctor.cbegin(), last = node.details->ctor.cend()]()
mutable { return first == last ? nullptr : &(first++)->second; }); candidate) {
1401 return candidate->
invoke(*ctx, args);
1405 if(sz == 0u && node.default_constructor) {
1406 return node.default_constructor(*ctx);
1418 template<
typename... Args>
1420 meta_any arguments[
sizeof...(Args) + !
sizeof...(Args)]{{*ctx, std::forward<Args>(args)}...};
1421 return construct(arguments,
sizeof...(Args));
1430 return (element && node.from_void) ? node.from_void(*ctx, element,
nullptr) :
meta_any{
meta_ctx_arg, *ctx};
1435 return (element && node.from_void) ? node.from_void(*ctx,
nullptr, element) :
meta_any{
meta_ctx_arg, *ctx};
1452 if(
auto it = node.details->func.find(
id); it != node.details->func.cend()) {
1453 if(
const auto *candidate = lookup(args, sz, instance && (instance->
data() ==
nullptr), [curr = &it->second]()
mutable { return curr ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) {
1459 for(
auto &&curr:
base()) {
1460 if(
auto elem = curr.second.invoke(
id, *instance.operator->(), args, sz); elem) {
1476 template<
typename... Args>
1478 meta_any arguments[
sizeof...(Args) + !
sizeof...(Args)]{{*ctx, std::forward<Args>(args)}...};
1479 return invoke(
id, std::move(instance), arguments,
sizeof...(Args));
1490 template<
typename Type>
1492 const auto candidate =
data(
id);
1493 return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
1503 const auto candidate =
data(
id);
1511 [[nodiscard]]
meta_range<
meta_prop,
typename decltype(internal::meta_type_descriptor::prop)::const_iterator>
prop()
const noexcept {
1512 using range_type =
meta_range<
meta_prop,
typename decltype(internal::meta_type_descriptor::prop)::const_iterator>;
1513 return node.details ? range_type{{*ctx, node.details->prop.cbegin()}, {*ctx, node.details->prop.cend()}} : range_type{};
1522 const auto *elem = internal::look_for<&internal::meta_type_descriptor::prop>(internal::meta_context::from(*ctx), node, key);
1530 [[nodiscard]]
explicit operator bool() const noexcept {
1531 return !(ctx ==
nullptr);
1536 return (ctx == other.ctx) && ((!node.info && !other.node.info) || (node.info && other.node.info && *node.info == *other.node.info));
1540 internal::meta_type_node node;
1551 return !(lhs == rhs);
1558template<
typename... Args>
1560 return type().
invoke(
id, *
this, std::forward<Args>(args)...);
1563template<
typename... Args>
1565 return type().
invoke(
id, *
this, std::forward<Args>(args)...);
1568template<
typename Type>
1570 return type().
set(
id, *
this, std::forward<Type>(value));
1583 if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<
decltype(args)>>, internal::meta_type_node> || ...)) {
1584 return (args.from_void(*ctx,
nullptr, instance), ...);
1585 }
else if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<
decltype(args)>>, internal::meta_conv_node> || ...)) {
1586 return (args.conv(*ctx, instance), ...);
1587 }
else if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<
decltype(args)>>,
decltype(internal::meta_type_node::conversion_helper)> || ...)) {
1590 const auto value = (args(
nullptr, instance), ...);
1591 other.node.conversion_helper(other.data(), &value);
1602 return value &&
storage.assign(value.storage);
1606 if(*node.info == *other.node.info) {
1607 return storage.assign(std::move(other.storage));
1610 return assign(std::as_const(other));
1614 return meta_type{*ctx, node->type(internal::meta_context::from(*ctx))};
1618 return index < arity() ? node->arg(*ctx, index) :
meta_type{};
1622 return meta_type{*ctx, node->ret(internal::meta_context::from(*ctx))};
1626 return index < arity() ? node->arg(*ctx, index) :
meta_type{};
1630class meta_sequence_container::meta_iterator final {
1631 using vtable_type = void(
const void *,
const std::ptrdiff_t,
meta_any *);
1633 template<
typename It>
1634 static void basic_vtable(
const void *value,
const std::ptrdiff_t offset,
meta_any *other) {
1635 const auto &it = *
static_cast<const It *
>(value);
1636 other ? other->
emplace<
decltype(*it)>(*it) : std::advance(
const_cast<It &
>(it), offset);
1640 using difference_type = std::ptrdiff_t;
1641 using value_type = meta_any;
1642 using pointer = input_iterator_pointer<value_type>;
1643 using reference = value_type;
1644 using iterator_category = std::input_iterator_tag;
1645 using iterator_concept = std::bidirectional_iterator_tag;
1647 meta_iterator() noexcept
1648 : meta_iterator{locator<meta_ctx>::value_or()} {}
1650 meta_iterator(
const meta_ctx &area) noexcept
1653 template<
typename It>
1654 meta_iterator(
const meta_ctx &area, It iter) noexcept
1656 vtable{&basic_vtable<It>},
1659 meta_iterator &operator++() noexcept {
1660 vtable(
handle.data(), 1,
nullptr);
1664 meta_iterator operator++(
int value)
noexcept {
1665 meta_iterator orig = *
this;
1666 vtable(
handle.data(), ++value,
nullptr);
1670 meta_iterator &operator--() noexcept {
1671 vtable(
handle.data(), -1,
nullptr);
1675 meta_iterator operator--(
int value)
noexcept {
1676 meta_iterator orig = *
this;
1677 vtable(
handle.data(), --value,
nullptr);
1681 [[nodiscard]] reference operator*()
const {
1683 vtable(
handle.data(), 0, &other);
1687 [[nodiscard]] pointer operator->()
const {
1691 [[nodiscard]]
explicit operator bool() const noexcept {
1692 return static_cast<bool>(
handle);
1695 [[nodiscard]]
bool operator==(
const meta_iterator &other)
const noexcept {
1696 return handle == other.handle;
1699 [[nodiscard]]
bool operator!=(
const meta_iterator &other)
const noexcept {
1700 return !(*
this == other);
1703 [[nodiscard]]
const any &base() const noexcept {
1708 const meta_ctx *ctx{};
1709 vtable_type *vtable{};
1713class meta_associative_container::meta_iterator final {
1714 using vtable_type = void(
const void *, std::pair<meta_any, meta_any> *);
1716 template<
bool KeyOnly,
typename It>
1717 static void basic_vtable(
const void *value, std::pair<meta_any, meta_any> *other) {
1718 if(
const auto &it = *
static_cast<const It *
>(value); other) {
1719 if constexpr(KeyOnly) {
1720 other->first.emplace<
decltype(*it)>(*it);
1722 other->first.emplace<
decltype((it->first))>(it->first);
1723 other->second.emplace<
decltype((it->second))>(it->second);
1726 ++
const_cast<It &
>(it);
1731 using difference_type = std::ptrdiff_t;
1732 using value_type = std::pair<meta_any, meta_any>;
1733 using pointer = input_iterator_pointer<value_type>;
1734 using reference = value_type;
1735 using iterator_category = std::input_iterator_tag;
1736 using iterator_concept = std::forward_iterator_tag;
1738 meta_iterator() noexcept
1739 : meta_iterator{locator<meta_ctx>::value_or()} {}
1741 meta_iterator(
const meta_ctx &area) noexcept
1744 template<
bool KeyOnly,
typename It>
1745 meta_iterator(
const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
1747 vtable{&basic_vtable<KeyOnly, It>},
1750 meta_iterator &operator++() noexcept {
1751 vtable(
handle.data(),
nullptr);
1755 meta_iterator operator++(
int)
noexcept {
1756 meta_iterator orig = *
this;
1757 vtable(
handle.data(),
nullptr);
1761 [[nodiscard]] reference operator*()
const {
1763 vtable(
handle.data(), &other);
1767 [[nodiscard]] pointer operator->()
const {
1771 [[nodiscard]]
explicit operator bool() const noexcept {
1772 return static_cast<bool>(
handle);
1775 [[nodiscard]]
bool operator==(
const meta_iterator &other)
const noexcept {
1776 return handle == other.handle;
1779 [[nodiscard]]
bool operator!=(
const meta_iterator &other)
const noexcept {
1780 return !(*
this == other);
1784 const meta_ctx *ctx{};
1785 vtable_type *vtable{};
1795 return value_type_node ?
meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} :
meta_type{};
1803 return size_fn(data);
1812 return !const_only && resize_fn(
const_cast<void *
>(data), sz);
1820 return !const_only && clear_fn(
const_cast<void *
>(data));
1829 return !const_only && reserve_fn(
const_cast<void *
>(data), sz);
1837 return begin_fn(*ctx, const_only ?
nullptr :
const_cast<void *
>(data), data);
1845 return end_fn(*ctx, const_only ?
nullptr :
const_cast<void *
>(data), data);
1856 if(
const auto vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.
allow_cast({*ctx, vtype}) || value.
allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) {
1857 const bool is_value_type = (value.
type().
info() == *vtype.info);
1858 return insert_fn(*ctx,
const_cast<void *
>(data), is_value_type ? std::as_const(value).data() :
nullptr, is_value_type ? nullptr : std::as_const(value).data(), it);
1870 return const_only ?
iterator{*ctx} : erase_fn(*ctx,
const_cast<void *
>(data), it);
1881 it.operator++(
static_cast<int>(pos) - 1);
1889[[nodiscard]]
inline meta_sequence_container::operator bool() const noexcept {
1890 return (data !=
nullptr);
1898 return (mapped_type_node ==
nullptr);
1906 return key_type_node ?
meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} :
meta_type{};
1914 return mapped_type_node ?
meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} :
meta_type{};
1919 return value_type_node ?
meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} :
meta_type{};
1924 return size_fn(data);
1929 return !const_only && clear_fn(
const_cast<void *
>(data));
1934 return !const_only && reserve_fn(
const_cast<void *
>(data), sz);
1939 return begin_fn(*ctx, const_only ?
nullptr :
const_cast<void *
>(data), data);
1944 return end_fn(*ctx, const_only ?
nullptr :
const_cast<void *
>(data), data);
1954 return !const_only && key.
allow_cast(
meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})
1955 && (!mapped_type_node || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))}))
1956 && insert_fn(
const_cast<void *
>(data), std::as_const(key).data(), std::as_const(value).data());
1965 return (!const_only && key.
allow_cast(
meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(
const_cast<void *
>(data), std::as_const(key).data()) : 0u;
1974 return key.
allow_cast(
meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ?
nullptr :
const_cast<void *
>(data), data, std::as_const(key).data()) :
iterator{*ctx};
1981[[nodiscard]]
inline meta_associative_container::operator bool() const noexcept {
1982 return (data !=
nullptr);
basic_any as_ref() noexcept
Aliasing constructor.
pointer data() const noexcept
Direct access to the internal packed array.
deletion_policy policy() const noexcept
Returns the deletion policy of a sparse set.
Basic storage implementation.
value_type & emplace(const entity_type entt, Args &&...args)
Assigns an entity to a storage and constructs its object.
Service locator, nothing more.
static Service & value_or(Args &&...args)
Returns a service if available or sets it from a fallback type.
std::uint32_t id_type
Alias declaration for type identifiers.
basic_handle< registry > handle
Alias declaration for the most common use case.
basic_any<> any
Alias declaration for the most common use case.
constexpr get_t< Type... > get
Variable template for lists of observed components.
meta_type resolve() noexcept
Returns the meta type associated with a given type.
constexpr meta_ctx_arg_t meta_ctx_arg
Constant of type meta_context_arg_t used to disambiguate calls.
meta_any forward_as_meta(const meta_ctx &ctx, Type &&value)
Forwards its argument and avoids copies for lvalue references.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
any_policy
Possible modes of an any object.
@ ref
Aliasing mode, the object points to a non-const element.
@ cref
Const aliasing mode, the object points to a const element.
@ owner
Default mode, the object owns the contained element.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Utility class to create an iterable object from a pair of iterators.
Implementation specific information about a type.
constexpr id_type hash() const noexcept
Type hash.