summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-11-23 18:31:03 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-11-23 19:05:52 +0100
commite7d672ec1578319bad8e944e37c91fbcb8371e75 (patch)
treea6ac6b304ebcf5ada8323b755da68f7874da713b
parent710c2e9df4683ded59048a48a1d21dba9dd86e17 (diff)
use explicit instantiation for vector serializers
-rw-r--r--serialize/magnum-color.cpp33
-rw-r--r--serialize/magnum-color.hpp27
-rw-r--r--serialize/magnum-vector.cpp130
-rw-r--r--serialize/magnum-vector.hpp38
-rw-r--r--serialize/magnum-vector2i.cpp56
-rw-r--r--serialize/magnum-vector2i.hpp23
-rw-r--r--serialize/wall-atlas.cpp2
7 files changed, 199 insertions, 110 deletions
diff --git a/serialize/magnum-color.cpp b/serialize/magnum-color.cpp
new file mode 100644
index 00000000..390ce1f3
--- /dev/null
+++ b/serialize/magnum-color.cpp
@@ -0,0 +1,33 @@
+#include "magnum-color.hpp"
+#include <array>
+#include <Magnum/Math/Color.h>
+#include <nlohmann/json.hpp>
+
+namespace floormat {
+
+namespace {
+
+using c3_proxy = std::array<float, 3>;
+using c4_proxy = std::array<float, 4>;
+using c3ub_proxy = std::array<uint8_t, 3>;
+using c4ub_proxy = std::array<uint8_t, 4>;
+
+} // namespace
+
+} // namespace floormat
+
+namespace nlohmann {
+
+using namespace floormat;
+
+void adl_serializer<Color3>::to_json(json& val, const Color3& p) { val = c3_proxy { p[0], p[1], p[2] }; }
+void adl_serializer<Color3ub>::to_json(json& val, const Color3ub& p) { val = c3ub_proxy{ p[0], p[1], p[2] }; }
+void adl_serializer<Color4>::to_json(json& val, const Color4& p) { val = c4_proxy { p[0], p[1], p[2], p[3] }; }
+void adl_serializer<Color4ub>::to_json(json& val, const Color4ub& p) { val = c4ub_proxy{ p[0], p[1], p[2], p[3] }; }
+
+void adl_serializer<Color3>::from_json(const json& j, Color3& val) { auto p = c3_proxy{j}; val = { p[0], p[1], p[2] }; }
+void adl_serializer<Color3ub>::from_json(const json& j, Color3ub& val) { auto p = c3ub_proxy{j}; val = { p[0], p[1], p[2] }; }
+void adl_serializer<Color4>::from_json(const json& j, Color4& val) { auto p = c4_proxy{j}; val = { p[0], p[1], p[2], p[3] }; }
+void adl_serializer<Color4ub>::from_json(const json& j, Color4ub& val) { auto p = c4ub_proxy{j}; val = { p[0], p[1], p[2], p[3] }; }
+
+} // namespace nlohmann
diff --git a/serialize/magnum-color.hpp b/serialize/magnum-color.hpp
new file mode 100644
index 00000000..863eb711
--- /dev/null
+++ b/serialize/magnum-color.hpp
@@ -0,0 +1,27 @@
+#pragma once
+#include <Magnum/Math/Math.h>
+#include <nlohmann/json_fwd.hpp>
+
+template<>
+struct nlohmann::adl_serializer<Magnum::Color3> {
+ static void to_json(json& j, const Magnum::Color3& val);
+ static void from_json(const json& j, Magnum::Color3& val);
+};
+
+template<>
+struct nlohmann::adl_serializer<Magnum::Color4> {
+ static void to_json(json& j, const Magnum::Color4& val);
+ static void from_json(const json& j, Magnum::Color4& val);
+};
+
+template<>
+struct nlohmann::adl_serializer<Magnum::Color3ub> {
+ static void to_json(json& j, const Magnum::Color3ub& val);
+ static void from_json(const json& j, Magnum::Color3ub& val);
+};
+
+template<>
+struct nlohmann::adl_serializer<Magnum::Color4ub> {
+ static void to_json(json& j, const Magnum::Color4ub& val);
+ static void from_json(const json& j, Magnum::Color4ub& val);
+};
diff --git a/serialize/magnum-vector.cpp b/serialize/magnum-vector.cpp
new file mode 100644
index 00000000..151730be
--- /dev/null
+++ b/serialize/magnum-vector.cpp
@@ -0,0 +1,130 @@
+#include "magnum-vector.hpp"
+#include "compat/format.hpp"
+#include "compat/exception.hpp"
+#include <Magnum/Math/Vector.h>
+#include <cstdio>
+#include <string>
+#include <nlohmann/json.hpp>
+
+namespace floormat::Serialize {
+
+namespace {
+
+[[noreturn]] void throw_failed_to_parse_vector2(const std::string& str)
+{
+ fm_throw("failed to parse Vector2 '{}'"_cf, str);
+}
+
+[[noreturn]] void throw_vector2_overflow(const std::string& str)
+{
+ fm_throw("numeric overflow in Vector2 '{}'"_cf, str);
+}
+
+using nlohmann::json;
+using Math::Vector;
+using Math::Vector2;
+using Math::Vector3;
+using Math::Vector4;
+
+template<size_t N, typename T>
+struct vec_serializer
+{
+ static void to_json(json& j, Math::Vector<N, T> val)
+ {
+ std::array<T, N> array{};
+ for (auto i = 0uz; i < N; i++)
+ array[i] = val[i];
+ using nlohmann::to_json;
+ to_json(j, array);
+ }
+ static void from_json(const json& j, Math::Vector<N, T>& val)
+ {
+ std::array<T, N> array{};
+ using nlohmann::from_json;
+ from_json(j, array);
+ for (auto i = 0uz; i < N; i++)
+ val[i] = array[i];
+ }
+};
+
+template<typename T>
+struct vec2_serializer
+{
+ static void to_json(json& j, Vector<2, T> val)
+ {
+ char buf[64];
+ using type = std::conditional_t<std::is_signed_v<T>, intmax_t, uintmax_t>;
+ constexpr auto format_string = std::is_signed_v<T> ? "%jd x %jd" : "%ju x %ju";
+ snprintf(buf, sizeof(buf), format_string, (type)val[0], (type)val[1]);
+ j = buf;
+ }
+
+ static void from_json(const json& j, Vector<2, T>& val)
+ {
+ using namespace floormat;
+ std::string str = j;
+ using type = std::conditional_t<std::is_signed_v<T>, intmax_t, uintmax_t>;
+ constexpr auto format_string = std::is_signed_v<T> ? "%jd x %jd%n" : "%ju x %ju%n";
+ type x = 0, y = 0;
+ int n = 0;
+ int ret = std::sscanf(str.data(), format_string, &x, &y, &n);
+ if (ret != 2 || (size_t)n != str.size() || x != (T)x || y != (T)y)
+ throw_failed_to_parse_vector2(str);
+ if constexpr(sizeof(T) < sizeof(type))
+ if (x != (type)(T)x || y != (type)(T)y)
+ throw_vector2_overflow(str);
+ val = { (T)x, (T)y };
+ }
+};
+
+} // namespace
+} // namespace floormat::Serialize
+
+namespace nlohmann {
+
+using floormat::Serialize::vec_serializer;
+using floormat::Serialize::vec2_serializer;
+using floormat::size_t;
+using namespace Magnum::Math;
+
+template<size_t N, typename T>
+void adl_serializer<Vector<N, T>>::to_json(json& j, Vector<N, T> val)
+{
+ if constexpr(N != 2 || !std::is_integral_v<T>)
+ vec_serializer<N, T>::to_json(j, val);
+ else
+ vec2_serializer<T>::to_json(j, val);
+}
+
+template<size_t N, typename T>
+void adl_serializer<Vector<N, T>>::from_json(const json& j, Vector<N, T>& val)
+{
+ if constexpr(N != 2 || !std::is_integral_v<T>)
+ vec_serializer<N, T>::from_json(j, val);
+ else
+ vec2_serializer<T>::from_json(j, val);
+}
+
+#define FM_INST_VEC_SERIALIZER_1(N, Type) \
+ template struct adl_serializer< Vector<N, Type>>; \
+ template struct adl_serializer< Vector##N<Type>>
+
+#define FM_INST_VEC_SERIALIZER_F(Type) \
+
+#define FM_INST_VEC_SERIALIZER(Type) \
+ FM_INST_VEC_SERIALIZER_1(Type, float); \
+ FM_INST_VEC_SERIALIZER_1(Type, double); \
+ FM_INST_VEC_SERIALIZER_1(Type, int8_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, int16_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, int32_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, int64_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, uint8_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, uint16_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, uint32_t); \
+ FM_INST_VEC_SERIALIZER_1(Type, uint64_t)
+
+FM_INST_VEC_SERIALIZER(2);
+FM_INST_VEC_SERIALIZER(3);
+FM_INST_VEC_SERIALIZER(4);
+
+} // namespace nlohmann
diff --git a/serialize/magnum-vector.hpp b/serialize/magnum-vector.hpp
index ddd09228..ac6206d6 100644
--- a/serialize/magnum-vector.hpp
+++ b/serialize/magnum-vector.hpp
@@ -1,41 +1,17 @@
#pragma once
-#include "magnum-vector2i.hpp"
-#include <Magnum/Math/Vector.h>
-#include <nlohmann/json.hpp>
+#include <nlohmann/json_fwd.hpp>
namespace nlohmann {
-template<size_t N, typename T>
-struct adl_serializer<Magnum::Math::Vector<N, T>> {
- using vec = Magnum::Math::Vector<N, T>;
- static void to_json(json& j, const vec& val);
- static void from_json(const json& j, vec& val);
-};
-
-template <size_t N, typename T>
-void adl_serializer<Magnum::Math::Vector<N, T>>::to_json(json& j, const vec& val)
+template<floormat::size_t N, typename T>
+struct adl_serializer<Magnum::Math::Vector<N, T>>
{
- std::array<T, N> array{};
- for (auto i = 0uz; i < N; i++)
- array[i] = val[i];
- using nlohmann::to_json;
- to_json(j, array);
-}
-
-template <size_t N, typename T>
-void adl_serializer<Magnum::Math::Vector<N, T>>::from_json(const json& j, vec& val)
-{
- std::array<T, N> array{};
- using nlohmann::from_json;
- from_json(j, array);
- for (auto i = 0uz; i < N; i++)
- val[i] = array[i];
-}
+ static void to_json(json& j, Magnum::Math::Vector<N, T> val);
+ static void from_json(const json& j, Magnum::Math::Vector<N, T>& val);
+};
-template<typename T> requires (!std::is_integral_v<T>) struct adl_serializer<Magnum::Math::Vector2<T>> : adl_serializer<Magnum::Math::Vector<2, T>> {};
+template<typename T> struct adl_serializer<Magnum::Math::Vector2<T>> : adl_serializer<Magnum::Math::Vector<2, T>> {};
template<typename T> struct adl_serializer<Magnum::Math::Vector3<T>> : adl_serializer<Magnum::Math::Vector<3, T>> {};
template<typename T> struct adl_serializer<Magnum::Math::Vector4<T>> : adl_serializer<Magnum::Math::Vector<4, T>> {};
-template<typename T> struct adl_serializer<Magnum::Math::Color3<T>> : adl_serializer<Magnum::Math::Vector<3, T>> {};
-template<typename T> struct adl_serializer<Magnum::Math::Color4<T>> : adl_serializer<Magnum::Math::Vector<4, T>> {};
} // namespace nlohmann
diff --git a/serialize/magnum-vector2i.cpp b/serialize/magnum-vector2i.cpp
deleted file mode 100644
index 0b52d508..00000000
--- a/serialize/magnum-vector2i.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "magnum-vector2i.hpp"
-#include "compat/exception.hpp"
-#include <nlohmann/json.hpp>
-
-using namespace floormat;
-
-void floormat::Serialize::throw_failed_to_parse_vector2(const std::string& str)
-{
- fm_throw("failed to parse Vector2 '{}'"_cf, str);
-}
-
-void floormat::Serialize::throw_vector2_overflow(const std::string& str)
-{
- fm_throw("numeric overflow in Vector2 '{}'"_cf, str);
-}
-
-using namespace nlohmann;
-
-template<typename T>
-requires std::is_integral_v<T>
-void nlohmann::adl_serializer<Magnum::Math::Vector2<T>>::to_json(json& j, const Magnum::Math::Vector2<T>& val)
-{
- char buf[64];
- using type = std::conditional_t<std::is_signed_v<T>, intmax_t, uintmax_t>;
- constexpr auto format_string = std::is_signed_v<T> ? "%jd x %jd" : "%ju x %ju";
- snprintf(buf, sizeof(buf), format_string, (type)val[0], (type)val[1]);
- j = buf;
-}
-
-template<typename T>
-requires std::is_integral_v<T>
-void nlohmann::adl_serializer<Magnum::Math::Vector2<T>>::from_json(const json& j, Magnum::Math::Vector2<T>& val)
-{
- using namespace floormat;
- std::string str = j;
- using type = std::conditional_t<std::is_signed_v<T>, intmax_t, uintmax_t>;
- constexpr auto format_string = std::is_signed_v<T> ? "%jd x %jd%n" : "%ju x %ju%n";
- type x = 0, y = 0;
- int n = 0;
- int ret = std::sscanf(str.data(), format_string, &x, &y, &n);
- if (ret != 2 || (size_t)n != str.size() || x != (T)x || y != (T)y)
- floormat::Serialize::throw_failed_to_parse_vector2(str);
- if constexpr(sizeof(T) < sizeof(type))
- if (x != (type)(T)x || y != (type)(T)y)
- floormat::Serialize::throw_vector2_overflow(str);
- val = { (T)x, (T)y };
-}
-
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<uint8_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<uint16_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<uint32_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<uint64_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<int8_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<int16_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<int32_t>>;
-template struct nlohmann::adl_serializer<Magnum::Math::Vector2<int64_t>>;
diff --git a/serialize/magnum-vector2i.hpp b/serialize/magnum-vector2i.hpp
index ddb79e98..caed2275 100644
--- a/serialize/magnum-vector2i.hpp
+++ b/serialize/magnum-vector2i.hpp
@@ -1,23 +1,2 @@
#pragma once
-#include "compat/assert.hpp"
-#include <cstdio>
-#include <string>
-#include <Magnum/Math/Vector2.h>
-#include <nlohmann/json_fwd.hpp>
-
-namespace floormat::Serialize {
- [[noreturn]] void throw_failed_to_parse_vector2(const std::string& str);
- [[noreturn]] void throw_vector2_overflow(const std::string& str);
-}
-
-namespace nlohmann {
-
-template<typename T>
-requires std::is_integral_v<T>
-struct adl_serializer<Magnum::Math::Vector2<T>> final
-{
- static void to_json(json& j, const Magnum::Math::Vector2<T>& val);
- static void from_json(const json& j, Magnum::Math::Vector2<T>& val);
-};
-
-} // namespace nlohmann
+#include "magnum-vector.hpp"
diff --git a/serialize/wall-atlas.cpp b/serialize/wall-atlas.cpp
index c045678b..3d4a90dd 100644
--- a/serialize/wall-atlas.cpp
+++ b/serialize/wall-atlas.cpp
@@ -1,6 +1,6 @@
#include "wall-atlas.hpp"
-#include "magnum-vector2i.hpp"
#include "magnum-vector.hpp"
+#include "magnum-color.hpp"
#include "corrade-string.hpp"
#include "compat/exception.hpp"
#include "loader/loader.hpp"