bitflags instead bool list

This commit is contained in:
BlackMATov
2021-08-06 14:21:30 +07:00
parent 999a57dc62
commit b2c3ec6584
12 changed files with 443 additions and 230 deletions

View File

@@ -32,6 +32,12 @@
#include <kari.hpp/kari.hpp>
namespace meta_hpp
{
template < typename Enum >
using bitflags = enum_hpp::bitflags::bitflags<Enum>;
}
namespace meta_hpp
{
class class_info;

View File

@@ -10,6 +10,16 @@
namespace meta_hpp
{
enum class arithmetic_flags : unsigned {
is_const = 1 << 0,
is_signed = 1 << 1,
is_unsigned = 1 << 2,
is_integral = 1 << 3,
is_floating_point = 1 << 4,
};
ENUM_HPP_OPERATORS_DECL(arithmetic_flags)
class arithmetic_type final : public base_type {
public:
arithmetic_type() = default;
@@ -23,8 +33,10 @@ namespace meta_hpp
template < typename T >
explicit arithmetic_type(typename_arg_t<T>);
any_type raw_type() const noexcept;
std::size_t size() const noexcept;
any_type raw_type() const noexcept;
bitflags<arithmetic_flags> flags() const noexcept;
bool is_const() const noexcept;
bool is_signed() const noexcept;
bool is_unsigned() const noexcept;
@@ -36,19 +48,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct arithmetic_type::state final {
const any_type raw_type;
const std::size_t size;
const bool is_const;
const bool is_signed;
const bool is_unsigned;
const bool is_integral;
const bool is_floating_point;
};
}
namespace meta_hpp::detail
{
template < typename T, typename = void >
@@ -56,60 +55,75 @@ namespace meta_hpp::detail
template < typename T >
struct arithmetic_traits<T, std::enable_if_t<std::is_arithmetic_v<T>>> {
using raw_type = std::remove_const_t<T>;
static constexpr std::size_t size{sizeof(T)};
static constexpr bool is_const{std::is_const_v<T>};
static constexpr bool is_signed{std::is_signed_v<T>};
static constexpr bool is_unsigned{std::is_unsigned_v<T>};
static constexpr bool is_integral{std::is_integral_v<T>};
static constexpr bool is_floating_point{std::is_floating_point_v<T>};
static any_type make_raw_type(const arithmetic_type& self) {
using raw_type = std::remove_const_t<T>;
return std::is_same_v<T, raw_type>
? any_type{self}
: type_db::get<raw_type>();
}
static bitflags<arithmetic_flags> make_flags() noexcept {
bitflags<arithmetic_flags> flags;
if ( std::is_const_v<T> ) flags.set(arithmetic_flags::is_const);
if ( std::is_signed_v<T> ) flags.set(arithmetic_flags::is_signed);
if ( std::is_unsigned_v<T> ) flags.set(arithmetic_flags::is_unsigned);
if ( std::is_integral_v<T> ) flags.set(arithmetic_flags::is_integral);
if ( std::is_floating_point_v<T> ) flags.set(arithmetic_flags::is_floating_point);
return flags;
}
};
}
namespace meta_hpp
{
struct arithmetic_type::state final {
const std::size_t size;
const any_type raw_type;
const bitflags<arithmetic_flags> flags;
};
template < typename T >
inline arithmetic_type::arithmetic_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
std::is_same_v<T, typename detail::arithmetic_traits<T>::raw_type>
? any_type{*this}
: type_db::get<typename detail::arithmetic_traits<T>::raw_type>(),
detail::arithmetic_traits<T>::size,
detail::arithmetic_traits<T>::is_const,
detail::arithmetic_traits<T>::is_signed,
detail::arithmetic_traits<T>::is_unsigned,
detail::arithmetic_traits<T>::is_integral,
detail::arithmetic_traits<T>::is_floating_point,
detail::arithmetic_traits<T>::make_raw_type(*this),
detail::arithmetic_traits<T>::make_flags(),
})} {
static_assert(std::is_arithmetic_v<T>);
}
inline any_type arithmetic_type::raw_type() const noexcept {
return state_->raw_type;
}
inline std::size_t arithmetic_type::size() const noexcept {
return state_->size;
}
inline any_type arithmetic_type::raw_type() const noexcept {
return state_->raw_type;
}
inline bitflags<arithmetic_flags> arithmetic_type::flags() const noexcept {
return state_->flags;
}
inline bool arithmetic_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(arithmetic_flags::is_const);
}
inline bool arithmetic_type::is_signed() const noexcept {
return state_->is_signed;
return state_->flags.has(arithmetic_flags::is_signed);
}
inline bool arithmetic_type::is_unsigned() const noexcept {
return state_->is_unsigned;
return state_->flags.has(arithmetic_flags::is_unsigned);
}
inline bool arithmetic_type::is_integral() const noexcept {
return state_->is_integral;
return state_->flags.has(arithmetic_flags::is_integral);
}
inline bool arithmetic_type::is_floating_point() const noexcept {
return state_->is_floating_point;
return state_->flags.has(arithmetic_flags::is_floating_point);
}
}

