Skip to content

Commit 5af4ec4

Browse files
committed
Resolve CI errors and use qualified std::uint64_t
The fix was relying on implicit conversions in the non-taken branch. - Ordinarily (work on a C++20 codebase) I would have used `if constexpr` here, sidestepping the issue, but that's not available on C++11 so I didn't bother. - So instead of an `if` statement, I used a compile-time constant to select the correct overload. - This is arguably better in this case, anyway. I was using function-style casts for typed constants, which I consider superior for constants, but the CI checks disagree, so changed all to `static_cast`. - For some reason, the CI checks didn't point at all of them, so I hope I caught them all myself. Built with clang14 and all unit tests pass.
1 parent 1402ca4 commit 5af4ec4

File tree

3 files changed

+10
-22
lines changed

3 files changed

+10
-22
lines changed

include/nlohmann/detail/conversions/to_json.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,8 @@ template<typename BasicJsonType, typename EnumType,
320320
inline void to_json(BasicJsonType& j, EnumType e) noexcept
321321
{
322322
using underlying_type = typename std::underlying_type<EnumType>::type;
323-
if (std::is_unsigned<underlying_type>::value)
324-
{
325-
external_constructor<value_t::number_unsigned>::construct(j, static_cast<underlying_type>(e));
326-
}
327-
else
328-
{
329-
external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
330-
}
323+
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
324+
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
331325
}
332326
#endif // JSON_DISABLE_ENUM_SERIALIZATION
333327

single_include/nlohmann/json.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5697,14 +5697,8 @@ template<typename BasicJsonType, typename EnumType,
56975697
inline void to_json(BasicJsonType& j, EnumType e) noexcept
56985698
{
56995699
using underlying_type = typename std::underlying_type<EnumType>::type;
5700-
if (std::is_unsigned<underlying_type>::value)
5701-
{
5702-
external_constructor<value_t::number_unsigned>::construct(j, static_cast<underlying_type>(e));
5703-
}
5704-
else
5705-
{
5706-
external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5707-
}
5700+
static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
5701+
external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
57085702
}
57095703
#endif // JSON_DISABLE_ENUM_SERIALIZATION
57105704

tests/src/unit-udt.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ struct contact
6767
contact(person p, address a) : m_person(std::move(p)), m_address(std::move(a)) {}
6868
};
6969

70-
enum class book_id : uint64_t;
70+
enum class book_id : std::uint64_t;
7171

7272
struct contact_book
7373
{
7474
name m_book_name{};
7575
book_id m_book_id{};
7676
std::vector<contact> m_contacts{};
7777
contact_book() = default;
78-
contact_book(name n, book_id i, std::vector<contact> c) : m_book_name(std::move(n)), m_book_id(std::move(i)), m_contacts(std::move(c)) {}
78+
contact_book(name n, book_id i, std::vector<contact> c) : m_book_name(std::move(n)), m_book_id(i), m_contacts(std::move(c)) {}
7979
};
8080
} // namespace udt
8181

@@ -241,8 +241,8 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
241241
const udt::person senior_programmer{{42}, {"王芳"}, udt::country::china};
242242
const udt::address addr{"Paris"};
243243
const udt::contact cpp_programmer{sfinae_addict, addr};
244-
const udt::book_id large_id{udt::book_id(uint64_t(1) << 63)}; // verify large unsigned enums are handled correctly
245-
const udt::contact_book book{{"C++"}, {udt::book_id(42u)}, {cpp_programmer, {senior_programmer, addr}}};
244+
const udt::book_id large_id{static_cast<udt::book_id>(static_cast<std::uint64_t>(1) << 63)}; // verify large unsigned enums are handled correctly
245+
const udt::contact_book book{{"C++"}, static_cast<udt::book_id>(42u), {cpp_programmer, {senior_programmer, addr}}};
246246

247247
SECTION("conversion to json via free-functions")
248248
{
@@ -253,7 +253,7 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
253253
CHECK(json("Paris") == json(addr));
254254
CHECK(json(cpp_programmer) ==
255255
R"({"person" : {"age":23, "name":"theo", "country":"France"}, "address":"Paris"})"_json);
256-
CHECK(json(large_id) == json(uint64_t(1) << 63));
256+
CHECK(json(large_id) == json(static_cast<std::uint64_t>(1) << 63));
257257
CHECK(json(large_id) > 0u);
258258
CHECK(to_string(json(large_id)) == "9223372036854775808");
259259
CHECK(json(large_id).is_number_unsigned());
@@ -332,7 +332,7 @@ TEST_CASE("basic usage" * doctest::test_suite("udt"))
332332
CHECK(contact == cpp_programmer);
333333
CHECK(contacts == book.m_contacts);
334334
CHECK(book_name == udt::name{"C++"});
335-
CHECK(book_id == udt::book_id(42u));
335+
CHECK(book_id == static_cast<udt::book_id>(42u));
336336
CHECK(book == parsed_book);
337337
}
338338
#endif

0 commit comments

Comments
 (0)