mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 14:09:02 +07:00
little fixes of types
This commit is contained in:
@@ -109,40 +109,29 @@ namespace meta_hpp
|
||||
struct typename_arg_t {};
|
||||
|
||||
template < typename... Args >
|
||||
inline typename_arg_t<Args...> typename_arg;
|
||||
inline constexpr typename_arg_t<Args...> typename_arg;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
namespace meta_hpp::stdex
|
||||
{
|
||||
template < typename T >
|
||||
struct add_ptr {
|
||||
using type = std::add_pointer_t<T>;
|
||||
};
|
||||
struct is_bounded_array: std::false_type {};
|
||||
template < typename T, std::size_t N >
|
||||
struct is_bounded_array<T[N]>: std::true_type {};
|
||||
template < typename T >
|
||||
inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
|
||||
|
||||
template < typename T >
|
||||
struct remove_cv {
|
||||
using type = std::remove_cv_t<T>;
|
||||
};
|
||||
|
||||
struct is_unbounded_array: std::false_type {};
|
||||
template < typename T >
|
||||
struct remove_ref {
|
||||
using type = std::remove_reference_t<T>;
|
||||
};
|
||||
struct is_unbounded_array<T[]>: std::true_type {};
|
||||
template < typename T >
|
||||
inline constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
|
||||
|
||||
template < typename T >
|
||||
struct remove_cvref {
|
||||
using type = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
using add_ptr_t = typename add_ptr<T>::type;
|
||||
|
||||
template < typename T >
|
||||
using remove_cv_t = typename remove_cv<T>::type;
|
||||
|
||||
template < typename T >
|
||||
using remove_ref_t = typename remove_ref<T>::type;
|
||||
|
||||
template < typename T >
|
||||
using remove_cvref_t = typename remove_cvref<T>::type;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ namespace meta_hpp
|
||||
void add_(const std::string& prefix, const enum_<Enum>& internal);
|
||||
template < typename Function >
|
||||
void add_(const std::string& prefix, const function_<Function>& internal);
|
||||
template < typename Member >
|
||||
void add_(const std::string& prefix, const member_<Member>& internal);
|
||||
template < typename Method >
|
||||
void add_(const std::string& prefix, const method_<Method>& internal);
|
||||
void add_(const std::string& prefix, const namespace_& internal);
|
||||
void add_(const std::string& prefix, ...) = delete;
|
||||
private:
|
||||
@@ -139,16 +135,6 @@ namespace meta_hpp
|
||||
add_info_(prefix, internal.make_info());
|
||||
}
|
||||
|
||||
template < typename Member >
|
||||
inline void registry::add_(const std::string& prefix, const member_<Member>& internal) {
|
||||
add_info_(prefix, internal.make_info());
|
||||
}
|
||||
|
||||
template < typename Method >
|
||||
inline void registry::add_(const std::string& prefix, const method_<Method>& internal) {
|
||||
add_info_(prefix, internal.make_info());
|
||||
}
|
||||
|
||||
inline void registry::add_(const std::string& prefix, const namespace_& internal) {
|
||||
add_info_(prefix, internal.make_info());
|
||||
}
|
||||
|
||||
@@ -9,4 +9,3 @@
|
||||
#include "../meta_fwd.hpp"
|
||||
#include "../meta_infos.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
|
||||
|
||||
@@ -70,13 +70,13 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
inline any_type type_db::get() {
|
||||
any_type type_db::get() {
|
||||
static const auto raw_type = detail::make_any_type<T>();
|
||||
return any_type{raw_type};
|
||||
}
|
||||
|
||||
template < typename Tuple >
|
||||
inline std::vector<any_type> type_db::multi_get() {
|
||||
std::vector<any_type> type_db::multi_get() {
|
||||
return detail::multi_get_impl<Tuple>::get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,28 @@ namespace meta_hpp
|
||||
const reference_type*,
|
||||
const void_type*> type_;
|
||||
};
|
||||
|
||||
inline bool operator<(const any_type& l, const any_type& r) noexcept {
|
||||
return l.id() < r.id();
|
||||
}
|
||||
|
||||
inline bool operator==(const any_type& l, const any_type& r) noexcept {
|
||||
return l.id() == r.id();
|
||||
}
|
||||
|
||||
inline bool operator!=(const any_type& l, const any_type& r) noexcept {
|
||||
return l.id() != r.id();
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<meta_hpp::any_type> {
|
||||
size_t operator()(const meta_hpp::any_type& type) const noexcept {
|
||||
return type.id().hash();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -50,15 +50,14 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename = void >
|
||||
struct arithmetic_traits;
|
||||
|
||||
template < typename T >
|
||||
struct arithmetic_traits<T, std::enable_if_t<std::is_arithmetic_v<T>>> {
|
||||
struct arithmetic_traits {
|
||||
static_assert(std::is_arithmetic_v<T>);
|
||||
static constexpr std::size_t size{sizeof(T)};
|
||||
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
|
||||
static any_type make_raw_type() {
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
return std::is_same_v<T, raw_type>
|
||||
? any_type{}
|
||||
: type_db::get<raw_type>();
|
||||
|
||||
@@ -54,33 +54,21 @@ namespace meta_hpp
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct array_traits;
|
||||
struct array_traits {
|
||||
static_assert(std::is_array_v<T>);
|
||||
static constexpr std::size_t extent{std::extent_v<T>};
|
||||
|
||||
template < typename T >
|
||||
struct array_traits<T[]> {
|
||||
static constexpr std::size_t extent{0};
|
||||
using data_type = std::remove_extent_t<T>;
|
||||
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<array_flags> make_flags() noexcept {
|
||||
return array_flags::is_unbounded;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t N >
|
||||
struct array_traits<T[N]> {
|
||||
static constexpr std::size_t extent{N};
|
||||
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<array_flags> make_flags() noexcept {
|
||||
return array_flags::is_bounded;
|
||||
bitflags<array_flags> flags;
|
||||
if ( stdex::is_bounded_array_v<T> ) flags.set(array_flags::is_bounded);
|
||||
if ( stdex::is_unbounded_array_v<T> ) flags.set(array_flags::is_unbounded);
|
||||
return flags;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,15 +50,14 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename = void >
|
||||
struct class_traits;
|
||||
|
||||
template < typename T >
|
||||
struct class_traits<T, std::enable_if_t<std::is_class_v<T>>> {
|
||||
struct class_traits {
|
||||
static_assert(std::is_class_v<T>);
|
||||
static constexpr std::size_t size{sizeof(T)};
|
||||
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
|
||||
static any_type make_raw_type() {
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
return std::is_same_v<T, raw_type>
|
||||
? any_type{}
|
||||
: type_db::get<raw_type>();
|
||||
|
||||
@@ -44,24 +44,25 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename C, typename... Args >
|
||||
template < typename Class, typename... Args >
|
||||
struct ctor_traits {
|
||||
static_assert(std::is_constructible_v<C, Args...>);
|
||||
static_assert(std::is_constructible_v<Class, Args...>);
|
||||
static constexpr std::size_t arity{sizeof...(Args)};
|
||||
|
||||
using class_type = Class;
|
||||
using argument_types = std::tuple<Args...>;
|
||||
|
||||
static any_type make_class_type() {
|
||||
using class_type = C;
|
||||
return type_db::get<class_type>();
|
||||
}
|
||||
|
||||
static std::vector<any_type> make_argument_types() {
|
||||
using argument_types = std::tuple<Args...>;
|
||||
return type_db::multi_get<argument_types>();
|
||||
}
|
||||
|
||||
static bitflags<ctor_flags> make_flags() noexcept {
|
||||
bitflags<ctor_flags> flags;
|
||||
if ( std::is_nothrow_constructible_v<C, Args...> ) flags.set(ctor_flags::is_noexcept);
|
||||
if ( std::is_nothrow_constructible_v<Class, Args...> ) flags.set(ctor_flags::is_noexcept);
|
||||
return flags;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace meta_hpp
|
||||
template < typename T >
|
||||
explicit enum_type(typename_arg_t<T>);
|
||||
|
||||
std::size_t size() const noexcept;
|
||||
any_type raw_type() const noexcept;
|
||||
any_type underlying_type() const noexcept;
|
||||
|
||||
@@ -42,20 +43,21 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename = void >
|
||||
struct enum_traits;
|
||||
|
||||
template < typename T >
|
||||
struct enum_traits<T, std::enable_if_t<std::is_enum_v<T>>> {
|
||||
struct enum_traits {
|
||||
static_assert(std::is_enum_v<T>);
|
||||
static constexpr std::size_t size{sizeof(T)};
|
||||
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
using underlying_type = std::underlying_type_t<T>;
|
||||
|
||||
static any_type make_raw_type() {
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
return std::is_same_v<T, raw_type>
|
||||
? any_type{}
|
||||
: type_db::get<raw_type>();
|
||||
}
|
||||
|
||||
static any_type make_underlying_type() {
|
||||
using underlying_type = std::underlying_type_t<T>;
|
||||
return type_db::get<underlying_type>();
|
||||
}
|
||||
|
||||
@@ -70,6 +72,7 @@ namespace meta_hpp::detail
|
||||
namespace meta_hpp
|
||||
{
|
||||
struct enum_type::state final {
|
||||
const std::size_t size;
|
||||
const any_type raw_type;
|
||||
const any_type underlying_type;
|
||||
const bitflags<enum_flags> flags;
|
||||
@@ -79,6 +82,7 @@ namespace meta_hpp
|
||||
enum_type::enum_type(typename_arg_t<T>)
|
||||
: type_base{typename_arg<struct enum_type_tag, T>}
|
||||
, state_{std::make_shared<state>(state{
|
||||
detail::enum_traits<T>::size,
|
||||
detail::enum_traits<T>::make_raw_type(),
|
||||
detail::enum_traits<T>::make_underlying_type(),
|
||||
detail::enum_traits<T>::make_flags(),
|
||||
@@ -86,6 +90,10 @@ namespace meta_hpp
|
||||
static_assert(std::is_enum_v<T>);
|
||||
}
|
||||
|
||||
inline std::size_t enum_type::size() const noexcept {
|
||||
return state_->size;
|
||||
}
|
||||
|
||||
inline any_type enum_type::raw_type() const noexcept {
|
||||
return state_->raw_type;
|
||||
}
|
||||
|
||||
@@ -51,13 +51,14 @@ namespace meta_hpp::detail
|
||||
struct function_pointer_traits<R(*)(Args...)> {
|
||||
static constexpr std::size_t arity{sizeof...(Args)};
|
||||
|
||||
using return_type = R;
|
||||
using argument_types = std::tuple<Args...>;
|
||||
|
||||
static any_type make_return_type() {
|
||||
using return_type = R;
|
||||
return type_db::get<return_type>();
|
||||
}
|
||||
|
||||
static std::vector<any_type> make_argument_types() {
|
||||
using argument_types = std::tuple<Args...>;
|
||||
return type_db::multi_get<argument_types>();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,13 +46,14 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename V, typename C >
|
||||
struct member_pointer_traits<V C::*> {
|
||||
using class_type = C;
|
||||
using value_type = V;
|
||||
|
||||
static any_type make_class_type() {
|
||||
using class_type = C;
|
||||
return type_db::get<class_type>();
|
||||
}
|
||||
|
||||
static any_type make_value_type() {
|
||||
using value_type = V;
|
||||
return type_db::get<value_type>();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,18 +54,19 @@ namespace meta_hpp::detail
|
||||
struct method_pointer_traits<R(C::*)(Args...)> {
|
||||
static constexpr std::size_t arity{sizeof...(Args)};
|
||||
|
||||
using class_type = C;
|
||||
using return_type = R;
|
||||
using argument_types = std::tuple<Args...>;
|
||||
|
||||
static any_type make_class_type() {
|
||||
using class_type = C;
|
||||
return type_db::get<class_type>();
|
||||
}
|
||||
|
||||
static any_type make_return_type() {
|
||||
using return_type = R;
|
||||
return type_db::get<return_type>();
|
||||
}
|
||||
|
||||
static std::vector<any_type> make_argument_types() {
|
||||
using argument_types = std::tuple<Args...>;
|
||||
return type_db::multi_get<argument_types>();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,29 +40,18 @@ namespace meta_hpp
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct pointer_traits;
|
||||
struct pointer_traits {
|
||||
static_assert(std::is_pointer_v<T>);
|
||||
using data_type = std::remove_pointer_t<T>;
|
||||
|
||||
template < typename T >
|
||||
struct pointer_traits<T*> {
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<pointer_flags> make_flags() noexcept {
|
||||
return bitflags<pointer_flags>{};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct pointer_traits<T* const> {
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<pointer_flags> make_flags() noexcept {
|
||||
return pointer_flags::is_const;
|
||||
bitflags<pointer_flags> flags;
|
||||
if ( std::is_const_v<T> ) flags.set(pointer_flags::is_const);
|
||||
return flags;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,29 +44,19 @@ namespace meta_hpp
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct reference_traits;
|
||||
struct reference_traits {
|
||||
static_assert(std::is_reference_v<T>);
|
||||
using data_type = std::remove_reference_t<T>;
|
||||
|
||||
template < typename T >
|
||||
struct reference_traits<T&> {
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<reference_flags> make_flags() noexcept {
|
||||
return reference_flags::is_lvalue;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct reference_traits<T&&> {
|
||||
static any_type make_data_type() {
|
||||
using data_type = T;
|
||||
return type_db::get<data_type>();
|
||||
}
|
||||
|
||||
static bitflags<reference_flags> make_flags() noexcept {
|
||||
return reference_flags::is_rvalue;
|
||||
bitflags<reference_flags> flags;
|
||||
if ( std::is_lvalue_reference_v<T> ) flags.set(reference_flags::is_lvalue);
|
||||
if ( std::is_rvalue_reference_v<T> ) flags.set(reference_flags::is_rvalue);
|
||||
return flags;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -49,13 +49,12 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename = void >
|
||||
struct void_traits;
|
||||
|
||||
template < typename T >
|
||||
struct void_traits<T, std::enable_if_t<std::is_void_v<T>>> {
|
||||
struct void_traits {
|
||||
static_assert(std::is_void_v<T>);
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
|
||||
static any_type make_raw_type() {
|
||||
using raw_type = std::remove_const_t<T>;
|
||||
return std::is_same_v<T, raw_type>
|
||||
? any_type{}
|
||||
: type_db::get<raw_type>();
|
||||
|
||||
@@ -30,6 +30,40 @@ TEST_CASE("features/types/array") {
|
||||
CHECK(at.is_unbounded());
|
||||
}
|
||||
|
||||
SUBCASE("unsigned[42][]") {
|
||||
using type = unsigned[][42];
|
||||
|
||||
REQUIRE(type_db::get<type>());
|
||||
REQUIRE(type_db::get<type>().is<array_type>());
|
||||
|
||||
const array_type at = type_db::get<type>().as<array_type>();
|
||||
|
||||
CHECK(at.data_type().id() == type_db::get<unsigned[42]>().id());
|
||||
CHECK(at.extent() == 0);
|
||||
|
||||
CHECK(at.flags() == (array_flags::is_unbounded));
|
||||
|
||||
CHECK_FALSE(at.is_bounded());
|
||||
CHECK(at.is_unbounded());
|
||||
}
|
||||
|
||||
SUBCASE("const int[42][21]") {
|
||||
using type = const int[42][21];
|
||||
|
||||
REQUIRE(type_db::get<type>());
|
||||
REQUIRE(type_db::get<type>().is<array_type>());
|
||||
|
||||
const array_type at = type_db::get<type>().as<array_type>();
|
||||
|
||||
CHECK(at.data_type().id() == type_db::get<const int[21]>().id());
|
||||
CHECK(at.extent() == 42);
|
||||
|
||||
CHECK(at.flags() == (array_flags::is_bounded));
|
||||
|
||||
CHECK(at.is_bounded());
|
||||
CHECK_FALSE(at.is_unbounded());
|
||||
}
|
||||
|
||||
SUBCASE("const unsigned[42]") {
|
||||
using type = const unsigned[42];
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ TEST_CASE("features/types/enum") {
|
||||
|
||||
const enum_type et = type_db::get<type>().as<enum_type>();
|
||||
|
||||
CHECK(et.size() == sizeof(type));
|
||||
CHECK_FALSE(et.raw_type());
|
||||
CHECK(et.underlying_type().id() == type_db::get<unsigned>().id());
|
||||
|
||||
@@ -45,6 +46,7 @@ TEST_CASE("features/types/enum") {
|
||||
|
||||
const enum_type et = type_db::get<type>().as<enum_type>();
|
||||
|
||||
CHECK(et.size() == sizeof(type));
|
||||
REQUIRE(et.raw_type());
|
||||
CHECK(et.raw_type().id() == type_db::get<ecolor>().id());
|
||||
CHECK(et.underlying_type().id() == type_db::get<unsigned>().id());
|
||||
|
||||
Reference in New Issue
Block a user