View File

@@ -10,6 +10,13 @@
namespace meta_hpp
{
enum class array_flags : unsigned {
is_bounded = 1 << 0,
is_unbounded = 1 << 1,
};
ENUM_HPP_OPERATORS_DECL(array_flags)
class array_type final : public base_type {
public:
array_type() = default;
@@ -23,8 +30,10 @@ namespace meta_hpp
template < typename T >
explicit array_type(typename_arg_t<T>);
any_type data_type() const noexcept;
std::size_t extent() const noexcept;
any_type data_type() const noexcept;
bitflags<array_flags> flags() const noexcept;
bool is_bounded() const noexcept;
bool is_unbounded() const noexcept;
private:
@@ -36,10 +45,9 @@ namespace meta_hpp
namespace meta_hpp
{
struct array_type::state final {
const any_type data_type;
const std::size_t extent;
const bool is_bounded;
const bool is_unbounded;
const any_type data_type;
const bitflags<array_flags> flags;
};
}
@@ -50,18 +58,30 @@ namespace meta_hpp::detail
template < typename T >
struct array_traits<T[]> {
using data_type = T;
static constexpr std::size_t extent{0};
static constexpr bool is_bounded{false};
static constexpr bool is_unbounded{true};
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]> {
using data_type = T;
static constexpr std::size_t extent{N};
static constexpr bool is_bounded{true};
static constexpr bool is_unbounded{false};
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;
}
};
}
@@ -71,27 +91,30 @@ namespace meta_hpp
inline array_type::array_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::array_traits<T>::data_type>(),
detail::array_traits<T>::extent,
detail::array_traits<T>::is_bounded,
detail::array_traits<T>::is_unbounded,
detail::array_traits<T>::make_data_type(),
detail::array_traits<T>::make_flags(),
})} {
static_assert(std::is_array_v<T>);
}
inline any_type array_type::data_type() const noexcept {
return state_->data_type;
}
inline std::size_t array_type::extent() const noexcept {
return state_->extent;
}
inline any_type array_type::data_type() const noexcept {
return state_->data_type;
}
inline bitflags<array_flags> array_type::flags() const noexcept {
return state_->flags;
}
inline bool array_type::is_bounded() const noexcept {
return state_->is_bounded;
return state_->flags.has(array_flags::is_bounded);
}
inline bool array_type::is_unbounded() const noexcept {
return state_->is_unbounded;
return state_->flags.has(array_flags::is_unbounded);
}
}

View File

