little fixes of types

This commit is contained in:
BlackMATov
2021-08-10 02:51:08 +07:00
parent a9dafed5b5
commit 18ffff8ea0
18 changed files with 134 additions and 126 deletions

View File

@@ -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;
}

View File

@@ -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());
}

View File

@@ -9,4 +9,3 @@
#include "../meta_fwd.hpp"
#include "../meta_infos.hpp"
#include "../meta_utilities.hpp"

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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>();

View File

@@ -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;
}
};
}

View File

@@ -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>();

View File

@@ -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;
}
};

View File

@@ -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;
}

View File

@@ -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>();
}

View File

@@ -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>();
}
};

View File

@@ -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>();
}

View File

@@ -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;
}
};
}

View File

@@ -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;
}
};
}

View File

@@ -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>();

View File

@@ -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];

View File

@@ -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());