mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
add family id to value
This commit is contained in:
@@ -20,27 +20,30 @@ namespace meta_hpp
|
|||||||
value& operator=(value&&) = default;
|
value& operator=(value&&) = default;
|
||||||
value& operator=(const value&) = default;
|
value& operator=(const value&) = default;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T
|
||||||
value(T&& value)
|
, typename U = std::decay_t<T>
|
||||||
: raw_{std::forward<T>(value)} {}
|
, typename = std::enable_if_t<!std::is_same_v<U, value>> >
|
||||||
|
value(T&& val)
|
||||||
|
: raw_{std::forward<T>(val)}
|
||||||
|
, fid_{get_type_family_id<U>()} {}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T
|
||||||
value& operator=(T&& value) noexcept {
|
, typename U = std::decay_t<T>
|
||||||
raw_ = std::forward<T>(value);
|
, typename = std::enable_if_t<!std::is_same_v<U, value>> >
|
||||||
|
value& operator=(T&& val) {
|
||||||
|
value{std::forward<T>(val)}.swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
value(std::in_place_type_t<T>, Args&&... args)
|
explicit value(std::in_place_type_t<T>, Args&&... args)
|
||||||
: raw_{std::in_place_type<T>, std::forward<Args>(args)...} {}
|
: raw_{std::in_place_type<T>, std::forward<Args>(args)...}
|
||||||
|
, fid_{get_type_family_id<T>()} {}
|
||||||
|
|
||||||
template < typename T, typename U, typename... Args >
|
template < typename T, typename U, typename... Args >
|
||||||
value(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args)
|
explicit value(std::in_place_type_t<T>, std::initializer_list<U> ilist, Args&&... args)
|
||||||
: raw_{std::in_place_type<T>, ilist, std::forward<Args>(args)...} {}
|
: raw_{std::in_place_type<T>, ilist, std::forward<Args>(args)...}
|
||||||
|
, fid_{get_type_family_id<T>()} {}
|
||||||
void swap(value& other) noexcept {
|
|
||||||
raw_.swap(other.raw_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T cast() && {
|
T cast() && {
|
||||||
@@ -68,6 +71,16 @@ namespace meta_hpp
|
|||||||
try_cast() const noexcept {
|
try_cast() const noexcept {
|
||||||
return std::any_cast<T>(&raw_);
|
return std::any_cast<T>(&raw_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
family_id fid() const noexcept {
|
||||||
|
return fid_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(value& other) noexcept {
|
||||||
|
using std::swap;
|
||||||
|
swap(raw_, other.raw_);
|
||||||
|
swap(fid_, other.fid_);
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
bool to_bool() const { return cast<bool>(); }
|
bool to_bool() const { return cast<bool>(); }
|
||||||
int to_int() const { return cast<int>(); }
|
int to_int() const { return cast<int>(); }
|
||||||
@@ -91,6 +104,7 @@ namespace meta_hpp
|
|||||||
std::uintptr_t to_uintptr_t() const { return cast<std::uintptr_t>(); }
|
std::uintptr_t to_uintptr_t() const { return cast<std::uintptr_t>(); }
|
||||||
private:
|
private:
|
||||||
std::any raw_;
|
std::any raw_;
|
||||||
|
family_id fid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void swap(value& l, value& r) noexcept {
|
inline void swap(value& l, value& r) noexcept {
|
||||||
|
|||||||
@@ -7,8 +7,13 @@
|
|||||||
#include <meta.hpp/meta_value.hpp>
|
#include <meta.hpp/meta_value.hpp>
|
||||||
#include "doctest/doctest.hpp"
|
#include "doctest/doctest.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
class clazz {};
|
||||||
|
class clazz2 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/value") {
|
TEST_CASE("meta/value") {
|
||||||
@@ -36,3 +41,37 @@ TEST_CASE("meta/value") {
|
|||||||
CHECK(meta::value{std::in_place_type<std::size_t>, std::size_t{1}}.to_size_t() == 1u);
|
CHECK(meta::value{std::in_place_type<std::size_t>, std::size_t{1}}.to_size_t() == 1u);
|
||||||
CHECK(meta::value{std::in_place_type<std::uintptr_t>, std::uintptr_t{1}}.to_uintptr_t() == 1u);
|
CHECK(meta::value{std::in_place_type<std::uintptr_t>, std::uintptr_t{1}}.to_uintptr_t() == 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/value/fid") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
CHECK(meta::value{clazz{}}.fid() == meta::get_type_family_id<clazz>());
|
||||||
|
CHECK(meta::value{clazz2{}}.fid() == meta::get_type_family_id<clazz2>());
|
||||||
|
CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid());
|
||||||
|
|
||||||
|
{
|
||||||
|
meta::value v = clazz{};
|
||||||
|
CHECK(v.fid() == meta::get_type_family_id<clazz>());
|
||||||
|
v = clazz2{};
|
||||||
|
CHECK(v.fid() == meta::get_type_family_id<clazz2>());
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(meta::value{std::in_place_type<int>, 1}.fid() == meta::get_type_family_id<int>());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::vector<int>>, {1,2,3,4}}.fid() == meta::get_type_family_id<std::vector<int>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/value/swap") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
meta::value v1{"hello"s};
|
||||||
|
meta::value v2{42};
|
||||||
|
meta::swap(v1, v2);
|
||||||
|
|
||||||
|
CHECK(v1.fid() == meta::get_type_family_id<int>());
|
||||||
|
CHECK(v1.to_int() == 42);
|
||||||
|
|
||||||
|
CHECK(v2.fid() == meta::get_type_family_id<std::string>());
|
||||||
|
CHECK(v2.to_string() == "hello");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user