new unmap uvalue operator

This commit is contained in:
BlackMATov
2023-01-18 03:29:29 +07:00
parent 702349dca9
commit cdbd078f02
5 changed files with 171 additions and 7 deletions

View File

@@ -0,0 +1,45 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include "../../meta_base.hpp"
#include "../../meta_uvalue.hpp"
namespace meta_hpp::detail
{
template < typename T >
struct unmap_traits;
template < typename T >
concept has_unmap_traits = requires(const T& v) {
{ unmap_traits<T>{}(v) } -> std::convertible_to<uvalue>;
};
}
namespace meta_hpp::detail
{
template < typename T >
struct unmap_traits<std::shared_ptr<T>> {
uvalue operator()(const std::shared_ptr<T>& v) const {
return uvalue{v.get()};
}
};
template < typename T, typename D >
struct unmap_traits<std::unique_ptr<T, D>> {
uvalue operator()(const std::unique_ptr<T, D>& v) const {
return uvalue{v.get()};
}
};
template < typename T >
struct unmap_traits<std::reference_wrapper<T>> {
uvalue operator()(const std::reference_wrapper<T>& v) const {
return uvalue{std::addressof(v.get())};
}
};
}

View File

@@ -88,6 +88,9 @@ namespace meta_hpp
[[nodiscard]] uvalue operator[](std::size_t index) const;
[[nodiscard]] bool has_index_op() const noexcept;
[[nodiscard]] uvalue unmap() const;
[[nodiscard]] bool has_unmap_op() const noexcept;
template < typename T >
[[nodiscard]] T get_as() &&;

View File

@@ -12,6 +12,7 @@
#include "../meta_detail/value_traits/deref_traits.hpp"
#include "../meta_detail/value_traits/index_traits.hpp"
#include "../meta_detail/value_traits/unmap_traits.hpp"
#include "../meta_detail/value_utilities/utraits.hpp"
@@ -29,6 +30,7 @@ namespace meta_hpp
uvalue (*const deref)(const storage_u& from);
uvalue (*const index)(const storage_u& from, std::size_t);
uvalue (*const unmap)(const storage_u& from);
template < typename T >
static T* buffer_cast(buffer_t& buffer) noexcept {
@@ -180,7 +182,6 @@ namespace meta_hpp
self.vtable_ = nullptr;
},
.deref = [](){
if constexpr ( detail::has_deref_traits<Tp> ) {
return +[](const storage_u& from) -> uvalue {
@@ -200,6 +201,16 @@ namespace meta_hpp
return nullptr;
}
}(),
.unmap = [](){
if constexpr ( detail::has_unmap_traits<Tp> ) {
return +[](const storage_u& from) -> uvalue {
return detail::unmap_traits<Tp>{}(*storage_cast<Tp>(from));
};
} else {
return nullptr;
}
}(),
};
return &table;
@@ -338,6 +349,14 @@ namespace meta_hpp
return vtable_ != nullptr && vtable_->index != nullptr;
}
inline uvalue uvalue::unmap() const {
return has_unmap_op() ? vtable_->unmap(storage_) : uvalue{};
}
inline bool uvalue::has_unmap_op() const noexcept {
return vtable_ != nullptr && vtable_->unmap != nullptr;
}
template < typename T >
T uvalue::get_as() && {
static_assert(std::is_same_v<T, std::decay_t<T>>);