@@ -10,6 +10,16 @@
namespace meta_hpp
{
enum class class_flags : unsigned {
is_const = 1 << 0,
is_empty = 1 << 1,
is_final = 1 << 2,
is_abstract = 1 << 3,
is_polymorphic = 1 << 4,
};
ENUM_HPP_OPERATORS_DECL(class_flags)
class class_type final : public base_type {
public:
class_type() = default;
@@ -23,8 +33,10 @@ namespace meta_hpp
template < typename T >
explicit class_type(typename_arg_t<T>);
any_type raw_type() const noexcept;
std::size_t size() const noexcept;
any_type raw_type() const noexcept;
bitflags<class_flags> flags() const noexcept;
bool is_const() const noexcept;
bool is_empty() const noexcept;
bool is_final() const noexcept;
@@ -36,19 +48,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct class_type::state final {
const any_type raw_type;
const std::size_t size;
const bool is_const;
const bool is_empty;
const bool is_final;
const bool is_abstract;
const bool is_polymorphic;
};
}
namespace meta_hpp::detail
{
template < typename T, typename = void >
@@ -56,60 +55,75 @@ namespace meta_hpp::detail
template < typename T >
struct class_traits<T, std::enable_if_t<std::is_class_v<T>>> {
using raw_type = std::remove_const_t<T>;
static constexpr std::size_t size{sizeof(T)};
static constexpr bool is_const{std::is_const_v<T>};
static constexpr bool is_empty{std::is_empty_v<T>};
static constexpr bool is_final{std::is_final_v<T>};
static constexpr bool is_abstract{std::is_abstract_v<T>};
static constexpr bool is_polymorphic{std::is_polymorphic_v<T>};
static any_type make_raw_type(const class_type& self) {
using raw_type = std::remove_const_t<T>;
return std::is_same_v<T, raw_type>
? any_type{self}
: type_db::get<raw_type>();
}
static bitflags<class_flags> make_flags() noexcept {
bitflags<class_flags> flags;
if ( std::is_const_v<T> ) flags.set(class_flags::is_const);
if ( std::is_empty_v<T> ) flags.set(class_flags::is_empty);
if ( std::is_final_v<T> ) flags.set(class_flags::is_final);
if ( std::is_abstract_v<T> ) flags.set(class_flags::is_abstract);
if ( std::is_polymorphic_v<T> ) flags.set(class_flags::is_polymorphic);
return flags;
}
};
}
namespace meta_hpp
{
struct class_type::state final {
const std::size_t size;
const any_type raw_type;
const bitflags<class_flags> flags;
};
template < typename T >
inline class_type::class_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
std::is_same_v<T, typename detail::class_traits<T>::raw_type>
? any_type{*this}
: type_db::get<typename detail::class_traits<T>::raw_type>(),
detail::class_traits<T>::size,
detail::class_traits<T>::is_const,
detail::class_traits<T>::is_empty,
detail::class_traits<T>::is_final,
detail::class_traits<T>::is_abstract,
detail::class_traits<T>::is_polymorphic,
detail::class_traits<T>::make_raw_type(*this),
detail::class_traits<T>::make_flags(),
})} {
static_assert(std::is_class_v<T>);
}
inline any_type class_type::raw_type() const noexcept {
return state_->raw_type;
}
inline std::size_t class_type::size() const noexcept {
return state_->size;
}
inline any_type class_type::raw_type() const noexcept {
return state_->raw_type;
}
inline bitflags<class_flags> class_type::flags() const noexcept {
return state_->flags;
}
inline bool class_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(class_flags::is_const);
}
inline bool class_type::is_empty() const noexcept {
return state_->is_empty;
return state_->flags.has(class_flags::is_empty);
}
inline bool class_type::is_final() const noexcept {
return state_->is_final;
return state_->flags.has(class_flags::is_final);
}
inline bool class_type::is_abstract() const noexcept {
return state_->is_abstract;
return state_->flags.has(class_flags::is_abstract);
}
inline bool class_type::is_polymorphic() const noexcept {
return state_->is_polymorphic;
return state_->flags.has(class_flags::is_polymorphic);
}
}

