fix cmake install directory (for real this time)
* Rename 'develop' folder to 'include/nlohmann' * Rename 'src' folder to 'single_include/nlohmann' * Use <nlohmann/*> headers in sources and tests * Change amalgamate config file
This commit is contained in:
		
							parent
							
								
									9958dde3da
								
							
						
					
					
						commit
						14cd019861
					
				
					 73 changed files with 226 additions and 224 deletions
				
			
		
							
								
								
									
										25
									
								
								include/nlohmann/detail/iterators/internal_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								include/nlohmann/detail/iterators/internal_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <nlohmann/detail/iterators/primitive_iterator.hpp> | ||||
| 
 | ||||
| namespace nlohmann | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
| /*!
 | ||||
| @brief an iterator value | ||||
| 
 | ||||
| @note This structure could easily be a union, but MSVC currently does not allow | ||||
| unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
 | ||||
| */ | ||||
| template<typename BasicJsonType> struct internal_iterator | ||||
| { | ||||
|     /// iterator for JSON objects
 | ||||
|     typename BasicJsonType::object_t::iterator object_iterator {}; | ||||
|     /// iterator for JSON arrays
 | ||||
|     typename BasicJsonType::array_t::iterator array_iterator {}; | ||||
|     /// generic iterator for all other types
 | ||||
|     primitive_iterator_t primitive_iterator {}; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										614
									
								
								include/nlohmann/detail/iterators/iter_impl.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										614
									
								
								include/nlohmann/detail/iterators/iter_impl.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,614 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <ciso646> // not
 | ||||
| #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
 | ||||
| #include <type_traits> // conditional, is_const, remove_const
 | ||||
| 
 | ||||
| #include <nlohmann/detail/exceptions.hpp> | ||||
| #include <nlohmann/detail/iterators/internal_iterator.hpp> | ||||
| #include <nlohmann/detail/iterators/primitive_iterator.hpp> | ||||
| #include <nlohmann/detail/macro_scope.hpp> | ||||
| #include <nlohmann/detail/meta.hpp> | ||||
| #include <nlohmann/detail/value_t.hpp> | ||||
| 
 | ||||
| namespace nlohmann | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
| // forward declare, to be able to friend it later on
 | ||||
| template<typename IteratorType> class iteration_proxy; | ||||
| 
 | ||||
| /*!
 | ||||
| @brief a template for a bidirectional iterator for the @ref basic_json class | ||||
| 
 | ||||
| This class implements a both iterators (iterator and const_iterator) for the | ||||
| @ref basic_json class. | ||||
| 
 | ||||
| @note An iterator is called *initialized* when a pointer to a JSON value has | ||||
|       been set (e.g., by a constructor or a copy assignment). If the iterator is | ||||
|       default-constructed, it is *uninitialized* and most methods are undefined. | ||||
|       **The library uses assertions to detect calls on uninitialized iterators.** | ||||
| 
 | ||||
| @requirement The class satisfies the following concept requirements: | ||||
| - | ||||
| [BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
 | ||||
|   The iterator that can be moved can be moved in both directions (i.e. | ||||
|   incremented and decremented). | ||||
| 
 | ||||
| @since version 1.0.0, simplified in version 2.0.9, change to bidirectional | ||||
|        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
 | ||||
| */ | ||||
| template<typename BasicJsonType> | ||||
| class iter_impl | ||||
| { | ||||
|     /// allow basic_json to access private members
 | ||||
|     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>; | ||||
|     friend BasicJsonType; | ||||
|     friend iteration_proxy<iter_impl>; | ||||
| 
 | ||||
|     using object_t = typename BasicJsonType::object_t; | ||||
|     using array_t = typename BasicJsonType::array_t; | ||||
|     // make sure BasicJsonType is basic_json or const basic_json
 | ||||
|     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value, | ||||
|                   "iter_impl only accepts (const) basic_json"); | ||||
| 
 | ||||
|   public: | ||||
| 
 | ||||
|     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
 | ||||
|     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
 | ||||
|     /// A user-defined iterator should provide publicly accessible typedefs named
 | ||||
|     /// iterator_category, value_type, difference_type, pointer, and reference.
 | ||||
|     /// Note that value_type is required to be non-const, even for constant iterators.
 | ||||
|     using iterator_category = std::bidirectional_iterator_tag; | ||||
| 
 | ||||
|     /// the type of the values when the iterator is dereferenced
 | ||||
|     using value_type = typename BasicJsonType::value_type; | ||||
|     /// a type to represent differences between iterators
 | ||||
|     using difference_type = typename BasicJsonType::difference_type; | ||||
|     /// defines a pointer to the type iterated over (value_type)
 | ||||
|     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value, | ||||
|           typename BasicJsonType::const_pointer, | ||||
|           typename BasicJsonType::pointer>::type; | ||||
|     /// defines a reference to the type iterated over (value_type)
 | ||||
|     using reference = | ||||
|         typename std::conditional<std::is_const<BasicJsonType>::value, | ||||
|         typename BasicJsonType::const_reference, | ||||
|         typename BasicJsonType::reference>::type; | ||||
| 
 | ||||
|     /// default constructor
 | ||||
|     iter_impl() = default; | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief constructor for a given JSON instance | ||||
|     @param[in] object  pointer to a JSON object for this iterator | ||||
|     @pre object != nullptr | ||||
|     @post The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     explicit iter_impl(pointer object) noexcept : m_object(object) | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 m_it.object_iterator = typename object_t::iterator(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 m_it.array_iterator = typename array_t::iterator(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 m_it.primitive_iterator = primitive_iterator_t(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @note The conventional copy constructor and copy assignment are implicitly | ||||
|           defined. Combined with the following converting constructor and | ||||
|           assignment, they support: (1) copy from iterator to iterator, (2) | ||||
|           copy from const iterator to const iterator, and (3) conversion from | ||||
|           iterator to const iterator. However conversion from const iterator | ||||
|           to iterator is not defined. | ||||
|     */ | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief converting constructor | ||||
|     @param[in] other  non-const iterator to copy from | ||||
|     @note It is not checked whether @a other is initialized. | ||||
|     */ | ||||
|     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept | ||||
|         : m_object(other.m_object), m_it(other.m_it) {} | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief converting assignment | ||||
|     @param[in,out] other  non-const iterator to copy from | ||||
|     @return const/non-const iterator | ||||
|     @note It is not checked whether @a other is initialized. | ||||
|     */ | ||||
|     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept | ||||
|     { | ||||
|         m_object = other.m_object; | ||||
|         m_it = other.m_it; | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     /*!
 | ||||
|     @brief set the iterator to the first value | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     void set_begin() noexcept | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 m_it.object_iterator = m_object->m_value.object->begin(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 m_it.array_iterator = m_object->m_value.array->begin(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::null: | ||||
|             { | ||||
|                 // set to end so begin()==end() is true: null is empty
 | ||||
|                 m_it.primitive_iterator.set_end(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 m_it.primitive_iterator.set_begin(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief set the iterator past the last value | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     void set_end() noexcept | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 m_it.object_iterator = m_object->m_value.object->end(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 m_it.array_iterator = m_object->m_value.array->end(); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 m_it.primitive_iterator.set_end(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   public: | ||||
|     /*!
 | ||||
|     @brief return a reference to the value pointed to by the iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     reference operator*() const | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 assert(m_it.object_iterator != m_object->m_value.object->end()); | ||||
|                 return m_it.object_iterator->second; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 assert(m_it.array_iterator != m_object->m_value.array->end()); | ||||
|                 return *m_it.array_iterator; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::null: | ||||
|                 JSON_THROW(invalid_iterator::create(214, "cannot get value")); | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) | ||||
|                 { | ||||
|                     return *m_object; | ||||
|                 } | ||||
| 
 | ||||
|                 JSON_THROW(invalid_iterator::create(214, "cannot get value")); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief dereference the iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     pointer operator->() const | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 assert(m_it.object_iterator != m_object->m_value.object->end()); | ||||
|                 return &(m_it.object_iterator->second); | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 assert(m_it.array_iterator != m_object->m_value.array->end()); | ||||
|                 return &*m_it.array_iterator; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) | ||||
|                 { | ||||
|                     return m_object; | ||||
|                 } | ||||
| 
 | ||||
|                 JSON_THROW(invalid_iterator::create(214, "cannot get value")); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief post-increment (it++) | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl const operator++(int) | ||||
|     { | ||||
|         auto result = *this; | ||||
|         ++(*this); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief pre-increment (++it) | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl& operator++() | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 std::advance(m_it.object_iterator, 1); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 std::advance(m_it.array_iterator, 1); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 ++m_it.primitive_iterator; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief post-decrement (it--) | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl const operator--(int) | ||||
|     { | ||||
|         auto result = *this; | ||||
|         --(*this); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief pre-decrement (--it) | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl& operator--() | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|             { | ||||
|                 std::advance(m_it.object_iterator, -1); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 std::advance(m_it.array_iterator, -1); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 --m_it.primitive_iterator; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: equal | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator==(const iter_impl& other) const | ||||
|     { | ||||
|         // if objects are not the same, the comparison is undefined
 | ||||
|         if (JSON_UNLIKELY(m_object != other.m_object)) | ||||
|         { | ||||
|             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); | ||||
|         } | ||||
| 
 | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|                 return (m_it.object_iterator == other.m_it.object_iterator); | ||||
| 
 | ||||
|             case value_t::array: | ||||
|                 return (m_it.array_iterator == other.m_it.array_iterator); | ||||
| 
 | ||||
|             default: | ||||
|                 return (m_it.primitive_iterator == other.m_it.primitive_iterator); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: not equal | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator!=(const iter_impl& other) const | ||||
|     { | ||||
|         return not operator==(other); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: smaller | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator<(const iter_impl& other) const | ||||
|     { | ||||
|         // if objects are not the same, the comparison is undefined
 | ||||
|         if (JSON_UNLIKELY(m_object != other.m_object)) | ||||
|         { | ||||
|             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); | ||||
|         } | ||||
| 
 | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators")); | ||||
| 
 | ||||
|             case value_t::array: | ||||
|                 return (m_it.array_iterator < other.m_it.array_iterator); | ||||
| 
 | ||||
|             default: | ||||
|                 return (m_it.primitive_iterator < other.m_it.primitive_iterator); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: less than or equal | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator<=(const iter_impl& other) const | ||||
|     { | ||||
|         return not other.operator < (*this); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: greater than | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator>(const iter_impl& other) const | ||||
|     { | ||||
|         return not operator<=(other); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  comparison: greater than or equal | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     bool operator>=(const iter_impl& other) const | ||||
|     { | ||||
|         return not operator<(other); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  add to iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl& operator+=(difference_type i) | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); | ||||
| 
 | ||||
|             case value_t::array: | ||||
|             { | ||||
|                 std::advance(m_it.array_iterator, i); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 m_it.primitive_iterator += i; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  subtract from iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl& operator-=(difference_type i) | ||||
|     { | ||||
|         return operator+=(-i); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  add to iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl operator+(difference_type i) const | ||||
|     { | ||||
|         auto result = *this; | ||||
|         result += i; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  addition of distance and iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     friend iter_impl operator+(difference_type i, const iter_impl& it) | ||||
|     { | ||||
|         auto result = it; | ||||
|         result += i; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  subtract from iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     iter_impl operator-(difference_type i) const | ||||
|     { | ||||
|         auto result = *this; | ||||
|         result -= i; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  return difference | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     difference_type operator-(const iter_impl& other) const | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators")); | ||||
| 
 | ||||
|             case value_t::array: | ||||
|                 return m_it.array_iterator - other.m_it.array_iterator; | ||||
| 
 | ||||
|             default: | ||||
|                 return m_it.primitive_iterator - other.m_it.primitive_iterator; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  access to successor | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     reference operator[](difference_type n) const | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         switch (m_object->m_type) | ||||
|         { | ||||
|             case value_t::object: | ||||
|                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators")); | ||||
| 
 | ||||
|             case value_t::array: | ||||
|                 return *std::next(m_it.array_iterator, n); | ||||
| 
 | ||||
|             case value_t::null: | ||||
|                 JSON_THROW(invalid_iterator::create(214, "cannot get value")); | ||||
| 
 | ||||
|             default: | ||||
|             { | ||||
|                 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) | ||||
|                 { | ||||
|                     return *m_object; | ||||
|                 } | ||||
| 
 | ||||
|                 JSON_THROW(invalid_iterator::create(214, "cannot get value")); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  return the key of an object iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     typename object_t::key_type key() const | ||||
|     { | ||||
|         assert(m_object != nullptr); | ||||
| 
 | ||||
|         if (JSON_LIKELY(m_object->is_object())) | ||||
|         { | ||||
|             return m_it.object_iterator->first; | ||||
|         } | ||||
| 
 | ||||
|         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators")); | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|     @brief  return the value of an iterator | ||||
|     @pre The iterator is initialized; i.e. `m_object != nullptr`. | ||||
|     */ | ||||
|     reference value() const | ||||
|     { | ||||
|         return operator*(); | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     /// associated JSON instance
 | ||||
|     pointer m_object = nullptr; | ||||
|     /// the actual iterator of the associated instance
 | ||||
|     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										98
									
								
								include/nlohmann/detail/iterators/iteration_proxy.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								include/nlohmann/detail/iterators/iteration_proxy.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,98 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <cstddef> // size_t
 | ||||
| #include <string> // string, to_string
 | ||||
| 
 | ||||
| #include <nlohmann/detail/value_t.hpp> | ||||
| 
 | ||||
| namespace nlohmann | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
| /// proxy class for the items() function
 | ||||
| template<typename IteratorType> class iteration_proxy | ||||
| { | ||||
|   private: | ||||
|     /// helper class for iteration
 | ||||
|     class iteration_proxy_internal | ||||
|     { | ||||
|       private: | ||||
|         /// the iterator
 | ||||
|         IteratorType anchor; | ||||
|         /// an index for arrays (used to create key names)
 | ||||
|         std::size_t array_index = 0; | ||||
| 
 | ||||
|       public: | ||||
|         explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {} | ||||
| 
 | ||||
|         /// dereference operator (needed for range-based for)
 | ||||
|         iteration_proxy_internal& operator*() | ||||
|         { | ||||
|             return *this; | ||||
|         } | ||||
| 
 | ||||
|         /// increment operator (needed for range-based for)
 | ||||
|         iteration_proxy_internal& operator++() | ||||
|         { | ||||
|             ++anchor; | ||||
|             ++array_index; | ||||
| 
 | ||||
|             return *this; | ||||
|         } | ||||
| 
 | ||||
|         /// inequality operator (needed for range-based for)
 | ||||
|         bool operator!=(const iteration_proxy_internal& o) const noexcept | ||||
|         { | ||||
|             return anchor != o.anchor; | ||||
|         } | ||||
| 
 | ||||
|         /// return key of the iterator
 | ||||
|         std::string key() const | ||||
|         { | ||||
|             assert(anchor.m_object != nullptr); | ||||
| 
 | ||||
|             switch (anchor.m_object->type()) | ||||
|             { | ||||
|                 // use integer array index as key
 | ||||
|                 case value_t::array: | ||||
|                     return std::to_string(array_index); | ||||
| 
 | ||||
|                 // use key from the object
 | ||||
|                 case value_t::object: | ||||
|                     return anchor.key(); | ||||
| 
 | ||||
|                 // use an empty key for all primitive types
 | ||||
|                 default: | ||||
|                     return ""; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// return value of the iterator
 | ||||
|         typename IteratorType::reference value() const | ||||
|         { | ||||
|             return anchor.value(); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     /// the container to iterate
 | ||||
|     typename IteratorType::reference container; | ||||
| 
 | ||||
|   public: | ||||
|     /// construct iteration proxy from a container
 | ||||
|     explicit iteration_proxy(typename IteratorType::reference cont) noexcept | ||||
|         : container(cont) {} | ||||
| 
 | ||||
|     /// return iterator begin (needed for range-based for)
 | ||||
|     iteration_proxy_internal begin() noexcept | ||||
|     { | ||||
|         return iteration_proxy_internal(container.begin()); | ||||
|     } | ||||
| 
 | ||||
|     /// return iterator end (needed for range-based for)
 | ||||
|     iteration_proxy_internal end() noexcept | ||||
|     { | ||||
|         return iteration_proxy_internal(container.end()); | ||||
|     } | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										119
									
								
								include/nlohmann/detail/iterators/json_reverse_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								include/nlohmann/detail/iterators/json_reverse_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,119 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <cstddef> // ptrdiff_t
 | ||||
| #include <iterator> // reverse_iterator
 | ||||
| #include <utility> // declval
 | ||||
| 
 | ||||
| namespace nlohmann | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
| //////////////////////
 | ||||
| // reverse_iterator //
 | ||||
| //////////////////////
 | ||||
| 
 | ||||
| /*!
 | ||||
| @brief a template for a reverse iterator class | ||||
| 
 | ||||
| @tparam Base the base iterator type to reverse. Valid types are @ref | ||||
| iterator (to create @ref reverse_iterator) and @ref const_iterator (to | ||||
| create @ref const_reverse_iterator). | ||||
| 
 | ||||
| @requirement The class satisfies the following concept requirements: | ||||
| - | ||||
| [BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
 | ||||
|   The iterator that can be moved can be moved in both directions (i.e. | ||||
|   incremented and decremented). | ||||
| - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
 | ||||
|   It is possible to write to the pointed-to element (only if @a Base is | ||||
|   @ref iterator). | ||||
| 
 | ||||
| @since version 1.0.0 | ||||
| */ | ||||
| template<typename Base> | ||||
| class json_reverse_iterator : public std::reverse_iterator<Base> | ||||
| { | ||||
|   public: | ||||
|     using difference_type = std::ptrdiff_t; | ||||
|     /// shortcut to the reverse iterator adapter
 | ||||
|     using base_iterator = std::reverse_iterator<Base>; | ||||
|     /// the reference type for the pointed-to element
 | ||||
|     using reference = typename Base::reference; | ||||
| 
 | ||||
|     /// create reverse iterator from iterator
 | ||||
|     json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept | ||||
|         : base_iterator(it) {} | ||||
| 
 | ||||
|     /// create reverse iterator from base class
 | ||||
|     json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} | ||||
| 
 | ||||
|     /// post-increment (it++)
 | ||||
|     json_reverse_iterator const operator++(int) | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator>(base_iterator::operator++(1)); | ||||
|     } | ||||
| 
 | ||||
|     /// pre-increment (++it)
 | ||||
|     json_reverse_iterator& operator++() | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator&>(base_iterator::operator++()); | ||||
|     } | ||||
| 
 | ||||
|     /// post-decrement (it--)
 | ||||
|     json_reverse_iterator const operator--(int) | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator>(base_iterator::operator--(1)); | ||||
|     } | ||||
| 
 | ||||
|     /// pre-decrement (--it)
 | ||||
|     json_reverse_iterator& operator--() | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator&>(base_iterator::operator--()); | ||||
|     } | ||||
| 
 | ||||
|     /// add to iterator
 | ||||
|     json_reverse_iterator& operator+=(difference_type i) | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i)); | ||||
|     } | ||||
| 
 | ||||
|     /// add to iterator
 | ||||
|     json_reverse_iterator operator+(difference_type i) const | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator>(base_iterator::operator+(i)); | ||||
|     } | ||||
| 
 | ||||
|     /// subtract from iterator
 | ||||
|     json_reverse_iterator operator-(difference_type i) const | ||||
|     { | ||||
|         return static_cast<json_reverse_iterator>(base_iterator::operator-(i)); | ||||
|     } | ||||
| 
 | ||||
|     /// return difference
 | ||||
|     difference_type operator-(const json_reverse_iterator& other) const | ||||
|     { | ||||
|         return base_iterator(*this) - base_iterator(other); | ||||
|     } | ||||
| 
 | ||||
|     /// access to successor
 | ||||
|     reference operator[](difference_type n) const | ||||
|     { | ||||
|         return *(this->operator+(n)); | ||||
|     } | ||||
| 
 | ||||
|     /// return the key of an object iterator
 | ||||
|     auto key() const -> decltype(std::declval<Base>().key()) | ||||
|     { | ||||
|         auto it = --this->base(); | ||||
|         return it.key(); | ||||
|     } | ||||
| 
 | ||||
|     /// return the value of an iterator
 | ||||
|     reference value() const | ||||
|     { | ||||
|         auto it = --this->base(); | ||||
|         return it.operator * (); | ||||
|     } | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										120
									
								
								include/nlohmann/detail/iterators/primitive_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								include/nlohmann/detail/iterators/primitive_iterator.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,120 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <cstddef> // ptrdiff_t
 | ||||
| #include <limits>  // numeric_limits
 | ||||
| 
 | ||||
| namespace nlohmann | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
| /*
 | ||||
| @brief an iterator for primitive JSON types | ||||
| 
 | ||||
| This class models an iterator for primitive JSON types (boolean, number, | ||||
| string). It's only purpose is to allow the iterator/const_iterator classes | ||||
| to "iterate" over primitive values. Internally, the iterator is modeled by | ||||
| a `difference_type` variable. Value begin_value (`0`) models the begin, | ||||
| end_value (`1`) models past the end. | ||||
| */ | ||||
| class primitive_iterator_t | ||||
| { | ||||
|   private: | ||||
|     using difference_type = std::ptrdiff_t; | ||||
|     static constexpr difference_type begin_value = 0; | ||||
|     static constexpr difference_type end_value = begin_value + 1; | ||||
| 
 | ||||
|     /// iterator as signed integer type
 | ||||
|     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)(); | ||||
| 
 | ||||
|   public: | ||||
|     constexpr difference_type get_value() const noexcept | ||||
|     { | ||||
|         return m_it; | ||||
|     } | ||||
| 
 | ||||
|     /// set iterator to a defined beginning
 | ||||
|     void set_begin() noexcept | ||||
|     { | ||||
|         m_it = begin_value; | ||||
|     } | ||||
| 
 | ||||
|     /// set iterator to a defined past the end
 | ||||
|     void set_end() noexcept | ||||
|     { | ||||
|         m_it = end_value; | ||||
|     } | ||||
| 
 | ||||
|     /// return whether the iterator can be dereferenced
 | ||||
|     constexpr bool is_begin() const noexcept | ||||
|     { | ||||
|         return m_it == begin_value; | ||||
|     } | ||||
| 
 | ||||
|     /// return whether the iterator is at end
 | ||||
|     constexpr bool is_end() const noexcept | ||||
|     { | ||||
|         return m_it == end_value; | ||||
|     } | ||||
| 
 | ||||
|     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | ||||
|     { | ||||
|         return lhs.m_it == rhs.m_it; | ||||
|     } | ||||
| 
 | ||||
|     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | ||||
|     { | ||||
|         return lhs.m_it < rhs.m_it; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t operator+(difference_type n) noexcept | ||||
|     { | ||||
|         auto result = *this; | ||||
|         result += n; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept | ||||
|     { | ||||
|         return lhs.m_it - rhs.m_it; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t& operator++() noexcept | ||||
|     { | ||||
|         ++m_it; | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t const operator++(int) noexcept | ||||
|     { | ||||
|         auto result = *this; | ||||
|         m_it++; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t& operator--() noexcept | ||||
|     { | ||||
|         --m_it; | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t const operator--(int) noexcept | ||||
|     { | ||||
|         auto result = *this; | ||||
|         m_it--; | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t& operator+=(difference_type n) noexcept | ||||
|     { | ||||
|         m_it += n; | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     primitive_iterator_t& operator-=(difference_type n) noexcept | ||||
|     { | ||||
|         m_it -= n; | ||||
|         return *this; | ||||
|     } | ||||
| }; | ||||
| } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue