is_xxx and data functions for value

This commit is contained in:
BlackMATov
2021-07-06 01:24:25 +07:00
parent 5e10b46f08
commit c006d10e33
2 changed files with 95 additions and 0 deletions

View File

@@ -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() ) {

View File

@@ -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;