Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #117

Merged
merged 1 commit into from
Jan 23, 2025
Merged

Dev #117

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 107 additions & 11 deletions develop/singles/headers/meta.hpp/meta_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <exception>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <map>
#include <memory>
#include <mutex>
Expand Down Expand Up @@ -2756,6 +2757,9 @@ namespace meta_hpp
[[nodiscard]] uvalue unmap() const;
[[nodiscard]] bool has_unmap_op() const noexcept;

[[nodiscard]] std::size_t size() const;
[[nodiscard]] bool has_size_op() const noexcept;

[[nodiscard]] bool less(const uvalue& other) const;
[[nodiscard]] bool has_less_op() const noexcept;

Expand Down Expand Up @@ -11280,6 +11284,71 @@ namespace meta_hpp::detail
}; \
}

namespace meta_hpp::detail
{
template < typename T >
struct size_traits;

template < typename T >
concept has_size_traits //
= requires(const T& v) { size_traits<std::remove_cv_t<T>>{}(v); };
}

namespace meta_hpp::detail
{
template < typename T, std::size_t Size >
struct size_traits<std::array<T, Size>> {
std::size_t operator()(const std::array<T, Size>& v) const {
using std::size;
return size(v);
}
};

template < typename T, typename Traits, typename Allocator >
struct size_traits<std::basic_string<T, Traits, Allocator>> {
std::size_t operator()(const std::basic_string<T, Traits, Allocator>& v) const {
using std::size;
return size(v);
}
};

template < typename T, typename Traits >
struct size_traits<std::basic_string_view<T, Traits>> {
std::size_t operator()(const std::basic_string_view<T, Traits>& v) const {
using std::size;
return size(v);
}
};

template < typename T, std::size_t Extent >
struct size_traits<std::span<T, Extent>> {
std::size_t operator()(const std::span<T, Extent>& v) const {
using std::size;
return size(v);
}
};

template < typename T, typename Allocator >
struct size_traits<std::vector<T, Allocator>> {
std::size_t operator()(const std::vector<T, Allocator>& v) const {
using std::size;
return size(v);
}
};
}

#define META_HPP_DECLARE_SIZE_TRAITS_FOR(T) \
namespace meta_hpp::detail \
{ \
template <> \
struct size_traits<T> { \
std::size_t operator()(const T& v) const { \
using std::size; \
return size(v); \
} \
}; \
}

namespace meta_hpp::detail
{
template < typename T >
Expand Down Expand Up @@ -11323,9 +11392,11 @@ namespace meta_hpp
void (*const move)(uvalue&& self, uvalue& to) noexcept;
void (*const reset)(uvalue& self) noexcept;

uvalue (*const index)(const storage_u& self, std::size_t i);
std::size_t (*const size)(const storage_u& self);

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

bool (*const less)(const storage_u& l, const storage_u& r);
Expand Down Expand Up @@ -11493,6 +11564,26 @@ namespace meta_hpp
self.storage_.vtag = 0;
}},

.index{[]() {
if constexpr ( detail::has_index_traits<Tp> ) {
return +[](const storage_u& self, std::size_t i) -> uvalue {
return detail::index_traits<Tp>{}(*storage_cast<Tp>(self), i);
};
} else {
return nullptr;
}
}()},

.size{[]() {
if constexpr ( detail::has_size_traits<Tp> ) {
return +[](const storage_u& self) -> std::size_t {
return detail::size_traits<Tp>{}(*storage_cast<Tp>(self));
};
} else {
return nullptr;
}
}()},

