diff --git a/include/UECS/RTDCmptTraits.h b/include/UECS/RTDCmptTraits.h index ac75fef..8c140cc 100644 --- a/include/UECS/RTDCmptTraits.h +++ b/include/UECS/RTDCmptTraits.h @@ -18,56 +18,33 @@ namespace Ubpa { public: static constexpr size_t default_alignment = alignof(std::max_align_t); - static RTDCmptTraits& Instance() noexcept { - static RTDCmptTraits instance; - return instance; - } + inline static RTDCmptTraits& Instance() noexcept; // neccessary - RTDCmptTraits& RegisterSize(CmptType type, size_t size) { - sizeofs[type] = size; - return *this; - } + inline RTDCmptTraits& RegisterSize(CmptType type, size_t size); // optional - RTDCmptTraits& RegisterAlignment(CmptType type, size_t alignment) { - alignments[type] = alignment; - return *this; - } + inline RTDCmptTraits& RegisterAlignment(CmptType type, size_t alignment); // optional - RTDCmptTraits& RegisterDefaultConstructor(CmptType type, std::function f) { - default_constructors[type] = std::move(f); - return *this; - } + inline RTDCmptTraits& RegisterDefaultConstructor(CmptType type, std::function f); // optional - RTDCmptTraits& RegisterCopyConstructor(CmptType type, std::function f) { - copy_constructors[type] = std::move(f); - return *this; - } + inline RTDCmptTraits& RegisterCopyConstructor(CmptType type, std::function f); // optional - RTDCmptTraits& RegisterMoveConstructor(CmptType type, std::function f) { - move_constructors[type] = std::move(f); - return *this; - } + inline RTDCmptTraits& RegisterMoveConstructor(CmptType type, std::function f); // optional - RTDCmptTraits& RegisterDestructor(CmptType type, std::function f) { - destructors[type] = std::move(f); - return *this; - } - - RTDCmptTraits& Deregister(CmptType type) { - sizeofs.erase(type); - alignments.erase(type); - default_constructors.erase(type); - copy_constructors.erase(type); - move_constructors.erase(type); - destructors.erase(type); - return *this; - } + inline RTDCmptTraits& RegisterDestructor(CmptType type, std::function f); + + inline RTDCmptTraits& Deregister(CmptType type) noexcept; + + template + void Register(); + + template + void Deregister(); private: friend class RTSCmptTraits; @@ -76,6 +53,7 @@ namespace Ubpa { RTDCmptTraits() = default; + std::unordered_map sizeofs; std::unordered_map alignments; std::unordered_map> default_constructors; // dst <- src @@ -84,3 +62,5 @@ namespace Ubpa { std::unordered_map> destructors; }; } + +#include "detail/RTDCmptTraits.inl" diff --git a/include/UECS/detail/RTDCmptTraits.inl b/include/UECS/detail/RTDCmptTraits.inl new file mode 100644 index 0000000..6d92bba --- /dev/null +++ b/include/UECS/detail/RTDCmptTraits.inl @@ -0,0 +1,99 @@ +#pragma once + +#include "../RTDCmptTraits.h" + +namespace Ubpa { + inline RTDCmptTraits& RTDCmptTraits::Instance() noexcept { + static RTDCmptTraits instance; + return instance; + } + + // neccessary + inline RTDCmptTraits& RTDCmptTraits::RegisterSize(CmptType type, size_t size) { + sizeofs[type] = size; + return *this; + } + + // optional + inline RTDCmptTraits& RTDCmptTraits::RegisterAlignment(CmptType type, size_t alignment) { + alignments[type] = alignment; + return *this; + } + + // optional + inline RTDCmptTraits& RTDCmptTraits::RegisterDefaultConstructor(CmptType type, std::function f) { + default_constructors[type] = std::move(f); + return *this; + } + + // optional + inline RTDCmptTraits& RTDCmptTraits::RegisterCopyConstructor(CmptType type, std::function f) { + copy_constructors[type] = std::move(f); + return *this; + } + + // optional + inline RTDCmptTraits& RTDCmptTraits::RegisterMoveConstructor(CmptType type, std::function f) { + move_constructors[type] = std::move(f); + return *this; + } + + // optional + inline RTDCmptTraits& RTDCmptTraits::RegisterDestructor(CmptType type, std::function f) { + destructors[type] = std::move(f); + return *this; + } + + template + void RTDCmptTraits::Register() { + static_assert(std::is_copy_constructible_v, " must be copy-constructible"); + static_assert(std::is_move_constructible_v, " must be move-constructible"); + static_assert(std::is_destructible_v, " must be destructible"); + + constexpr CmptType type = CmptType::Of(); + + sizeofs[type] = sizeof(Cmpt); + alignments[type] = alignof(Cmpt); + + if constexpr (!std::is_trivially_destructible_v) { + destructors[type] = [](void* cmpt) { + reinterpret_cast(cmpt)->~Cmpt(); + }; + } + if constexpr (!std::is_trivially_move_constructible_v) { + move_constructors[type] = [](void* dst, void* src) { + new(dst)Cmpt(std::move(*reinterpret_cast(src))); + }; + } + if constexpr (!std::is_trivially_copy_constructible_v) { + copy_constructors[type] = [](void* dst, void* src) { + new(dst)Cmpt(*reinterpret_cast(src)); + }; + } + } + + template + void RTDCmptTraits::Deregister() { + constexpr CmptType type = CmptType::Of(); + + sizeofs.erase(type); + alignments.erase(type); + + if constexpr (!std::is_trivially_destructible_v) + destructors.erase(type); + if constexpr (!std::is_trivially_move_constructible_v) + move_constructors.erase(type); + if constexpr (!std::is_trivially_copy_constructible_v) + copy_constructors.erase(type); + } + + inline RTDCmptTraits& RTDCmptTraits::Deregister(CmptType type) noexcept { + sizeofs.erase(type); + alignments.erase(type); + default_constructors.erase(type); + copy_constructors.erase(type); + move_constructors.erase(type); + destructors.erase(type); + return *this; + } +} diff --git a/include/UECS/detail/RTSCmptTraits.h b/include/UECS/detail/RTSCmptTraits.h index 9df5394..8ed6c7a 100644 --- a/include/UECS/detail/RTSCmptTraits.h +++ b/include/UECS/detail/RTSCmptTraits.h @@ -49,7 +49,7 @@ namespace Ubpa { template void Deregister(); - inline void Deregister(CmptType type); + inline void Deregister(CmptType type) noexcept; private: std::unordered_map sizeofs; diff --git a/include/UECS/detail/RTSCmptTraits.inl b/include/UECS/detail/RTSCmptTraits.inl index 6a6aa2f..ce136e6 100644 --- a/include/UECS/detail/RTSCmptTraits.inl +++ b/include/UECS/detail/RTSCmptTraits.inl @@ -71,7 +71,7 @@ namespace Ubpa { move_constructors[type] = move_constructor_target->second; } - inline void RTSCmptTraits::Deregister(CmptType type) { + inline void RTSCmptTraits::Deregister(CmptType type) noexcept { sizeofs.erase(type); alignments.erase(type); copy_constructors.erase(type);