any/meta/poly: as_ref const and non-const overloads
This commit is contained in:
3
TODO
3
TODO
@@ -18,9 +18,8 @@
|
||||
- ...
|
||||
|
||||
WIP:
|
||||
* HP: any/meta_any/poly: ::REF -> ::CREF?
|
||||
* HP: const poly storage function for the registry
|
||||
* HP: meta, support for custom deref function other than operator*
|
||||
* HP: meta, as_cref_t other than as_ref_t
|
||||
* HP: headless (sparse set only) view
|
||||
* HP: pass the registry to pools, basic poly storage should have only component member
|
||||
* HP: make view pack work also with groups, make packs input iterator only, add view adapter for external sources
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace entt {
|
||||
|
||||
/*! @brief A SBO friendly, type-safe container for single values of any type. */
|
||||
class any {
|
||||
enum class operation { COPY, MOVE, DTOR, ADDR, CADDR, REF, TYPE };
|
||||
enum class operation { COPY, MOVE, DTOR, ADDR, CADDR, REF, CREF, TYPE };
|
||||
|
||||
using storage_type = std::aligned_storage_t<sizeof(double[2]), alignof(double[2])>;
|
||||
using vtable_type = const void *(const operation, const any &, const void *);
|
||||
@@ -39,7 +39,8 @@ class any {
|
||||
} else if constexpr(std::is_lvalue_reference_v<Type>) {
|
||||
switch(op) {
|
||||
case operation::REF:
|
||||
as_any(to).vtable = from.vtable;
|
||||
case operation::CREF:
|
||||
as_any(to).vtable = (op == operation::REF) ? basic_vtable<Type &> : basic_vtable<const Type &>;
|
||||
[[fallthrough]];
|
||||
case operation::COPY:
|
||||
case operation::MOVE:
|
||||
@@ -72,7 +73,8 @@ class any {
|
||||
case operation::CADDR:
|
||||
return instance;
|
||||
case operation::REF:
|
||||
as_any(to).vtable = basic_vtable<Type &>;
|
||||
case operation::CREF:
|
||||
as_any(to).vtable = (op == operation::REF) ? basic_vtable<Type &> : basic_vtable<const Type &>;
|
||||
as_any(to).instance = instance;
|
||||
break;
|
||||
case operation::TYPE:
|
||||
@@ -84,6 +86,10 @@ class any {
|
||||
case operation::COPY:
|
||||
as_any(to).instance = new Type{*static_cast<const Type *>(from.instance)};
|
||||
break;
|
||||
case operation::REF:
|
||||
case operation::CREF:
|
||||
as_any(to).vtable = (op == operation::REF) ? basic_vtable<Type &> : basic_vtable<const Type &>;
|
||||
[[fallthrough]];
|
||||
case operation::MOVE:
|
||||
as_any(to).instance = from.instance;
|
||||
break;
|
||||
@@ -93,10 +99,6 @@ class any {
|
||||
case operation::ADDR:
|
||||
case operation::CADDR:
|
||||
return from.instance;
|
||||
case operation::REF:
|
||||
as_any(to).vtable = basic_vtable<Type &>;
|
||||
as_any(to).instance = from.instance;
|
||||
break;
|
||||
case operation::TYPE:
|
||||
as_type_info(to) = type_id<Type>();
|
||||
break;
|
||||
@@ -251,12 +253,19 @@ public:
|
||||
* @param other A reference to an object that isn't necessarily initialized.
|
||||
* @return An any that shares a reference to an unmanaged object.
|
||||
*/
|
||||
[[nodiscard]] friend any as_ref(const any &other) ENTT_NOEXCEPT {
|
||||
[[nodiscard]] friend any as_ref(any &other) ENTT_NOEXCEPT {
|
||||
any ref{};
|
||||
other.vtable(operation::REF, other, &ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*! @copydoc as_ref */
|
||||
[[nodiscard]] friend any as_ref(const any &other) ENTT_NOEXCEPT {
|
||||
any ref{};
|
||||
other.vtable(operation::CREF, other, &ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
private:
|
||||
vtable_type *vtable;
|
||||
union { const void *instance; storage_type storage; };
|
||||
|
||||
@@ -221,7 +221,7 @@ public:
|
||||
template<typename Type>
|
||||
meta_any(std::reference_wrapper<Type> value)
|
||||
: storage{value},
|
||||
vtable{&basic_vtable<Type>},
|
||||
vtable{&basic_vtable<std::remove_const_t<Type>>},
|
||||
node{internal::meta_info<Type>::resolve()}
|
||||
{}
|
||||
|
||||
@@ -500,6 +500,13 @@ public:
|
||||
* @param other A reference to an object that isn't necessarily initialized.
|
||||
* @return A meta any that shares a reference to an unmanaged object.
|
||||
*/
|
||||
[[nodiscard]] friend meta_any as_ref(meta_any &other) ENTT_NOEXCEPT {
|
||||
meta_any ref = as_ref(std::as_const(other));
|
||||
ref.storage = as_ref(other.storage);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*! @copydoc as_ref */
|
||||
[[nodiscard]] friend meta_any as_ref(const meta_any &other) ENTT_NOEXCEPT {
|
||||
meta_any ref{};
|
||||
ref.node = other.node;
|
||||
@@ -1655,9 +1662,9 @@ class meta_sequence_container::meta_iterator {
|
||||
template<typename It>
|
||||
[[nodiscard]] static meta_any deref(meta_any any) {
|
||||
if constexpr(std::is_const_v<std::remove_reference_t<decltype(*std::declval<It>())>>) {
|
||||
return *any.cast<It &>();
|
||||
return *any.cast<const It &>();
|
||||
} else {
|
||||
return std::ref(*any.cast<It &>());
|
||||
return std::ref(*any.cast<const It &>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1901,9 +1908,9 @@ class meta_associative_container::meta_iterator {
|
||||
template<bool KeyOnly, typename It>
|
||||
[[nodiscard]] static meta_any key(meta_any any) {
|
||||
if constexpr(KeyOnly) {
|
||||
return *any.cast<It &>();
|
||||
return *any.cast<const It &>();
|
||||
} else {
|
||||
return any.cast<It &>()->first;
|
||||
return any.cast<const It &>()->first;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1912,7 +1919,7 @@ class meta_associative_container::meta_iterator {
|
||||
if constexpr(KeyOnly) {
|
||||
return meta_any{};
|
||||
} else {
|
||||
return std::ref(any.cast<It &>()->second);
|
||||
return std::ref(any.cast<const It &>()->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ public:
|
||||
*/
|
||||
template<typename Type>
|
||||
[[nodiscard]] static const auto * instance() {
|
||||
static_assert(std::is_same_v<Type, std::decay_t<Type>>);
|
||||
static const auto vtable = fill_vtable<Type>(std::make_index_sequence<Concept::template impl<Type>::size>{});
|
||||
return &vtable;
|
||||
}
|
||||
@@ -205,7 +206,7 @@ public:
|
||||
template<typename Type>
|
||||
poly(std::reference_wrapper<Type> value)
|
||||
: storage{value},
|
||||
vtable{poly_vtable<Concept>::template instance<Type>()}
|
||||
vtable{poly_vtable<Concept>::template instance<std::remove_const_t<Type>>()}
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -314,6 +315,13 @@ public:
|
||||
* @param other A reference to an object that isn't necessarily initialized.
|
||||
* @return A poly that shares a reference to an unmanaged object.
|
||||
*/
|
||||
[[nodiscard]] friend poly as_ref(poly &other) ENTT_NOEXCEPT {
|
||||
poly ref = as_ref(std::as_const(other));
|
||||
ref.storage = as_ref(other.storage);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*! @copydoc as_ref */
|
||||
[[nodiscard]] friend poly as_ref(const poly &other) ENTT_NOEXCEPT {
|
||||
poly ref;
|
||||
ref.storage = as_ref(other.storage);
|
||||
|
||||
Reference in New Issue
Block a user