array_range.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /************************************************************************************
  2. * *
  3. * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
  4. * *
  5. * This file is part of RTTR (Run Time Type Reflection) *
  6. * License: MIT License *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining *
  9. * a copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
  24. * SOFTWARE. *
  25. * *
  26. *************************************************************************************/
  27. #ifndef RTTR_ARRAY_RANGE_H_
  28. #define RTTR_ARRAY_RANGE_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include <vector>
  31. #include <cstddef>
  32. namespace rttr
  33. {
  34. class property;
  35. class method;
  36. class constructor;
  37. class enumeration;
  38. class parameter_info;
  39. namespace detail
  40. {
  41. template<typename T>
  42. struct default_predicate;
  43. } // end namespace detail
  44. /*!
  45. * The \ref array_range class provides a view into an underlying data structure with lower and upper limits.
  46. * In order to iterate over the data structure use the returned forward iterators from begin() or rbegin().
  47. * To check whether the end of the range has reached use end() or rend().
  48. * Using the standard C++ range-based for loop will implicit do all this work.
  49. *
  50. * \remark When the underlying data structure gets modified while holding a range,
  51. * its iterators and the range itself will be invalidated.
  52. */
  53. template<typename T, typename Predicate = detail::default_predicate<T>>
  54. class array_range
  55. {
  56. public:
  57. using value_type = T;
  58. using bounds_type = T*;
  59. using size_type = std::size_t;
  60. /*!
  61. * \brief Default constructor. Constructs an empty array_range.
  62. */
  63. array_range();
  64. /*!
  65. * \brief Constructs an array range starting from \p begin to \p end [begin, end).
  66. *
  67. * \param begin Marks the start of the range. Is included of the range.
  68. * \param size The number of elements to include in the range.
  69. * \param pred Determines whether an element in the range fulfills the condition of the predicate.
  70. */
  71. array_range(const T* begin, size_type size, const Predicate& pred = Predicate());
  72. #ifndef DOXYGEN
  73. /*!
  74. * The base class for all item forward iterators.
  75. */
  76. template<typename DataType>
  77. class array_iterator_base
  78. {
  79. public:
  80. using self_type = array_iterator_base<DataType>;
  81. using value_type = DataType;
  82. using reference = DataType&;
  83. using pointer = DataType*;
  84. using iterator_category = std::forward_iterator_tag;
  85. using difference_type = std::ptrdiff_t;
  86. bool operator==(const self_type& rhs) const;
  87. bool operator!=(const self_type& rhs) const;
  88. array_iterator_base& operator=(const self_type& other);
  89. protected:
  90. friend class array_range<T, Predicate>;
  91. array_iterator_base();
  92. array_iterator_base(pointer ptr, const array_range<T, Predicate>* const range);
  93. pointer m_ptr;
  94. const array_range<T, Predicate>* m_range;
  95. };
  96. /*!
  97. * A forward iterator for items of type \p DataType.
  98. */
  99. template<typename DataType>
  100. class array_iterator : public array_iterator_base<DataType>
  101. {
  102. public:
  103. using self_type = array_iterator<DataType>;
  104. using reference = typename array_iterator_base<DataType>::reference;
  105. using pointer = typename array_iterator_base<DataType>::pointer;
  106. array_iterator();
  107. array_iterator(const array_iterator<DataType>& other);
  108. reference operator*() const;
  109. pointer operator->();
  110. self_type& operator++();
  111. self_type operator++(int index);
  112. private:
  113. array_iterator(typename array_iterator_base<DataType>::pointer ptr,
  114. const array_range<T, Predicate>* const range);
  115. friend class array_range<T, Predicate>;
  116. };
  117. /*!
  118. * A forward reverse iterator for items of type \p DataType.
  119. */
  120. template<typename DataType>
  121. class array_reverse_iterator : public array_iterator_base<DataType>
  122. {
  123. public:
  124. using self_type = array_reverse_iterator<DataType>;
  125. using reference = typename array_iterator_base<DataType>::reference;
  126. using pointer = typename array_iterator_base<DataType>::pointer;
  127. array_reverse_iterator();
  128. array_reverse_iterator(const array_reverse_iterator<DataType>& other);
  129. reference operator*() const;
  130. pointer operator->();
  131. self_type& operator++();
  132. self_type operator++(int index);
  133. private:
  134. array_reverse_iterator(typename array_iterator_base<DataType>::pointer ptr,
  135. const array_range<T, Predicate>* const range);
  136. friend class array_range<T, Predicate>;
  137. };
  138. #endif
  139. //! A forward iterator.
  140. using iterator = array_iterator<T>;
  141. //! A constant forward iterator.
  142. using const_iterator = array_iterator<const T>;
  143. //! A forward iterator that reverses the direction.
  144. using reverse_iterator = array_reverse_iterator<T>;
  145. //! A constant forward iterator that reverses the direction.
  146. using const_reverse_iterator = array_reverse_iterator<const T>;
  147. /*!
  148. * \brief Returns an iterator to the first element of the range.
  149. *
  150. * \remark If the range is empty, the returned iterator will be equal to \ref end().
  151. *
  152. * \return Iterator to the first element.
  153. */
  154. const_iterator begin();
  155. /*!
  156. * \brief Returns an iterator to the element following the last element of the range.
  157. *
  158. * \remark This element acts as placeholder, attempting to access it results in **undefined behavior**.
  159. * If the range is empty, the returned iterator will be equal to \ref begin().
  160. *
  161. * \return Iterator to the element following the last element.
  162. */
  163. const_iterator end();
  164. /*!
  165. * \brief Returns a constant iterator to the first element of the range.
  166. *
  167. * \remark If the range is empty, the returned iterator will be equal to \ref end().
  168. *
  169. * \return Constant iterator to the first element.
  170. */
  171. const_iterator begin() const;
  172. /*!
  173. * \brief Returns a constant iterator to the element following the last element of the range.
  174. *
  175. * \remark This element acts as placeholder, attempting to access it results in **undefined behavior**.
  176. * If the range is empty, the returned iterator will be equal to \ref begin().
  177. *
  178. * \return Constant iterator to the element following the last element.
  179. */
  180. const_iterator end() const;
  181. /*!
  182. * \brief Returns a constant iterator to the first element of the range.
  183. *
  184. * \remark If the range is empty, the returned iterator will be equal to \ref end().
  185. *
  186. * \return Constant iterator to the first element.
  187. */
  188. const_iterator cbegin() const;
  189. /*!
  190. * \brief Returns a constant iterator to the element following the last element of the range.
  191. *
  192. * \remark This element acts as placeholder, attempting to access it results in **undefined behavior**.
  193. * If the range is empty, the returned iterator will be equal to \ref begin().
  194. *
  195. * \return Constant iterator to the element following the last element.
  196. */
  197. const_iterator cend() const;
  198. /*!
  199. * \brief Returns a reverse iterator to the first element of the reversed range.
  200. * It corresponds to the last element of the non-reversed range.
  201. *
  202. * \remark If the range is empty, the returned iterator will be equal to \ref rend().
  203. *
  204. * \return Reverse iterator to the first element.
  205. */
  206. const_reverse_iterator rbegin();
  207. /*!
  208. * \brief Returns a reverse iterator to the element following the last element of the reversed range.
  209. * It corresponds to the element preceding the first element of the non-reversed range.
  210. *
  211. * \remark If the range is empty, the returned iterator will be equal to \ref rbegin().
  212. *
  213. * \return Reverse iterator to the element following the last element.
  214. */
  215. const_reverse_iterator rend();
  216. /*!
  217. * \brief Returns a constant reverse iterator to the first element of the reversed range.
  218. * It corresponds to the last element of the non-reversed range.
  219. *
  220. * \remark If the range is empty, the returned iterator will be equal to \ref rend().
  221. *
  222. * \return Constant reverse iterator to the first element.
  223. */
  224. const_reverse_iterator rbegin() const;
  225. /*!
  226. * \brief Returns a constant reverse iterator to the element following the last element of the reversed range.
  227. * It corresponds to the element preceding the first element of the non-reversed range.
  228. *
  229. * \remark If the range is empty, the returned iterator will be equal to \ref rbegin().
  230. *
  231. * \return Constant reverse iterator to the element following the last element.
  232. */
  233. const_reverse_iterator rend() const;
  234. /*!
  235. * \brief Returns a constant reverse iterator to the first element of the reversed range.
  236. * It corresponds to the last element of the non-reversed range.
  237. *
  238. * \remark If the range is empty, the returned iterator will be equal to \ref rend().
  239. *
  240. * \return Constant reverse iterator to the first element.
  241. */
  242. const_reverse_iterator crbegin() const;
  243. /*!
  244. * \brief Returns a constant reverse iterator to the element following the last element of the reversed range.
  245. * It corresponds to the element preceding the first element of the non-reversed range.
  246. *
  247. * \remark If the range is empty, the returned iterator will be equal to \ref rbegin().
  248. *
  249. * \return Constant reverse iterator to the element following the last element.
  250. */
  251. const_reverse_iterator crend() const;
  252. /*!
  253. * \brief Returns the number of elements in the range.
  254. *
  255. * \remark Every element will be checked against the condition of the used predicate.
  256. * Only elements which fulfill the condition of predicate will be included in the counter.
  257. * That means, in order to determine the size of the range, the underlying algorithm needs to iterate
  258. * through the whole range. So don't call it to often. It's better to cache the result in a temporary variable.
  259. *
  260. * \return The number of elements in the range.
  261. */
  262. size_t size() const;
  263. /*!
  264. * \brief Checks if the range has no elements, i.e. whether `begin() == end()`.
  265. *
  266. * \remark Every element will be checked against the condition of the used predicate.
  267. * Only when every element doe not fulfill the condition of predicate, the range is declared empty.
  268. * That means, in order to check for emptiness, the underlying algorithm needs to iterate
  269. * through the whole range. So don't call it to often. It's better to cache the result in a temporary variable.
  270. *
  271. * \return `True` if this range is empty, otherwise `false`.
  272. */
  273. bool empty() const;
  274. private:
  275. template<typename DataType>
  276. void next(array_iterator<DataType>& itr) const;
  277. template<typename DataType>
  278. void prev(array_reverse_iterator<DataType>& itr) const;
  279. bool empty_() const;
  280. array_range<T, Predicate>& operator=(const array_range<T, Predicate>& other);
  281. private:
  282. const T* const m_begin;
  283. const T* const m_end;
  284. const Predicate m_pred;
  285. };
  286. /////////////////////////////////////////////////////////////////////////////////////////
  287. } // end namespace rttr
  288. #include "rttr/detail/impl/array_range_impl.h"
  289. #endif // RTTR_ARRAY_RANGE_H_