View File

@@ -10,6 +10,12 @@
namespace meta_hpp
{
enum class ctor_flags : unsigned {
is_noexcept = 1 << 0,
};
ENUM_HPP_OPERATORS_DECL(ctor_flags)
class ctor_type final : public base_type {
public:
ctor_type() = default;
@@ -23,10 +29,12 @@ namespace meta_hpp
template < typename Class, typename... Args >
explicit ctor_type(typename_arg_t<Class>, typename_arg_t<Args...>);
std::size_t arity() const noexcept;
any_type class_type() const noexcept;
any_type argument_type(std::size_t i) const noexcept;
const std::vector<any_type>& argument_types() const noexcept;
std::size_t arity() const noexcept;
bitflags<ctor_flags> flags() const noexcept;
bool is_noexcept() const noexcept;
private:
struct state;
@@ -34,43 +42,57 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct ctor_type::state final {
const any_type class_type;
const std::vector<any_type> argument_types;
const std::size_t arity;
const bool is_noexcept;
};
}
namespace meta_hpp::detail
{
template < typename C, typename... Args >
struct ctor_traits {
static_assert(std::is_constructible_v<C, Args...>);
using class_type = C;
using argument_types = std::tuple<Args...>;
static constexpr std::size_t arity{sizeof...(Args)};
static constexpr bool is_noexcept{std::is_nothrow_constructible_v<C, 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);
return flags;
}
};
}
namespace meta_hpp
{
struct ctor_type::state final {
const std::size_t arity;
const any_type class_type;
const std::vector<any_type> argument_types;
const bitflags<ctor_flags> flags;
};
template < typename Class, typename... Args >
inline ctor_type::ctor_type(typename_arg_t<Class>, typename_arg_t<Args...>)
: base_type{typename_arg<Class, Args...>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::ctor_traits<Class, Args...>::class_type>(),
type_db::multi_get<typename detail::ctor_traits<Class, Args...>::argument_types>(),
detail::ctor_traits<Class, Args...>::arity,
detail::ctor_traits<Class, Args...>::is_noexcept,
detail::ctor_traits<Class, Args...>::make_class_type(),
detail::ctor_traits<Class, Args...>::make_argument_types(),
detail::ctor_traits<Class, Args...>::make_flags(),
})} {
static_assert(std::is_class_v<Class>);
static_assert(std::is_constructible_v<Class, Args...>);
}
inline std::size_t ctor_type::arity() const noexcept {
return state_->arity;
}
inline any_type ctor_type::class_type() const noexcept {
return state_->class_type;
}
@@ -85,11 +107,11 @@ namespace meta_hpp
return state_->argument_types;
}
inline std::size_t ctor_type::arity() const noexcept {
return state_->arity;
inline bitflags<ctor_flags> ctor_type::flags() const noexcept {
return state_->flags;
}
inline bool ctor_type::is_noexcept() const noexcept {
return state_->is_noexcept;
return state_->flags.has(ctor_flags::is_noexcept);
}
}

View File

