Refureku v2.2.0
C++17 runtime reflection library.
Struct.h
1
8#pragma once
9
10#include <cstddef> //std::ptrdiff_t
11#include <type_traits> //std::is_default_constructible_v, std::is_pointer_v, std::is_reference_v
12
13#include "Refureku/TypeInfo/Cast.h"
14#include "Refureku/TypeInfo/Archetypes/Archetype.h"
15#include "Refureku/TypeInfo/Functions/StaticMethod.h" //make[Unique/Shared]Instance<> uses StaticMethod wrapper so must include
16#include "Refureku/TypeInfo/Archetypes/EClassKind.h"
17#include "Refureku/TypeInfo/Variables/EFieldFlags.h"
18#include "Refureku/TypeInfo/Functions/EMethodFlags.h"
19#include "Refureku/TypeInfo/Functions/MethodHelper.h"
20#include "Refureku/Containers/Vector.h"
21#include "Refureku/Misc/SharedPtr.h"
22#include "Refureku/Misc/UniquePtr.h"
23
24namespace rfk
25{
26 //Forward declarations
27 class ParentStruct;
28 class Enum;
29 class Field;
30 class StaticField;
31 class Method;
32 class Type;
33 class ICallable;
34 class Struct;
35
36 /* In C++, a struct and a class contain exactly the same data. Alias for convenience. */
37 using Class = Struct;
38
39 class Struct : public Archetype
40 {
41 public:
42 REFUREKU_API Struct(char const* name,
43 std::size_t id,
44 std::size_t memorySize,
45 bool isClass) noexcept;
46 REFUREKU_API ~Struct() noexcept;
47
59 template <typename ReturnType, typename... ArgTypes>
60 RFK_NODISCARD
61 rfk::SharedPtr<ReturnType> makeSharedInstance(ArgTypes&&... args) const;
62
72 template <typename ReturnType, typename... ArgTypes>
73 RFK_NODISCARD
74 rfk::UniquePtr<ReturnType> makeUniqueInstance(ArgTypes&&... args) const;
75
83 RFK_NODISCARD REFUREKU_API
85
94 RFK_NODISCARD REFUREKU_API bool isSubclassOf(Struct const& archetype) const noexcept;
95
104 RFK_NODISCARD REFUREKU_API bool isBaseOf(Struct const& archetype) const noexcept;
105
112 RFK_NODISCARD REFUREKU_API
113 ParentStruct const& getDirectParentAt(std::size_t index) const noexcept;
114
120 RFK_NODISCARD REFUREKU_API std::size_t getDirectParentsCount() const noexcept;
121
133 REFUREKU_API bool foreachDirectParent(Visitor<ParentStruct> visitor,
134 void* userData) const;
135
142 RFK_NODISCARD REFUREKU_API
143 Struct const* getNestedStructByName(char const* name,
144 EAccessSpecifier access = EAccessSpecifier::Undefined) const noexcept;
145
156 RFK_NODISCARD REFUREKU_API
158 void* userData) const;
159
170 RFK_NODISCARD REFUREKU_API
172 void* userData) const;
173
180 RFK_NODISCARD REFUREKU_API
181 Class const* getNestedClassByName(char const* name,
182 EAccessSpecifier access = EAccessSpecifier::Undefined) const noexcept;
183
194 RFK_NODISCARD REFUREKU_API
196 void* userData) const;
197
208 RFK_NODISCARD REFUREKU_API
210 void* userData) const;
211
218 RFK_NODISCARD REFUREKU_API
219 Enum const* getNestedEnumByName(char const* name,
220 EAccessSpecifier access = EAccessSpecifier::Undefined) const noexcept;
221
232 RFK_NODISCARD REFUREKU_API
234 void* userData) const;
235
246 RFK_NODISCARD REFUREKU_API
248 void* userData) const;
249
261 REFUREKU_API bool foreachNestedArchetype(Visitor<Archetype> visitor,
262 void* userData) const;
263
269 REFUREKU_API std::size_t getNestedArchetypesCount() const noexcept;
270
283 RFK_NODISCARD REFUREKU_API
284 Field const* getFieldByName(char const* name,
285 EFieldFlags minFlags = EFieldFlags::Default,
286 bool shouldInspectInherited = false) const noexcept;
287
300 RFK_NODISCARD REFUREKU_API
302 void* userData,
303 bool shouldInspectInherited = false) const;
304
318 RFK_NODISCARD REFUREKU_API
320 void* userData,
321 bool shouldInspectInherited = false,
322 bool orderedByDeclaration = false) const;
323
337 REFUREKU_API bool foreachField(Visitor<Field> visitor,
338 void* userData,
339 bool shouldInspectInherited = false) const;
340
346 REFUREKU_API std::size_t getFieldsCount() const noexcept;
347
361 RFK_NODISCARD REFUREKU_API
362 StaticField const* getStaticFieldByName(char const* name,
363 EFieldFlags minFlags = EFieldFlags::Default,
364 bool shouldInspectInherited = false) const noexcept;
365
378 RFK_NODISCARD REFUREKU_API
380 void* userData,
381 bool shouldInspectInherited = false) const;
382
395 RFK_NODISCARD REFUREKU_API
397 void* userData,
398 bool shouldInspectInherited = false) const;
399
413 REFUREKU_API bool foreachStaticField(Visitor<StaticField> visitor,
414 void* userData,
415 bool shouldInspectInherited = false) const;
416
422 REFUREKU_API std::size_t getStaticFieldsCount() const noexcept;
423
438 template <typename MethodSignature>
439 RFK_NODISCARD Method const* getMethodByName(char const* name,
440 EMethodFlags minFlags = EMethodFlags::Default,
441 bool shouldInspectInherited = false) const noexcept;
442
454 RFK_NODISCARD REFUREKU_API
455 Method const* getMethodByName(char const* name,
456 EMethodFlags minFlags = EMethodFlags::Default,
457 bool shouldInspectInherited = false) const noexcept;
458
470 RFK_NODISCARD REFUREKU_API
471 Vector<Method const*> getMethodsByName(char const* name,
472 EMethodFlags minFlags = EMethodFlags::Default,
473 bool shouldInspectInherited = false) const noexcept;
474
487 RFK_NODISCARD REFUREKU_API
489 void* userData,
490 bool shouldInspectInherited = false) const;
491
504 RFK_NODISCARD REFUREKU_API
506 void* userData,
507 bool shouldInspectInherited = false) const;
508
521 REFUREKU_API bool foreachMethod(Visitor<Method> visitor,
522 void* userData,
523 bool shouldInspectInherited = false) const;
524
530 REFUREKU_API std::size_t getMethodsCount() const noexcept;
531
544 template <typename StaticMethodSignature>
545 RFK_NODISCARD StaticMethod const* getStaticMethodByName(char const* name,
546 EMethodFlags minFlags = EMethodFlags::Default,
547 bool shouldInspectInherited = false) const noexcept;
548
561 RFK_NODISCARD REFUREKU_API
562 StaticMethod const* getStaticMethodByName(char const* name,
563 EMethodFlags minFlags = EMethodFlags::Default,
564 bool shouldInspectInherited = false) const noexcept;
565
578 RFK_NODISCARD REFUREKU_API
580 EMethodFlags minFlags = EMethodFlags::Default,
581 bool shouldInspectInherited = false) const noexcept;
582
595 RFK_NODISCARD REFUREKU_API
597 void* userData,
598 bool shouldInspectInherited = false) const;
599
612 RFK_NODISCARD REFUREKU_API
614 void* userData,
615 bool shouldInspectInherited = false) const;
616
629 REFUREKU_API bool foreachStaticMethod(Visitor<StaticMethod> visitor,
630 void* userData,
631 bool shouldInspectInherited = false) const;
632
638 REFUREKU_API std::size_t getStaticMethodsCount() const noexcept;
639
645 RFK_NODISCARD REFUREKU_API EClassKind getClassKind() const noexcept;
646
656 RFK_NODISCARD REFUREKU_API bool getPointerOffset(Struct const& to, std::ptrdiff_t& out_pointerOffset) const noexcept;
657
667 RFK_NODISCARD REFUREKU_API bool getSubclassPointerOffset(Struct const& to, std::ptrdiff_t& out_pointerOffset) const noexcept;
668
675 REFUREKU_API void addDirectParent(Archetype const* archetype,
676 EAccessSpecifier inheritanceAccess) noexcept;
677
685 REFUREKU_API void setDirectParentsCapacity(std::size_t capacity) noexcept;
686
693 REFUREKU_API void addSubclass(Struct const& subclass,
694 std::ptrdiff_t subclassPointerOffset) noexcept;
695
702 REFUREKU_API void addNestedArchetype(Archetype const* nestedArchetype,
703 EAccessSpecifier accessSpecifier) noexcept;
704
711 REFUREKU_API void setNestedArchetypesCapacity(std::size_t capacity) noexcept;
712
727 REFUREKU_API Field* addField(char const* name,
728 std::size_t id,
729 Type const& type,
730 EFieldFlags flags,
731 std::size_t memoryOffset,
732 Struct const* outerEntity) noexcept;
733
740 REFUREKU_API void setFieldsCapacity(std::size_t capacity) noexcept;
741
756 REFUREKU_API StaticField* addStaticField(char const* name,
757 std::size_t id,
758 Type const& type,
759 EFieldFlags flags,
760 void* fieldPtr,
761 Struct const* outerEntity) noexcept;
762 REFUREKU_API StaticField* addStaticField(char const* name,
763 std::size_t id,
764 Type const& type,
765 EFieldFlags flags,
766 void const* fieldPtr,
767 Struct const* outerEntity) noexcept;
768
775 REFUREKU_API void setStaticFieldsCapacity(std::size_t capacity) noexcept;
776
789 REFUREKU_API Method* addMethod(char const* name,
790 std::size_t id,
791 Type const& returnType,
792 ICallable* internalMethod,
793 EMethodFlags flags) noexcept;
794
801 REFUREKU_API void setMethodsCapacity(std::size_t capacity) noexcept;
802
815 REFUREKU_API StaticMethod* addStaticMethod(char const* name,
816 std::size_t id,
817 Type const& returnType,
818 ICallable* internalMethod,
819 EMethodFlags flags) noexcept;
820
827 REFUREKU_API void setStaticMethodsCapacity(std::size_t capacity) noexcept;
828
836 REFUREKU_API void addSharedInstantiator(StaticMethod const& instantiator) noexcept;
837
845 REFUREKU_API void addUniqueInstantiator(StaticMethod const& instantiator) noexcept;
846
847 protected:
848 //Forward declaration
849 class StructImpl;
850
851 REFUREKU_INTERNAL Struct(char const* name,
852 std::size_t id,
853 std::size_t memorySize,
854 bool isClass,
855 EClassKind classKind) noexcept;
856 REFUREKU_INTERNAL Struct(StructImpl* implementation) noexcept;
857
858 RFK_GEN_GET_PIMPL(StructImpl, Entity::getPimpl())
859
860 private:
873 REFUREKU_API bool foreachSharedInstantiator(std::size_t argCount,
874 Visitor<StaticMethod> visitor,
875 void* userData) const;
876
889 REFUREKU_API bool foreachUniqueInstantiator(std::size_t argCount,
890 Visitor<StaticMethod> visitor,
891 void* userData) const;
892 };
893
894 REFUREKU_TEMPLATE_API(rfk::Allocator<Struct const*>);
895 REFUREKU_TEMPLATE_API(rfk::Vector<Struct const*, rfk::Allocator<Struct const*>>);
896
897 #include "Refureku/TypeInfo/Archetypes/Struct.inl"
898}
Definition: Allocator.h:19
Definition: Archetype.h:16
Definition: Entity.h:29
Definition: Enum.h:18
Definition: Field.h:18
Definition: ICallable.h:13
Definition: Method.h:24
Definition: ParentStruct.h:19
Definition: StaticField.h:19
Definition: StaticMethod.h:16
Definition: Struct.h:40
RFK_NODISCARD REFUREKU_API std::size_t getDirectParentsCount() const noexcept
Get the number of reflected direct parents this struct is inheriting from.
REFUREKU_API StaticMethod * addStaticMethod(char const *name, std::size_t id, Type const &returnType, ICallable *internalMethod, EMethodFlags flags) noexcept
Add a static method to the struct.
RFK_NODISCARD REFUREKU_API Vector< StaticField const * > getStaticFieldsByPredicate(Predicate< StaticField > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve all static fields satisfying the provided predicate.
REFUREKU_API std::size_t getMethodsCount() const noexcept
Get the number of methods (excluding inherited ones) in this struct.
REFUREKU_API void setStaticFieldsCapacity(std::size_t capacity) noexcept
Internally pre-allocate enough memory for the provided number of static fields. If the number of stat...
REFUREKU_API Field * addField(char const *name, std::size_t id, Type const &type, EFieldFlags flags, std::size_t memoryOffset, Struct const *outerEntity) noexcept
Add a field to the struct.
REFUREKU_API std::size_t getStaticFieldsCount() const noexcept
Get the number of static fields (including inherited ones) in this struct.
RFK_NODISCARD REFUREKU_API Enum const * getNestedEnumByPredicate(Predicate< Enum > predicate, void *userData) const
Retrieve the first nested enum satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API ParentStruct const & getDirectParentAt(std::size_t index) const noexcept
Get the index'th direct parent of this struct. If index is greater or equal to getDirectParentsCount(...
RFK_NODISCARD REFUREKU_API Vector< StaticMethod const * > getStaticMethodsByPredicate(Predicate< StaticMethod > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve all static methods satisfying the provided predicate.
REFUREKU_API void setDirectParentsCapacity(std::size_t capacity) noexcept
Set the number of direct parents for this struct. Useful to avoid reallocations and avoid having unus...
REFUREKU_API bool foreachStaticField(Visitor< StaticField > visitor, void *userData, bool shouldInspectInherited=false) const
Execute the given visitor on all static fields in this struct.
RFK_NODISCARD REFUREKU_API Struct const * getNestedStructByPredicate(Predicate< Struct > predicate, void *userData) const
Retrieve the first nested struct satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API StaticField const * getStaticFieldByName(char const *name, EFieldFlags minFlags=EFieldFlags::Default, bool shouldInspectInherited=false) const noexcept
REFUREKU_API void setFieldsCapacity(std::size_t capacity) noexcept
Internally pre-allocate enough memory for the provided number of fields. If the number of fields is a...
RFK_NODISCARD REFUREKU_API Vector< Method const * > getMethodsByPredicate(Predicate< Method > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve all methods satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API Vector< Field const * > getFieldsByPredicate(Predicate< Field > predicate, void *userData, bool shouldInspectInherited=false, bool orderedByDeclaration=false) const
Retrieve all fields satisfying the provided predicate.
REFUREKU_API bool foreachField(Visitor< Field > visitor, void *userData, bool shouldInspectInherited=false) const
Execute the given visitor on all fields in this struct.
RFK_NODISCARD REFUREKU_API bool getSubclassPointerOffset(Struct const &to, std::ptrdiff_t &out_pointerOffset) const noexcept
Get the pointer offset to transform an instance of this Struct pointer to a pointer of the provided S...
RFK_NODISCARD REFUREKU_API Vector< Class const * > getNestedClassesByPredicate(Predicate< Class > predicate, void *userData) const
Retrieve all nested classes satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API Enum const * getNestedEnumByName(char const *name, EAccessSpecifier access=EAccessSpecifier::Undefined) const noexcept
RFK_NODISCARD REFUREKU_API Vector< StaticMethod const * > getStaticMethodsByName(char const *name, EMethodFlags minFlags=EMethodFlags::Default, bool shouldInspectInherited=false) const noexcept
REFUREKU_API bool foreachStaticMethod(Visitor< StaticMethod > visitor, void *userData, bool shouldInspectInherited=false) const
Execute the given visitor on all static methods in this struct.
REFUREKU_API bool foreachMethod(Visitor< Method > visitor, void *userData, bool shouldInspectInherited=false) const
Execute the given visitor on all methods in this struct.
RFK_NODISCARD REFUREKU_API Vector< Struct const * > getNestedStructsByPredicate(Predicate< Struct > predicate, void *userData) const
Retrieve all nested structs satisfying the provided predicate.
REFUREKU_API std::size_t getNestedArchetypesCount() const noexcept
Get the number of archetypes nested in this struct.
RFK_NODISCARD REFUREKU_API Vector< Enum const * > getNestedEnumsByPredicate(Predicate< Enum > predicate, void *userData) const
Retrieve all nested enums satisfying the provided predicate.
REFUREKU_API void addUniqueInstantiator(StaticMethod const &instantiator) noexcept
Add a new way to instantiate this struct through the makeUniqueInstance method. The passed static met...
RFK_NODISCARD REFUREKU_API Method const * getMethodByPredicate(Predicate< Method > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve the first method satisfying the provided predicate.
REFUREKU_API bool foreachDirectParent(Visitor< ParentStruct > visitor, void *userData) const
Execute the given visitor on all direct parents of this struct.
RFK_NODISCARD REFUREKU_API Vector< Struct const * > getDirectSubclasses() const noexcept
Compute the list of all direct reflected subclasses of this struct. Direct subclasses are computed by...
REFUREKU_API Method * addMethod(char const *name, std::size_t id, Type const &returnType, ICallable *internalMethod, EMethodFlags flags) noexcept
Add a method to the struct.
REFUREKU_API void addNestedArchetype(Archetype const *nestedArchetype, EAccessSpecifier accessSpecifier) noexcept
Add a nested archetype to the struct.
RFK_NODISCARD rfk::SharedPtr< ReturnType > makeSharedInstance(ArgTypes &&... args) const
Make an instance of the class represented by this archetype with the matching instantiator....
RFK_NODISCARD REFUREKU_API Vector< Method const * > getMethodsByName(char const *name, EMethodFlags minFlags=EMethodFlags::Default, bool shouldInspectInherited=false) const noexcept
RFK_NODISCARD REFUREKU_API bool isBaseOf(Struct const &archetype) const noexcept
Check if this struct is a base class of another struct/class.
REFUREKU_API void addSubclass(Struct const &subclass, std::ptrdiff_t subclassPointerOffset) noexcept
Add a subclass to this struct.
RFK_NODISCARD REFUREKU_API bool getPointerOffset(Struct const &to, std::ptrdiff_t &out_pointerOffset) const noexcept
Get the pointer offset to transform an instance of this Struct pointer to a pointer of the provided S...
RFK_NODISCARD REFUREKU_API Class const * getNestedClassByPredicate(Predicate< Class > predicate, void *userData) const
Retrieve the first nested class satisfying the provided predicate.
REFUREKU_API void setMethodsCapacity(std::size_t capacity) noexcept
Internally pre-allocate enough memory for the provided number of methods. If the number of methods is...
RFK_NODISCARD StaticMethod const * getStaticMethodByName(char const *name, EMethodFlags minFlags=EMethodFlags::Default, bool shouldInspectInherited=false) const noexcept
RFK_NODISCARD Method const * getMethodByName(char const *name, EMethodFlags minFlags=EMethodFlags::Default, bool shouldInspectInherited=false) const noexcept
Get a method by name and signature. This template overload using signature comes handy when wanting t...
RFK_NODISCARD REFUREKU_API Field const * getFieldByName(char const *name, EFieldFlags minFlags=EFieldFlags::Default, bool shouldInspectInherited=false) const noexcept
RFK_NODISCARD rfk::UniquePtr< ReturnType > makeUniqueInstance(ArgTypes &&... args) const
Make an instance of the class represented by this archetype with the matching instantiator....
RFK_NODISCARD REFUREKU_API StaticField const * getStaticFieldByPredicate(Predicate< StaticField > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve the first static field satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API Struct const * getNestedStructByName(char const *name, EAccessSpecifier access=EAccessSpecifier::Undefined) const noexcept
REFUREKU_API void setStaticMethodsCapacity(std::size_t capacity) noexcept
Internally pre-allocate enough memory for the provided number of static methods. If the number of sta...
RFK_NODISCARD REFUREKU_API EClassKind getClassKind() const noexcept
Get the class kind of this instance.
RFK_NODISCARD REFUREKU_API Class const * getNestedClassByName(char const *name, EAccessSpecifier access=EAccessSpecifier::Undefined) const noexcept
REFUREKU_API StaticField * addStaticField(char const *name, std::size_t id, Type const &type, EFieldFlags flags, void *fieldPtr, Struct const *outerEntity) noexcept
Add a static field to the struct.
REFUREKU_API void addSharedInstantiator(StaticMethod const &instantiator) noexcept
Add a new way to instantiate this struct through the makeSharedInstance method. The passed static met...
REFUREKU_API std::size_t getStaticMethodsCount() const noexcept
Get the number of static methods (excluding inherited ones) in this struct.
RFK_NODISCARD REFUREKU_API Field const * getFieldByPredicate(Predicate< Field > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve the first field satisfying the provided predicate.
REFUREKU_API void addDirectParent(Archetype const *archetype, EAccessSpecifier inheritanceAccess) noexcept
Add a parent to this struct if the provided archetype is a valid struct/class.
REFUREKU_API void setNestedArchetypesCapacity(std::size_t capacity) noexcept
Internally pre-allocate enough memory for the provided number of nested archetypes....
RFK_NODISCARD REFUREKU_API StaticMethod const * getStaticMethodByPredicate(Predicate< StaticMethod > predicate, void *userData, bool shouldInspectInherited=false) const
Retrieve the first static method satisfying the provided predicate.
RFK_NODISCARD REFUREKU_API bool isSubclassOf(Struct const &archetype) const noexcept
Check if this struct is a subclass of another struct/class.
REFUREKU_API std::size_t getFieldsCount() const noexcept
Get the number of fields (including inherited ones) in this struct.
REFUREKU_API bool foreachNestedArchetype(Visitor< Archetype > visitor, void *userData) const
Execute the given visitor on all archetypes nested in this struct.
Definition: Type.h:20
Definition: Vector.h:19
Definition: Allocator.h:16
EClassKind
Defines the kind of a rfk::Class or a rfk::Struct instance:
Definition: EClassKind.h:19
bool(*)(T const &value, void *userData) Predicate
Predicate defining if a value is valid or not.
Definition: Predicate.h:21
EFieldFlags
Definition: EFieldFlags.h:16
bool(*)(T const &value, void *userData) Visitor
Visitor function.
Definition: Visitor.h:21
EMethodFlags
Definition: EMethodFlags.h:17