.copy{[]() {
if constexpr ( detail::has_copy_traits<Tp> ) {
return +[](const storage_u& self) -> uvalue {
Expand All @@ -11513,16 +11604,6 @@ namespace meta_hpp
}
}()},

.index{[]() {
if constexpr ( detail::has_index_traits<Tp> ) {
return +[](const storage_u& self, std::size_t i) -> uvalue {
return detail::index_traits<Tp>{}(*storage_cast<Tp>(self), i);
};
} else {
return nullptr;
}
}()},

.unmap{[]() {
if constexpr ( detail::has_unmap_traits<Tp> ) {
return +[](const storage_u& self) -> uvalue {
Expand Down Expand Up @@ -11749,6 +11830,21 @@ namespace meta_hpp
return tag != storage_e::nothing && vtable->unmap != nullptr;
}

inline std::size_t uvalue::size() const {
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);

if ( tag != storage_e::nothing && vtable->size != nullptr ) {
return vtable->size(storage_);
}

throw_exception(error_code::bad_uvalue_operation);
}

inline bool uvalue::has_size_op() const noexcept {
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
return tag != storage_e::nothing && vtable->size != nullptr;
}

inline bool uvalue::less(const uvalue& other) const {
if ( this == &other ) {
return false;
Expand Down
33 changes: 33 additions & 0 deletions develop/untests/meta_utilities/value_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ namespace
return {l.x + r.x, l.y + r.y};
}

[[maybe_unused]]
std::size_t size(const ivec2&) {
return 2;
}

[[maybe_unused]]
bool operator==(const ivec2& l, const ivec2& r) noexcept {
return l.x == r.x && l.y == r.y;
Expand Down Expand Up @@ -136,6 +141,7 @@ META_HPP_DECLARE_COPY_TRAITS_FOR(ivec2_big)
META_HPP_DECLARE_DEREF_TRAITS_FOR(deref_custom_class)

META_HPP_DECLARE_INDEX_TRAITS_FOR(ivec2)
META_HPP_DECLARE_SIZE_TRAITS_FOR(ivec2)

META_HPP_DECLARE_EQUALS_TRAITS_FOR(ivec2)

Expand Down Expand Up @@ -911,7 +917,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{42};
CHECK(v.get_type() == meta::resolve_type<int>());
CHECK_FALSE(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v[0]);
CHECK_THROWS(std::ignore = v.size());
}

SUBCASE("void*") {
Expand All @@ -920,7 +928,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{p};
CHECK(v.get_type() == meta::resolve_type<void*>());
CHECK_FALSE(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v[0]);
CHECK_THROWS(std::ignore = v.size());
}

SUBCASE("const void*") {
Expand All @@ -929,7 +939,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{p};
CHECK(v.get_type() == meta::resolve_type<const void*>());
CHECK_FALSE(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v[0]);
CHECK_THROWS(std::ignore = v.size());
}

SUBCASE("int[3]") {
Expand All @@ -938,7 +950,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{arr};
CHECK(v.get_type() == meta::resolve_type<int*>());
CHECK(v.has_index_op());
CHECK_FALSE(v.has_size_op());

CHECK_THROWS(std::ignore = v.size());
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
CHECK(v[2].as<int>() == 3);
Expand All @@ -948,6 +962,8 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{arr};
CHECK(v.get_type() == meta::resolve_type<int*>());
CHECK(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v.size());
CHECK_FALSE(v[0]);
}
}
Expand All @@ -958,7 +974,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{arr};
CHECK(v.get_type() == meta::resolve_type<const int*>());
CHECK(v.has_index_op());
CHECK_FALSE(v.has_size_op());

CHECK_THROWS(std::ignore = v.size());
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
CHECK(v[2].as<int>() == 3);
Expand All @@ -968,6 +986,8 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{arr};
CHECK(v.get_type() == meta::resolve_type<const int*>());
CHECK(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v.size());
CHECK_FALSE(v[0]);
}
}
Expand All @@ -976,7 +996,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{std::array{1,2,3}};
CHECK(v.get_type() == meta::resolve_type<std::array<int, 3>>());
CHECK(v.has_index_op());
CHECK(v.has_size_op());

CHECK(v.size() == 3);
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
CHECK(v[2].as<int>() == 3);
Expand All @@ -988,6 +1010,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
CHECK(v.get_type() == meta::resolve_type<std::string>());
CHECK(v.has_index_op());

CHECK(v.size() == 3);
CHECK(v[0].as<char>() == 'h');
CHECK(v[1].as<char>() == 'i');
CHECK(v[2].as<char>() == '!');
Expand All @@ -998,7 +1021,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{std::string_view{"hi!"}};
CHECK(v.get_type() == meta::resolve_type<std::string_view>());
CHECK(v.has_index_op());
CHECK(v.has_size_op());

CHECK(v.size() == 3);
CHECK(v[0].as<char>() == 'h');
CHECK(v[1].as<char>() == 'i');
CHECK(v[2].as<char>() == '!');
Expand All @@ -1010,7 +1035,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{std::span{arr}};
CHECK(v.get_type() == meta::resolve_type<std::span<int>>());
CHECK(v.has_index_op());
CHECK(v.has_size_op());

CHECK(v.size() == 3);
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
CHECK(v[2].as<int>() == 3);
Expand All @@ -1021,7 +1048,9 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
const meta::uvalue v{std::vector{1,2,3}};
CHECK(v.get_type() == meta::resolve_type<std::vector<int>>());
CHECK(v.has_index_op());
CHECK(v.has_size_op());

CHECK(v.size() == 3);
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
CHECK(v[2].as<int>() == 3);
Expand All @@ -1033,14 +1062,18 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
meta::uvalue v{ivec2{1,2}};
CHECK(v.get_type() == meta::resolve_type<ivec2>());
CHECK(v.has_index_op());
CHECK(v.has_size_op());

CHECK(v.size() == 2);
CHECK(v[0].as<int>() == 1);
CHECK(v[1].as<int>() == 2);
}
{
meta::uvalue v{ivec3{1,2,3}};
CHECK(v.get_type() == meta::resolve_type<ivec3>());
CHECK_FALSE(v.has_index_op());
CHECK_FALSE(v.has_size_op());
CHECK_THROWS(std::ignore = v.size());
CHECK_THROWS(std::ignore = v[0]);
}
}
Expand Down
1 change: 1 addition & 0 deletions headers/meta.hpp/meta_base/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <exception>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <map>
#include <memory>
#include <mutex>
Expand Down
Loading
Loading