From 1d055261b4144dbf86b2658437015b15d4dd9bff Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 4 Sep 2022 00:32:56 +0100 Subject: initial --- include/jsoncons/json_array.hpp | 324 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 include/jsoncons/json_array.hpp (limited to 'include/jsoncons/json_array.hpp') diff --git a/include/jsoncons/json_array.hpp b/include/jsoncons/json_array.hpp new file mode 100644 index 0000000..5877f4d --- /dev/null +++ b/include/jsoncons/json_array.hpp @@ -0,0 +1,324 @@ +// Copyright 2013 Daniel Parker +// Distributed under the Boost license, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See https://github.com/danielaparker/jsoncons for latest version + +#ifndef JSONCONS_JSON_ARRAY_HPP +#define JSONCONS_JSON_ARRAY_HPP + +#include +#include +#include +#include +#include // std::sort, std::stable_sort, std::lower_bound, std::unique +#include +#include +#include // std::iterator_traits +#include // std::allocator +#include // std::move +#include // assert +#include // std::enable_if +#include +#include + +namespace jsoncons { + + // json_array + + template class SequenceContainer = std::vector> + class json_array : public allocator_holder + { + public: + using allocator_type = typename Json::allocator_type; + using value_type = Json; + private: + using value_allocator_type = typename std::allocator_traits:: template rebind_alloc; + using value_container_type = SequenceContainer; + value_container_type elements_; + public: + using iterator = typename value_container_type::iterator; + using const_iterator = typename value_container_type::const_iterator; + using reference = typename std::iterator_traits::reference; + using const_reference = typename std::iterator_traits::reference; + + using allocator_holder::get_allocator; + + json_array() + { + } + + explicit json_array(const allocator_type& alloc) + : allocator_holder(alloc), + elements_(value_allocator_type(alloc)) + { + } + + explicit json_array(std::size_t n, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(n,Json(),value_allocator_type(alloc)) + { + } + + explicit json_array(std::size_t n, + const Json& value, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(n,value,value_allocator_type(alloc)) + { + } + + template + json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(begin,end,value_allocator_type(alloc)) + { + } + json_array(const json_array& val) + : allocator_holder(val.get_allocator()), + elements_(val.elements_) + { + } + json_array(const json_array& val, const allocator_type& alloc) + : allocator_holder(alloc), + elements_(val.elements_,value_allocator_type(alloc)) + { + } + + json_array(json_array&& val) noexcept + : allocator_holder(val.get_allocator()), + elements_(std::move(val.elements_)) + { + } + json_array(json_array&& val, const allocator_type& alloc) + : allocator_holder(alloc), + elements_(std::move(val.elements_),value_allocator_type(alloc)) + { + } + + json_array(const std::initializer_list& init, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(init,value_allocator_type(alloc)) + { + } + ~json_array() noexcept + { + flatten_and_destroy(); + } + + reference back() + { + return elements_.back(); + } + + const_reference back() const + { + return elements_.back(); + } + + void pop_back() + { + elements_.pop_back(); + } + + bool empty() const + { + return elements_.empty(); + } + + void swap(json_array& val) noexcept + { + elements_.swap(val.elements_); + } + + std::size_t size() const {return elements_.size();} + + std::size_t capacity() const {return elements_.capacity();} + + void clear() {elements_.clear();} + + void shrink_to_fit() + { + for (std::size_t i = 0; i < elements_.size(); ++i) + { + elements_[i].shrink_to_fit(); + } + elements_.shrink_to_fit(); + } + + void reserve(std::size_t n) {elements_.reserve(n);} + + void resize(std::size_t n) {elements_.resize(n);} + + void resize(std::size_t n, const Json& val) {elements_.resize(n,val);} + + #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED_MSG("Instead, use erase(const_iterator, const_iterator)") + void remove_range(std::size_t from_index, std::size_t to_index) + { + JSONCONS_ASSERT(from_index <= to_index); + JSONCONS_ASSERT(to_index <= elements_.size()); + elements_.erase(elements_.cbegin()+from_index,elements_.cbegin()+to_index); + } + #endif + + iterator erase(const_iterator pos) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.erase(it); + #else + return elements_.erase(pos); + #endif + } + + iterator erase(const_iterator first, const_iterator last) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it1 = elements_.begin() + (first - elements_.begin()); + iterator it2 = elements_.begin() + (last - elements_.begin()); + return elements_.erase(it1,it2); + #else + return elements_.erase(first,last); + #endif + } + + Json& operator[](std::size_t i) {return elements_[i];} + + const Json& operator[](std::size_t i) const {return elements_[i];} + + // push_back + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value)); + } + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value),get_allocator()); + } + + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value)); + #else + return elements_.emplace(pos, std::forward(value)); + #endif + } + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value), get_allocator()); + #else + return elements_.emplace(pos, std::forward(value), get_allocator()); + #endif + } + + template + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + elements_.insert(it, first, last); + return first == last ? it : it + 1; + #else + return elements_.insert(pos, first, last); + #endif + } + + template + typename std::enable_if::value,iterator>::type + emplace(const_iterator pos, Args&&... args) + { + #if defined(JSONCONS_NO_VECTOR_ERASE_TAKES_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(args)...); + #else + return elements_.emplace(pos, std::forward(args)...); + #endif + } + + template + Json& emplace_back(Args&&... args) + { + elements_.emplace_back(std::forward(args)...); + return elements_.back(); + } + + iterator begin() {return elements_.begin();} + + iterator end() {return elements_.end();} + + const_iterator begin() const {return elements_.begin();} + + const_iterator end() const {return elements_.end();} + + bool operator==(const json_array& rhs) const noexcept + { + return elements_ == rhs.elements_; + } + + bool operator<(const json_array& rhs) const noexcept + { + return elements_ < rhs.elements_; + } + private: + + json_array& operator=(const json_array&) = delete; + + void flatten_and_destroy() noexcept + { + while (!elements_.empty()) + { + value_type current = std::move(elements_.back()); + elements_.pop_back(); + switch (current.storage_kind()) + { + case json_storage_kind::array_value: + { + for (auto&& item : current.array_range()) + { + if (item.size() > 0) // non-empty object or array + { + elements_.push_back(std::move(item)); + } + } + current.clear(); + break; + } + case json_storage_kind::object_value: + { + for (auto&& kv : current.object_range()) + { + if (kv.value().size() > 0) // non-empty object or array + { + elements_.push_back(std::move(kv.value())); + } + } + current.clear(); + break; + } + default: + break; + } + } + } + }; + +} // namespace jsoncons + +#endif -- cgit v1.2.3