mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2026-01-04 17:21:07 +07:00
bitflags instead bool list
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user