@@ -10,6 +10,12 @@
namespace meta_hpp
{
enum class enum_flags : unsigned {
is_const = 1 << 0,
};
ENUM_HPP_OPERATORS_DECL(enum_flags)
class enum_type final : public base_type {
public:
enum_type() = default;
@@ -25,6 +31,8 @@ namespace meta_hpp
any_type raw_type() const noexcept;
any_type underlying_type() const noexcept;
bitflags<enum_flags> flags() const noexcept;
bool is_const() const noexcept;
private:
struct state;
@@ -32,15 +40,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct enum_type::state final {
const any_type raw_type;
const any_type underlying_type;
const bool is_const;
};
}
namespace meta_hpp::detail
{
template < typename T, typename = void >
@@ -48,23 +47,41 @@ namespace meta_hpp::detail
template < typename T >
struct enum_traits<T, std::enable_if_t<std::is_enum_v<T>>> {
using raw_type = std::remove_const_t<T>;
using underlying_type = std::underlying_type_t<T>;
static constexpr bool is_const{std::is_const_v<T>};
static any_type make_raw_type(const enum_type& self) {
using raw_type = std::remove_const_t<T>;
return std::is_same_v<T, raw_type>
? any_type{self}
: 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>();
}
static bitflags<enum_flags> make_flags() noexcept {
bitflags<enum_flags> flags;
if ( std::is_const_v<T> ) flags.set(enum_flags::is_const);
return flags;
}
};
}
namespace meta_hpp
{
struct enum_type::state final {
const any_type raw_type;
const any_type underlying_type;
const bitflags<enum_flags> flags;
};
template < typename T >
inline enum_type::enum_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
std::is_same_v<T, typename detail::enum_traits<T>::raw_type>
? any_type{*this}
: type_db::get<typename detail::enum_traits<T>::raw_type>(),
type_db::get<typename detail::enum_traits<T>::underlying_type>(),
detail::enum_traits<T>::is_const,
detail::enum_traits<T>::make_raw_type(*this),
detail::enum_traits<T>::make_underlying_type(),
detail::enum_traits<T>::make_flags(),
})} {
static_assert(std::is_enum_v<T>);
}
@@ -77,7 +94,11 @@ namespace meta_hpp
return state_->underlying_type;
}
inline bitflags<enum_flags> enum_type::flags() const noexcept {
return state_->flags;
}
inline bool enum_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(enum_flags::is_const);
}
}

View File

@@ -10,6 +10,12 @@
namespace meta_hpp
{
enum class function_flags : unsigned {
is_noexcept = 1 << 0,
};
ENUM_HPP_OPERATORS_DECL(function_flags)
class function_type final : public base_type {
public:
function_type() = default;
@@ -23,10 +29,12 @@ namespace meta_hpp
template < typename T >
explicit function_type(typename_arg_t<T>);
std::size_t arity() const noexcept;
any_type return_type() const noexcept;
any_type argument_type(std::size_t i) const noexcept;
const std::vector<any_type>& argument_types() const noexcept;
std::size_t arity() const noexcept;
bitflags<function_flags> flags() const noexcept;
bool is_noexcept() const noexcept;
private:
struct state;
@@ -34,16 +42,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct function_type::state final {
const any_type return_type;
const std::vector<any_type> argument_types;
const std::size_t arity;
const bool is_noexcept;
};
}
namespace meta_hpp::detail
{
template < typename T >
@@ -51,33 +49,57 @@ namespace meta_hpp::detail
template < typename R, typename... Args >
struct function_pointer_traits<R(*)(Args...)> {
using return_type = R;
using argument_types = std::tuple<Args...>;
static constexpr std::size_t arity{sizeof...(Args)};
static constexpr bool is_noexcept{false};
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>();
}
static bitflags<function_flags> make_flags() noexcept {
return bitflags<function_flags>{};
}
};
template < typename R, typename... Args >
struct function_pointer_traits<R(*)(Args...) noexcept> : function_pointer_traits<R(*)(Args...)> {
static constexpr bool is_noexcept{true};
static bitflags<function_flags> make_flags() noexcept {
return function_flags::is_noexcept;
}
};
}
namespace meta_hpp
{
struct function_type::state final {
const std::size_t arity;
const any_type return_type;
const std::vector<any_type> argument_types;
const bitflags<function_flags> flags;
};
template < typename T >
inline function_type::function_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::function_pointer_traits<T>::return_type>(),
type_db::multi_get<typename detail::function_pointer_traits<T>::argument_types>(),
detail::function_pointer_traits<T>::arity,
detail::function_pointer_traits<T>::is_noexcept,
detail::function_pointer_traits<T>::make_return_type(),
detail::function_pointer_traits<T>::make_argument_types(),
detail::function_pointer_traits<T>::make_flags(),
})} {
static_assert(std::is_pointer_v<T>);
static_assert(std::is_function_v<std::remove_pointer_t<T>>);
}
inline std::size_t function_type::arity() const noexcept {
return state_->arity;
}
inline any_type function_type::return_type() const noexcept {
return state_->return_type;
}
@@ -92,11 +114,11 @@ namespace meta_hpp
return state_->argument_types;
}
inline std::size_t function_type::arity() const noexcept {
return state_->arity;
inline bitflags<function_flags> function_type::flags() const noexcept {
return state_->flags;
}
inline bool function_type::is_noexcept() const noexcept {
return state_->is_noexcept;
return state_->flags.has(function_flags::is_noexcept);
}
}

