Skip to content

Instantly share code, notes, and snippets.

@JonathanCline
Created July 21, 2021 05:24
Show Gist options
  • Save JonathanCline/94b6aa196c44a152ae38e98bfb641066 to your computer and use it in GitHub Desktop.
Save JonathanCline/94b6aa196c44a152ae38e98bfb641066 to your computer and use it in GitHub Desktop.
Small prototype for using CRTP static mixins in combination with an ECS
#include <iostream>
#include <concepts>
template <typename T>
concept entity_extension = true;
template <typename T, typename ExT>
struct apply_extension;
template <typename T, template <typename U> typename ExT, typename U>
struct apply_extension<T, ExT<U>>
{
using type = ExT<T>;
};
template <typename T, typename ExT>
using apply_extension_t = typename apply_extension<T, ExT>::type;
template <std::integral T, entity_extension... Exts>
struct basic_entity :
public apply_extension_t<basic_entity<T, Exts...>, Exts>...
{
public:
using value_type = T;
constexpr value_type id() const noexcept { return this->id_; };
constexpr basic_entity() noexcept = default;
constexpr basic_entity(const basic_entity & other) noexcept = default;
constexpr basic_entity& operator=(const basic_entity & other) noexcept = default;
constexpr basic_entity(basic_entity && other) noexcept = default;
constexpr basic_entity& operator=(basic_entity && other) noexcept = default;
constexpr explicit basic_entity(value_type _id) noexcept :
id_{ _id }
{};
template <entity_extension... _Exts>
constexpr basic_entity(const basic_entity<T, _Exts...>& _other) noexcept :
id_{ _other.id() }
{};
template <entity_extension... _Exts>
constexpr basic_entity(basic_entity<T, _Exts...>&& _other) noexcept :
id_{ _other.id() }
{};
template <entity_extension... _Exts>
constexpr basic_entity& operator=(const basic_entity<T, _Exts...>& _other) noexcept
{
this->id_ = _other.id();
return *this;
};
template <entity_extension... _Exts>
constexpr basic_entity& operator=(basic_entity<T, _Exts...>&& _other) noexcept
{
this->id_ = _other.id();
return *this;
};
private:
value_type id_;
};
template <entity_extension... Exts>
using entity = basic_entity<int, Exts...>;
template <typename T = void>
struct test_ext
{
void print()
{
std::cout << static_cast<T*>(this)->id() << '\n';
};
};
using test_entity = entity<test_ext<>>;
int main()
{
entity<> _foo{ 12 };
test_entity _test{ _foo };
_test.print();
static_assert(sizeof(_foo) == sizeof(_test));
return 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment