18 using internal =
typename std::vector<PointerT>;
24 this->walk(document, accumulator);
27 using const_iterator =
typename internal::const_iterator;
28 [[nodiscard]]
auto begin() const -> const_iterator {
29 return this->pointers.begin();
31 [[nodiscard]]
auto end() const -> const_iterator {
32 return this->pointers.end();
34 [[nodiscard]]
auto cbegin() const -> const_iterator {
35 return this->pointers.cbegin();
37 [[nodiscard]]
auto cend() const -> const_iterator {
38 return this->pointers.cend();
42 auto walk(
const JSON &document, PointerT &pointer) ->
void {
46 std::vector<std::pair<const JSON *, PointerT>> pending;
47 pending.emplace_back(&document, pointer);
48 while (!pending.empty()) {
49 auto entry{std::move(pending.back())};
51 const JSON &node{*entry.first};
54 const auto start{pending.size()};
55 if (node.is_array()) {
56 for (std::size_t index = 0; index < node.size(); index++) {
57 PointerT child{entry.second};
58 child.emplace_back(index);
59 pending.emplace_back(&node.at(index), std::move(child));
61 }
else if (node.is_object()) {
62 for (
const auto &pair : node.as_object()) {
63 PointerT child{entry.second};
64 child.emplace_back(pair.first);
65 pending.emplace_back(&pair.second, std::move(child));
69 std::reverse(pending.begin() +
static_cast<std::ptrdiff_t
>(start),
71 this->pointers.push_back(std::move(entry.second));
79#pragma warning(disable : 4251)
83#pragma warning(default : 4251)