Skip to content

Commit 56ef214

Browse files
committed
meta: user defined traits for meta objects
1 parent d331f75 commit 56ef214

File tree

4 files changed

+71
-17
lines changed

4 files changed

+71
-17
lines changed

TODO

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,14 @@ TODO:
3232
* table: pop back to support swap and pop, single column access, empty type optimization
3333
* checkout tools workflow
3434
* review constrained noexcept-ness (ie sigh)
35-
* offer 16b from meta_traits to users or change type
3635
* registry::view const invokes refresh multiple times implicitly
3736
* improve front (no multiple checks) and back (ie no contains) for multi-type view
3837
* cleanup common view from tricks to handle single swap-only and in-place, if constexpr branches
39-
* consider returning subrange for swap-only sparse sets or consider using filtered each for in-place storage (smilar to storage entity), cleanup views
4038
* exploit ref/cref in any to avoid invoking the vtable if possible
4139
* review meta properties and details, maybe a dense map is too much
4240
* self assignment support for any and meta_any
4341
* meta support for use defined traits (room for them on meta traits)
4442
* entity based component_traits
45-
* seek functions for meta factory (data/func/whatever)
4643
* investigate using any rather than shared<void> for meta properties
44+
* refine user defined meta traits implementation
45+

src/entt/meta/factory.hpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <type_traits>
1010
#include <utility>
1111
#include "../config/config.h"
12+
#include "../core/bit.hpp"
1213
#include "../core/fwd.hpp"
1314
#include "../core/type_info.hpp"
1415
#include "../core/type_traits.hpp"
@@ -103,6 +104,18 @@ class basic_meta_factory {
103104
}
104105
}
105106

107+
void traits(const std::underlying_type_t<internal::meta_traits> value) {
108+
constexpr auto shift = popcount(static_cast<std::underlying_type_t<internal::meta_traits>>(internal::meta_traits::_user_defined_traits));
109+
110+
if(const internal::meta_traits data{value << shift}; bucket == parent) {
111+
internal::meta_context::from(*ctx).value[parent].traits |= data;
112+
} else if(is_data) {
113+
details->data[bucket].traits |= data;
114+
} else {
115+
details->func[bucket].traits |= data;
116+
}
117+
}
118+
106119
public:
107120
basic_meta_factory(const type_info &info, meta_ctx &area)
108121
: ctx{&area},
@@ -480,7 +493,7 @@ class meta_factory: private internal::basic_meta_factory {
480493
}
481494

482495
/**
483-
* @brief Assigns a property to the last meta object created.
496+
* @brief Assigns a property to the last created meta object.
484497
*
485498
* Both the key and the value (if any) must be at least copy constructible.
486499
*
@@ -499,6 +512,22 @@ class meta_factory: private internal::basic_meta_factory {
499512

500513
return *this;
501514
}
515+
516+
/**
517+
* @brief Sets traits on the last created meta object.
518+
*
519+
* The assigned value must be an enum and intended as a bitmask.
520+
*
521+
* @tparam Value Type of the traits value.
522+
* @param value Traits value.
523+
* @return A meta factory for the parent type.
524+
*/
525+
template<typename Value>
526+
meta_factory traits(const Value value) {
527+
static_assert(std::is_enum_v<Value>, "Invalid enum type");
528+
base_type::traits(static_cast<std::underlying_type_t<internal::meta_traits>>(static_cast<std::underlying_type_t<Value>>(value)));
529+
return *this;
530+
}
502531
};
503532

