mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
inst cast to base
This commit is contained in:
@@ -97,12 +97,12 @@ namespace meta_hpp::detail
|
||||
arg_base& operator=(const arg_base&) = delete;
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_pointer_v<T> || std::is_lvalue_reference_v<T>
|
||||
(std::is_pointer_v<T> || std::is_lvalue_reference_v<T>)
|
||||
, int> = 0 >
|
||||
explicit arg_base(type_list<T>);
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_rvalue_reference_v<T> ||
|
||||
(std::is_rvalue_reference_v<T>) ||
|
||||
(!std::is_pointer_v<T> && !std::is_reference_v<T>)
|
||||
, int> = 0 >
|
||||
explicit arg_base(type_list<T>);
|
||||
@@ -139,17 +139,16 @@ namespace meta_hpp::detail
|
||||
arg(const arg&) = delete;
|
||||
arg& operator=(const arg&) = delete;
|
||||
|
||||
template < typename T, typename Tp = std::decay_t<T>
|
||||
, std::enable_if_t<std::is_same_v<Tp, value>, int> = 0 >
|
||||
explicit arg(T&& v);
|
||||
|
||||
template < typename T, typename Tp = std::decay_t<T>
|
||||
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0
|
||||
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0
|
||||
, std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 >
|
||||
explicit arg(T&& v);
|
||||
|
||||
explicit arg(value& v);
|
||||
explicit arg(value&& v);
|
||||
explicit arg(const value& v);
|
||||
explicit arg(const value&& v);
|
||||
|
||||
template < typename To >
|
||||
To cast() const;
|
||||
private:
|
||||
@@ -177,12 +176,12 @@ namespace meta_hpp::detail
|
||||
inst_base& operator=(const inst_base&) = delete;
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>
|
||||
(std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
|
||||
, int> = 0>
|
||||
explicit inst_base(type_list<T>);
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_class_v<T> ||
|
||||
(std::is_class_v<T>) ||
|
||||
(std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
|
||||
, int> = 0>
|
||||
explicit inst_base(type_list<T>);
|
||||
@@ -196,14 +195,17 @@ namespace meta_hpp::detail
|
||||
bool is_lvalue() const noexcept;
|
||||
bool is_rvalue() const noexcept;
|
||||
|
||||
any_type get_raw_type() const noexcept;
|
||||
ref_types get_ref_type() const noexcept;
|
||||
const class_type& get_raw_type() const noexcept;
|
||||
|
||||
template < typename To >
|
||||
template < typename To, std::enable_if_t<
|
||||
(std::is_class_v<To>) ||
|
||||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
|
||||
, int> = 0>
|
||||
bool can_cast_to() const noexcept;
|
||||
private:
|
||||
any_type raw_type_{};
|
||||
ref_types ref_type_{};
|
||||
class_type raw_type_{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -220,17 +222,19 @@ namespace meta_hpp::detail
|
||||
inst& operator=(const inst&) = delete;
|
||||
|
||||
template < typename T, typename Tp = std::decay_t<T>
|
||||
, std::enable_if_t<std::is_same_v<Tp, value>, int> = 0 >
|
||||
explicit inst(T&& v);
|
||||
|
||||
template < typename T, class_kind Tp = std::decay_t<T>
|
||||
, std::enable_if_t<!std::is_same_v<Tp, arg>, int> = 0
|
||||
, std::enable_if_t<!std::is_same_v<Tp, inst>, int> = 0
|
||||
, std::enable_if_t<!std::is_same_v<Tp, value>, int> = 0 >
|
||||
explicit inst(T&& v);
|
||||
|
||||
explicit inst(value& v);
|
||||
explicit inst(value&& v);
|
||||
explicit inst(const value& v);
|
||||
explicit inst(const value&& v);
|
||||
|
||||
template < typename To >
|
||||
template < typename To, std::enable_if_t<
|
||||
(std::is_class_v<To>) ||
|
||||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
|
||||
, int> = 0>
|
||||
decltype(auto) cast() const;
|
||||
private:
|
||||
void* data_{};
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_pointer_v<T> || std::is_lvalue_reference_v<T>
|
||||
(std::is_pointer_v<T> || std::is_lvalue_reference_v<T>)
|
||||
, int> >
|
||||
arg_base::arg_base(type_list<T>)
|
||||
: raw_type_{resolve_type<std::remove_cvref_t<T>>()}
|
||||
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref} {}
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_rvalue_reference_v<T> ||
|
||||
(std::is_rvalue_reference_v<T>) ||
|
||||
(!std::is_pointer_v<T> && !std::is_reference_v<T>)
|
||||
, int> >
|
||||
arg_base::arg_base(type_list<T>)
|
||||
@@ -126,6 +126,12 @@ namespace meta_hpp::detail
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename Tp
|
||||
, std::enable_if_t<std::is_same_v<Tp, value>, int> >
|
||||
arg::arg(T&& v)
|
||||
: arg_base{std::forward<T>(v)}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < typename T, typename Tp
|
||||
, std::enable_if_t<!std::is_same_v<Tp, arg>, int>
|
||||
, std::enable_if_t<!std::is_same_v<Tp, inst>, int>
|
||||
@@ -134,22 +140,6 @@ namespace meta_hpp::detail
|
||||
: arg_base{type_list<T&&>{}}
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
inline arg::arg(value& v)
|
||||
: arg_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline arg::arg(value&& v)
|
||||
: arg_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline arg::arg(const value& v)
|
||||
: arg_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline arg::arg(const value&& v)
|
||||
: arg_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < typename To >
|
||||
To arg::cast() const {
|
||||
if ( !can_cast_to<To>() ) {
|
||||
|
||||
@@ -12,35 +12,51 @@
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>
|
||||
(std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
|
||||
, int> >
|
||||
inst_base::inst_base(type_list<T>)
|
||||
: raw_type_{resolve_type<std::remove_cvref_t<T>>()}
|
||||
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref} {}
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::cref : ref_types::ref}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
template < typename T, std::enable_if_t<
|
||||
std::is_class_v<T> ||
|
||||
(std::is_class_v<T>) ||
|
||||
(std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>)
|
||||
, int> >
|
||||
inst_base::inst_base(type_list<T>)
|
||||
: raw_type_{resolve_type<std::remove_cvref_t<T>>()}
|
||||
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::crref : ref_types::rref} {}
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>> ? ref_types::crref : ref_types::rref}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
inline inst_base::inst_base(value& v)
|
||||
: raw_type_{v.get_type()}
|
||||
, ref_type_{ref_types::ref} {}
|
||||
: ref_type_{ref_types::ref}
|
||||
, raw_type_{v.get_type().as_class()} {
|
||||
if ( !v.get_type().is_class() ) {
|
||||
throw std::logic_error("an attempt to create an instance with a non-class value type");
|
||||
}
|
||||
}
|
||||
|
||||
inline inst_base::inst_base(value&& v)
|
||||
: raw_type_{v.get_type()}
|
||||
, ref_type_{ref_types::rref} {}
|
||||
: ref_type_{ref_types::rref}
|
||||
, raw_type_{v.get_type().as_class()} {
|
||||
if ( !v.get_type().is_class() ) {
|
||||
throw std::logic_error("an attempt to create an instance with a non-class value type");
|
||||
}
|
||||
}
|
||||
|
||||
inline inst_base::inst_base(const value& v)
|
||||
: raw_type_{v.get_type()}
|
||||
, ref_type_{ref_types::cref} {}
|
||||
: ref_type_{ref_types::cref}
|
||||
, raw_type_{v.get_type().as_class()} {
|
||||
if ( !v.get_type().is_class() ) {
|
||||
throw std::logic_error("an attempt to create an instance with a non-class value type");
|
||||
}
|
||||
}
|
||||
|
||||
inline inst_base::inst_base(const value&& v)
|
||||
: raw_type_{v.get_type()}
|
||||
, ref_type_{ref_types::crref} {}
|
||||
: ref_type_{ref_types::crref}
|
||||
, raw_type_{v.get_type().as_class()} {
|
||||
if ( !v.get_type().is_class() ) {
|
||||
throw std::logic_error("an attempt to create an instance with a non-class value type");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool inst_base::is_const() const noexcept {
|
||||
return ref_type_ == ref_types::cref
|
||||
@@ -57,20 +73,19 @@ namespace meta_hpp::detail
|
||||
|| ref_type_ == ref_types::crref;
|
||||
}
|
||||
|
||||
inline any_type inst_base::get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
|
||||
inline inst_base::ref_types inst_base::get_ref_type() const noexcept {
|
||||
return ref_type_;
|
||||
}
|
||||
|
||||
template < typename To >
|
||||
bool inst_base::can_cast_to() const noexcept {
|
||||
static_assert(
|
||||
std::is_class_v<To> ||
|
||||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>));
|
||||
inline const class_type& inst_base::get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
|
||||
template < typename To, std::enable_if_t<
|
||||
(std::is_class_v<To>) ||
|
||||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
|
||||
, int> >
|
||||
bool inst_base::can_cast_to() const noexcept {
|
||||
constexpr bool to_const = std::is_const_v<std::remove_reference_t<To>>;
|
||||
|
||||
if constexpr ( !to_const ) {
|
||||
@@ -92,13 +107,21 @@ namespace meta_hpp::detail
|
||||
}
|
||||
|
||||
using to_raw_type = std::remove_cvref_t<To>;
|
||||
return get_raw_type() == resolve_type<to_raw_type>();
|
||||
|
||||
return get_raw_type() == resolve_type<to_raw_type>()
|
||||
|| get_raw_type().is_derived_from(resolve_type<to_raw_type>());
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T, typename Tp
|
||||
, std::enable_if_t<std::is_same_v<Tp, value>, int> >
|
||||
inst::inst(T&& v)
|
||||
: inst_base{std::forward<T>(v)}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < typename T, class_kind Tp
|
||||
, std::enable_if_t<!std::is_same_v<Tp, arg>, int>
|
||||
, std::enable_if_t<!std::is_same_v<Tp, inst>, int>
|
||||
, std::enable_if_t<!std::is_same_v<Tp, value>, int> >
|
||||
@@ -106,26 +129,13 @@ namespace meta_hpp::detail
|
||||
: inst_base{type_list<T&&>{}}
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
inline inst::inst(value& v)
|
||||
: inst_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline inst::inst(value&& v)
|
||||
: inst_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline inst::inst(const value& v)
|
||||
: inst_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
inline inst::inst(const value&& v)
|
||||
: inst_base{v}
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < typename To >
|
||||
template < typename To, std::enable_if_t<
|
||||
(std::is_class_v<To>) ||
|
||||
(std::is_reference_v<To> && std::is_class_v<std::remove_reference_t<To>>)
|
||||
, int> >
|
||||
decltype(auto) inst::cast() const {
|
||||
if ( !can_cast_to<To>() ) {
|
||||
throw std::logic_error("bad inst cast");
|
||||
throw std::logic_error("bad an instance cast");
|
||||
}
|
||||
|
||||
if constexpr ( std::is_reference_v<To> ) {
|
||||
|
||||
Reference in New Issue
Block a user