|
|
@@ -13,6 +13,12 @@
|
|
|
#include <unordered_map>
|
|
|
#include <utility>
|
|
|
|
|
|
+#if defined __has_include
|
|
|
+#if __has_include(<magic_enum.hpp>)
|
|
|
+#include <magic_enum.hpp>
|
|
|
+#endif
|
|
|
+#endif
|
|
|
+
|
|
|
#include "reflection/forward.h"
|
|
|
#include "reflection/object.h"
|
|
|
|
|
|
@@ -31,17 +37,18 @@ public:
|
|
|
|
|
|
template <typename I, typename O, typename S>
|
|
|
TypeCast & bind(T (*to)(I), O (*from)(S)) {
|
|
|
- return bind(std::function(to), std::function(from));
|
|
|
- }
|
|
|
-
|
|
|
- template <typename I, typename O, typename S>
|
|
|
- TypeCast & bind(std::function<T(I)> to, std::function<O(S)> from) {
|
|
|
bind_impl(to, from);
|
|
|
TypeCast<std::decay_t<I>>().template bind_impl(from, to);
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
template <typename V> TypeCast & bind() {
|
|
|
+#if defined NEARGYE_MAGIC_ENUM_HPP
|
|
|
+ if constexpr (std::is_same_v<V, std::string> && std::is_enum_v<T>) {
|
|
|
+ bind<V const &, V, T>([](V const &str) -> T { return *magic_enum::enum_cast<T>(str); },
|
|
|
+ [](T val) { return std::string(magic_enum::enum_name(val)); });
|
|
|
+ } else
|
|
|
+#endif
|
|
|
if constexpr (!std::is_same_v<V, T>) {
|
|
|
bind_impl<V>();
|
|
|
TypeCast<V>().template bind_impl<T>();
|
|
|
@@ -55,7 +62,7 @@ public:
|
|
|
|
|
|
private:
|
|
|
template <typename I, typename O, typename S>
|
|
|
- void bind_impl(std::function<T(I)> to, std::function<O(S)> from) {
|
|
|
+ void bind_impl(T (*to)(I), O (*from)(S)) {
|
|
|
static_assert(std::is_same_v<std::decay_t<S>, T>,
|
|
|
"this types must be compatible");
|
|
|
static_assert(std::is_same_v<std::decay_t<I>, std::decay_t<I>>,
|
|
|
@@ -111,27 +118,33 @@ REFLECTION_TYPE_CAST(bool)
|
|
|
// Bind all integer types (wider than 1byte) to each other.
|
|
|
REFLECTION_TYPE_CAST(int32_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
REFLECTION_TYPE_CAST(uint32_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
REFLECTION_TYPE_CAST(int16_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
REFLECTION_TYPE_CAST(uint16_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
REFLECTION_TYPE_CAST(int64_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
REFLECTION_TYPE_CAST(uint64_t)
|
|
|
.bind<int16_t, int32_t, int64_t>()
|
|
|
- .bind<uint16_t, uint32_t, uint64_t>();
|
|
|
+ .bind<uint16_t, uint32_t, uint64_t>()
|
|
|
+ .bind<float, double, long double>();
|
|
|
|
|
|
// Mututally bind all floating point numbers
|
|
|
REFLECTION_TYPE_CAST(float).bind<float, double, long double>();
|