forked from pool/nlohmann_json
char8_t fallback, that also makes it possible to use C++20 without implicitly enabling char8_t in case projects build with -fno-char8_t. OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/nlohmann_json?expand=0&rev=42
124 lines
5.5 KiB
Diff
124 lines
5.5 KiB
Diff
From 93e20c9afa13197984f3033659d1c724cf2ab769 Mon Sep 17 00:00:00 2001
|
|
From: Sergiu Deitsch <sergiud@users.noreply.github.com>
|
|
Date: Wed, 23 Apr 2025 18:36:41 +0200
|
|
Subject: [PATCH] Provide fallback for missing `char8_t` support (#4736)
|
|
|
|
---
|
|
.../nlohmann/detail/conversions/from_json.hpp | 5 +++-
|
|
.../nlohmann/detail/conversions/to_json.hpp | 21 ++++++++++-----
|
|
single_include/nlohmann/json.hpp | 26 +++++++++++++------
|
|
tests/src/unit-deserialization.cpp | 5 ++--
|
|
4 files changed, 39 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp
|
|
index d647d742..e161a428 100644
|
|
--- a/include/nlohmann/detail/conversions/from_json.hpp
|
|
+++ b/include/nlohmann/detail/conversions/from_json.hpp
|
|
@@ -540,7 +540,10 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
|
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
|
|
}
|
|
const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
|
-#ifdef JSON_HAS_CPP_20
|
|
+ // Checking for C++20 standard or later can be insufficient in case the
|
|
+ // library support for char8_t is either incomplete or was disabled
|
|
+ // altogether. Use the __cpp_lib_char8_t feature test instead.
|
|
+#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
|
|
p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
|
|
#else
|
|
p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20
|
|
diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp
|
|
index ead45665..b17e8af4 100644
|
|
--- a/include/nlohmann/detail/conversions/to_json.hpp
|
|
+++ b/include/nlohmann/detail/conversions/to_json.hpp
|
|
@@ -15,7 +15,8 @@
|
|
|
|
#include <algorithm> // copy
|
|
#include <iterator> // begin, end
|
|
-#include <string> // string
|
|
+#include <memory> // allocator_traits
|
|
+#include <string> // basic_string, char_traits
|
|
#include <tuple> // tuple, get
|
|
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
|
|
#include <utility> // move, forward, declval, pair
|
|
@@ -440,15 +441,21 @@ inline void to_json(BasicJsonType& j, const T& t)
|
|
}
|
|
|
|
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
+#if defined(__cpp_lib_char8_t)
|
|
+template<typename BasicJsonType, typename Tr, typename Allocator>
|
|
+inline void to_json(BasicJsonType& j, const std::basic_string<char8_t, Tr, Allocator>& s)
|
|
+{
|
|
+ using OtherAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<char>;
|
|
+ j = std::basic_string<char, std::char_traits<char>, OtherAllocator>(s.begin(), s.end(), s.get_allocator());
|
|
+}
|
|
+#endif
|
|
+
|
|
template<typename BasicJsonType>
|
|
inline void to_json(BasicJsonType& j, const std_fs::path& p)
|
|
{
|
|
-#ifdef JSON_HAS_CPP_20
|
|
- const std::u8string s = p.u8string();
|
|
- j = std::string(s.begin(), s.end());
|
|
-#else
|
|
- j = p.u8string(); // returns std::string in C++17
|
|
-#endif
|
|
+ // Returns either a std::string or a std::u8string depending whether library
|
|
+ // support for char8_t is enabled.
|
|
+ j = p.u8string();
|
|
}
|
|
#endif
|
|
|
|
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
|
|
index 82d69f7c..be3493ef 100644
|
|
--- a/single_include/nlohmann/json.hpp
|
|
+++ b/single_include/nlohmann/json.hpp
|
|
@@ -5325,7 +5325,10 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
|
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
|
|
}
|
|
const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
|
-#ifdef JSON_HAS_CPP_20
|
|
+ // Checking for C++20 standard or later can be insufficient in case the
|
|
+ // library support for char8_t is either incomplete or was disabled
|
|
+ // altogether. Use the __cpp_lib_char8_t feature test instead.
|
|
+#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
|
|
p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
|
|
#else
|
|
p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20
|
|
@@ -5380,7 +5383,8 @@ NLOHMANN_JSON_NAMESPACE_END
|
|
|
|
#include <algorithm> // copy
|
|
#include <iterator> // begin, end
|
|
-#include <string> // string
|
|
+#include <memory> // allocator_traits
|
|
+#include <string> // basic_string, char_traits
|
|
#include <tuple> // tuple, get
|
|
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
|
|
#include <utility> // move, forward, declval, pair
|
|
@@ -6087,15 +6091,21 @@ inline void to_json(BasicJsonType& j, const T& t)
|
|
}
|
|
|
|
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
|
|
+#if defined(__cpp_lib_char8_t)
|
|
+template<typename BasicJsonType, typename Tr, typename Allocator>
|
|
+inline void to_json(BasicJsonType& j, const std::basic_string<char8_t, Tr, Allocator>& s)
|
|
+{
|
|
+ using OtherAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<char>;
|
|
+ j = std::basic_string<char, std::char_traits<char>, OtherAllocator>(s.begin(), s.end(), s.get_allocator());
|
|
+}
|
|
+#endif
|
|
+
|
|
template<typename BasicJsonType>
|
|
inline void to_json(BasicJsonType& j, const std_fs::path& p)
|
|
{
|
|
-#ifdef JSON_HAS_CPP_20
|
|
- const std::u8string s = p.u8string();
|
|
- j = std::string(s.begin(), s.end());
|
|
-#else
|
|
- j = p.u8string(); // returns std::string in C++17
|
|
-#endif
|
|
+ // Returns either a std::string or a std::u8string depending whether library
|
|
+ // support for char8_t is enabled.
|
|
+ j = p.u8string();
|
|
}
|
|
#endif
|