22#define CE_POLY_TMPL(T) typename T, size_t T##SmallSize, bool T##Copyable, typename T##BaseType
23#define CE_POLY_TYPE(T) Poly<T, T##SmallSize, T##Copyable, T##BaseType>
57 template<
typename T,
size_t SmallSize = sizeof(
int*) * 4,
bool Copyable = true,
typename BaseType = T>
class Poly {
58 template<
typename,
size_t,
bool,
typename>
friend class Poly;
62 static_assert(
SmallSize >=
sizeof(
void*),
"SmallSize must be at least the size of a single pointer.");
72 template<
typename U>
static constexpr inline bool isSmall =
sizeof(
U) <=
SmallSize&& std::is_move_constructible_v<U>;
81 .
get = [](
void*
const ptr) ->
BaseType* {
return reinterpret_cast<TT*
>(ptr); },
83 if constexpr(std::is_copy_constructible_v<TT>) {
84 return [](
void*
const destination,
const void* source) {
91 if constexpr(std::is_move_constructible_v<TT>) {
92 return [](
void*
const destination,
void*
const source) {
98 .destroy = [](
void*
const ptr) {
reinterpret_cast<TT*
>(ptr)->~
TT(); },
105 .
get = [](
void*
const ptr) ->
BaseType* {
return *
reinterpret_cast<TT**
>(ptr); },
107 if constexpr(std::is_copy_constructible_v<TT>) {
108 return [](
void*
const destination,
const void*
const source) {
116 *
reinterpret_cast<TT**
>(
destination) = std::exchange(*
reinterpret_cast<TT**
>(source),
nullptr);
118 .destroy = [](
void*
const ptr) {
delete *
reinterpret_cast<TT**
>(ptr); },
128 .
get = [](
void*
const ptr) ->
BaseType* {
return *
reinterpret_cast<T**
>(ptr); },
129 .copy = [](
void*
const dst,
const void*
const src) { *
reinterpret_cast<T**
>(dst) = *
reinterpret_cast<T*
const*
>(src); },
130 .move = [](
void*
const dst,
void*
const src) { *
reinterpret_cast<T**
>(dst) = *
reinterpret_cast<T**
>(src); },
131 .destroy = [](
void*
const ptr) { *
reinterpret_cast<T**
>(ptr) =
nullptr; },
229 template<
typename TT,
typename... Args>
230 explicit Poly(
ConstructTag<TT>, Args&&... args)
requires(std::is_convertible_v<TT*, T*>&& std::is_constructible_v<
TT, Args&&...>) {
242 template<
typename TT,
typename... Args>
243 explicit Poly(std::in_place_type_t<TT>, Args&&... args)
requires(std::is_convertible_v<TT*, T*>&& std::is_constructible_v<
TT, Args&&...>) {
251 template<
typename... Args>
252 explicit Poly(Args&&... args)
requires(std::is_constructible_v<
T, Args...>) :
Poly(
ConstructTag<
T>{}, std::forward<Args>(args)...) {}
257 template<
typename TT>
264 template<
typename TT>
277 *
reinterpret_cast<T**
>(
mRaw) = instance;
284 template<
typename TT,
typename... Args>
TT&
emplace(Args&&... args)
requires std::is_constructible_v<
TT, Args...> {
297 TT*
const pointer =
new TT(std::forward<Args>(args)...);
301 return static_cast<TT&
>(*
get());
317 TT*
const pointer =
new TT(std::move(instance));
321 return static_cast<TT&
>(*
get());
328 template<
typename U>
requires(
Copyable)
393 return std::move(*
get());
400 return typeid(*
get());
421 template<
typename TT>
TT&
as() &
requires std::is_convertible_v<TT*, T*> {
424 return static_cast<TT&
>(*
get());
428 template<
typename TT>
TT&&
as() &&
requires std::is_convertible_v<TT*, T*> {
431 return static_cast<TT&&
>(*
get());
438 return static_cast<const TT&
>(*
get());
453 std::memset(
mRaw, 0x00,
sizeof(
mRaw));
463 if(lhs.get() ==
nullptr) {
466 if(rhs.get() ==
nullptr) {
469 return *(lhs.get()) == *(rhs.get());
477 if(lhs.get() ==
nullptr) {
480 return *(lhs.get()) == rhs;
488 if(rhs.get() ==
nullptr) {
491 return lhs == *(rhs.get());
499 if(lhs.get() ==
nullptr) {
502 if(rhs.get() ==
nullptr) {
505 return *(lhs.get()) != *(rhs.get());
513 if(lhs.get() ==
nullptr) {
516 return *(lhs.get()) != rhs;
524 if(rhs.get() ==
nullptr) {
527 return lhs != *(rhs.get());
535 if(lhs.get() ==
nullptr) {
538 if(rhs.get() ==
nullptr) {
541 return *(lhs.get()) > *(rhs.get());
549 if(lhs.get() ==
nullptr) {
552 return *(lhs.get()) > rhs;
560 if(rhs.get() ==
nullptr) {
563 return lhs > *(rhs.get());
571 if(lhs.get() ==
nullptr) {
574 if(rhs.get() ==
nullptr) {
577 return *(lhs.get()) >= *(rhs.get());
585 if(lhs.get() ==
nullptr) {
588 return *(lhs.get()) >= rhs;
596 if(rhs.get() ==
nullptr) {
599 return lhs >= *(rhs.get());
607 if(lhs.get() ==
nullptr) {
610 if(rhs.get() ==
nullptr) {
613 return *(lhs.get()) < *(rhs.get());
621 if(lhs.get() ==
nullptr) {
624 return *(lhs.get()) < rhs;
632 if(rhs.get() ==
nullptr) {
635 return lhs < *(rhs.get());
643 if(lhs.get() ==
nullptr) {
646 if(rhs.get() ==
nullptr) {
649 return *(lhs.get()) <= *(rhs.get());
657 if(lhs.get() ==
nullptr) {
660 return *(lhs.get()) <= rhs;
668 if(rhs.get() ==
nullptr) {
671 return lhs <= *(rhs.get());
677 template<CE_POLY_TMPL(T)>
bool operator==(
const CE_POLY_TYPE(
T) & lhs, std::nullptr_t)
noexcept {
return lhs.get() ==
nullptr; }
682 template<CE_POLY_TMPL(T)>
bool operator!=(
const CE_POLY_TYPE(
T) & lhs, std::nullptr_t)
noexcept {
return lhs.get() !=
nullptr; }
#define CE_ASSERT(...)
Definition Macros.hpp:323
#define CE_ASSERT_DEBUG(...)
Definition Macros.hpp:334
#define CE_EXPLICIT(EXPR)
Definition Macros.hpp:413
#define CE_POLY_TYPE(T)
Definition Poly.hpp:23
A pointer type that has value semantics.
Definition Poly.hpp:57
TT * being()
Safely casts the hold type to TT.
Definition Poly.hpp:412
static const Implementation * create()
Creates a new implementation for the concrete type TT.
Definition Poly.hpp:76
bool valid() const
Checks if the pointer has a valid object stored in it.
Definition Poly.hpp:357
T & operator*() &
&
Definition Poly.hpp:385
static constexpr bool isSmall
true if an object of type U will not cause an allocation.
Definition Poly.hpp:72
Poly() noexcept
Creates a new empty Poly.
Definition Poly.hpp:236
void reset()
Resets the stored object into an empty state.
Definition Poly.hpp:444
static const Implementation * getReference()
Gets the implementation table for referencing the polymorphic object as a reference.
Definition Poly.hpp:126
Poly & operator=(const Poly &other)
Assigns a Poly by copying an existing one.
Definition Poly.hpp:156
Byte mRaw[SmallSize]
The underlying storage memory.
Definition Poly.hpp:65
bool empty() const
Checks if the pointer has a valid object stored in it.
Definition Poly.hpp:360
TT & as() &
Casts the hold type to TT.
Definition Poly.hpp:421
TT & emplace(TT &&instance)
Definition Poly.hpp:304
Poly(const Poly< U, SmallSize, Copyable, BaseType > &other)
Creates a new Poly instance by referencing another.
Definition Poly.hpp:329
const Implementation * mImplementation
A Implementation that contains implementation for copy, move and destroy.
Definition Poly.hpp:68
const T & operator*() const &
Definition Poly.hpp:379
~Poly() noexcept
Destroys the Poly and destroys the object is present.
Definition Poly.hpp:216
Poly(std::nullptr_t) noexcept
Creates a new empty Poly.
Definition Poly.hpp:206
T * operator->()
Definition Poly.hpp:373
Poly(TT object)
Creates a new Poly that holds a copy constructed object of type TT.
Definition Poly.hpp:258
Poly(std::in_place_type_t< TT >, Args &&... args)
Creates a new Poly that holds a newly constructed object of type TT.
Definition Poly.hpp:243
TT && as() &&
Casts the hold type to TT.
Definition Poly.hpp:428
T * get()
Definition Poly.hpp:367
bool isCopyable() const noexcept
Checks if the Poly copy constructor can be safely called.
Definition Poly.hpp:138
const T * get() const
Definition Poly.hpp:370
Poly(TT &&object)
Creates a new Poly that holds a copy constructed object of type TT.
Definition Poly.hpp:265
bool is() const
Checks if the hold object is of type TT.
Definition Poly.hpp:406
Poly & operator=(std::nullptr_t) noexcept
Assigns the Poly a nullptr value.
Definition Poly.hpp:210
Poly(ConstructTag< TT >, Args &&... args)
Creates a new Poly that holds a newly constructed object of type TT.
Definition Poly.hpp:230
const T * operator->() const
Definition Poly.hpp:376
const TT * being() const
Safely casts the hold type to TT.
Definition Poly.hpp:415
bool isMovable() const noexcept
Checks if the Poly move constructor can be safely called.
Definition Poly.hpp:172
const TT & as() const &
Casts the hold type to TT.
Definition Poly.hpp:435
Poly & operator=(Poly &&other)
Assigns a Poly by moving an existing one.
Definition Poly.hpp:190
T && operator*() &&
&
Definition Poly.hpp:391
Poly(Args &&... args)
Creates a new Poly that holds a newly constructed object of type T.
Definition Poly.hpp:252
const std::type_info & getTypeID() const
Definition Poly.hpp:398
TT & emplace(Args &&... args)
Emplace a new object of type TT into the Poly.
Definition Poly.hpp:284
Poly(Poly &&other) noexcept
Creates a new Poly by moving an existing one.
Definition Poly.hpp:176
Poly(const Poly &other)
Creates a new Poly by copying an existing one.
Definition Poly.hpp:142
Definition Application.hpp:19
Byte
Definition DataTypes.hpp:40
constexpr bool operator<(const Optional< A > &lhs, const Optional< B > &rhs)
Definition Optional.hpp:162
auto move(Vector3 position)
Moves a entity to the given position.
Definition Helpers.hpp:22
bool operator!=(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:416
constexpr bool operator>=(const Optional< A > &lhs, const Optional< B > &rhs)
Definition Optional.hpp:157
bool operator==(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:411
constexpr bool operator>(const Optional< A > &lhs, const Optional< B > &rhs)
Definition Optional.hpp:152
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
constexpr bool operator<=(const Optional< A > &lhs, const Optional< B > &rhs)
Definition Optional.hpp:167
A tag used for tagged dispatching the object constructing constructor.
Definition Poly.hpp:222
A struct that contains the implementation for each concrete type get, copy, move and destroy function...
Definition Poly.hpp:28
void(* move)(void *lhs, void *rhs)
Moves the object at rhs to lhs.
Definition Poly.hpp:36
void(* copy)(void *lhs, const void *rhs)
Copies the object at rhs to lhs.
Definition Poly.hpp:33
T *(* get)(void *raw)
Extracts a function pointer from the raw data.
Definition Poly.hpp:30
void(* destroy)(void *raw)
Destroys the object stored at the given raw location.
Definition Poly.hpp:39