View File

@@ -46,8 +46,15 @@ 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>();
}
};
}
@@ -57,8 +64,8 @@ namespace meta_hpp
inline member_type::member_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::member_pointer_traits<T>::class_type>(),
type_db::get<typename detail::member_pointer_traits<T>::value_type>(),
detail::member_pointer_traits<T>::make_class_type(),
detail::member_pointer_traits<T>::make_value_type(),
})} {
static_assert(std::is_member_object_pointer_v<T>);
}

View File

@@ -10,6 +10,13 @@
namespace meta_hpp
{
enum class method_flags : unsigned {
is_const = 1 << 0,
is_noexcept = 1 << 1,
};
ENUM_HPP_OPERATORS_DECL(method_flags)
class method_type final : public base_type {
public:
method_type() = default;
@@ -23,11 +30,13 @@ namespace meta_hpp
template < typename T >
explicit method_type(typename_arg_t<T>);
std::size_t arity() const noexcept;
any_type class_type() const noexcept;
any_type return_type() const noexcept;
any_type argument_type(std::size_t i) const noexcept;
const std::vector<any_type>& argument_types() const noexcept;
std::size_t arity() const noexcept;
bitflags<method_flags> flags() const noexcept;
bool is_const() const noexcept;
bool is_noexcept() const noexcept;
private:
@@ -36,18 +45,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct method_type::state final {
const any_type class_type;
const any_type return_type;
const std::vector<any_type> argument_types;
const std::size_t arity;
const bool is_const;
const bool is_noexcept;
};
}
namespace meta_hpp::detail
{
template < typename T >
@@ -55,47 +52,77 @@ namespace meta_hpp::detail
template < typename R, typename C, typename... Args >
struct method_pointer_traits<R(C::*)(Args...)> {
using class_type = C;
using return_type = R;
using argument_types = std::tuple<Args...>;
static constexpr std::size_t arity{sizeof...(Args)};
static constexpr bool is_const{false};
static constexpr bool is_noexcept{false};
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>();
}
static bitflags<method_flags> make_flags() noexcept {
return bitflags<method_flags>{};
}
};
template < typename R, typename C, typename... Args >
struct method_pointer_traits<R(C::*)(Args...) const> : method_pointer_traits<R(C::*)(Args...)> {
static constexpr bool is_const{true};
static bitflags<method_flags> make_flags() noexcept {
return method_flags::is_const;
}
};
template < typename R, typename C, typename... Args >
struct method_pointer_traits<R(C::*)(Args...) noexcept> : method_pointer_traits<R(C::*)(Args...)> {
static constexpr bool is_noexcept{true};
static bitflags<method_flags> make_flags() noexcept {
return method_flags::is_noexcept;
}
};
template < typename R, typename C, typename... Args >
struct method_pointer_traits<R(C::*)(Args...) const noexcept> : method_pointer_traits<R(C::*)(Args...)> {
static constexpr bool is_const{true};
static constexpr bool is_noexcept{true};
static bitflags<method_flags> make_flags() noexcept {
return method_flags::is_const | method_flags::is_noexcept;
}
};
}
namespace meta_hpp
{
struct method_type::state final {
const std::size_t arity;
const any_type class_type;
const any_type return_type;
const std::vector<any_type> argument_types;
const bitflags<method_flags> flags;
};
template < typename T >
inline method_type::method_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::method_pointer_traits<T>::class_type>(),
type_db::get<typename detail::method_pointer_traits<T>::return_type>(),
type_db::multi_get<typename detail::method_pointer_traits<T>::argument_types>(),
detail::method_pointer_traits<T>::arity,
detail::method_pointer_traits<T>::is_const,
detail::method_pointer_traits<T>::is_noexcept,
detail::method_pointer_traits<T>::make_class_type(),
detail::method_pointer_traits<T>::make_return_type(),
detail::method_pointer_traits<T>::make_argument_types(),
detail::method_pointer_traits<T>::make_flags(),
})} {
static_assert(std::is_member_function_pointer_v<T>);
}
inline std::size_t method_type::arity() const noexcept {
return state_->arity;
}
inline any_type method_type::class_type() const noexcept {
return state_->class_type;
}
@@ -114,15 +141,15 @@ namespace meta_hpp
return state_->argument_types;
}
inline std::size_t method_type::arity() const noexcept {
return state_->arity;
inline bitflags<method_flags> method_type::flags() const noexcept {
return state_->flags;
}
inline bool method_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(method_flags::is_const);
}
inline bool method_type::is_noexcept() const noexcept {
return state_->is_noexcept;
return state_->flags.has(method_flags::is_noexcept);
}
}

