mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +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]] uvalue operator[](std::size_t index) const;
|
||||||
[[nodiscard]] bool has_index_op() const noexcept;
|
[[nodiscard]] bool has_index_op() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] uvalue unmap() const;
|
||||||
|
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] T get_as() &&;
|
[[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
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
struct uvalue::vtable_t final {
|
struct uvalue::vtable_t final {
|
||||||
@@ -8253,6 +8291,7 @@ namespace meta_hpp
|
|||||||
|
|
||||||
uvalue (*const deref)(const storage_u& from);
|
uvalue (*const deref)(const storage_u& from);
|
||||||
uvalue (*const index)(const storage_u& from, std::size_t);
|
uvalue (*const index)(const storage_u& from, std::size_t);
|
||||||
|
uvalue (*const unmap)(const storage_u& from);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
static T* buffer_cast(buffer_t& buffer) noexcept {
|
static T* buffer_cast(buffer_t& buffer) noexcept {
|
||||||
@@ -8404,7 +8443,6 @@ namespace meta_hpp
|
|||||||
self.vtable_ = nullptr;
|
self.vtable_ = nullptr;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
.deref = [](){
|
.deref = [](){
|
||||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||||
return +[](const storage_u& from) -> uvalue {
|
return +[](const storage_u& from) -> uvalue {
|
||||||
@@ -8424,6 +8462,16 @@ namespace meta_hpp
|
|||||||
return nullptr;
|
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;
|
return &table;
|
||||||
@@ -8562,6 +8610,14 @@ namespace meta_hpp
|
|||||||
return vtable_ != nullptr && vtable_->index != nullptr;
|
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 >
|
template < typename T >
|
||||||
T uvalue::get_as() && {
|
T uvalue::get_as() && {
|
||||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
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});
|
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") {
|
SUBCASE("deref") {
|
||||||
{
|
{
|
||||||
int i{42};
|
int i{42};
|
||||||
@@ -389,8 +433,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
|||||||
CHECK(u.has_deref_op());
|
CHECK(u.has_deref_op());
|
||||||
|
|
||||||
const meta::uvalue v{*u};
|
const meta::uvalue v{*u};
|
||||||
CHECK(v.get_type() == meta::resolve_type<int>());
|
CHECK(v.get_as<int>() == i);
|
||||||
CHECK(v.get_data() != &i);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const char i{42};
|
const char i{42};
|
||||||
@@ -398,8 +441,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
|||||||
CHECK(u.has_deref_op());
|
CHECK(u.has_deref_op());
|
||||||
|
|
||||||
const meta::uvalue v{*u};
|
const meta::uvalue v{*u};
|
||||||
CHECK(v.get_type() == meta::resolve_type<char>());
|
CHECK(v.get_as<char>() == i);
|
||||||
CHECK(v.get_data() != &i);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const int i{42};
|
const int i{42};
|
||||||
@@ -408,7 +450,6 @@ TEST_CASE("meta/meta_utilities/value") {
|
|||||||
CHECK(u.has_deref_op());
|
CHECK(u.has_deref_op());
|
||||||
|
|
||||||
const meta::uvalue v{*u};
|
const meta::uvalue v{*u};
|
||||||
CHECK(v.get_type() == meta::resolve_type<const int*>() );
|
|
||||||
CHECK(v.get_as<const int*>() == pi);
|
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]] uvalue operator[](std::size_t index) const;
|
||||||
[[nodiscard]] bool has_index_op() const noexcept;
|
[[nodiscard]] bool has_index_op() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] uvalue unmap() const;
|
||||||
|
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] T get_as() &&;
|
[[nodiscard]] T get_as() &&;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "../meta_detail/value_traits/deref_traits.hpp"
|
#include "../meta_detail/value_traits/deref_traits.hpp"
|
||||||
#include "../meta_detail/value_traits/index_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"
|
#include "../meta_detail/value_utilities/utraits.hpp"
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ namespace meta_hpp
|
|||||||
|
|
||||||
uvalue (*const deref)(const storage_u& from);
|
uvalue (*const deref)(const storage_u& from);
|
||||||
uvalue (*const index)(const storage_u& from, std::size_t);
|
uvalue (*const index)(const storage_u& from, std::size_t);
|
||||||
|
uvalue (*const unmap)(const storage_u& from);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
static T* buffer_cast(buffer_t& buffer) noexcept {
|
static T* buffer_cast(buffer_t& buffer) noexcept {
|
||||||
@@ -180,7 +182,6 @@ namespace meta_hpp
|
|||||||
self.vtable_ = nullptr;
|
self.vtable_ = nullptr;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
.deref = [](){
|
.deref = [](){
|
||||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||||
return +[](const storage_u& from) -> uvalue {
|
return +[](const storage_u& from) -> uvalue {
|
||||||
@@ -200,6 +201,16 @@ namespace meta_hpp
|
|||||||
return nullptr;
|
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;
|
return &table;
|
||||||
@@ -338,6 +349,14 @@ namespace meta_hpp
|
|||||||
return vtable_ != nullptr && vtable_->index != nullptr;
|
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 >
|
template < typename T >
|
||||||
T uvalue::get_as() && {
|
T uvalue::get_as() && {
|
||||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||||
|
|||||||
Reference in New Issue
Block a user