mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 19:41:29 +07:00
new unmap uvalue operator
This commit is contained in:
@@ -2542,6 +2542,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() &&;
|
||||
|
||||
@@ -8239,6 +8242,41 @@ namespace meta_hpp::detail
|
||||
};
|
||||
}
|
||||
|
||||
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())};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
struct uvalue::vtable_t final {
|
||||
@@ -8253,6 +8291,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 {
|
||||
@@ -8404,7 +8443,6 @@ namespace meta_hpp
|
||||
self.vtable_ = nullptr;
|
||||
},
|
||||
|
||||
|
||||
.deref = [](){
|
||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||
return +[](const storage_u& from) -> uvalue {
|
||||
@@ -8424,6 +8462,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;
|
||||
@@ -8562,6 +8610,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>>);
|
||||
|
||||
@@ -382,6 +382,50 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(val2.get_as<ivec2>() == ivec2{1,2});
|
||||
}
|
||||
|
||||
SUBCASE("unmap") {
|
||||
{
|
||||
const meta::uvalue u{42};
|
||||
CHECK_FALSE(u.has_unmap_op());
|
||||
CHECK_FALSE(u.unmap());
|
||||
}
|
||||
{
|
||||
int i{42};
|
||||
const meta::uvalue u{std::ref(i)};
|
||||
CHECK(u.has_unmap_op());
|
||||
|
||||
const meta::uvalue v{u.unmap()};
|
||||
CHECK(v.get_type() == meta::resolve_type<int*>());
|
||||
CHECK(v.get_as<int*>() == &i);
|
||||
}
|
||||
{
|
||||
const int i{42};
|
||||
const meta::uvalue u{std::ref(i)};
|
||||
CHECK(u.has_unmap_op());
|
||||
|
||||
const meta::uvalue v{u.unmap()};
|
||||
CHECK(v.get_type() == meta::resolve_type<const int*>());
|
||||
CHECK(v.get_as<const int*>() == &i);
|
||||
}
|
||||
{
|
||||
const auto i = std::make_shared<ivec2>(3, 4);
|
||||
const meta::uvalue u{i};
|
||||
CHECK(u.has_unmap_op());
|
||||
|
||||
const meta::uvalue v{u.unmap()};
|
||||
CHECK(v.get_type() == meta::resolve_type<ivec2*>());
|
||||
CHECK(v.get_as<ivec2*>() == i.get());
|
||||
}
|
||||
{
|
||||
const auto i = std::make_shared<const ivec2>(3, 4);
|
||||
const meta::uvalue u{i};
|
||||
CHECK(u.has_unmap_op());
|
||||
|
||||
const meta::uvalue v{u.unmap()};
|
||||
CHECK(v.get_type() == meta::resolve_type<const ivec2*>());
|
||||
CHECK(v.get_as<const ivec2*>() == i.get());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("deref") {
|
||||
{
|
||||
int i{42};
|
||||
@@ -389,8 +433,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(u.has_deref_op());
|
||||
|
||||
const meta::uvalue v{*u};
|
||||
CHECK(v.get_type() == meta::resolve_type<int>());
|
||||
CHECK(v.get_data() != &i);
|
||||
CHECK(v.get_as<int>() == i);
|
||||
}
|
||||
{
|
||||
const char i{42};
|
||||
@@ -398,8 +441,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(u.has_deref_op());
|
||||
|
||||
const meta::uvalue v{*u};
|
||||
CHECK(v.get_type() == meta::resolve_type<char>());
|
||||
CHECK(v.get_data() != &i);
|
||||
CHECK(v.get_as<char>() == i);
|
||||
}
|
||||
{
|
||||
const int i{42};
|
||||
@@ -408,7 +450,6 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(u.has_deref_op());
|
||||
|
||||
const meta::uvalue v{*u};
|
||||
CHECK(v.get_type() == meta::resolve_type<const int*>() );
|
||||
CHECK(v.get_as<const int*>() == pi);
|
||||
}
|
||||
{
|
||||
|
||||
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