type_traits: added shortcut entt::integral_constant

This commit is contained in:
Michele Caini
2020-03-19 23:03:07 +01:00
parent e16a8d29ea
commit c9a3ae8149
5 changed files with 34 additions and 21 deletions

2
TODO
View File

@@ -22,7 +22,7 @@ Next:
* ENTT_ENABLE_ETO -> ENTT_IS_EMPTY (ignore default constructible)
* review multi component views to reduce instantiations once empty types are gone...
* avoid using deprecated functions all around
* accept fixed type iterators like std::container<T> does rather than all possible types
* accept fixed type iterators like std::container<T> does rather than all possible types
* WIP:
- deprecate snapshot, loader, ...

View File

@@ -13,6 +13,14 @@
namespace entt {
/**
* @brief Wraps a static constant.
* @tparam Value A static constant.
*/
template<auto Value>
using integral_constant = std::integral_constant<decltype(Value), Value>;
/**
* @brief Utility class to disambiguate overloaded functions.
* @tparam N Number of choices available.
@@ -207,7 +215,7 @@ using member_class_t = typename member_class<Member>::type;
* @tparam Value A constant value at least convertible to `id_type`.
*/
template<id_type Value>
using tag = std::integral_constant<id_type, Value>;
using tag = integral_constant<Value>;
}

View File

@@ -527,7 +527,7 @@ public:
node.next = type->ctor;
type->ctor = &node;
return meta_factory<Type, std::integral_constant<decltype(Func), Func>>{&node.prop};
return meta_factory<Type, integral_constant<Func>>{&node.prop};
}
/**
@@ -674,7 +674,7 @@ public:
curr->next = type->data;
type->data = curr;
return meta_factory<Type, std::integral_constant<decltype(Data), Data>>{&curr->prop};
return meta_factory<Type, integral_constant<Data>>{&curr->prop};
}
/**
@@ -721,7 +721,7 @@ public:
node.next = type->data;
type->data = &node;
return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
return meta_factory<Type, integral_constant<Setter>, integral_constant<Getter>>{&node.prop};
}
/**
@@ -763,7 +763,7 @@ public:
node.next = type->func;
type->func = &node;
return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
return meta_factory<Type, integral_constant<Candidate>>{&node.prop};
}
/**

View File

@@ -5,6 +5,7 @@
#include <utility>
#include <type_traits>
#include "../config/config.h"
#include "../core/type_traits.hpp"
namespace entt {
@@ -81,41 +82,37 @@ class process {
FINISHED
};
template<state value>
using state_value_t = std::integral_constant<state, value>;
template<typename Target = Derived>
auto tick(int, state_value_t<state::UNINITIALIZED>)
auto next(integral_constant<state::UNINITIALIZED>)
-> decltype(std::declval<Target>().init()) {
static_cast<Target *>(this)->init();
}
template<typename Target = Derived>
auto tick(int, state_value_t<state::RUNNING>, Delta delta, void *data)
auto next(integral_constant<state::RUNNING>, Delta delta, void *data)
-> decltype(std::declval<Target>().update(delta, data)) {
static_cast<Target *>(this)->update(delta, data);
}
template<typename Target = Derived>
auto tick(int, state_value_t<state::SUCCEEDED>)
auto next(integral_constant<state::SUCCEEDED>)
-> decltype(std::declval<Target>().succeeded()) {
static_cast<Target *>(this)->succeeded();
}
template<typename Target = Derived>
auto tick(int, state_value_t<state::FAILED>)
auto next(integral_constant<state::FAILED>)
-> decltype(std::declval<Target>().failed()) {
static_cast<Target *>(this)->failed();
}
template<typename Target = Derived>
auto tick(int, state_value_t<state::ABORTED>)
auto next(integral_constant<state::ABORTED>)
-> decltype(std::declval<Target>().aborted()) {
static_cast<Target *>(this)->aborted();
}
template<state value, typename... Args>
void tick(char, state_value_t<value>, Args &&...) const ENTT_NOEXCEPT {}
void next(...) const ENTT_NOEXCEPT {}
protected:
/**
@@ -233,11 +230,11 @@ public:
void tick(const Delta delta, void *data = nullptr) {
switch (current) {
case state::UNINITIALIZED:
tick(0, state_value_t<state::UNINITIALIZED>{});
next(integral_constant<state::UNINITIALIZED>{});
current = state::RUNNING;
break;
case state::RUNNING:
tick(0, state_value_t<state::RUNNING>{}, delta, data);
next(integral_constant<state::RUNNING>{}, delta, data);
break;
default:
// suppress warnings
@@ -247,16 +244,16 @@ public:
// if it's dead, it must be notified and removed immediately
switch(current) {
case state::SUCCEEDED:
tick(0, state_value_t<state::SUCCEEDED>{});
next(integral_constant<state::SUCCEEDED>{});
current = state::FINISHED;
break;
case state::FAILED:
tick(0, state_value_t<state::FAILED>{});
next(integral_constant<state::FAILED>{});
current = state::FINISHED;
stopped = true;
break;
case state::ABORTED:
tick(0, state_value_t<state::ABORTED>{});
next(integral_constant<state::ABORTED>{});
current = state::FINISHED;
stopped = true;
break;

View File

@@ -1,8 +1,16 @@
#include <type_traits>
#include <gtest/gtest.h>
#include <entt/config/config.h>
#include <entt/core/hashed_string.hpp>
#include <entt/core/type_traits.hpp>
TEST(IntegralConstant, Functionalities) {
entt::integral_constant<3> constant;
ASSERT_TRUE((std::is_same_v<typename entt::integral_constant<3>::value_type, int>));
ASSERT_EQ(constant.value, 3);
}
TEST(Choice, Functionalities) {
ASSERT_TRUE((std::is_base_of_v<entt::choice_t<0>, entt::choice_t<1>>));
ASSERT_FALSE((std::is_base_of_v<entt::choice_t<1>, entt::choice_t<0>>));