mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
add value deref function
This commit is contained in:
@@ -116,6 +116,11 @@ namespace meta_hpp::detail
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept has_deref_op_kind = requires(const T& v) {
|
||||
{ *v } -> convertible_to<std::remove_pointer_t<T>>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
concept has_less_op_kind = requires(const T& v) {
|
||||
{ v < v } -> convertible_to<bool>;
|
||||
@@ -182,6 +187,10 @@ namespace meta_hpp
|
||||
[[nodiscard]] const void* data() const noexcept;
|
||||
[[nodiscard]] const void* cdata() const noexcept;
|
||||
|
||||
[[nodiscard]] value deref();
|
||||
[[nodiscard]] value deref() const;
|
||||
[[nodiscard]] value cderef() const;
|
||||
|
||||
template < typename T, typename Tp = std::decay_t<T> >
|
||||
[[nodiscard]] Tp& cast() &;
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace meta_hpp
|
||||
void* (*const data)(value&) noexcept;
|
||||
const void* (*const cdata)(const value&) noexcept;
|
||||
|
||||
value (*const deref)(value&);
|
||||
value (*const cderef)(const value&);
|
||||
|
||||
bool (*const less)(const value&, const value&);
|
||||
bool (*const equals)(const value&, const value&);
|
||||
|
||||
@@ -32,6 +35,8 @@ namespace meta_hpp
|
||||
|
||||
template < typename T >
|
||||
const value::traits* value::traits::get() noexcept {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
|
||||
static const traits traits{
|
||||
.type = resolve_type<T>(),
|
||||
|
||||
@@ -43,6 +48,22 @@ namespace meta_hpp
|
||||
return v.try_cast<T>();
|
||||
},
|
||||
|
||||
.deref = +[]([[maybe_unused]] value& v) -> value {
|
||||
if constexpr ( detail::has_deref_op_kind<T> ) {
|
||||
return value{*v.cast<T>()};
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have deref operator");
|
||||
}
|
||||
},
|
||||
|
||||
.cderef = +[]([[maybe_unused]] const value& v) -> value {
|
||||
if constexpr ( detail::has_deref_op_kind<T> ) {
|
||||
return value{*v.cast<T>()};
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have deref operator");
|
||||
}
|
||||
},
|
||||
|
||||
.less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool {
|
||||
if constexpr ( detail::has_less_op_kind<T> ) {
|
||||
return l.cast<T>() < r.cast<T>();
|
||||
@@ -91,6 +112,7 @@ namespace meta_hpp
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return &traits;
|
||||
}
|
||||
}
|
||||
@@ -159,6 +181,18 @@ namespace meta_hpp
|
||||
return traits_->cdata(*this);
|
||||
}
|
||||
|
||||
inline value value::deref() {
|
||||
return traits_->deref(*this);
|
||||
}
|
||||
|
||||
inline value value::deref() const {
|
||||
return traits_->cderef(*this);
|
||||
}
|
||||
|
||||
inline value value::cderef() const {
|
||||
return traits_->cderef(*this);
|
||||
}
|
||||
|
||||
template < typename T, typename Tp >
|
||||
Tp& value::cast() & {
|
||||
if ( get_type() != resolve_type<Tp>() ) {
|
||||
|
||||
Reference in New Issue
Block a user