From 916c908c8cc230950cfda036941be1968a245a37 Mon Sep 17 00:00:00 2001 From: Peppersawce Date: Wed, 17 Dec 2025 00:13:38 +0100 Subject: Provide fallback for missing char8_t support Copied from github pull #4736 at @nlohmann/json diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index d647d74..39fff02 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -540,7 +540,7 @@ 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(); -#ifdef JSON_HAS_CPP_20 +#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L) p = std_fs::path(std::u8string_view(reinterpret_cast(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 ead4566..b17e8af 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -15,7 +15,8 @@ #include // copy #include // begin, end -#include // string +#include // allocator_traits +#include // basic_string, char_traits #include // tuple, get #include // is_same, is_constructible, is_floating_point, is_enum, underlying_type #include // 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 +inline void to_json(BasicJsonType& j, const std::basic_string& s) +{ + using OtherAllocator = typename std::allocator_traits::template rebind_alloc; + j = std::basic_string, OtherAllocator>(s.begin(), s.end(), s.get_allocator()); +} +#endif + template 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 82d69f7..bba9976 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5325,7 +5325,7 @@ 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(); -#ifdef JSON_HAS_CPP_20 +#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L) p = std_fs::path(std::u8string_view(reinterpret_cast(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 +5380,8 @@ NLOHMANN_JSON_NAMESPACE_END #include // copy #include // begin, end -#include // string +#include // allocator_traits +#include // basic_string, char_traits #include // tuple, get #include // is_same, is_constructible, is_floating_point, is_enum, underlying_type #include // move, forward, declval, pair @@ -6087,15 +6088,19 @@ inline void to_json(BasicJsonType& j, const T& t) } #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM +#if defined(__cpp_lib_char8_t) +template +inline void to_json(BasicJsonType& j, const std::basic_string& s) +{ + using OtherAllocator = typename std::allocator_traits::template rebind_alloc; + j = std::basic_string, OtherAllocator>(s.begin(), s.end(), s.get_allocator()); +} +#endif + template 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 } #endif diff --git a/tests/src/unit-deserialization.cpp b/tests/src/unit-deserialization.cpp index 84a970a..b892715 100644 --- a/tests/src/unit-deserialization.cpp +++ b/tests/src/unit-deserialization.cpp @@ -1136,7 +1136,7 @@ TEST_CASE("deserialization") // select the types to test - char8_t is only available in C++20 #define TYPE_LIST(...) __VA_ARGS__ -#ifdef JSON_HAS_CPP_20 +#if defined(__cpp_char8_t) && (__cpp_char8_t >= 201811L) #define ASCII_TYPES TYPE_LIST(char, wchar_t, char16_t, char32_t, char8_t) #else #define ASCII_TYPES TYPE_LIST(char, wchar_t, char16_t, char32_t) -- 2.51.0