Skip to content

Commit fb023fe

Browse files
committed
Add C++20 ranges constructor
Signed-off-by: Daniel Hwangbo <ghwangbo78@gmail.com>
1 parent cfd5a81 commit fb023fe

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

include/nlohmann/json.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,51 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
10331033
assert_invariant();
10341034
}
10351035

1036+
////////////////////////////////////////////////////////////////////////////
1037+
// PATCH START: C++20 Range Constructor (Strict Version)
1038+
////////////////////////////////////////////////////////////////////////////
1039+
1040+
/// @brief create a JSON value from a C++20 Range/View
1041+
/// @note This allows nlohmann::json j(myView) where myView has .begin()/.end()
1042+
/// @param[in] r range to read from
1043+
template <typename Range,
1044+
typename std::enable_if<
1045+
// 1. It must not be a basic_json object itself
1046+
!std::is_same<typename std::decay<Range>::type, basic_json>::value &&
1047+
1048+
// 2. It must not be a JSON reference
1049+
!detail::is_json_ref<Range>::value &&
1050+
1051+
// 3. CRITICAL FIX: It must NOT be a String.
1052+
// (Prevents ambiguity with the existing string constructor)
1053+
!std::is_constructible<StringType, typename std::decay<Range>::type>::value &&
1054+
1055+
// 4. It must NOT be a type the library already supports (like std::vector)
1056+
!detail::is_compatible_type<basic_json, typename std::decay<Range>::type>::value,
1057+
1058+
int>::type = 0,
1059+
1060+
// 5. It MUST have .begin() and .end()
1061+
typename = decltype(std::declval<Range>().begin()),
1062+
typename = decltype(std::declval<Range>().end())
1063+
>
1064+
basic_json(Range&& r)
1065+
{
1066+
// Construct an array from any range by converting each element
1067+
// to a `basic_json` and appending it. This avoids calling the
1068+
// iterator-pair constructor which only accepts internal json
1069+
// iterators and would be a mismatch for arbitrary ranges
1070+
// (for example, views from <ranges>).
1071+
m_data.m_type = value_t::array;
1072+
m_data.m_value.array = create<array_t>();
1073+
for (auto&& el : r)
1074+
{
1075+
m_data.m_value.array->emplace_back(el);
1076+
}
1077+
set_parents();
1078+
assert_invariant();
1079+
}
1080+
10361081
/// @brief construct a JSON container given an iterator range
10371082
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
10381083
template < class InputIT, typename std::enable_if <

0 commit comments

Comments
 (0)