mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
uvalue doesn't require copyable type now
This commit is contained in:
@@ -70,7 +70,7 @@ namespace meta_hpp
|
||||
};
|
||||
|
||||
struct method_opts final {
|
||||
argument_opts_list arguments;
|
||||
argument_opts_list arguments{};
|
||||
metadata_map metadata{};
|
||||
};
|
||||
|
||||
@@ -412,3 +412,95 @@ namespace meta_hpp
|
||||
return scope_bind{scope, std::move(metadata)};
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class arguments_bind final {
|
||||
public:
|
||||
arguments_bind() = default;
|
||||
~arguments_bind() = default;
|
||||
|
||||
arguments_bind(arguments_bind&&) = default;
|
||||
arguments_bind(const arguments_bind&) = delete;
|
||||
|
||||
arguments_bind& operator=(arguments_bind&&) = default;
|
||||
arguments_bind& operator=(const arguments_bind&) = delete;
|
||||
|
||||
arguments_bind& operator()(std::string name) & {
|
||||
arguments_.push_back(argument_opts{
|
||||
.name = std::move(name),
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
arguments_bind operator()(std::string name) && {
|
||||
arguments_.push_back(argument_opts{
|
||||
.name = std::move(name),
|
||||
});
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
arguments_bind& operator()(std::string name, metadata_map metadata) & {
|
||||
arguments_.push_back(argument_opts{
|
||||
.name = std::move(name),
|
||||
.metadata = std::move(metadata),
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
arguments_bind operator()(std::string name, metadata_map metadata) && {
|
||||
arguments_.push_back(argument_opts{
|
||||
.name = std::move(name),
|
||||
.metadata = std::move(metadata),
|
||||
});
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
operator argument_opts_list() && {
|
||||
return std::move(arguments_);
|
||||
}
|
||||
|
||||
private:
|
||||
argument_opts_list arguments_;
|
||||
};
|
||||
|
||||
inline arguments_bind arguments_() {
|
||||
return arguments_bind{};
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class metadata_bind final {
|
||||
public:
|
||||
metadata_bind() = default;
|
||||
~metadata_bind() = default;
|
||||
|
||||
metadata_bind(metadata_bind&&) = default;
|
||||
metadata_bind(const metadata_bind&) = delete;
|
||||
|
||||
metadata_bind& operator=(metadata_bind&&) = default;
|
||||
metadata_bind& operator=(const metadata_bind&) = delete;
|
||||
|
||||
metadata_bind& operator()(std::string name, uvalue value) & {
|
||||
metadata_.insert_or_assign(std::move(name), std::move(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
metadata_bind operator()(std::string name, uvalue value) && {
|
||||
metadata_.insert_or_assign(std::move(name), std::move(value));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
operator metadata_map() && {
|
||||
return std::move(metadata_);
|
||||
}
|
||||
|
||||
private:
|
||||
metadata_map metadata_;
|
||||
};
|
||||
|
||||
inline metadata_bind metadata_() {
|
||||
return metadata_bind{};
|
||||
}
|
||||
}
|
||||
|
||||
33
headers/meta.hpp/meta_detail/value_traits/copy_traits.hpp
Normal file
33
headers/meta.hpp/meta_detail/value_traits/copy_traits.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* 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 copy_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_copy_traits //
|
||||
= requires(const T& v) {
|
||||
{ copy_traits<T>{}(v) } -> std::convertible_to<uvalue>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
struct copy_traits<T> {
|
||||
uvalue operator()(const T& v) const {
|
||||
return uvalue{v};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -31,14 +31,6 @@ namespace meta_hpp::detail
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
struct deref_traits<const T*> {
|
||||
uvalue operator()(const T* v) const {
|
||||
return v != nullptr ? uvalue{*v} : uvalue{};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
struct deref_traits<std::shared_ptr<T>> {
|
||||
|
||||
@@ -32,15 +32,6 @@ namespace meta_hpp::detail
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
struct index_traits<const T*> {
|
||||
uvalue operator()(const T* v, std::size_t i) const {
|
||||
// NOLINTNEXTLINE(*-pointer-arithmetic)
|
||||
return v != nullptr ? uvalue{v[i]} : uvalue{};
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires std::is_copy_constructible_v<T>
|
||||
struct index_traits<std::array<T, Size>> {
|
||||
|
||||
@@ -24,9 +24,12 @@ namespace meta_hpp
|
||||
|
||||
struct as_shared_pointer_t final {};
|
||||
|
||||
struct as_unique_pointer_t final {};
|
||||
|
||||
inline constexpr as_object_t as_object{};
|
||||
inline constexpr as_raw_pointer_t as_raw_pointer{};
|
||||
inline constexpr as_shared_pointer_t as_shared_pointer{};
|
||||
inline constexpr as_unique_pointer_t as_unique_pointer{};
|
||||
}
|
||||
|
||||
namespace function_policy
|
||||
@@ -82,34 +85,35 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename Policy >
|
||||
concept constructor_policy_family //
|
||||
= std::is_same_v<Policy, constructor_policy::as_object_t> //
|
||||
|| std::is_same_v<Policy, constructor_policy::as_raw_pointer_t> //
|
||||
|| std::is_same_v<Policy, constructor_policy::as_shared_pointer_t>;
|
||||
concept constructor_policy_family //
|
||||
= std::is_same_v<Policy, constructor_policy::as_object_t> //
|
||||
|| std::is_same_v<Policy, constructor_policy::as_raw_pointer_t> //
|
||||
|| std::is_same_v<Policy, constructor_policy::as_shared_pointer_t> //
|
||||
|| std::is_same_v<Policy, constructor_policy::as_unique_pointer_t>; //
|
||||
|
||||
template < typename Policy >
|
||||
concept function_policy_family //
|
||||
= std::is_same_v<Policy, function_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, function_policy::discard_return_t> //
|
||||
|| std::is_same_v<Policy, function_policy::return_reference_as_pointer_t>;
|
||||
concept function_policy_family //
|
||||
= std::is_same_v<Policy, function_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, function_policy::discard_return_t> //
|
||||
|| std::is_same_v<Policy, function_policy::return_reference_as_pointer_t>; //
|
||||
|
||||
template < typename Policy >
|
||||
concept member_policy_family //
|
||||
= std::is_same_v<Policy, member_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, member_policy::as_pointer_t> //
|
||||
|| std::is_same_v<Policy, member_policy::as_reference_wrapper_t>;
|
||||
concept member_policy_family //
|
||||
= std::is_same_v<Policy, member_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, member_policy::as_pointer_t> //
|
||||
|| std::is_same_v<Policy, member_policy::as_reference_wrapper_t>; //
|
||||
|
||||
template < typename Policy >
|
||||
concept method_policy_family //
|
||||
= std::is_same_v<Policy, method_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, method_policy::discard_return_t> //
|
||||
|| std::is_same_v<Policy, method_policy::return_reference_as_pointer_t>;
|
||||
concept method_policy_family //
|
||||
= std::is_same_v<Policy, method_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, method_policy::discard_return_t> //
|
||||
|| std::is_same_v<Policy, method_policy::return_reference_as_pointer_t>; //
|
||||
|
||||
template < typename Policy >
|
||||
concept variable_policy_family //
|
||||
= std::is_same_v<Policy, variable_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, variable_policy::as_pointer_t> //
|
||||
|| std::is_same_v<Policy, variable_policy::as_reference_wrapper_t>;
|
||||
concept variable_policy_family //
|
||||
= std::is_same_v<Policy, variable_policy::as_copy_t> //
|
||||
|| std::is_same_v<Policy, variable_policy::as_pointer_t> //
|
||||
|| std::is_same_v<Policy, variable_policy::as_reference_wrapper_t>; //
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -21,9 +21,8 @@ namespace meta_hpp::detail
|
||||
using class_type = typename ct::class_type;
|
||||
using argument_types = typename ct::argument_types;
|
||||
|
||||
constexpr bool as_object //
|
||||
= std::is_copy_constructible_v<class_type> //
|
||||
&& std::is_same_v<Policy, constructor_policy::as_object_t>;
|
||||
constexpr bool as_object //
|
||||
= std::is_same_v<Policy, constructor_policy::as_object_t>;
|
||||
|
||||
constexpr bool as_raw_ptr //
|
||||
= std::is_same_v<Policy, constructor_policy::as_raw_pointer_t>;
|
||||
@@ -31,7 +30,10 @@ namespace meta_hpp::detail
|
||||
constexpr bool as_shared_ptr //
|
||||
= std::is_same_v<Policy, constructor_policy::as_shared_pointer_t>;
|
||||
|
||||
static_assert(as_object || as_raw_ptr || as_shared_ptr);
|
||||
constexpr bool as_unique_ptr //
|
||||
= std::is_same_v<Policy, constructor_policy::as_unique_pointer_t>;
|
||||
|
||||
static_assert(as_object || as_raw_ptr || as_shared_ptr || as_unique_ptr);
|
||||
|
||||
META_HPP_ASSERT( //
|
||||
args.size() == ct::arity //
|
||||
@@ -55,6 +57,10 @@ namespace meta_hpp::detail
|
||||
if constexpr ( as_shared_ptr ) {
|
||||
return std::make_shared<class_type>(META_HPP_FWD(all_args)...);
|
||||
}
|
||||
|
||||
if constexpr ( as_unique_ptr ) {
|
||||
return std::make_unique<class_type>(META_HPP_FWD(all_args)...);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace meta_hpp::detail
|
||||
using return_type = typename ft::return_type;
|
||||
using argument_types = typename ft::argument_types;
|
||||
|
||||
constexpr bool as_copy //
|
||||
= std::is_copy_constructible_v<return_type> //
|
||||
constexpr bool as_copy //
|
||||
= std::is_constructible_v<uvalue, return_type> //
|
||||
&& std::is_same_v<Policy, function_policy::as_copy_t>;
|
||||
|
||||
constexpr bool as_void //
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace meta_hpp::detail
|
||||
using value_type = typename mt::value_type;
|
||||
|
||||
constexpr bool as_copy //
|
||||
= std::is_copy_constructible_v<value_type> //
|
||||
= std::is_constructible_v<uvalue, value_type> //
|
||||
&& std::is_same_v<Policy, member_policy::as_copy_t>; //
|
||||
|
||||
constexpr bool as_ptr //
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace meta_hpp::detail
|
||||
using qualified_type = typename mt::qualified_type;
|
||||
using argument_types = typename mt::argument_types;
|
||||
|
||||
constexpr bool as_copy //
|
||||
= std::is_copy_constructible_v<return_type> //
|
||||
constexpr bool as_copy //
|
||||
= std::is_constructible_v<uvalue, return_type> //
|
||||
&& std::is_same_v<Policy, method_policy::as_copy_t>;
|
||||
|
||||
constexpr bool as_void //
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace meta_hpp::detail
|
||||
using data_type = typename pt::data_type;
|
||||
|
||||
constexpr bool as_copy //
|
||||
= std::is_copy_constructible_v<data_type> //
|
||||
= std::is_constructible_v<uvalue, data_type> //
|
||||
&& std::is_same_v<Policy, variable_policy::as_copy_t>; //
|
||||
|
||||
constexpr bool as_ptr //
|
||||
|
||||
@@ -350,7 +350,7 @@ namespace meta_hpp
|
||||
|
||||
template < detail::enum_kind Enum >
|
||||
[[nodiscard]] std::string_view value_to_name(Enum value) const noexcept;
|
||||
[[nodiscard]] uvalue name_to_value(std::string_view name) const noexcept;
|
||||
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
};
|
||||
|
||||
class function_type final : public type_base<function_type> {
|
||||
|
||||
@@ -62,11 +62,10 @@ namespace meta_hpp
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
inline uvalue enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
inline const uvalue& enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
if ( const evalue& value = get_evalue(name) ) {
|
||||
return value.get_value();
|
||||
}
|
||||
|
||||
return uvalue{};
|
||||
return uvalue::empty_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@ namespace meta_hpp
|
||||
~uresult() = default;
|
||||
|
||||
uresult(uresult&&) noexcept = default;
|
||||
uresult(const uresult&) = default;
|
||||
uresult(const uresult&) = delete;
|
||||
|
||||
uresult& operator=(uresult&&) noexcept = default;
|
||||
uresult& operator=(const uresult&) = default;
|
||||
uresult& operator=(const uresult&) = delete;
|
||||
|
||||
explicit(false) uresult(uerror error) noexcept;
|
||||
explicit(false) uresult(uvalue value) noexcept;
|
||||
@@ -85,35 +85,31 @@ namespace meta_hpp
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
!detail::is_in_place_type_v<Tp> && //
|
||||
std::is_copy_constructible_v<Tp>>> //
|
||||
std::is_constructible_v<Tp, T>>> //
|
||||
uresult(T&& val);
|
||||
|
||||
template < //
|
||||
typename T, //
|
||||
typename Tp = std::decay_t<T>, //
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
std::is_copy_constructible_v<Tp>>> //
|
||||
template < //
|
||||
typename T, //
|
||||
typename Tp = std::decay_t<T>, //
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
std::is_constructible_v<Tp, T>>> //
|
||||
uresult& operator=(T&& val);
|
||||
|
||||
template < typename T, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
explicit uresult(std::in_place_type_t<T>, Args&&... args);
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
explicit uresult(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args);
|
||||
|
||||
template < typename T, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
Tp& emplace(Args&&... args);
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
Tp& emplace(std::initializer_list<U> ilist, Args&&... args);
|
||||
|
||||
[[nodiscard]] bool has_error() const noexcept;
|
||||
|
||||
@@ -83,20 +83,17 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename T, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
uresult::uresult(std::in_place_type_t<T>, Args&&... args)
|
||||
: value_{std::in_place_type<T>, std::forward<Args>(args)...} {}
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
uresult::uresult(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args)
|
||||
: value_{std::in_place_type<T>, ilist, std::forward<Args>(args)...} {}
|
||||
|
||||
template < typename T, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
Tp& uresult::emplace(Args&&... args) {
|
||||
Tp& val{value_.emplace<Tp>(std::forward<Args>(args)...)};
|
||||
error_ = error_code::no_error;
|
||||
@@ -104,8 +101,7 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
Tp& uresult::emplace(std::initializer_list<U> ilist, Args&&... args) {
|
||||
Tp& val{value_.emplace<Tp>(ilist, std::forward<Args>(args)...)};
|
||||
error_ = error_code::no_error;
|
||||
|
||||
@@ -11,15 +11,18 @@
|
||||
namespace meta_hpp
|
||||
{
|
||||
class uvalue final {
|
||||
public:
|
||||
static const uvalue empty_value;
|
||||
|
||||
public:
|
||||
uvalue() = default;
|
||||
~uvalue() noexcept;
|
||||
|
||||
uvalue(uvalue&& other) noexcept;
|
||||
uvalue(const uvalue& other);
|
||||
uvalue(const uvalue& other) = delete;
|
||||
|
||||
uvalue& operator=(uvalue&& other) noexcept;
|
||||
uvalue& operator=(const uvalue& other);
|
||||
uvalue& operator=(const uvalue& other) = delete;
|
||||
|
||||
template < //
|
||||
typename T, //
|
||||
@@ -27,35 +30,31 @@ namespace meta_hpp
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
!detail::is_in_place_type_v<Tp> && //
|
||||
std::is_copy_constructible_v<Tp>>> //
|
||||
std::is_constructible_v<Tp, T>>> //
|
||||
uvalue(T&& val);
|
||||
|
||||
template < //
|
||||
typename T, //
|
||||
typename Tp = std::decay_t<T>, //
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
std::is_copy_constructible_v<Tp>>> //
|
||||
template < //
|
||||
typename T, //
|
||||
typename Tp = std::decay_t<T>, //
|
||||
typename = std::enable_if_t< //
|
||||
!uvalue_family<Tp> && //
|
||||
std::is_constructible_v<Tp, T>>> //
|
||||
uvalue& operator=(T&& val);
|
||||
|
||||
template < typename T, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
explicit uvalue(std::in_place_type_t<T>, Args&&... args);
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
explicit uvalue(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args);
|
||||
|
||||
template < typename T, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...> //
|
||||
requires std::is_constructible_v<Tp, Args...> //
|
||||
Tp& emplace(Args&&... args);
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp = std::decay_t<T> >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...> //
|
||||
Tp& emplace(std::initializer_list<U> ilist, Args&&... args);
|
||||
|
||||
[[nodiscard]] bool has_value() const noexcept;
|
||||
@@ -76,6 +75,9 @@ namespace meta_hpp
|
||||
[[nodiscard]] uvalue operator[](std::size_t index) const;
|
||||
[[nodiscard]] bool has_index_op() const noexcept;
|
||||
|
||||
[[nodiscard]] uvalue copy() const;
|
||||
[[nodiscard]] bool has_copy_op() const noexcept;
|
||||
|
||||
[[nodiscard]] uvalue unmap() const;
|
||||
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../meta_registry.hpp"
|
||||
#include "../meta_uvalue.hpp"
|
||||
|
||||
#include "../meta_detail/value_traits/copy_traits.hpp"
|
||||
#include "../meta_detail/value_traits/deref_traits.hpp"
|
||||
#include "../meta_detail/value_traits/index_traits.hpp"
|
||||
#include "../meta_detail/value_traits/unmap_traits.hpp"
|
||||
@@ -24,9 +25,9 @@ namespace meta_hpp
|
||||
const any_type type;
|
||||
|
||||
void (*const move)(uvalue&& self, uvalue& to) noexcept;
|
||||
void (*const copy)(const uvalue& self, uvalue& to);
|
||||
void (*const reset)(uvalue& self) noexcept;
|
||||
|
||||
uvalue (*const copy)(const storage_u& self);
|
||||
uvalue (*const deref)(const storage_u& self);
|
||||
uvalue (*const index)(const storage_u& self, std::size_t i);
|
||||
uvalue (*const unmap)(const storage_u& self);
|
||||
@@ -111,24 +112,6 @@ namespace meta_hpp
|
||||
}
|
||||
}
|
||||
|
||||
static void do_copy(const uvalue& self, uvalue& to) {
|
||||
META_HPP_DEV_ASSERT(!to);
|
||||
|
||||
auto&& [tag, vtable] = unpack_vtag(self);
|
||||
|
||||
switch ( tag ) {
|
||||
case storage_e::nothing:
|
||||
break;
|
||||
case storage_e::trivial:
|
||||
to.storage_ = self.storage_;
|
||||
break;
|
||||
case storage_e::internal:
|
||||
case storage_e::external:
|
||||
vtable->copy(self, to);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_reset(uvalue& self) noexcept {
|
||||
auto&& [tag, vtable] = unpack_vtag(self);
|
||||
|
||||
@@ -195,21 +178,6 @@ namespace meta_hpp
|
||||
}
|
||||
}},
|
||||
|
||||
.copy{[](const uvalue& self, uvalue& to) {
|
||||
META_HPP_DEV_ASSERT(!to);
|
||||
META_HPP_DEV_ASSERT(self);
|
||||
|
||||
const Tp* src = storage_cast<Tp>(self.storage_);
|
||||
|
||||
if constexpr ( in_internal_v<Tp> ) {
|
||||
do_ctor<Tp>(to, *src);
|
||||
} else {
|
||||
// NOLINTNEXTLINE(*-union-access, *-owning-memory)
|
||||
to.storage_.external.ptr = new Tp(*src);
|
||||
to.storage_.vtag = self.storage_.vtag;
|
||||
}
|
||||
}},
|
||||
|
||||
.reset{[](uvalue& self) noexcept {
|
||||
META_HPP_DEV_ASSERT(self);
|
||||
|
||||
@@ -225,6 +193,16 @@ namespace meta_hpp
|
||||
self.storage_.vtag = 0;
|
||||
}},
|
||||
|
||||
.copy{[]() {
|
||||
if constexpr ( detail::has_copy_traits<Tp> ) {
|
||||
return +[](const storage_u& self) -> uvalue {
|
||||
return detail::copy_traits<Tp>{}(*storage_cast<Tp>(self));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
|
||||
.deref{[]() {
|
||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||
return +[](const storage_u& self) -> uvalue {
|
||||
@@ -263,6 +241,8 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline const uvalue uvalue::empty_value;
|
||||
|
||||
inline uvalue::~uvalue() noexcept {
|
||||
reset();
|
||||
}
|
||||
@@ -271,10 +251,6 @@ namespace meta_hpp
|
||||
vtable_t::do_move(std::move(other), *this);
|
||||
}
|
||||
|
||||
inline uvalue::uvalue(const uvalue& other) {
|
||||
vtable_t::do_copy(other, *this);
|
||||
}
|
||||
|
||||
inline uvalue& uvalue::operator=(uvalue&& other) noexcept {
|
||||
if ( this != &other ) {
|
||||
uvalue{std::move(other)}.swap(*this);
|
||||
@@ -282,13 +258,6 @@ namespace meta_hpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uvalue& uvalue::operator=(const uvalue& other) {
|
||||
if ( this != &other ) {
|
||||
uvalue{other}.swap(*this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename T, typename Tp, typename >
|
||||
uvalue::uvalue(T&& val) {
|
||||
vtable_t::do_ctor<T>(*this, std::forward<T>(val));
|
||||
@@ -301,30 +270,26 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
template < typename T, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...>
|
||||
requires std::is_constructible_v<Tp, Args...>
|
||||
uvalue::uvalue(std::in_place_type_t<T>, Args&&... args) {
|
||||
vtable_t::do_ctor<T>(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...>
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...>
|
||||
uvalue::uvalue(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args) {
|
||||
vtable_t::do_ctor<T>(*this, ilist, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template < typename T, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, Args...>
|
||||
requires std::is_constructible_v<Tp, Args...>
|
||||
Tp& uvalue::emplace(Args&&... args) {
|
||||
vtable_t::do_reset(*this);
|
||||
return vtable_t::do_ctor<T>(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template < typename T, typename U, typename... Args, typename Tp >
|
||||
requires std::is_copy_constructible_v<Tp> //
|
||||
&& std::is_constructible_v<Tp, std::initializer_list<U>&, Args...>
|
||||
requires std::is_constructible_v<Tp, std::initializer_list<U>&, Args...>
|
||||
Tp& uvalue::emplace(std::initializer_list<U> ilist, Args&&... args) {
|
||||
vtable_t::do_reset(*this);
|
||||
return vtable_t::do_ctor<T>(*this, ilist, std::forward<Args>(args)...);
|
||||
@@ -426,6 +391,18 @@ namespace meta_hpp
|
||||
return tag != storage_e::nothing && vtable->index != nullptr;
|
||||
}
|
||||
|
||||
inline uvalue uvalue::copy() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr //
|
||||
? vtable->copy(storage_)
|
||||
: uvalue{};
|
||||
}
|
||||
|
||||
inline bool uvalue::has_copy_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr;
|
||||
}
|
||||
|
||||
inline uvalue uvalue::unmap() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr //
|
||||
|
||||
Reference in New Issue
Block a user