33 using is_class_ptr = std::conditional_t<std::is_pointer_v<std::remove_reference_t<T>> && std::is_class_v<std::remove_pointer_t<std::remove_reference_t<T>>>,
34 std::true_type, std::false_type>;
42 static constexpr const size_t kSmallSize =
sizeof(
void*) * 2;
119 return Box(std::in_place_type_t<T>{}, std::forward<Args>(args)...);
149#if !CE_COMPILER_MSVC && 0
151 template<
typename T>
requires(!std::is_same_v<T, Box>)
152 [[
nodiscard]]
friend bool operator==(
const Box& lhs,
const T& rhs) {
153 return lhs ==
Box(std::cref(rhs));
157 template<
typename T>
requires(!std::is_same_v<T, Box>)
158 [[
nodiscard]]
friend bool operator!=(
const Box* lhs,
const T& rhs) {
159 return !(lhs == rhs);
164 template<
typename T> [[
nodiscard]]
bool eq(
const T& value)
const;
167 template<
typename T> [[
nodiscard]]
bool neq(
const T& value)
const {
return !
eq(value); }
214 using U = std::remove_reference_t<T>;
224 return const_cast<Box&
>(*this);
229 template<
typename T> [[
nodiscard]]
T&&
ref() && {
return std::move(*this).rref<
T>(); }
232 return std::move(*
this);
246 using U = std::remove_reference_t<T>;
252 return std::move(*
result);
256 return std::move(*
this);
269 using U = std::remove_reference_t<T>;
301 static_assert(!std::is_reference_v<T>,
"Type cannot be reference");
333 static_assert(!std::is_reference_v<T>,
"Type cannot be reference");
335 std::aligned_storage_t<
sizeof(
T),
alignof(
T)> buffer;
340 return std::move(*
reinterpret_cast<T*
>(&buffer));
481 using C = std::remove_pointer_t<Decay>;
482 using tag_t = std::conditional_t<std::is_class_v<Decay>, std::integral_constant<int, 1>,
483 std::conditional_t<internal::is_class_ptr_v<Decay>, std::integral_constant<int, 2>, std::integral_constant<int, 0>>>;
487 using namespace std::literals;
493 const Decay* result =
nullptr;
497 if(Type::compatible(from, to)) {
499 result =
static_cast<const Decay*
>(self.
data());
500 }
else if(
const void*
const ptr = cast(self, from,
tag_t{})) {
501 result =
static_cast<const Decay*
>(ptr);
506 result =
static_cast<const Decay*
>(self.
data());
511 if constexpr(std::is_array_v<T>) {
512 return reinterpret_cast<T*
>(*result);
514 return const_cast<T*
>(result);
520 [[nodiscard]]
static const void*
cast(
const Box&,
Type, std::integral_constant<int, 0>) {
return nullptr; }
523 [[nodiscard]]
static const void*
cast(
const Box& self,
const Type from, std::integral_constant<int, 1>) {
528 [[nodiscard]]
static const void*
cast(
const Box& self,
const Type from, std::integral_constant<int, 2>) {
547 static_assert(!std::is_array_v<T>,
"Array types aren't supported");
555 const Type from(typeID);
557 if(Type::compatible(from, to)) {
561 }
else if(cast(self, from, to, buffer,
tag_t{})) {
566 if(Type::convert(self.
data(), from, buffer, to)) {
575 using C = std::remove_pointer_t<Decay>;
576 using tag_t = std::conditional_t<std::is_class_v<Decay>, std::integral_constant<int, 1>,
577 std::conditional_t<internal::is_class_ptr_v<Decay>, std::integral_constant<int, 2>, std::integral_constant<int, 0>>>;
580 [[nodiscard]]
static bool cast(
const Box&,
Type,
Type,
void*, std::integral_constant<int, 0>) {
return false; }
583 [[nodiscard]]
static bool cast(
const Box& self,
const Type from,
const Type to,
void* buffer, std::integral_constant<int, 1>) {
594 [[nodiscard]]
static bool cast(
const Box& self,
const Type from,
const Type to,
void* buffer, std::integral_constant<int, 2>) {
605 template<
typename T>
requires(!std::is_same_v<std::decay_t<T>,
Box>)
607 using Type = std::remove_reference_t<T>;
612 template<
typename T>
requires(!std::is_same_v<std::decay_t<T>,
Box>)
613 Box& Box::operator=(
T&& value) {
614 using Type = std::remove_reference_t<T>;
620 template<
typename T>
requires(!std::is_same_v<T, Box>)
Box::Box(std::reference_wrapper<T> value) {
625 new(
allocate(&typeInfo))
T*(&value.get());
628 template<
typename T,
typename... Args>
requires(!std::is_same_v<T, Box>)
Box::Box(std::in_place_type_t<T>, Args&&... args) {
629 using Type = std::remove_reference_t<T>;
631 new(
allocate(&typeInfo))
T(std::forward<Args>(args)...);
634 template<
typename T>
bool Box::eq(
const T& value)
const {
635 if(*
this ==
Box{std::cref(value)})
642 std::aligned_storage_t<
sizeof(
T),
alignof(
T)> buffer;
645 return value == *
reinterpret_cast<const T*
>(&buffer);
654 auto tmp = std::addressof(value);
663 ptr = *
reinterpret_cast<const void*
const*
>(ptr);
664 return mt_self.compareEquality(ptr, buffer);
672 template<
typename T>
Box box(
T& value) {
return Box(std::ref(value)); }
675 template<
typename T>
Box box(
const T& value) {
return Box(std::cref(value)); }
678 template<
typename T>
Box box(
T&& value) {
return Box(std::forward<T>(value)); }
696 static
bool is(const
Box& value) noexcept;
700 [[nodiscard]]
Box get() const;
703 [[nodiscard]]
Box operator*() const;
706 [[nodiscard]]
Box operator->() const;
712 [[nodiscard]]
Box dereference(
Box&& value);
713 [[nodiscard]]
Box dereference(const
Box& value);
716 template<typename T> [[nodiscard]]
Box dereference(
Box&& value) {
return dereference(std::forward<Box>(value)).ref<
T>(); }
721 template<>
struct GetTypeInfo<Box> {
722 static const TypeInfo& get();
729 [[nodiscard]] std::size_t operator()(
const BoxType& value)
const noexcept;
#define CE_ASSERT(...)
Definition Macros.hpp:323
#define CE_EXPLICIT(EXPR)
Definition Macros.hpp:413
#define CE_SCOPE_EXIT
Definition ScopeExit.hpp:40
Definition Box.collection.hpp:86
Definition Box.collection.hpp:55
Definition Box.collection.hpp:14
Definition Box.collection.hpp:269
Pointer(Pointer &&) noexcept=default
Pointer(const Pointer &)=default
Pointer & operator=(const Pointer &)=default
A value type that can hold any alongside it's type information.
Definition Box.hpp:40
bool canConvert(const TypeInfo &target) const
Checks if the value held by the variant is convertible to T.
Type getType() const noexcept
Gets the type held by the variant.
bool isSmall() const noexcept
Determines if the value fits on the small buffer storage.
void * data() noexcept
Returns pointer to decayed type.
Definition Box.hpp:260
void convert()
Converts the variant to type T.
Definition Box.hpp:364
const Class * getClass() const noexcept
friend class Type
Definition Box.hpp:128
bool neq(const T &value) const
Checks if a variant holds the same value as another.
Definition Box.hpp:167
friend bool operator!=(const Box &lhs, const Box &rhs)
Checks if a variant holds the same value as another.
Definition Box.hpp:147
bool is() const
Checks if the value held by the variant is T.
Definition Box.hpp:183
bool canConvert(const TypeID &target) const
Checks if the value held by the variant is convertible to T.
Definition Box.hpp:316
T && ref() &&
Gets the value of the variant as a reference to T.
Definition Box.hpp:229
Pointer asPointer() const &
Views the Box as an Pointer type.
TypeID getTypeID() const noexcept
Gets the ID of the type held by the variant.
Definition Box.hpp:171
Box to(const Type &target) const
Gets the value of the variant as a T.
Definition Box.hpp:351
const TypeInfo * mTypeInfo
The stored value type.
Definition Box.hpp:60
bool empty() const noexcept
Checks if the variant is empty (i.e. holds no value).
void clear() noexcept
Clears the variant and makes it empty.
Box to(const TypeID &target) const
Gets the value of the variant as a T.
Definition Box.hpp:348
~Box() noexcept
Destroys the variant. Will call the contained object destructor.
Box(const void *ptr, const TypeInfo *typeInfo)
static constexpr const size_t kSmallSize
Definition Box.hpp:42
bool tryConvert()
Tries to convert the variant to type T.
Definition Box.hpp:371
void * allocate(const TypeInfo *typeInfo)
void * storage() noexcept
Returns pointer to decayed type.
Definition Box.hpp:406
Type getClassType() const noexcept
Gets the type held by the variant.
ClassInfo getClassInfo() const noexcept
Gets the ClassInfo of the stored value.
T & ref() const &
Gets the value of the variant as a reference to T.
Definition Box.hpp:213
const void * data() const noexcept
Returns pointer to decayed type.
Iterable asIterable() const &
Views the Box as an Iterable type.
const void * storage() const noexcept
Returns pointer to decayed type.
Definition Box.hpp:409
Box rref() &&
Gets a reference to the meta value.
bool eq(const T &value) const
Checks if a variant holds the same value as another.
Definition Box.hpp:634
friend void swap(Box &, Box &) noexcept
Definition Box.hpp:438
bool is(const Type &type) const
Array asArray() const &
Views the Box as an Array type.
Box to(const TypeInfo &target) const
Gets the value of the variant as a T.
friend bool operator==(const Box &lhs, const Box &rhs)
Checks if a variant holds the same value as another.
Box copy() const
Makes a copy of the object.
bool canConvert() const
Checks if the value held by the variant is convertible to T.
Definition Box.hpp:300
Map asMap() const &
Views the Box as an Map type.
const T & cref() const
Gets the value of the variant as a const reference to T.
Definition Box.hpp:237
T to() const &
Gets the value of the variant as a T.
Definition Box.hpp:332
bool canConvert(const Type &target) const
Checks if the value held by the variant is convertible to T.
Definition Box.hpp:319
Box ref() const &
Gets a reference to the meta value.
Storage mStorage
The value storage.
Definition Box.hpp:57
Box() noexcept
Creates a new variant holding an empty value.
Iterator asIterator() const &
Views the Box as an Iterator type.
const Enum * getMetaEnum() const noexcept
TypeID getInternalTypeID(TypeAttribute attr=TypeAttribute::NONE) const noexcept
Gets the type ID for the given type attribute.
T && rref() &&
Gets the value of the variant as a r-value reference to T.
Definition Box.hpp:245
static Box create(Args &&... args)
Definition Box.hpp:118
Represents a reflected enum from C++.
Definition Enum.hpp:26
Represents a reflected C++ type. Can be used to get metadata from a C++ type.
Definition Type.hpp:32
bool isClassPtr() const noexcept
Returns true if the type is a class pointer, false otherwise.
TypeID getDecayTypeID() const noexcept
Gets the decayed type.
const TypeInfo * mTypeInfo
The TypeInfo structure that describes the reflected type.
Definition Type.hpp:35
static bool hasConverter() noexcept
Determines if there is a converter available to convert a value from From to To.
Definition Type.hpp:360
StringView getTypeName() const noexcept
bool isClass() const noexcept
Returns true if the type is a class, false otherwise.
void copyConstruct(const void *source, void *where) const
static bool convert(const void *from, Type fromType, void *to, Type toType)
Definition TypeInfo.hpp:36
const void * castInternal(const Box &self, const Type &type)
constexpr auto is_class_ptr_v
Definition Box.hpp:36
typename is_class_ptr< T >::type is_class_ptr_t
Definition Box.hpp:35
std::conditional_t< std::is_pointer_v< std::remove_reference_t< T > > &&std::is_class_v< std::remove_pointer_t< std::remove_reference_t< T > > >, std::true_type, std::false_type > is_class_ptr
Definition Box.hpp:34
Definition Application.hpp:19
Box box(T &value)
Creates a new Box object by wraping the value as a reference type.
Definition Box.hpp:672
remove_all_cv< std::decay_t< T > > full_decay
Definition TypeTraits.hpp:97
auto dereference(Container &container)
Returns an iterable object that iterates over the values of Container but also dereferences the point...
Definition Iterator.hpp:421
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Implementation for type casting in Box.
Definition Box.hpp:478
std::remove_pointer_t< Decay > C
Definition Box.hpp:481
std::conditional_t< std::is_class_v< Decay >, std::integral_constant< int, 1 >, std::conditional_t< internal::is_class_ptr_v< Decay >, std::integral_constant< int, 2 >, std::integral_constant< int, 0 > > > tag_t
Definition Box.hpp:483
static const void * cast(const Box &self, const Type from, std::integral_constant< int, 1 >)
Definition Box.hpp:523
static const void * cast(const Box &, Type, std::integral_constant< int, 0 >)
Definition Box.hpp:520
full_decay< T > Decay
Definition Box.hpp:480
static const void * cast(const Box &self, const Type from, std::integral_constant< int, 2 >)
Definition Box.hpp:528
static T * invoke(const Box &self, const TypeID fromID, const TypeID toID)
Definition Box.hpp:486
Implementation for type checks in Box.
Definition Box.hpp:429
Implementation for type conversion in Box.
Definition Box.hpp:546
std::remove_pointer_t< Decay > C
Definition Box.hpp:575
full_decay< T > Decay
Definition Box.hpp:574
static void invoke(const Box &self, const TypeID typeID, void *const buffer)
Definition Box.hpp:549
static bool cast(const Box &, Type, Type, void *, std::integral_constant< int, 0 >)
Definition Box.hpp:580
std::conditional_t< std::is_class_v< Decay >, std::integral_constant< int, 1 >, std::conditional_t< internal::is_class_ptr_v< Decay >, std::integral_constant< int, 2 >, std::integral_constant< int, 0 > > > tag_t
Definition Box.hpp:577
static bool cast(const Box &self, const Type from, const Type to, void *buffer, std::integral_constant< int, 1 >)
Definition Box.hpp:583
static bool cast(const Box &self, const Type from, const Type to, void *buffer, std::integral_constant< int, 2 >)
Definition Box.hpp:594
A structure that contains type information for a class.
Definition IReflectable.hpp:15
static const TypeInfo & get()
A type that contains storage for the Box.
Definition Box.hpp:45
char buffer[kSmallSize]
The buffer to allocate the small object on.
Definition Box.hpp:51
Storage()
Definition Box.hpp:53
void * ptr
The pointer to the object. Only valid if the object is larger than kSmallSize.
Definition Box.hpp:47