mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-15 03:45:30 +07:00
is_xxx and data functions for value
This commit is contained in:
@@ -16,10 +16,18 @@ namespace meta_hpp
|
|||||||
namespace meta_hpp::value_detail
|
namespace meta_hpp::value_detail
|
||||||
{
|
{
|
||||||
struct traits {
|
struct traits {
|
||||||
|
void*(*data)(value&);
|
||||||
|
const void*(*cdata)(const value&);
|
||||||
bool(*equal)(const value&, const value&){};
|
bool(*equal)(const value&, const value&){};
|
||||||
bool(*not_equal)(const value&, const value&){};
|
bool(*not_equal)(const value&, const value&){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
void* value_data(value& v);
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
const void* value_cdata(const value& v);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool value_equal(const value& l, const value& r);
|
bool value_equal(const value& l, const value& r);
|
||||||
|
|
||||||
@@ -29,6 +37,8 @@ namespace meta_hpp::value_detail
|
|||||||
template < typename T >
|
template < typename T >
|
||||||
const traits* get_traits() noexcept {
|
const traits* get_traits() noexcept {
|
||||||
static traits traits{
|
static traits traits{
|
||||||
|
&value_data<T>,
|
||||||
|
&value_cdata<T>,
|
||||||
&value_equal<T>,
|
&value_equal<T>,
|
||||||
&value_not_equal<T>,
|
&value_not_equal<T>,
|
||||||
};
|
};
|
||||||
@@ -107,6 +117,14 @@ namespace meta_hpp
|
|||||||
return fid_;
|
return fid_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* data() noexcept {
|
||||||
|
return traits_->data(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* data() const noexcept {
|
||||||
|
return traits_->cdata(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void swap(value& other) noexcept {
|
void swap(value& other) noexcept {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(raw_, other.raw_);
|
swap(raw_, other.raw_);
|
||||||
@@ -178,12 +196,41 @@ namespace meta_hpp
|
|||||||
std::uint64_t to_uint64() const { return cast<std::uint64_t>(); }
|
std::uint64_t to_uint64() const { return cast<std::uint64_t>(); }
|
||||||
std::size_t to_size_t() const { return cast<std::size_t>(); }
|
std::size_t to_size_t() const { return cast<std::size_t>(); }
|
||||||
std::uintptr_t to_uintptr_t() const { return cast<std::uintptr_t>(); }
|
std::uintptr_t to_uintptr_t() const { return cast<std::uintptr_t>(); }
|
||||||
|
public:
|
||||||
|
bool is_bool() const noexcept { return !!try_cast<bool>(); }
|
||||||
|
bool is_int() const noexcept { return !!try_cast<int>(); }
|
||||||
|
bool is_uint() const noexcept { return !!try_cast<unsigned>(); }
|
||||||
|
bool is_float() const noexcept { return !!try_cast<float>(); }
|
||||||
|
bool is_double() const noexcept { return !!try_cast<double>(); }
|
||||||
|
bool is_string() const noexcept { return !!try_cast<std::string>(); }
|
||||||
|
|
||||||
|
bool is_int8() const noexcept { return !!try_cast<std::int8_t>(); }
|
||||||
|
bool is_int16() const noexcept { return !!try_cast<std::int16_t>(); }
|
||||||
|
bool is_int32() const noexcept { return !!try_cast<std::int32_t>(); }
|
||||||
|
bool is_int64() const noexcept { return !!try_cast<std::int64_t>(); }
|
||||||
|
bool is_ptrdiff_t() const noexcept { return !!try_cast<std::ptrdiff_t>(); }
|
||||||
|
bool is_intptr_t() const noexcept { return !!try_cast<std::intptr_t>(); }
|
||||||
|
|
||||||
|
bool is_uint8() const noexcept { return !!try_cast<std::uint8_t>(); }
|
||||||
|
bool is_uint16() const noexcept { return !!try_cast<std::uint16_t>(); }
|
||||||
|
bool is_uint32() const noexcept { return !!try_cast<std::uint32_t>(); }
|
||||||
|
bool is_uint64() const noexcept { return !!try_cast<std::uint64_t>(); }
|
||||||
|
bool is_size_t() const noexcept { return !!try_cast<std::size_t>(); }
|
||||||
|
bool is_uintptr_t() const noexcept { return !!try_cast<std::uintptr_t>(); }
|
||||||
private:
|
private:
|
||||||
std::any raw_;
|
std::any raw_;
|
||||||
family_id fid_;
|
family_id fid_;
|
||||||
const value_detail::traits* traits_{};
|
const value_detail::traits* traits_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void* data(value& v) noexcept {
|
||||||
|
return v.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const void* data(const value& v) noexcept {
|
||||||
|
return v.data();
|
||||||
|
}
|
||||||
|
|
||||||
inline void swap(value& l, value& r) noexcept {
|
inline void swap(value& l, value& r) noexcept {
|
||||||
l.swap(r);
|
l.swap(r);
|
||||||
}
|
}
|
||||||
@@ -191,6 +238,16 @@ namespace meta_hpp
|
|||||||
|
|
||||||
namespace meta_hpp::value_detail
|
namespace meta_hpp::value_detail
|
||||||
{
|
{
|
||||||
|
template < typename T >
|
||||||
|
void* value_data(value& v) {
|
||||||
|
return v.try_cast<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
const void* value_cdata(const value& v) {
|
||||||
|
return v.try_cast<T>();
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool value_equal(const value& l, const value& r) {
|
bool value_equal(const value& l, const value& r) {
|
||||||
if ( l.fid() != r.fid() ) {
|
if ( l.fid() != r.fid() ) {
|
||||||
|
|||||||
@@ -29,6 +29,19 @@ TEST_CASE("meta/value") {
|
|||||||
CHECK(meta::value{1.0}.to_double() == 1.0);
|
CHECK(meta::value{1.0}.to_double() == 1.0);
|
||||||
CHECK(meta::value{"meta"s}.to_string() == "meta");
|
CHECK(meta::value{"meta"s}.to_string() == "meta");
|
||||||
|
|
||||||
|
CHECK(meta::value{true}.is_bool());
|
||||||
|
CHECK_FALSE(meta::value{true}.is_int());
|
||||||
|
CHECK(meta::value{1}.is_int());
|
||||||
|
CHECK_FALSE(meta::value{1}.is_uint());
|
||||||
|
CHECK(meta::value{1u}.is_uint());
|
||||||
|
CHECK_FALSE(meta::value{1u}.is_float());
|
||||||
|
CHECK(meta::value{1.f}.is_float());
|
||||||
|
CHECK_FALSE(meta::value{1.f}.is_double());
|
||||||
|
CHECK(meta::value{1.0}.is_double());
|
||||||
|
CHECK_FALSE(meta::value{1.0}.is_string());
|
||||||
|
CHECK(meta::value{"meta"s}.is_string());
|
||||||
|
CHECK_FALSE(meta::value{"meta"s}.is_bool());
|
||||||
|
|
||||||
CHECK(meta::value{std::in_place_type<std::int8_t>, std::int8_t{1}}.to_int8() == 1);
|
CHECK(meta::value{std::in_place_type<std::int8_t>, std::int8_t{1}}.to_int8() == 1);
|
||||||
CHECK(meta::value{std::in_place_type<std::int16_t>, std::int16_t{1}}.to_int16() == 1);
|
CHECK(meta::value{std::in_place_type<std::int16_t>, std::int16_t{1}}.to_int16() == 1);
|
||||||
CHECK(meta::value{std::in_place_type<std::int32_t>, std::int32_t{1}}.to_int32() == 1);
|
CHECK(meta::value{std::in_place_type<std::int32_t>, std::int32_t{1}}.to_int32() == 1);
|
||||||
@@ -42,6 +55,20 @@ TEST_CASE("meta/value") {
|
|||||||
CHECK(meta::value{std::in_place_type<std::uint64_t>, std::uint64_t{1}}.to_uint64() == 1u);
|
CHECK(meta::value{std::in_place_type<std::uint64_t>, std::uint64_t{1}}.to_uint64() == 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::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);
|
||||||
|
|
||||||
|
CHECK(meta::value{std::in_place_type<std::int8_t>, std::int8_t{1}}.is_int8());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::int16_t>, std::int16_t{1}}.is_int16());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::int32_t>, std::int32_t{1}}.is_int32());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::int64_t>, std::int64_t{1}}.is_int64());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::ptrdiff_t>, std::ptrdiff_t{1}}.is_ptrdiff_t());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::intptr_t>, std::intptr_t{1}}.is_intptr_t());
|
||||||
|
|
||||||
|
CHECK(meta::value{std::in_place_type<std::uint8_t>, std::uint8_t{1}}.is_uint8());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::uint16_t>, std::uint16_t{1}}.is_uint16());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::uint32_t>, std::uint32_t{1}}.is_uint32());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::uint64_t>, std::uint64_t{1}}.is_uint64());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::size_t>, std::size_t{1}}.is_size_t());
|
||||||
|
CHECK(meta::value{std::in_place_type<std::uintptr_t>, std::uintptr_t{1}}.is_uintptr_t());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/value/fid") {
|
TEST_CASE("meta/value/fid") {
|
||||||
@@ -63,6 +90,17 @@ TEST_CASE("meta/value/fid") {
|
|||||||
CHECK(meta::value{std::in_place_type<std::vector<int>>, {1,2,3,4}}.fid() == meta::get_type_family_id<std::vector<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/data") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
meta::value v{1};
|
||||||
|
CHECK(*static_cast<int*>(v.data()) == 1);
|
||||||
|
*static_cast<int*>(v.data()) = 2;
|
||||||
|
CHECK(v.to_int() == 2);
|
||||||
|
CHECK(*static_cast<const int*>(std::as_const(v).data()) == 2);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/value/equal") {
|
TEST_CASE("meta/value/equal") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|||||||
Reference in New Issue
Block a user