Skip to content

Commit

Permalink
feat: make stringable class can be key of reflection map
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Dec 18, 2023
1 parent 6655585 commit 25f52e2
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/ll/api/base/Concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ struct is_all_same : std::bool_constant<is_all_same_v<T, Ts...>> {};
template <class T, class... Ts>
concept IsAllSame = is_all_same_v<T, Ts...>;

template <class T, class... Ts>
static constexpr bool is_string_v = std::convertible_to<T, std::string_view>;
template <class T>
static constexpr bool is_string_v = std::is_constructible_v<std::string, T>;

template <class T>
concept IsString = is_string_v<T>;
Expand Down Expand Up @@ -111,7 +111,7 @@ inline constexpr bool always_false = false;

template <class T>
concept Stringable = requires(T t) {
{ t.toString() } -> std::convertible_to<std::string>;
{ t.toString() } -> IsString;
};

} // namespace ll::concepts
20 changes: 7 additions & 13 deletions src/ll/api/reflection/Deserialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,18 @@ inline void deserialize(T&, J const&)

template <class J, class T>
inline void deserialize(T&, J const&)
requires(
!std::is_enum_v<T>
&& (std::is_convertible_v<T, std::string_view> || std::is_floating_point_v<T> || std::is_integral_v<T>)
);
requires(!std::is_enum_v<T> && (concepts::IsString<T> || std::is_floating_point_v<T> || std::is_integral_v<T>));

template <class J, concepts::Associative T>
inline void deserialize(T&, J const&)
requires(std::is_convertible_v<typename T::key_type, std::string_view>);
requires(concepts::IsString<typename T::key_type>);

template <class J, concepts::TupleLike T>
inline void deserialize(T&, J const&);

template <class J, concepts::ArrayLike T>
inline void deserialize(T&, J const&)
requires(!std::is_convertible_v<T, std::string_view>);
requires(!concepts::IsString<T>);

template <class J, concepts::IsOptional T>
inline void deserialize(T&, J const&);
Expand Down Expand Up @@ -79,12 +76,9 @@ inline void deserialize(T& e, J const& j)

template <class J, class T>
inline void deserialize(T& obj, J const& j) // TODO: improve this
requires(
!std::is_enum_v<T>
&& (std::is_convertible_v<T, std::string_view> || std::is_floating_point_v<T> || std::is_integral_v<T>)
)
requires(!std::is_enum_v<T> && (concepts::IsString<T> || std::is_floating_point_v<T> || std::is_integral_v<T>))
{
if constexpr (std::is_convertible_v<T, std::string_view>) {
if constexpr (concepts::IsString<T>) {
if (!j.is_string()) throw std::runtime_error("field must be a string");
} else {
if (!j.is_number() && !j.is_boolean()) throw std::runtime_error("field must be a number");
Expand All @@ -94,7 +88,7 @@ inline void deserialize(T& obj, J const& j) // TODO: improve this

template <class J, concepts::Associative T>
inline void deserialize(T& map, J const& j)
requires(std::is_convertible_v<typename T::key_type, std::string_view>)
requires(concepts::IsString<typename T::key_type>)
{
if (!j.is_object()) throw std::runtime_error("field must be an object");
map.clear();
Expand All @@ -112,7 +106,7 @@ inline void deserialize(T& tuple, J const& j) {

template <class J, concepts::ArrayLike T>
inline void deserialize(T& arr, J const& j)
requires(!std::is_convertible_v<T, std::string_view>)
requires(!concepts::IsString<T>)
{
if (!j.is_array()) throw std::runtime_error("field must be an array");

Expand Down
4 changes: 2 additions & 2 deletions src/ll/api/reflection/Serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ inline J serialize(T const&)

template <class J, concepts::Associative T>
inline J serialize(T const&)
requires(std::is_convertible_v<typename T::key_type, std::string_view> && !std::convertible_to<T, J>);
requires(concepts::IsString<typename T::key_type> && !std::convertible_to<T, J>);


template <class J, concepts::TupleLike T>
Expand Down Expand Up @@ -78,7 +78,7 @@ inline J serialize(T const& obj)

template <class J, concepts::Associative T>
inline J serialize(T const& map)
requires(std::is_convertible_v<typename T::key_type, std::string_view> && !std::convertible_to<T, J>)
requires(concepts::IsString<typename T::key_type> && !std::convertible_to<T, J>)
{
J res;
for (auto& [k, v] : map) {
Expand Down
7 changes: 7 additions & 0 deletions src/ll/test/ConfigTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "mc/server/ServerLevel.h"
#include "mc/server/commands/standard/FillCommand.h"

#include "mc/deps/core/mce/UUID.h"

template <class T>

class TestClass {
Expand Down Expand Up @@ -52,6 +54,11 @@ class TestClass {
{"key2", {"a new thing", 42}},
{"key3", {} },
};
std::map<mce::UUID, int> bmap = {
{{0, 1}, 4454556},
{{2, 3}, 4366},
{{4, 5}, -63556654},
};
std::tuple<int, bool, float> tuple;
std::pair<std::string_view, MyPair> pair;
std::array<int, 5> array{};
Expand Down
30 changes: 29 additions & 1 deletion src/mc/deps/core/mce/UUID.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "ll/api/base/Hash.h"
#include "mc/_HeaderOutputPredefine.h"

namespace mce {
Expand All @@ -8,12 +9,27 @@ class UUID {
public:
uint64 a, b;

UUID(uint64 a = 0, uint64 b = 0) : a(a), b(b) {}
UUID(uint64 a, uint64 b) : a(a), b(b) {}

UUID() : UUID(EMPTY) {}

UUID(std::string const& str) : UUID(fromString(str)) {} // NOLINT

LLNDAPI static mce::UUID random();

[[nodiscard]] inline explicit operator bool() const { return !isEmpty(); }

[[nodiscard]] inline explicit operator std::string() const { return asString(); }

bool operator==(UUID const& other) const { return (a == other.a) && (b == other.b); }

std::strong_ordering operator<=>(UUID const& other) const {
if (a != other.a) {
return a <=> other.a;
}
return b <=> other.b;
}

public:
// NOLINTBEGIN
// symbol: ?asString@UUID@mce@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
Expand All @@ -38,3 +54,15 @@ class UUID {
};

}; // namespace mce


namespace std {
template <>
struct hash<mce::UUID> {
size_t operator()(mce::UUID id) const noexcept {
size_t hash = id.a;
ll::hash::hashCombine(id.b, hash);
return hash;
}
};
} // namespace std

0 comments on commit 25f52e2

Please sign in to comment.