View File

@@ -10,6 +10,10 @@
namespace meta_hpp
{
enum class pointer_flags : unsigned {
is_const = 1 << 0,
};
class pointer_type final : public base_type {
public:
pointer_type() = default;
@@ -24,6 +28,8 @@ namespace meta_hpp
explicit pointer_type(typename_arg_t<T>);
any_type data_type() const noexcept;
bitflags<pointer_flags> flags() const noexcept;
bool is_const() const noexcept;
private:
struct state;
@@ -31,14 +37,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct pointer_type::state final {
const any_type data_type;
const bool is_const;
};
}
namespace meta_hpp::detail
{
template < typename T >
@@ -46,25 +44,42 @@ namespace meta_hpp::detail
template < typename T >
struct pointer_traits<T*> {
using data_type = T;
static constexpr bool is_const{false};
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> {
using data_type = T;
static constexpr bool is_const{true};
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;
}
};
}
namespace meta_hpp
{
struct pointer_type::state final {
const any_type data_type;
const bitflags<pointer_flags> flags;
};
template < typename T >
inline pointer_type::pointer_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::pointer_traits<T>::data_type>(),
detail::pointer_traits<T>::is_const,
detail::pointer_traits<T>::make_data_type(),
detail::pointer_traits<T>::make_flags(),
})} {
static_assert(std::is_pointer_v<T>);
static_assert(!std::is_function_v<std::remove_pointer_t<T>>);
@@ -74,7 +89,11 @@ namespace meta_hpp
return state_->data_type;
}
inline bitflags<pointer_flags> pointer_type::flags() const noexcept {
return state_->flags;
}
inline bool pointer_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(pointer_flags::is_const);
}
}

View File

