json_view: view_mode enum instead of bool Editable, node_kind for node::kind (#5919)
* json_view: view_mode enum instead of bool Editable, node_kind for node::kind basic_json_document and basic_json_view take a view_mode (read_only, the default, or editable) instead of a bool: basic_json_document<json, true> did not say what true means. The shortcut aliases are unchanged. The kind of a node is a node_kind (the value_t values plus link, 10 as before), which removes the static_cast<std::uint8_t>(value_t::...) of every comparison. The node and image layouts are unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * json_view: node_kind in the node writers, spell out read_only, comment fixes The builder and the edit functions take and store a node_kind instead of casting a value_t; the numbering assertions and the comments now speak of node_kind, and the link kind notes that it follows value_t::discarded. The read-only aliases name view_mode::read_only like the editable ones. view_mode.md says the mode is a compile-time property of the type. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * json_view: views of read-only documents convert to editable views A read-only document has no edits, so a view of it reads correctly as a view of an editable document before its first edit. The implicit conversion lets a function taking a json_editable_view accept the views of both modes. There is no conversion the other way: a read-only view of an editable document would read wrong values after the next edit. The mode comparisons in the cross-mode operator==/!= use an is_other_mode trait, which astyle keeps compact. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
1 parent
24078c862d
commit
731f1b5bfb
38 files changed
+704
-293
No files matched your search
@@ -84,6 +84,7 @@
|
||||
#include <nlohmann/detail/view/serializer.hpp>
|
||||
#include <nlohmann/detail/view/string_ref.hpp>
|
||||
#include <nlohmann/detail/view/value.hpp>
|
||||
#include <nlohmann/detail/view/view_mode.hpp>
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
@@ -93,13 +94,16 @@ NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
Trivially copyable (two pointers). Valid as long as the document is alive and
|
||||
has not been re-parsed, and as long as a borrowed source text is alive.
|
||||
*/
|
||||
template<typename BasicJsonType, bool Editable = false>
|
||||
template<typename BasicJsonType, view_mode Mode = view_mode::read_only>
|
||||
class basic_json_view
|
||||
{
|
||||
/// whether this is a view of an editable document
|
||||
static constexpr bool is_editable = Mode == view_mode::editable;
|
||||
|
||||
using node = detail::view::node;
|
||||
using document_data = detail::view::document_data;
|
||||
/// how the index is walked (with edits only for editable documents)
|
||||
using navigation = detail::view::navigation<Editable>;
|
||||
using navigation = detail::view::navigation<is_editable>;
|
||||
|
||||
public:
|
||||
using value_t = detail::value_t;
|
||||
@@ -120,6 +124,15 @@ class basic_json_view
|
||||
/// an invalid view (type() == value_t::discarded)
|
||||
basic_json_view() noexcept = default;
|
||||
|
||||
/// a view of a read-only document as a view of an editable one, so that a
|
||||
/// function taking an editable view accepts both (a read-only document has
|
||||
/// no edits; the view reads it as an editable document before its first
|
||||
/// edit, at the cost of one check per access)
|
||||
template<view_mode M, detail::enable_if_t<detail::view::is_widening_mode<M, Mode>::value, int> = 0>
|
||||
basic_json_view(const basic_json_view<BasicJsonType, M>& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
: m_doc(other.m_doc), m_node(other.m_node)
|
||||
{}
|
||||
|
||||
//////////
|
||||
// type //
|
||||
//////////
|
||||
@@ -446,7 +459,7 @@ class basic_json_view
|
||||
if (is_structured() && m_node->len != 0)
|
||||
{
|
||||
return unedited() ? basic_json_view(m_doc, detail::view::last_child<false>(*m_doc, m_node) + (is_object() ? 1 : 0))
|
||||
: basic_json_view(m_doc, navigation::value(detail::view::last_child<Editable>(*m_doc, m_node) + (is_object() ? 1 : 0)));
|
||||
: basic_json_view(m_doc, navigation::value(detail::view::last_child<is_editable>(*m_doc, m_node) + (is_object() ? 1 : 0)));
|
||||
}
|
||||
return front();
|
||||
}
|
||||
@@ -504,7 +517,7 @@ class basic_json_view
|
||||
/// more than once); 0 if this is not an object
|
||||
size_type count(string_view_t key) const
|
||||
{
|
||||
return is_object() ? detail::view::count_members<Editable>(*m_doc, m_node, key.data(), key.size()) : 0;
|
||||
return is_object() ? detail::view::count_members<is_editable>(*m_doc, m_node, key.data(), key.size()) : 0;
|
||||
}
|
||||
|
||||
size_type count(const char* key) const
|
||||
@@ -646,7 +659,7 @@ class basic_json_view
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::view::view_serializer<BasicJsonType, Editable>(*m_doc, out, estimate, style).dump(m_node);
|
||||
detail::view::view_serializer<BasicJsonType, is_editable>(*m_doc, out, estimate, style).dump(m_node);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -682,14 +695,14 @@ class basic_json_view
|
||||
}
|
||||
|
||||
/// a view of an editable document compares with one of a read-only document
|
||||
template < bool E, typename std::enable_if < E != Editable, int >::type = 0 >
|
||||
friend bool operator==(const basic_json_view& a, const basic_json_view<BasicJsonType, E>& b)
|
||||
template<view_mode M, detail::enable_if_t<detail::view::is_other_mode<M, Mode>::value, int> = 0>
|
||||
friend bool operator==(const basic_json_view& a, const basic_json_view<BasicJsonType, M>& b)
|
||||
{
|
||||
return detail::view::equal<BasicJsonType>(side(a), detail::view::view_side<BasicJsonType, basic_json_view<BasicJsonType, E>>(b));
|
||||
return detail::view::equal<BasicJsonType>(side(a), detail::view::view_side<BasicJsonType, basic_json_view<BasicJsonType, M>>(b));
|
||||
}
|
||||
|
||||
template < bool E, typename std::enable_if < E != Editable, int >::type = 0 >
|
||||
friend bool operator!=(const basic_json_view& a, const basic_json_view<BasicJsonType, E>& b)
|
||||
template<view_mode M, detail::enable_if_t<detail::view::is_other_mode<M, Mode>::value, int> = 0>
|
||||
friend bool operator!=(const basic_json_view& a, const basic_json_view<BasicJsonType, M>& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
@@ -727,7 +740,7 @@ class basic_json_view
|
||||
{
|
||||
return BasicJsonType(value_t::discarded);
|
||||
}
|
||||
return unedited() ? detail::view::materialize<BasicJsonType, false>(*m_doc, m_node) : detail::view::materialize<BasicJsonType, Editable>(*m_doc, m_node);
|
||||
return unedited() ? detail::view::materialize<BasicJsonType, false>(*m_doc, m_node) : detail::view::materialize<BasicJsonType, is_editable>(*m_doc, m_node);
|
||||
}
|
||||
|
||||
/// byte offset of this value in the source text (for strings: of the
|
||||
@@ -740,8 +753,8 @@ class basic_json_view
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename, bool> friend class basic_json_document;
|
||||
template<typename, bool> friend class basic_json_view;
|
||||
template<typename, view_mode> friend class basic_json_document;
|
||||
template<typename, view_mode> friend class basic_json_view;
|
||||
template<typename, typename> friend class detail::view::editor;
|
||||
friend iterator;
|
||||
|
||||
@@ -757,11 +770,11 @@ class basic_json_view
|
||||
}
|
||||
|
||||
/// the template argument as a runtime condition: testing it directly in
|
||||
/// `Editable && ...` makes the condition constant, which MSVC reports as
|
||||
/// `is_editable && ...` makes the condition constant, which MSVC reports as
|
||||
/// C4127
|
||||
static bool editable() noexcept
|
||||
{
|
||||
return Editable;
|
||||
return is_editable;
|
||||
}
|
||||
|
||||
/// the number of source bytes of this value (estimated for values with
|
||||
@@ -810,7 +823,7 @@ class basic_json_view
|
||||
const node* const k = detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size());
|
||||
return k != nullptr ? basic_json_view(m_doc, k + 1) : basic_json_view();
|
||||
}
|
||||
const node* const k = detail::view::find_member<Editable>(*m_doc, m_node, key.data(), key.size());
|
||||
const node* const k = detail::view::find_member<is_editable>(*m_doc, m_node, key.data(), key.size());
|
||||
return k != nullptr ? basic_json_view(m_doc, navigation::value(k + 1)) : basic_json_view();
|
||||
}
|
||||
|
||||
@@ -824,7 +837,7 @@ class basic_json_view
|
||||
/// the member of this object with @a key (the last one if the key occurs more than once), or nullptr
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key) const
|
||||
{
|
||||
return find_key(key, std::integral_constant<bool, Editable> {});
|
||||
return find_key(key, std::integral_constant<bool, is_editable> {});
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key, std::true_type /*editable*/) const
|
||||
@@ -846,7 +859,7 @@ class basic_json_view
|
||||
{
|
||||
return basic_json_view(m_doc, detail::view::element_at<false>(*m_doc, m_node, idx));
|
||||
}
|
||||
return basic_json_view(m_doc, navigation::value(detail::view::element_at<Editable>(*m_doc, m_node, idx)));
|
||||
return basic_json_view(m_doc, navigation::value(detail::view::element_at<is_editable>(*m_doc, m_node, idx)));
|
||||
}
|
||||
|
||||
// --- get() dispatch ---
|
||||
@@ -952,16 +965,19 @@ Borrowed parses keep a pointer to the caller's text, which must outlive the
|
||||
document. Owned parses (parse_copy, rvalue std::string, streams, and inputs
|
||||
that are not contiguous byte ranges) keep their own copy.
|
||||
*/
|
||||
template<typename BasicJsonType, bool Editable = false>
|
||||
template<typename BasicJsonType, view_mode Mode = view_mode::read_only>
|
||||
class basic_json_document
|
||||
{
|
||||
/// whether the document can be edited
|
||||
static constexpr bool is_editable = Mode == view_mode::editable;
|
||||
|
||||
using document_data = detail::view::document_data;
|
||||
|
||||
static_assert(sizeof(typename BasicJsonType::number_integer_t) == 8 && sizeof(typename BasicJsonType::number_unsigned_t) == 8,
|
||||
"json_view supports 64-bit integer types only");
|
||||
|
||||
public:
|
||||
using view_type = basic_json_view<BasicJsonType, Editable>;
|
||||
using view_type = basic_json_view<BasicJsonType, Mode>;
|
||||
using value_t = detail::value_t;
|
||||
|
||||
/// an empty (discarded) document
|
||||
@@ -1357,7 +1373,7 @@ class basic_json_document
|
||||
|
||||
detail::view::editor<BasicJsonType, view_type> editor()
|
||||
{
|
||||
static_assert(Editable, "only an editable document can be edited: use basic_json_document<BasicJsonType, true> (json_editable_document)");
|
||||
static_assert(is_editable, "only an editable document can be edited: use basic_json_document<BasicJsonType, view_mode::editable> (json_editable_document)");
|
||||
if (NLOHMANN_VIEW_UNLIKELY(!m_data || m_data->discarded))
|
||||
{
|
||||
detail::view::throw_invalid_iterator(detail::exception_id::iterator_from_other_value, "view does not belong to this document");
|
||||
@@ -1634,21 +1650,21 @@ class basic_json_document
|
||||
};
|
||||
|
||||
/// a parsed JSON text for json
|
||||
using json_document = basic_json_document<json>;
|
||||
using json_document = basic_json_document<json, view_mode::read_only>;
|
||||
/// a value of a json_document
|
||||
using json_view = basic_json_view<json>;
|
||||
using json_view = basic_json_view<json, view_mode::read_only>;
|
||||
/// a parsed JSON text for ordered_json
|
||||
using ordered_json_document = basic_json_document<ordered_json>;
|
||||
using ordered_json_document = basic_json_document<ordered_json, view_mode::read_only>;
|
||||
/// a value of an ordered_json_document
|
||||
using ordered_json_view = basic_json_view<ordered_json>;
|
||||
using ordered_json_view = basic_json_view<ordered_json, view_mode::read_only>;
|
||||
/// an editable parsed JSON text for json
|
||||
using json_editable_document = basic_json_document<json, true>;
|
||||
using json_editable_document = basic_json_document<json, view_mode::editable>;
|
||||
/// a value of a json_editable_document
|
||||
using json_editable_view = basic_json_view<json, true>;
|
||||
using json_editable_view = basic_json_view<json, view_mode::editable>;
|
||||
/// an editable parsed JSON text for ordered_json
|
||||
using ordered_json_editable_document = basic_json_document<ordered_json, true>;
|
||||
using ordered_json_editable_document = basic_json_document<ordered_json, view_mode::editable>;
|
||||
/// a value of an ordered_json_editable_document
|
||||
using ordered_json_editable_view = basic_json_view<ordered_json, true>;
|
||||
using ordered_json_editable_view = basic_json_view<ordered_json, view_mode::editable>;
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
|
||||
Reference in new issue
Block a user