CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Class.define.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Box.hpp"
11#include "Class.hpp"
12#include "Enum.hpp"
13#include "MetaArgument.hpp"
14#include "MetaContainer.hpp"
15#include "MetaItem.hpp"
16#include "MetaSignature.hpp"
17#include "Type.define.hpp"
18#include "Type.hpp"
19
21
22#include <type_traits>
23
24namespace CeresEngine {
25 namespace impl {
26 template<typename T>
27 concept ReflectableClass = requires(T& object, const T& constObject) {
28 { object.getClassInfo() } -> std::convertible_to<ClassInfo>;
29 { constObject.getClassInfo() } -> std::convertible_to<ClassInfo>;
30 };
31
32 template<typename T> class TMetaReflectableClassType {};
33
34 template<typename T> requires ReflectableClass<T>
36 public:
37 [[nodiscard]] ClassInfo getClassInfo(const void* target) const final { return static_cast<const T*>(target)->getClassInfo(); }
38
39 [[nodiscard]] ClassInfo getClassInfo(void* target) const final { return static_cast<T*>(target)->getClassInfo(); }
40 };
41 } // namespace impl
42
44
45 template<typename T>
46 class TClass : public TTypeInfo<T>, //
47 public Class,
49 public:
50 explicit TClass() : Class(getTypeName<T>()) {
51 if constexpr(std::is_default_constructible_v<T>) {
53 }
54
55 if constexpr(std::is_copy_constructible_v<T>) {
57 }
58 }
59
60 public:
63
64 public: // Bases
65 template<typename B> void base();
66 template<typename Base0, typename... Bs> void bases();
67
68 public: // Constructors
69 template<typename... Args> void constructor();
70
71 public: // Properties
72 template<typename P> void property(StringView name, P&& property, MetaAttributeList&& attributes = {});
73 template<typename G, typename S> void property(StringView name, G&& getter, S&& setter, MetaAttributeList&& attributes = {});
74
75 public: // Methods
76 template<typename F> void method(StringView name, F func, MetaAttributeList&& attributes = {});
77 };
78
79#define CE_META_CLASS_DEFINE_BASE(...) \
80 class ::CeresEngine::TUserTypeInfo<__VA_ARGS__> final : public TClass<__VA_ARGS__> { \
81 using ClassType = __VA_ARGS__; \
82 \
83 public: \
84 explicit TUserTypeInfo() { define(*this); } \
85 \
86 private: \
87 inline void define(TUserTypeInfo& define); \
88 }
89
90#define CE_META_REFLECTABLE_CLASS_BASE(...) \
91 [[nodiscard]] ::CeresEngine::ClassInfo __VA_ARGS__::getClassInfo() noexcept { \
92 return ::CeresEngine::ClassInfo{ \
93 ::CeresEngine::getTypeID<std::decay_t<decltype(*this)>>(), \
94 this, \
95 }; \
96 } \
97 \
98 [[nodiscard]] ::CeresEngine::ClassInfo __VA_ARGS__::getClassInfo() const noexcept { \
99 return ::CeresEngine::ClassInfo{ \
100 ::CeresEngine::getTypeID<std::decay_t<decltype(*this)>>(), \
101 this, \
102 }; \
103 }
104
105#define CE_META_CLASS_DEFINE(...) \
106 template<> CE_META_CLASS_DEFINE_BASE(__VA_ARGS__); \
107 template<> const ::CeresEngine::TypeInfo& ::CeresEngine::GetTypeInfo<__VA_ARGS__>::get() { \
108 static const TUserTypeInfo<__VA_ARGS__> typeInfo; \
109 return typeInfo; \
110 } \
111 CE_META_TYPE_AUTO_REGISTRATION(__VA_ARGS__); \
112 void ::CeresEngine::TUserTypeInfo<__VA_ARGS__>::define(TUserTypeInfo& define)
113
114#define CE_META_REFLECTABLE_CLASS_DEFINE(...) \
115 template<> CE_META_CLASS_DEFINE_BASE(__VA_ARGS__); \
116 template<> const ::CeresEngine::TypeInfo& ::CeresEngine::GetTypeInfo<__VA_ARGS__>::get() { \
117 static const TUserTypeInfo<__VA_ARGS__> typeInfo; \
118 return typeInfo; \
119 } \
120 CE_META_TYPE_AUTO_REGISTRATION(__VA_ARGS__); \
121 CE_META_REFLECTABLE_CLASS_BASE(__VA_ARGS__) \
122 void ::CeresEngine::TUserTypeInfo<__VA_ARGS__>::define(TUserTypeInfo& define)
123
124#define CE_META_CLASS_TEMPLATE_DEFINE(TType, ...) \
125 template<__VA_ARGS__> CE_META_CLASS_DEFINE_BASE(TType); \
126 template<__VA_ARGS__> struct ::CeresEngine::GetTypeInfo<TType> { \
127 static const TypeInfo& get() noexcept { \
128 static const TUserTypeInfo<TType> typeInfo; \
129 return typeInfo; \
130 } \
131 }; \
132 \
133 template<__VA_ARGS__> void ::CeresEngine::TUserTypeInfo<TType>::define(TUserTypeInfo& define)
134
135#define CE_META_CLASS_TEMPLATE_SPECIALIZATION_EXTERN(...) extern template struct ::CeresEngine::GetTypeInfo<__VA_ARGS__>;
136#define CE_META_CLASS_TEMPLATE_SPECIALIZATION_DEFINE(...) \
137 template struct ::CeresEngine::GetTypeInfo<__VA_ARGS__>; \
138 CE_META_TYPE_AUTO_REGISTRATION(__VA_ARGS__);
139
140 // ---------------------------------------------------------------------------------------------
141
142 namespace internal {
147
148 template<typename F>
149 using MethodInvokerTag = std::conditional_t<std::is_void_v<typename function_traits<F>::result_type>,
150 std::conditional_t<std::is_void_v<typename function_traits<F>::class_type>, VoidStaticFunctionTag, VoidMemberFunctionTag>,
151 std::conditional_t<std::is_void_v<typename function_traits<F>::class_type>, ReturnStaticFunctionTag, ReturnMemberFunctionTag>>;
152
153 template<typename F, typename Tag = MethodInvokerTag<F>> struct MethodInvokerInternal;
154
155 template<typename F> struct MethodInvokerInternal<F, VoidStaticFunctionTag> {
157
158 [[nodiscard]] static bool isStatic() { return true; }
161 [[nodiscard]] static String signature(StringView name) { return f_signature<F>::get(name); }
162
163 [[nodiscard]] static Box invoke(const F& func, const MetaValues& arguments) { return invokeInternal(func, arguments, argument_indexes_t{}); }
164
165 private:
166 template<std::size_t I> using argument_get_t = MPL::Nth<I, Args>;
167 using argument_indexes_t = std::make_index_sequence<function_traits<F>::arity>;
168
169 template<std::size_t... I> [[nodiscard]] static Box invokeInternal(const F& func, const MetaValues& arguments, std::index_sequence<I...>) {
170 func(MetaArgument(arguments[I]).getValue<argument_get_t<I>>()...);
171 return Box();
172 }
173
175 return {getTypeID<argument_get_t<I>>()...};
176 }
177 };
178
179 template<typename F> struct MethodInvokerInternal<F, ReturnStaticFunctionTag> {
182
183 [[nodiscard]] static bool isStatic() { return true; }
186 [[nodiscard]] static String signature(StringView name) { return f_signature<F>::get(name); }
187
188 [[nodiscard]] static Box invoke(const F& func, const MetaValues& arguments) { return invokeInternal(func, arguments, argument_indexes_t{}); }
189
190 private:
191 template<std::size_t I> using argument_get_t = MPL::Nth<I, Args>;
193
195 return {getTypeID<argument_get_t<I>>()...};
196 }
197
198 template<std::size_t... I> [[nodiscard]] static Box invokeInternal(const F& func, const MetaValues& arguments, std::index_sequence<I...>) {
199 if constexpr(std::is_reference_v<Result>) {
200 return std::ref(func(MetaArgument(arguments[I]).getValue<argument_get_t<I>>()...));
201 } else {
202 return func(MetaArgument(arguments[I]).getValue<argument_get_t<I>>()...);
203 }
204 }
205 };
206
207 template<typename F> struct MethodInvokerInternal<F, VoidMemberFunctionTag> {
209
210 [[nodiscard]] static bool isStatic() { return false; }
213 [[nodiscard]] static String signature(StringView name) { return f_signature<F>::get(name); }
214
215 [[nodiscard]] static Box invoke(const F& func, const MetaValues& arguments) { return invokeInternal(func, arguments, argument_indexes_t{}); }
216
217 private:
218 template<std::size_t I> using argument_get_t = MPL::Nth<I, Args>;
220 //
223 using class_t = std::conditional_t<is_const_method::value, std::add_const_t<C>, C>;
224 using class_ref_t = std::add_lvalue_reference_t<class_t>;
225 using class_ptr_t = std::add_pointer_t<class_t>;
226
228 return {getTypeID<argument_get_t<I>>()...};
229 }
230
231 template<std::size_t... I> [[nodiscard]] static Box invokeInternal(const F& func, const MetaValues& arguments, mpl::index_sequence<I...>) {
232 const Box& instance = arguments[0];
233 const Type type{arguments[0].getTypeID()};
234 if(type.isClass()) {
235 if constexpr(is_const_method::value) {
236 (instance.ref<class_t>().*func)(MetaArgument(arguments[I + 1]).getValue<argument_get_t<I>>()...);
237 } else {
238 (instance.ref<class_ref_t>().*func)(MetaArgument(arguments[I + 1]).getValue<argument_get_t<I>>()...);
239 }
240 } else if(type.isClassPtr()) {
241 (instance.to<class_ptr_t>()->*func)(MetaArgument(arguments[I + 1]).getValue<argument_get_t<I>>()...);
242 }
243
244 return Box();
245 }
246 };
247
248 template<typename F> struct MethodInvokerInternal<F, ReturnMemberFunctionTag> {
251
252 [[nodiscard]] static bool isStatic() { return false; }
255 [[nodiscard]] static String signature(StringView name) { return f_signature<F>::get(name); }
256
257 [[nodiscard]] static Box invoke(const F& func, const MetaValues& arguments) { return invokeInternal(func, arguments, argument_indexes_t{}); }
258
259 private:
260 template<std::size_t I> using argument_get_t = MPL::Nth<I, Args>;
262 //
265 using class_t = std::conditional_t<is_const_method::value, std::add_const_t<C>, C>;
266 using class_ref_t = std::add_lvalue_reference_t<class_t>;
267 using class_ptr_t = std::add_pointer_t<class_t>;
268
270 return {getTypeID<argument_get_t<I>>()...};
271 }
272
273 template<typename R> [[nodiscard]] static Box reference_get(R&& result) {
274 if constexpr(std::is_reference_v<Result>) {
275 return std::ref(std::forward<R>(result));
276 } else {
277 return std::forward<R>(result);
278 }
279 }
280
281 template<std::size_t... I> [[nodiscard]] static Box invokeInternal(const F& func, const MetaValues& arguments, mpl::index_sequence<I...>) {
282 const Box& instance = arguments[0];
283 const Type type{instance.getTypeID()};
284 if(type.isClass()) {
285 if constexpr(is_const_method::value) {
286 return reference_get((instance.ref<class_t>().*func)(MetaArgument(arguments[I + 1]).getValue<argument_get_t<I>>()...));
287 } else {
288 throw BadMetaValueCast("Incompatible types: const CeresEngine::MetaValue& -> {0}", getTypeName<class_ref_t>());
289 }
290 } else if(type.isClassPtr()) {
291 return reference_get((instance.to<class_ptr_t>()->*func)(MetaArgument(arguments[I + 1]).getValue<argument_get_t<I>>()...));
292 }
293
294 throw BadMetaValueCast("Bad call");
295 }
296 };
297
298 template<typename P> struct PropertyTypeTrait;
299
300 template<typename P> struct PropertyTypeTrait<P*> : mpl::identity<P> {};
301
302 template<typename C, typename T> struct PropertyTypeTrait<T C::*> : mpl::identity<T> {};
303
304 template<typename P> using PropertyType = typename PropertyTypeTrait<P>::type;
305 template<typename P> struct PropertyClassTrait;
306
307 template<typename C, typename T> struct PropertyClassTrait<T C::*> : mpl::identity<C> {};
308
309 template<typename P> using PropertyClass = typename PropertyClassTrait<P>::type;
310
312
314
315 template<typename P> using MetaPropertyAccessorTag = std::conditional_t<std::is_member_pointer_v<P>, MemberPointerTag, StaticPointerTag>;
316
317 template<typename P, typename Tag> struct MetaPropertyAccessorInternal;
318
319 template<typename P> struct MetaPropertyAccessorInternal<P, StaticPointerTag> {
320 static_assert(std::is_pointer_v<P> && !std::is_function_v<P>, "Type should be pointer");
321
322 [[nodiscard]] static constexpr bool isStatic() { return true; }
324 [[nodiscard]] static bool isReadOnly() { return std::is_const_v<T>; }
325
326 [[nodiscard]] static Box getStatic(P property) { return std::cref(*property); }
327
328 static void setStatic([[maybe_unused]] P property, const MetaArgument& arg) {
329 if constexpr(std::is_const_v<T>) {
330 throw InvokeError("Write to readonly property");
331 } else {
332 *property = arg.getValue<T>();
333 }
334 }
335
336 [[nodiscard]] static Box getField(P, const Box&) {
337 CE_ASSERT(false);
338 return Box();
339 }
340
341 static void setField(P, const Box&, const MetaArgument&) { assert(false); }
342 static void setField(P, Box&, const MetaArgument&) { assert(false); }
343
344 private:
346 };
347
348 template<typename P> struct MetaPropertyAccessorInternal<P, MemberPointerTag> {
349 static_assert(std::is_member_object_pointer_v<P>, "Type should be member object pointer");
350
351 [[nodiscard]] static bool isStatic() { return false; }
353 [[nodiscard]] static bool isReadOnly() { return std::is_const_v<T>; }
354
355 [[nodiscard]] static Box getStatic(P) {
356 CE_ASSERT(false);
357 return Box();
358 }
359
360 static void setStatic(P, const MetaArgument&) { assert(false); }
361
362 [[nodiscard]] static Box getField(P property, const Box& instance) {
363 const auto type = Type{instance.getTypeID()};
364 if(type.isClass()) {
365 if(type.isConst()) {
366 return std::ref(instance.cref<C>().*property);
367 } else {
368 return std::ref(instance.ref<C>().*property);
369 }
370 } else if(type.isClassPtr()) {
371 return std::ref(instance.to<const C*>()->*property);
372 }
373 throw BadMetaValueCast("Unknown this type");
374 }
375
376 static void setField(P property, const Box& instance, const MetaArgument& arg) {
377 if constexpr(std::is_const_v<T>) {
378 throw InvokeError("Write to readonly property");
379 } else {
380 const Type type{instance.getTypeID()};
381 if(type.isClass()) {
382 if(type.isConst()) {
383 throw BadMetaValueCast("Incompatible types: const CeresEngine::MetaValue& -> {0}", getTypeName<class_ref_t>());
384 }
385
386 if constexpr(std::is_assignable_v<T, T>) {
387 instance.ref<C>().*property = arg.getValue<T>();
388 } else if constexpr(std::is_copy_constructible_v<T>) {
389 (instance.ref<C>().*property).~T();
390 new(&(instance.ref<C>().*property)) T(arg.getValue<T>());
391 } else {
392 throw BadMetaValueCast("Incompatible types: const CeresEngine::MetaValue& -> {0}", getTypeName<class_ref_t>());
393 }
394 } else if(type.isClassPtr()) {
395 if constexpr(std::is_assignable_v<T, T>) {
396 instance.to<C*>()->*property = arg.getValue<T>();
397 } else if constexpr(std::is_copy_constructible_v<T>) {
398 (instance.to<C*>()->*property).~T();
399 new(&(instance.to<C*>()->*property)) T(arg.getValue<T>());
400 } else {
401 throw BadMetaValueCast("Incompatible types: const CeresEngine::MetaValue& -> {0}", getTypeName<class_ref_t>());
402 }
403 }
404 }
405 }
406
407 static void setField(P property, Box& instance, const MetaArgument& arg) {
408 if constexpr(std::is_const_v<T>) {
409 throw InvokeError("Write to readonly property");
410 } else {
411 const auto type = Type{instance.getTypeID()};
412 if(type.isClass()) {
413 instance.ref<C>().*property = arg.getValue<T>();
414 } else if(type.isClassPtr()) {
415 instance.to<C*>()->*property = arg.getValue<T>();
416 }
417 }
418 }
419
420 private:
423 using class_ref_t = std::add_lvalue_reference_t<C>;
424 };
425 } // namespace internal
426
427 // ---------------------------------------------------------------------------------------------
428
432 template<typename PointerType> class MetaPointerProperty : public ClassProperty {
434
436 const PointerType mPointer;
437
438 public:
443 explicit MetaPointerProperty(Class& owner, const StringView name, PointerType pointer) noexcept : ClassProperty(owner, name), mPointer(pointer) {}
444
445 public:
447 [[nodiscard]] bool isStatic() const noexcept override { return AccessorTraits::isStatic(); }
448
450 [[nodiscard]] bool isReadOnly() const noexcept override { return AccessorTraits::isReadOnly(); }
451
453 [[nodiscard]] TypeID getGetterReturnTypeID() const noexcept override { return AccessorTraits::getTypeID(); }
454
456 [[nodiscard]] TypeID getSetterParameterTypeID() const noexcept override { return AccessorTraits::getTypeID(); }
457
459 [[nodiscard]] Box get(const Box& target) const override {
460 if(isStatic()) {
461 return AccessorTraits::getStatic(mPointer);
462 } else {
463 return AccessorTraits::getField(mPointer, target);
464 }
465 }
466
468 void set(const Box& target, const Box& value) const override {
469 if(isStatic()) {
470 AccessorTraits::setStatic(mPointer, value);
471 } else {
472 AccessorTraits::setField(mPointer, target, value);
473 }
474 }
475
477 void set(const Box& target, Box&& value) const override {
478 if(isStatic()) {
479 AccessorTraits::setStatic(mPointer, std::move(value));
480 } else {
481 AccessorTraits::setField(mPointer, target, std::move(value));
482 }
483 }
484 };
485
490 template<typename GetterType, typename SetterType> class MetaAccessorProperty : public ClassProperty {
491 private:
492 static constexpr auto valid = (std::is_function_v<GetterType> && (std::is_void_v<SetterType> || std::is_function_v<SetterType>)) ||
493 (std::is_member_function_pointer_v<GetterType> && (std::is_void_v<SetterType> || std::is_member_function_pointer_v<SetterType>));
494 static_assert(valid, "Getter and setter methods should be simultaneously static method or pointer to member");
495
498
501
503 using T = typename GetterTraits::result_type;
504
506 using SetterArgument = typename SetterTraits::template arg<0>;
507
508 static_assert(!std::is_void_v<T>, "Getter method should have non void result type");
509 static_assert(GetterTraits::arity == 0, "Getter method shouldn't have any parameters");
510 static_assert(std::is_void_v<typename SetterTraits::result_type>, "Setter method should have void result type");
511 static_assert(SetterTraits::arity == 1, "Setter method should have one parameters");
512 static_assert(std::is_same_v<std::decay_t<T>, std::decay_t<SetterArgument>>, "Getter method return type and setter method parameter type do not match");
513
516
519
520 public:
528
529 public:
531 [[nodiscard]] bool isStatic() const noexcept override { return std::is_function_v<GetterType>; }
532
534 [[nodiscard]] bool isReadOnly() const noexcept override { return !std::is_void_v<SetterType>; }
535
538
541
543 [[nodiscard]] Box get(const Box& target) const override {
544 if(isStatic()) {
546 } else {
548 }
549 }
550
552 void set(const Box& target, const Box& value) const override {
553 if(isStatic()) {
555 } else {
557 }
558 }
559
561 void set(const Box& target, Box&& value) const override {
562 if(isStatic()) {
564 } else {
566 }
567 }
568 };
569
570 // ---------------------------------------------------------------------------------------------
571
572 template<typename F> class TMetaMethod : public ClassMethod {
573 private:
574 F const mFunc;
575
577
578 public:
580
581 TMetaMethod(Class& owner, const StringView name, F&& func) noexcept : ClassMethod(owner, name), mFunc(std::move(func)) {}
582
583 public:
585 [[nodiscard]] bool isStatic() const noexcept override { return invoker_t::isStatic(); }
586
588 [[nodiscard]] TypeID getReturnTypeID() const noexcept override { return invoker_t::getReturnTypeID(); }
589
592 const Vector<TypeID> parameters = invoker_t::getParametersTypeID();
593 return parameters;
594 }
595
597 [[nodiscard]] String signature(StringView name) const { return invoker_t::signature(name); }
598
600 [[nodiscard]] Box invoke(const MetaValues& arguments) { invoker_t::invoke(mFunc, arguments); }
601 };
602
603 // ---------------------------------------------------------------------------------------------
604
605 template<typename C, typename... Args> class TMetaConstructor : public ClassConstructor {
606 private:
607 static_assert((sizeof...(Args) > 0) || std::is_default_constructible_v<C>, "Type is not default constructible");
608 static_assert((sizeof...(Args) == 0) || std::is_constructible_v<C, Args...>, "Type can not be constructed with given arguments");
609
610 template<std::size_t I> using argument_get_t = MPL::Nth<I, MPL::TypeList<Args...>>;
612
613 public:
615
616 public:
619 static const Array<const TypeID, sizeof...(Args)> parameters{getTypeID<Args>()...};
620 return Span<const TypeID>(parameters);
621 }
622
624 using args_size_t = std::integral_constant<int, sizeof...(Args)>;
625 return signature(name, args_size_t{});
626 }
627
629 [[nodiscard]] Box invoke(const MetaValues& arguments) const override { return invokeInternal(arguments, argument_indexes_t{}); }
630
631 private:
632 [[nodiscard]] static constexpr const char* signature(StringView, std::integral_constant<int, 0>) { return DefaultConstructorSignature; }
633
634 [[nodiscard]] static String signature(StringView name, std::integral_constant<int, 1>) {
636 if constexpr(std::is_same_v<std::decay_t<Argument>, C>) {
637 if constexpr(std::is_rvalue_reference_v<Argument>) {
639 } else {
641 }
642 } else {
643 return ::CeresEngine::MetaSignature<Args...>::get(name);
644 }
645 }
646
647 template<int N> [[nodiscard]] static String signature(StringView name, std::integral_constant<int, N>) {
648 return ::CeresEngine::MetaSignature<Args...>::get(name);
649 }
650
651 template<std::size_t... I> static Box invokeInternal(const MetaValues& args, mpl::index_sequence<I...>) {
652 if constexpr(std::is_same_v<C, Box>) {
653 throw "not supported";
654 } else {
655 return Box(std::in_place_type_t<C>{}, MetaArgument(args[I]).getValue<argument_get_t<I>>()...);
656 }
657 }
658 };
659
660 // ---------------------------------------------------------------------------------------------
661
662 template<typename DerivedType, typename BaseType> inline void const* metacast_to_base(void const* value) {
663 return static_cast<void const*>(static_cast<BaseType const*>(static_cast<DerivedType const*>(value)));
664 }
665
666 template<typename T> template<typename B> void TClass<T>::base() { addBaseClass(::CeresEngine::getTypeID<B>(), &metacast_to_base<T, B>); }
667
668 template<typename T> template<typename Base0, typename... Bs> void TClass<T>::bases() {
669 base<Base0>();
670 ((void)base<Bs>(), ...);
671 }
672
673 template<typename T> template<typename... Args> void TClass<T>::constructor() {
674 // TODO: Use unique ptr.
675 new TMetaConstructor<T, Args...>(*this);
676 //registerConvertingConstructor<MPL::TypeList<Args...>>(is_converting_constructor_t<T, Args...>{});
677 }
678
679 template<typename T> template<typename P> void TClass<T>::property(StringView name, P&& property, MetaAttributeList&& attributes) {
680 // TODO: Use unique ptr.
681 ClassProperty* const p = new MetaPointerProperty<P>(*this, name, property);
682 for(Box& attribute : attributes) {
683 p->attributes.set(std::move(attribute));
684 }
685 }
686
687 template<typename T> template<typename G, typename S> void TClass<T>::property(StringView name, G&& getter, S&& setter, MetaAttributeList&& attributes) {
688 // TODO: Use unique ptr.
689 ClassProperty* const p = new MetaAccessorProperty<std::decay_t<G>, std::decay_t<S>>(*this, name, std::forward<G>(getter), std::forward<S>(setter));
690 for(Box& attribute : attributes) {
691 p->attributes.set(std::move(attribute));
692 }
693 }
694
695 template<typename T> template<typename F> void TClass<T>::method(StringView name, F func, MetaAttributeList&& attributes) {
696 // TODO: Use unique ptr.
697 ClassMethod* const m = new TMetaMethod<std::decay_t<F>>(*this, name, std::forward<F>(func));
698 for(Box& attribute : attributes) {
699 m->attributes.set(std::move(attribute));
700 }
701 }
702} // namespace CeresEngine
#define CE_ASSERT(...)
Definition Macros.hpp:323
Definition MetaError.hpp:22
A value type that can hold any alongside it's type information.
Definition Box.hpp:40
TypeID getTypeID() const noexcept
Gets the ID of the type held by the variant.
Definition Box.hpp:171
Box cref() const &
Gets a reference to the meta value.
T to() const &
Gets the value of the variant as a T.
Definition Box.hpp:332
Box ref() const &
Gets a reference to the meta value.
Definition Class.hpp:155
String name
Definition Class.hpp:157
Definition Class.hpp:46
ReflectionAttributeContainer attributes
Definition Class.hpp:54
const StringView name
Definition Class.hpp:53
Definition Class.hpp:276
StringView name
Definition Class.hpp:278
ReflectionAttributeContainer attributes
Definition Class.hpp:279
Represents a reflected property from metadata defined by the class.
Definition Class.hpp:176
ReflectionAttributeContainer attributes
Definition Class.hpp:179
StringView name
Definition Class.hpp:178
Definition MetaError.hpp:19
An implementation of MetaProperty that uses a getter and setter method pairs to access the property.
Definition Class.define.hpp:490
bool isReadOnly() const noexcept override
Definition Class.define.hpp:534
bool isStatic() const noexcept override
Definition Class.define.hpp:531
const SetterType mSetter
The setter function.
Definition Class.define.hpp:518
typename GetterTraits::result_type T
The type returned by the getter function.
Definition Class.define.hpp:503
const GetterType mGetter
The getter function.
Definition Class.define.hpp:515
typename SetterTraits::template arg< 0 > SetterArgument
The type taken by the setter function.
Definition Class.define.hpp:506
static constexpr auto valid
Definition Class.define.hpp:492
MetaAccessorProperty(Class &owner, const StringView name, GetterType getter, SetterType setter) noexcept
Creates a new property by using accessors.
Definition Class.define.hpp:526
TypeID getGetterReturnTypeID() const noexcept override
Definition Class.define.hpp:537
void set(const Box &target, Box &&value) const override
Definition Class.define.hpp:561
TypeID getSetterParameterTypeID() const noexcept override
Definition Class.define.hpp:540
Box get(const Box &target) const override
Definition Class.define.hpp:543
void set(const Box &target, const Box &value) const override
Definition Class.define.hpp:552
Definition MetaArgument.hpp:15
T getValue() const
Definition MetaArgument.hpp:139
An implementation of MetaProperty that uses a direct pointer (or pointer to member) to access the pro...
Definition Class.define.hpp:432
bool isStatic() const noexcept override
Definition Class.define.hpp:447
const PointerType mPointer
The property pointer. Can be eiter a raw pointer or a pointer to data member.
Definition Class.define.hpp:436
TypeID getSetterParameterTypeID() const noexcept override
Definition Class.define.hpp:456
MetaPointerProperty(Class &owner, const StringView name, PointerType pointer) noexcept
Creates a new property by using a pointer.
Definition Class.define.hpp:443
bool isReadOnly() const noexcept override
Definition Class.define.hpp:450
void set(const Box &target, Box &&value) const override
Definition Class.define.hpp:477
Box get(const Box &target) const override
Definition Class.define.hpp:459
void set(const Box &target, const Box &value) const override
Definition Class.define.hpp:468
TypeID getGetterReturnTypeID() const noexcept override
Definition Class.define.hpp:453
void set(const Type &type, Box &&value)
Sets the attribute for the given type.
Definition Class.define.hpp:48
void property(StringView name, P &&property, MetaAttributeList &&attributes={})
Definition Class.define.hpp:679
void method(StringView name, F func, MetaAttributeList &&attributes={})
Definition Class.define.hpp:695
void constructor()
Definition Class.define.hpp:673
void bases()
Definition Class.define.hpp:668
StringView getName() const noexcept final
Definition Class.define.hpp:62
TClass()
Definition Class.define.hpp:50
void base()
Definition Class.define.hpp:666
Definition Class.define.hpp:605
static String signature(StringView name, std::integral_constant< int, 1 >)
Definition Class.define.hpp:634
String signature(StringView name) const
Definition Class.define.hpp:623
static Box invokeInternal(const MetaValues &args, mpl::index_sequence< I... >)
Definition Class.define.hpp:651
MPL::Nth< I, MPL::TypeList< Args... > > argument_get_t
Definition Class.define.hpp:610
static String signature(StringView name, std::integral_constant< int, N >)
Definition Class.define.hpp:647
static constexpr const char * signature(StringView, std::integral_constant< int, 0 >)
Definition Class.define.hpp:632
mpl::index_sequence_for_t< Args... > argument_indexes_t
Definition Class.define.hpp:611
Span< const TypeID > getParameterTypeIDs() const override
Definition Class.define.hpp:618
Box invoke(const MetaValues &arguments) const override
Definition Class.define.hpp:629
TMetaConstructor(Class &owner)
Definition Class.define.hpp:614
Definition Class.define.hpp:572
TMetaMethod(Class &owner, const StringView name, const F &func) noexcept
Definition Class.define.hpp:579
Box invoke(const MetaValues &arguments)
Definition Class.define.hpp:600
Span< const TypeID > getParameterTypeIDs() const noexcept override
Definition Class.define.hpp:591
TMetaMethod(Class &owner, const StringView name, F &&func) noexcept
Definition Class.define.hpp:581
TypeID getReturnTypeID() const noexcept override
Definition Class.define.hpp:588
String signature(StringView name) const
Definition Class.define.hpp:597
bool isStatic() const noexcept override
Definition Class.define.hpp:585
F const mFunc
Definition Class.define.hpp:574
Definition TypeInfo.core.hpp:843
Represents a reflected C++ type. Can be used to get metadata from a C++ type.
Definition Type.hpp:32
TypeID getTypeID() const noexcept
Gets the type ID.
ClassInfo getClassInfo(const void *target) const final
Definition Class.define.hpp:37
ClassInfo getClassInfo(void *target) const final
Definition Class.define.hpp:39
Definition Class.define.hpp:32
Definition Class.define.hpp:27
std::tuple_element_t< TIndex, Tuple< TTypeList > > Nth
"Nth" element of a type list.
Definition TypeListOps.hpp:29
typename PropertyTypeTrait< P >::type PropertyType
Definition Class.define.hpp:304
typename PropertyClassTrait< P >::type PropertyClass
Definition Class.define.hpp:309
std::conditional_t< std::is_member_pointer_v< P >, MemberPointerTag, StaticPointerTag > MetaPropertyAccessorTag
Definition Class.define.hpp:315
std::conditional_t< std::is_void_v< typename function_traits< F >::result_type >, std::conditional_t< std::is_void_v< typename function_traits< F >::class_type >, VoidStaticFunctionTag, VoidMemberFunctionTag >, std::conditional_t< std::is_void_v< typename function_traits< F >::class_type >, ReturnStaticFunctionTag, ReturnMemberFunctionTag > > MethodInvokerTag
Definition Class.define.hpp:151
typename index_sequence_for< Args... >::type index_sequence_for_t
Definition TypeTraits.hpp:155
Definition Application.hpp:19
SmallVector< Box, 4 > MetaValues
Definition Class.hpp:29
TypedID< internal::TypeTag, UInt64 > TypeID
Definition Forward.hpp:45
BasicStringView< char > StringView
Narrow string view used for handling narrow encoded text in UTF-8.
Definition String.hpp:190
void const * metacast_to_base(void const *value)
Definition Class.define.hpp:662
constexpr auto MoveConstructorSignature
Definition MetaContainer.hpp:24
std::vector< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Vector
Vector is a sequence container that encapsulates dynamic size arrays.
Definition Vector.hpp:17
constexpr StringView getTypeName()
Definition TypeName.hpp:72
CE_FLATTEN_INLINE TypeID getTypeID< void >()
Definition Type.hpp:247
constexpr auto DefaultConstructorSignature
Definition MetaContainer.hpp:22
std::array< T, N > Array
Array is a container that encapsulates fixed size arrays.
Definition Array.hpp:17
Vector< Box > MetaAttributeList
Definition Class.define.hpp:43
tcb ::span< T, Extent > Span
Span describes an object that can refer to a contiguous sequence of objects with the first element of...
Definition Span.hpp:708
constexpr auto CopyConstructorSignature
Definition MetaContainer.hpp:23
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
A structure that contains type information for a class.
Definition IReflectable.hpp:15
Compile-time list of types.
Definition TypeList.hpp:15
static String get(const StringView name)
Definition MetaSignature.hpp:56
Definition TypeTraits.hpp:130
Definition Class.define.hpp:313
static Box getField(P property, const Box &instance)
Definition Class.define.hpp:362
static void setField(P property, const Box &instance, const MetaArgument &arg)
Definition Class.define.hpp:376
static void setField(P property, Box &instance, const MetaArgument &arg)
Definition Class.define.hpp:407
std::add_lvalue_reference_t< C > class_ref_t
Definition Class.define.hpp:423
static void setStatic(P, const MetaArgument &)
Definition Class.define.hpp:360
static void setStatic(P property, const MetaArgument &arg)
Definition Class.define.hpp:328
static void setField(P, const Box &, const MetaArgument &)
Definition Class.define.hpp:341
static void setField(P, Box &, const MetaArgument &)
Definition Class.define.hpp:342
static Box getField(P, const Box &)
Definition Class.define.hpp:336
static Box getStatic(P property)
Definition Class.define.hpp:326
static constexpr bool isStatic()
Definition Class.define.hpp:322
static Box invokeInternal(const F &func, const MetaValues &arguments, mpl::index_sequence< I... >)
Definition Class.define.hpp:281
typename function_traits< F >::args Args
Definition Class.define.hpp:249
typename function_traits< F >::result_type Result
Definition Class.define.hpp:250
static Vector< TypeID > getParametersTypeID(mpl::index_sequence< I... >)
Definition Class.define.hpp:269
static Vector< TypeID > getParametersTypeID()
Definition Class.define.hpp:254
std::conditional_t< is_const_method::value, std::add_const_t< C >, C > class_t
Definition Class.define.hpp:265
mpl::index_sequence_for_t< Args > argument_indexes_t
Definition Class.define.hpp:261
std::add_pointer_t< class_t > class_ptr_t
Definition Class.define.hpp:267
typename function_traits< F >::is_const is_const_method
Definition Class.define.hpp:264
static Box reference_get(R &&result)
Definition Class.define.hpp:273
static String signature(StringView name)
Definition Class.define.hpp:255
std::add_lvalue_reference_t< class_t > class_ref_t
Definition Class.define.hpp:266
static Box invoke(const F &func, const MetaValues &arguments)
Definition Class.define.hpp:257
MPL::Nth< I, Args > argument_get_t
Definition Class.define.hpp:260
static TypeID getReturnTypeID()
Definition Class.define.hpp:253
typename function_traits< F >::class_type C
Definition Class.define.hpp:263
static String signature(StringView name)
Definition Class.define.hpp:186
typename function_traits< F >::result_type Result
Definition Class.define.hpp:181
MPL::Nth< I, Args > argument_get_t
Definition Class.define.hpp:191
mpl::index_sequence_for_t< Args > argument_indexes_t
Definition Class.define.hpp:192
static TypeID getReturnTypeID()
Definition Class.define.hpp:184
typename function_traits< F >::args Args
Definition Class.define.hpp:180
static Box invokeInternal(const F &func, const MetaValues &arguments, std::index_sequence< I... >)
Definition Class.define.hpp:198
static Box invoke(const F &func, const MetaValues &arguments)
Definition Class.define.hpp:188
static Vector< TypeID > getParametersTypeID(mpl::index_sequence< I... >)
Definition Class.define.hpp:194
static Vector< TypeID > getParametersTypeID()
Definition Class.define.hpp:185
static Vector< TypeID > getParametersTypeID()
Definition Class.define.hpp:212
typename function_traits< F >::args Args
Definition Class.define.hpp:208
static TypeID getReturnTypeID()
Definition Class.define.hpp:211
static Box invokeInternal(const F &func, const MetaValues &arguments, mpl::index_sequence< I... >)
Definition Class.define.hpp:231
static String signature(StringView name)
Definition Class.define.hpp:213
std::add_pointer_t< class_t > class_ptr_t
Definition Class.define.hpp:225
std::conditional_t< is_const_method::value, std::add_const_t< C >, C > class_t
Definition Class.define.hpp:223
MPL::Nth< I, Args > argument_get_t
Definition Class.define.hpp:218
mpl::index_sequence_for_t< Args > argument_indexes_t
Definition Class.define.hpp:219
static Vector< TypeID > getParametersTypeID(mpl::index_sequence< I... >)
Definition Class.define.hpp:227
std::add_lvalue_reference_t< class_t > class_ref_t
Definition Class.define.hpp:224
static Box invoke(const F &func, const MetaValues &arguments)
Definition Class.define.hpp:215
typename function_traits< F >::is_const is_const_method
Definition Class.define.hpp:222
typename function_traits< F >::class_type C
Definition Class.define.hpp:221
static Box invokeInternal(const F &func, const MetaValues &arguments, std::index_sequence< I... >)
Definition Class.define.hpp:169
static Box invoke(const F &func, const MetaValues &arguments)
Definition Class.define.hpp:163
static String signature(StringView name)
Definition Class.define.hpp:161
static Vector< TypeID > getParametersTypeID()
Definition Class.define.hpp:160
typename function_traits< F >::args Args
Definition Class.define.hpp:156
MPL::Nth< I, Args > argument_get_t
Definition Class.define.hpp:166
static TypeID getReturnTypeID()
Definition Class.define.hpp:159
static Vector< TypeID > getParametersTypeID(mpl::index_sequence< I... >)
Definition Class.define.hpp:174
std::make_index_sequence< function_traits< F >::arity > argument_indexes_t
Definition Class.define.hpp:167
Definition Class.define.hpp:153
Definition Class.define.hpp:305
Definition Class.define.hpp:298
Definition Class.define.hpp:146
Definition Class.define.hpp:144
Definition Class.define.hpp:311
Definition Class.define.hpp:145
Definition Class.define.hpp:143
Definition TypeTraits.hpp:141
Definition TypeTraits.hpp:146