@@ -10,6 +10,13 @@
namespace meta_hpp
{
enum class reference_flags : unsigned {
is_lvalue = 1 << 0,
is_rvalue = 1 << 1,
};
ENUM_HPP_OPERATORS_DECL(reference_flags)
class reference_type final : public base_type {
public:
reference_type() = default;
@@ -24,6 +31,8 @@ namespace meta_hpp
explicit reference_type(typename_arg_t<T>);
any_type data_type() const noexcept;
bitflags<reference_flags> flags() const noexcept;
bool is_lvalue() const noexcept;
bool is_rvalue() const noexcept;
private:
@@ -32,15 +41,6 @@ namespace meta_hpp
};
}
namespace meta_hpp
{
struct reference_type::state final {
const any_type data_type;
const bool is_lvalue;
const bool is_rvalue;
};
}
namespace meta_hpp::detail
{
template < typename T >
@@ -48,28 +48,42 @@ namespace meta_hpp::detail
template < typename T >
struct reference_traits<T&> {
using data_type = T;
static constexpr bool is_lvalue{true};
static constexpr bool is_rvalue{false};
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&&> {
using data_type = T;
static constexpr bool is_lvalue{false};
static constexpr bool is_rvalue{true};
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;
}
};
}
namespace meta_hpp
{
struct reference_type::state final {
const any_type data_type;
const bitflags<reference_flags> flags;
};
template < typename T >
inline reference_type::reference_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
type_db::get<typename detail::reference_traits<T>::data_type>(),
detail::reference_traits<T>::is_lvalue,
detail::reference_traits<T>::is_rvalue,
detail::reference_traits<T>::make_data_type(),
detail::reference_traits<T>::make_flags(),
})} {
static_assert(std::is_reference_v<T>);
}
@@ -78,11 +92,15 @@ namespace meta_hpp
return state_->data_type;
}
inline bitflags<reference_flags> reference_type::flags() const noexcept {
return state_->flags;
}
inline bool reference_type::is_lvalue() const noexcept {
return state_->is_lvalue;
return state_->flags.has(reference_flags::is_lvalue);
}
inline bool reference_type::is_rvalue() const noexcept {
return state_->is_rvalue;
return state_->flags.has(reference_flags::is_rvalue);
}
}

View File

@@ -10,6 +10,12 @@
namespace meta_hpp
{
enum class void_flags : unsigned {
is_const = 1 << 0,
};
ENUM_HPP_OPERATORS_DECL(void_flags)
class void_type final : public base_type {
public:
void_type() = default;
@@ -24,6 +30,8 @@ namespace meta_hpp
explicit void_type(typename_arg_t<T>);
any_type raw_type() const noexcept;
bitflags<void_flags> flags() const noexcept;
bool is_const() const noexcept;
private:
struct state;
@@ -35,7 +43,7 @@ namespace meta_hpp
{
struct void_type::state final {
const any_type raw_type;
const bool is_const;
const bitflags<void_flags> flags;
};
}
@@ -46,8 +54,18 @@ namespace meta_hpp::detail
template < typename T >
struct void_traits<T, std::enable_if_t<std::is_void_v<T>>> {
using raw_type = std::remove_const_t<T>;
static constexpr bool is_const{std::is_const_v<T>};
static any_type make_raw_type(const void_type& self) {
using raw_type = std::remove_const_t<T>;
return std::is_same_v<T, raw_type>
? any_type{self}
: type_db::get<raw_type>();
}
static bitflags<void_flags> make_flags() noexcept {
bitflags<void_flags> flags;
if ( std::is_const_v<T> ) flags.set(void_flags::is_const);
return flags;
}
};
}
@@ -57,10 +75,8 @@ namespace meta_hpp
inline void_type::void_type(typename_arg_t<T>)
: base_type{typename_arg<T>}
, state_{std::make_shared<state>(state{
std::is_same_v<T, typename detail::void_traits<T>::raw_type>
? any_type{*this}
: type_db::get<typename detail::void_traits<T>::raw_type>(),
detail::void_traits<T>::is_const,
detail::void_traits<T>::make_raw_type(*this),
detail::void_traits<T>::make_flags(),
})} {
static_assert(std::is_void_v<T>);
}
@@ -69,7 +85,11 @@ namespace meta_hpp
return state_->raw_type;
}
inline bitflags<void_flags> void_type::flags() const noexcept {
return state_->flags;
}
inline bool void_type::is_const() const noexcept {
return state_->is_const;
return state_->flags.has(void_flags::is_const);
}
}