add value deref function

This commit is contained in:
BlackMATov
2022-01-15 07:48:22 +07:00
parent ef5b04add0
commit fb604ba61e
4 changed files with 126 additions and 11 deletions

View File

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

View File

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