diff --git a/include/valijson/adapters/nlohmann_json_adapter.hpp b/include/valijson/adapters/nlohmann_json_adapter.hpp index 87c2705..aef9251 100644 --- a/include/valijson/adapters/nlohmann_json_adapter.hpp +++ b/include/valijson/adapters/nlohmann_json_adapter.hpp @@ -38,11 +38,194 @@ namespace valijson { namespace adapters { class NlohmannJsonAdapter; -class NlohmannJsonArrayValueIterator; -class NlohmannJsonObjectMemberIterator; typedef std::pair NlohmannJsonObjectMember; +/** + * @brief Class for iterating over values held in a JSON array. + * + * This class provides a JSON array iterator that dereferences as an instance of + * NlohmannJsonAdapter representing a value stored in the array. It has been + * implemented using the boost iterator_facade template. + * + * @see NlohmannJsonArray + */ +template +class NlohmannJsonArrayValueIterator +{ + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = ValueType; + using difference_type = ValueType; + using pointer = ValueType *; + using reference = ValueType &; + + /** + * @brief Construct a new NlohmannJsonArrayValueIterator using an existing + * NlohmannJson iterator. + * + * @param itr NlohmannJson iterator to store + */ + NlohmannJsonArrayValueIterator(const nlohmann::json::const_iterator &itr) + : m_itr(itr) + { + } + + /// Returns a NlohmannJsonAdapter that contains the value of the current + /// element. + ValueType operator*() const + { + return ValueType(*m_itr); + } + + DerefProxy operator->() const + { + return DerefProxy(**this); + } + + /** + * @brief Compare this iterator against another iterator. + * + * Note that this directly compares the iterators, not the underlying + * values, and assumes that two identical iterators will point to the same + * underlying object. + * + * @param other iterator to compare against + * + * @returns true if the iterators are equal, false otherwise. + */ + bool operator==(const NlohmannJsonArrayValueIterator &other) const + { + return m_itr == other.m_itr; + } + + bool operator!=(const NlohmannJsonArrayValueIterator &other) const + { + return !(m_itr == other.m_itr); + } + + const NlohmannJsonArrayValueIterator &operator++() + { + m_itr++; + + return *this; + } + + NlohmannJsonArrayValueIterator operator++(int) + { + NlohmannJsonArrayValueIterator iterator_pre(m_itr); + ++(*this); + return iterator_pre; + } + + const NlohmannJsonArrayValueIterator &operator--() + { + m_itr--; + + return *this; + } + + void advance(std::ptrdiff_t n) + { + m_itr += n; + } + + private: + nlohmann::json::const_iterator m_itr; +}; + + +/** + * @brief Class for iterating over the members belonging to a JSON object. + * + * This class provides a JSON object iterator that dereferences as an instance + * of NlohmannJsonObjectMember representing one of the members of the object. It + * has been implemented using the boost iterator_facade template. + * + * @see NlohmannJsonObject + * @see NlohmannJsonObjectMember + */ +template class NlohmannJsonObjectMemberIterator +{ + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = ValueType; + using difference_type = ValueType; + using pointer = ValueType *; + using reference = ValueType &; + + /** + * @brief Construct an iterator from a NlohmannJson iterator. + * + * @param itr NlohmannJson iterator to store + */ + NlohmannJsonObjectMemberIterator(const nlohmann::json::const_iterator &itr) + : m_itr(itr) + { + } + + /** + * @brief Returns a NlohmannJsonObjectMember that contains the key and + * value belonging to the object member identified by the iterator. + */ + ValueType operator*() const + { + return ValueType(m_itr.key(), m_itr.value()); + } + + DerefProxy operator->() const + { + return DerefProxy(**this); + } + + /** + * @brief Compare this iterator with another iterator. + * + * Note that this directly compares the iterators, not the underlying + * values, and assumes that two identical iterators will point to the same + * underlying object. + * + * @param other Iterator to compare with + * + * @returns true if the underlying iterators are equal, false otherwise + */ + bool operator==(const NlohmannJsonObjectMemberIterator &other) const + { + return m_itr == other.m_itr; + } + + bool operator!=(const NlohmannJsonObjectMemberIterator &other) const + { + return !(m_itr == other.m_itr); + } + + const NlohmannJsonObjectMemberIterator &operator++() + { + m_itr++; + + return *this; + } + + NlohmannJsonObjectMemberIterator operator++(int) + { + NlohmannJsonObjectMemberIterator iterator_pre(m_itr); + ++(*this); + return iterator_pre; + } + + const NlohmannJsonObjectMemberIterator &operator--() + { + m_itr--; + + return *this; + } + + private: + /// Iternal copy of the original NlohmannJson iterator + nlohmann::json::const_iterator m_itr; +}; + + /** * @brief Light weight wrapper for a NlohmannJson array value. * @@ -54,12 +237,13 @@ typedef std::pair NlohmannJsonObjectMember; * NlohmannJson value, assumed to be an array, so there is very little overhead * associated with copy construction and passing by value. */ +template class NlohmannJsonArray { public: - typedef NlohmannJsonArrayValueIterator const_iterator; - typedef NlohmannJsonArrayValueIterator iterator; + typedef NlohmannJsonArrayValueIterator const_iterator; + typedef NlohmannJsonArrayValueIterator iterator; /// Construct a NlohmannJsonArray referencing an empty array. NlohmannJsonArray() @@ -88,7 +272,10 @@ public: * The iterator return by this function is effectively the iterator * returned by the underlying NlohmannJson implementation. */ - NlohmannJsonArrayValueIterator begin() const; + NlohmannJsonArrayValueIterator begin() const { + return m_value.begin(); + } + /** * @brief Return an iterator for one-past the last element of the array. @@ -96,7 +283,9 @@ public: * The iterator return by this function is effectively the iterator * returned by the underlying NlohmannJson implementation. */ - NlohmannJsonArrayValueIterator end() const; + NlohmannJsonArrayValueIterator end() const { + return m_value.end(); + } /// Return the number of elements in the array size_t size() const @@ -136,8 +325,8 @@ class NlohmannJsonObject { public: - typedef NlohmannJsonObjectMemberIterator const_iterator; - typedef NlohmannJsonObjectMemberIterator iterator; + typedef NlohmannJsonObjectMemberIterator const_iterator; + typedef NlohmannJsonObjectMemberIterator iterator; /// Construct a NlohmannJsonObject referencing an empty object singleton. NlohmannJsonObject() @@ -166,7 +355,7 @@ public: * The iterator return by this function is effectively a wrapper around * the iterator value returned by the underlying NlohmannJson implementation. */ - NlohmannJsonObjectMemberIterator begin() const; + NlohmannJsonObjectMemberIterator begin() const; /** * @brief Return an iterator for an invalid object member that indicates @@ -175,7 +364,7 @@ public: * The iterator return by this function is effectively a wrapper around * the iterator value returned by the underlying NlohmannJson implementation. */ - NlohmannJsonObjectMemberIterator end() const; + NlohmannJsonObjectMemberIterator end() const; /** * @brief Return an iterator for the object member with the specified @@ -186,7 +375,8 @@ public: * * @param propertyName property name to search for */ - NlohmannJsonObjectMemberIterator find(const std::string &propertyName) const; + NlohmannJsonObjectMemberIterator + find(const std::string &propertyName) const; /// Returns the number of members belonging to this object. size_t size() const @@ -261,6 +451,7 @@ private: * * @see BasicAdapter */ +template class NlohmannJsonValue { public: @@ -294,10 +485,10 @@ public: * * Otherwise it will return an empty optional. */ - opt::optional getArrayOptional() const + opt::optional> getArrayOptional() const { if (m_value.is_array()) { - return opt::make_optional(NlohmannJsonArray(m_value)); + return opt::make_optional(NlohmannJsonArray(m_value)); } return {}; @@ -362,14 +553,7 @@ public: * * Otherwise it will return an empty optional. */ - opt::optional getObjectOptional() const - { - if (m_value.is_object()) { - return opt::make_optional(NlohmannJsonObject(m_value)); - } - - return {}; - } + opt::optional getObjectOptional() const; /** * @brief Retrieve the number of members in the object @@ -469,202 +653,35 @@ private: * @see Adapter * @see BasicAdapter */ -class NlohmannJsonAdapter: - public BasicAdapter +class NlohmannJsonAdapter + : public BasicAdapter, + NlohmannJsonObjectMember, NlohmannJsonObject, + NlohmannJsonValue> { public: /// Construct a NlohmannJsonAdapter that contains an empty object NlohmannJsonAdapter() : BasicAdapter() { } - /// Construct a NlohmannJsonAdapter containing a specific Nlohmann Json object + /// Construct a NlohmannJsonAdapter containing a specific Nlohmann Json + /// object NlohmannJsonAdapter(const nlohmann::json &value) - : BasicAdapter(NlohmannJsonValue{value}) { } + : BasicAdapter(NlohmannJsonValue{value}) + { + } }; -/** - * @brief Class for iterating over values held in a JSON array. - * - * This class provides a JSON array iterator that dereferences as an instance of - * NlohmannJsonAdapter representing a value stored in the array. It has been - * implemented using the boost iterator_facade template. - * - * @see NlohmannJsonArray - */ -class NlohmannJsonArrayValueIterator +template +opt::optional +NlohmannJsonValue::getObjectOptional() const { -public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = NlohmannJsonAdapter; - using difference_type = NlohmannJsonAdapter; - using pointer = NlohmannJsonAdapter*; - using reference = NlohmannJsonAdapter&; - - /** - * @brief Construct a new NlohmannJsonArrayValueIterator using an existing - * NlohmannJson iterator. - * - * @param itr NlohmannJson iterator to store - */ - NlohmannJsonArrayValueIterator(const nlohmann::json::const_iterator &itr) - : m_itr(itr) { } - - /// Returns a NlohmannJsonAdapter that contains the value of the current - /// element. - NlohmannJsonAdapter operator*() const - { - return NlohmannJsonAdapter(*m_itr); + if (m_value.is_object()) { + return opt::make_optional(NlohmannJsonObject(m_value)); } - DerefProxy operator->() const - { - return DerefProxy(**this); - } - - /** - * @brief Compare this iterator against another iterator. - * - * Note that this directly compares the iterators, not the underlying - * values, and assumes that two identical iterators will point to the same - * underlying object. - * - * @param other iterator to compare against - * - * @returns true if the iterators are equal, false otherwise. - */ - bool operator==(const NlohmannJsonArrayValueIterator &other) const - { - return m_itr == other.m_itr; - } - - bool operator!=(const NlohmannJsonArrayValueIterator &other) const - { - return !(m_itr == other.m_itr); - } - - const NlohmannJsonArrayValueIterator& operator++() - { - m_itr++; - - return *this; - } - - NlohmannJsonArrayValueIterator operator++(int) - { - NlohmannJsonArrayValueIterator iterator_pre(m_itr); - ++(*this); - return iterator_pre; - } - - const NlohmannJsonArrayValueIterator& operator--() - { - m_itr--; - - return *this; - } - - void advance(std::ptrdiff_t n) - { - m_itr += n; - } - -private: - nlohmann::json::const_iterator m_itr; -}; - - -/** - * @brief Class for iterating over the members belonging to a JSON object. - * - * This class provides a JSON object iterator that dereferences as an instance - * of NlohmannJsonObjectMember representing one of the members of the object. It - * has been implemented using the boost iterator_facade template. - * - * @see NlohmannJsonObject - * @see NlohmannJsonObjectMember - */ -class NlohmannJsonObjectMemberIterator -{ -public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = NlohmannJsonObjectMember; - using difference_type = NlohmannJsonObjectMember; - using pointer = NlohmannJsonObjectMember*; - using reference = NlohmannJsonObjectMember&; - - /** - * @brief Construct an iterator from a NlohmannJson iterator. - * - * @param itr NlohmannJson iterator to store - */ - NlohmannJsonObjectMemberIterator(const nlohmann::json::const_iterator &itr) - : m_itr(itr) { } - - /** - * @brief Returns a NlohmannJsonObjectMember that contains the key and value - * belonging to the object member identified by the iterator. - */ - NlohmannJsonObjectMember operator*() const - { - return NlohmannJsonObjectMember(m_itr.key(), m_itr.value()); - } - - DerefProxy operator->() const - { - return DerefProxy(**this); - } - - /** - * @brief Compare this iterator with another iterator. - * - * Note that this directly compares the iterators, not the underlying - * values, and assumes that two identical iterators will point to the same - * underlying object. - * - * @param other Iterator to compare with - * - * @returns true if the underlying iterators are equal, false otherwise - */ - bool operator==(const NlohmannJsonObjectMemberIterator &other) const - { - return m_itr == other.m_itr; - } - - bool operator!=(const NlohmannJsonObjectMemberIterator &other) const - { - return !(m_itr == other.m_itr); - } - - const NlohmannJsonObjectMemberIterator& operator++() - { - m_itr++; - - return *this; - } - - NlohmannJsonObjectMemberIterator operator++(int) - { - NlohmannJsonObjectMemberIterator iterator_pre(m_itr); - ++(*this); - return iterator_pre; - } - - const NlohmannJsonObjectMemberIterator& operator--() - { - m_itr--; - - return *this; - } - -private: - - /// Iternal copy of the original NlohmannJson iterator - nlohmann::json::const_iterator m_itr; -}; + return {}; +} /// Specialisation of the AdapterTraits template struct for NlohmannJsonAdapter. template<> @@ -683,27 +700,21 @@ inline bool NlohmannJsonFrozenValue::equalTo(const Adapter &other, bool strict) return NlohmannJsonAdapter(m_value).equalTo(other, strict); } -inline NlohmannJsonArrayValueIterator NlohmannJsonArray::begin() const + +inline NlohmannJsonObjectMemberIterator +NlohmannJsonObject::begin() const { return m_value.begin(); } -inline NlohmannJsonArrayValueIterator NlohmannJsonArray::end() const +inline NlohmannJsonObjectMemberIterator +NlohmannJsonObject::end() const { return m_value.end(); } -inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::begin() const -{ - return m_value.begin(); -} - -inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::end() const -{ - return m_value.end(); -} - -inline NlohmannJsonObjectMemberIterator NlohmannJsonObject::find( +inline NlohmannJsonObjectMemberIterator +NlohmannJsonObject::find( const std::string &propertyName) const { return m_value.find(propertyName);