mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
new unmap uvalue operator
This commit is contained in:
45
headers/meta.hpp/meta_detail/value_traits/unmap_traits.hpp
Normal file
45
headers/meta.hpp/meta_detail/value_traits/unmap_traits.hpp
Normal 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())};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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() &&;
|
||||
|
||||
|
||||
@@ -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>>);
|
||||
|
||||
Reference in New Issue
Block a user