504533
/**

src/entt/meta/meta.hpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <utility>
1010
#include "../config/config.h"
1111
#include "../core/any.hpp"
12+
#include "../core/bit.hpp"
1213
#include "../core/fwd.hpp"
1314
#include "../core/iterator.hpp"
1415
#include "../core/type_info.hpp"
@@ -912,6 +913,18 @@ struct meta_data {
912913
return it != node->prop.cend() ? meta_prop{*ctx, it->second} : meta_prop{};
913914
}
914915

916+
/**
917+
* @brief Returns all meta traits for a given meta object.
918+
* @tparam Type The type to convert the meta traits to.
919+
* @return The registered meta traits, if any.
920+
*/
921+
template<typename Type>
922+
[[nodiscard]] Type traits() const noexcept {
923+
static_assert(std::is_enum_v<Type>, "Invalid enum type");
924+
constexpr auto shift = popcount(static_cast<std::underlying_type_t<internal::meta_traits>>(internal::meta_traits::_user_defined_traits));
925+
return Type{static_cast<std::underlying_type_t<Type>>(static_cast<std::underlying_type_t<internal::meta_traits>>(node->traits) >> shift)};
926+
}
927+
915928
/**
916929
* @brief Returns true if an object is valid, false otherwise.
917930
* @return True if the object is valid, false otherwise.
@@ -996,10 +1009,6 @@ struct meta_func {
9961009

9971010
/**
9981011
* @brief Invokes the underlying function, if possible.
999-
*
1000-
* @warning
1001-
* The context of the arguments is **never** changed.
1002-
*
10031012
* @param instance An opaque instance of the underlying type.
10041013
* @param args Parameters to use to invoke the function.
10051014
* @param sz Number of parameters to use to invoke the function.
@@ -1038,6 +1047,18 @@ struct meta_func {
10381047
return it != node->prop.cend() ? meta_prop{*ctx, it->second} : meta_prop{};
10391048
}
10401049

1050+
/**
1051+
* @brief Returns all meta traits for a given meta object.
1052+
* @tparam Type The type to convert the meta traits to.
1053+
* @return The registered meta traits, if any.
1054+
*/
1055+
template<typename Type>
1056+
[[nodiscard]] Type traits() const noexcept {
1057+
static_assert(std::is_enum_v<Type>, "Invalid enum type");
1058+
constexpr auto shift = popcount(static_cast<std::underlying_type_t<internal::meta_traits>>(internal::meta_traits::_user_defined_traits));
1059+
return Type{static_cast<std::underlying_type_t<Type>>(static_cast<std::underlying_type_t<internal::meta_traits>>(node->traits) >> shift)};
1060+
}
1061+
10411062
/**
10421063
* @brief Returns the next overload of a given function, if any.
10431064
* @return The next overload of the given function, if any.
@@ -1373,10 +1394,6 @@ class meta_type {
13731394

13741395
/**
13751396
* @brief Creates an instance of the underlying type, if possible.
1376-
*
1377-
* @warning
1378-
* The context of the arguments is **never** changed.
1379-
*
13801397
* @param args Parameters to use to construct the instance.
13811398
* @param sz Number of parameters to use to construct the instance.
13821399
* @return A wrapper containing the new instance, if any.
@@ -1423,10 +1440,6 @@ class meta_type {
14231440

14241441
/**
14251442
* @brief Invokes a function given an identifier, if possible.
1426-
*
1427-
* @warning
1428-
* The context of the arguments is **never** changed.
1429-
*
14301443
* @param id Unique identifier.
14311444
* @param instance An opaque instance of the underlying type.
14321445
* @param args Parameters to use to invoke the function.
@@ -1510,6 +1523,18 @@ class meta_type {
15101523
return elem ? meta_prop{*ctx, *elem} : meta_prop{};
15111524
}
15121525

1526+
/**
1527+
* @brief Returns all meta traits for a given meta object.
1528+
* @tparam Type The type to convert the meta traits to.
1529+
* @return The registered meta traits, if any.
1530+
*/
1531+
template<typename Type>
1532+
[[nodiscard]] Type traits() const noexcept {
1533+
static_assert(std::is_enum_v<Type>, "Invalid enum type");
1534+
constexpr auto shift = popcount(static_cast<std::underlying_type_t<internal::meta_traits>>(internal::meta_traits::_user_defined_traits));
1535+
return Type{static_cast<std::underlying_type_t<Type>>(static_cast<std::underlying_type_t<internal::meta_traits>>(node.traits) >> shift)};
1536+
}
1537+
15131538
/**
15141539
* @brief Returns true if an object is valid, false otherwise.
15151540
* @return True if the object is valid, false otherwise.

src/entt/meta/node.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ enum class meta_traits : std::uint32_t {
3939
is_meta_pointer_like = 0x0200,
4040
is_meta_sequence_container = 0x0400,
4141
is_meta_associative_container = 0x0800,
42-
_entt_enum_as_bitmask
42+
_user_defined_traits = 0xFFFF,
43+
_entt_enum_as_bitmask = 0xFFFF
4344
};
4445

4546
struct meta_type_node;

0 commit comments

Comments
 (0)