General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
6.3 KiB

  1. #pragma once
  2. #include <gp/utils/iterators/iterator_properties.hpp>
  3. #include <cstddef>
  4. #include <cstdint>
  5. // TODO: Specify the concept of an iterator
  6. namespace gp {
  7. /**
  8. * @brief An abstraction of a pointer to iterate against, in both normal and reverse order
  9. *
  10. * @tparam T The type of data pointed by the iterator
  11. * @tparam sign the direction in which data is scrutinized, should be either 1 or -1, behaviour for other value is left undefined
  12. */
  13. template<typename T, int sign = 1>
  14. struct pointer_iterator final
  15. {
  16. T* data; /**< the only data field of the class */
  17. typedef T value_type; /**< The type of which a reference will be returned on dereferencing */
  18. typedef std::intptr_t difference_type; /**< The type of the substraction of two pointers */
  19. static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see iterator_type_t */
  20. /**
  21. * @brief Generates an empty iterator
  22. */
  23. constexpr pointer_iterator()
  24. : data{nullptr}
  25. {}
  26. constexpr pointer_iterator(const pointer_iterator& oth)
  27. : data{oth.data}
  28. {}
  29. /**
  30. * @brief Generates an iterator from any pointer
  31. */
  32. constexpr pointer_iterator(T* ptr)
  33. : data{ptr}
  34. {}
  35. /**
  36. * @brief Dereference unary operator
  37. *
  38. * @return constexpr T& returns a reference to the pointed value
  39. */
  40. constexpr T& operator*() const
  41. {
  42. return *data;
  43. }
  44. constexpr pointer_iterator& operator++()
  45. {
  46. data += sign;
  47. return *this;
  48. }
  49. constexpr pointer_iterator operator++(int)
  50. {
  51. auto p = *this;
  52. data += sign;
  53. return p;
  54. }
  55. constexpr pointer_iterator& operator--()
  56. {
  57. data -= sign;
  58. return *this;
  59. }
  60. constexpr pointer_iterator operator--(int)
  61. {
  62. auto p = *this;
  63. data -= sign;
  64. return p;
  65. }
  66. constexpr pointer_iterator operator+(const std::size_t offset) const
  67. {
  68. return pointer_iterator{data+sign*offset};
  69. }
  70. constexpr pointer_iterator operator+(const difference_type offset) const
  71. {
  72. return pointer_iterator{data+sign*offset};
  73. }
  74. constexpr pointer_iterator operator+(const int offset) const
  75. {
  76. return pointer_iterator{data+sign*offset};
  77. }
  78. constexpr pointer_iterator operator-(const std::size_t offset) const
  79. {
  80. return pointer_iterator{data-sign*offset};
  81. }
  82. constexpr pointer_iterator operator-(const difference_type offset) const
  83. {
  84. return pointer_iterator{data-sign*offset};
  85. }
  86. constexpr pointer_iterator operator-(const int offset) const
  87. {
  88. return pointer_iterator{data-sign*offset};
  89. }
  90. constexpr difference_type operator-(const pointer_iterator& oth) const
  91. {
  92. return (data-oth.data)*sign;
  93. }
  94. constexpr bool operator==(const pointer_iterator oth) const
  95. {
  96. return data==oth.data;
  97. }
  98. constexpr bool operator!=(pointer_iterator oth) const
  99. {
  100. return data!=oth.data;
  101. }
  102. constexpr bool before_or_equal(const pointer_iterator oth) const
  103. {
  104. return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
  105. }
  106. constexpr bool after_or_equal(const pointer_iterator oth) const
  107. {
  108. return reinterpret_cast<std::intptr_t>(data) >= reinterpret_cast<std::intptr_t>(oth.data);
  109. }
  110. constexpr bool operator<=(const pointer_iterator oth) const
  111. {
  112. return before_or_equal(oth);
  113. }
  114. constexpr bool operator>=(const pointer_iterator oth) const
  115. {
  116. return after_or_equal(oth);
  117. }
  118. };
  119. /**
  120. * @brief An identical twin to the pointer_iterator, but which dereference to a const reference
  121. *
  122. * @see pointer_iterator
  123. * @tparam T @see pointer_iterator
  124. * @tparam sign @see pointer_iterator
  125. */
  126. template<typename T, int sign = 1>
  127. struct const_pointer_iterator final
  128. {
  129. const T* data; /**< @see pointer_iterator */
  130. typedef T value_type; /**< @see pointer_iterator */
  131. typedef std::intptr_t difference_type; /**< @see pointer_iterator */
  132. static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see pointer_iterator */
  133. constexpr const_pointer_iterator(const const_pointer_iterator& oth)
  134. : data{oth.data}
  135. {}
  136. /**
  137. * @brief @see pointer_iterator
  138. */
  139. constexpr const_pointer_iterator(const T* ptr)
  140. : data{ptr}
  141. {}
  142. /**
  143. * @brief Dereferencing returns a const version of what a pointer_iterator would return
  144. */
  145. constexpr const T& operator*() const
  146. {
  147. return *data;
  148. }
  149. constexpr const_pointer_iterator& operator++()
  150. {
  151. data += sign;
  152. return *this;
  153. }
  154. constexpr const_pointer_iterator operator++(int)
  155. {
  156. auto p = data;
  157. data += sign;
  158. return const_pointer_iterator{p};
  159. }
  160. constexpr const_pointer_iterator& operator--()
  161. {
  162. data -= sign;
  163. return *this;
  164. }
  165. constexpr const_pointer_iterator operator--(int)
  166. {
  167. auto p = data;
  168. data -= sign;
  169. return const_pointer_iterator{p};
  170. }
  171. constexpr const_pointer_iterator operator+(const std::size_t offset) const
  172. {
  173. return const_pointer_iterator{data+sign*offset};
  174. }
  175. constexpr const_pointer_iterator operator+(const difference_type offset) const
  176. {
  177. return const_pointer_iterator{data+sign*offset};
  178. }
  179. constexpr const_pointer_iterator operator+(const int offset) const
  180. {
  181. return const_pointer_iterator{data+sign*offset};
  182. }
  183. constexpr const_pointer_iterator operator-(const difference_type offset) const
  184. {
  185. return const_pointer_iterator{data-sign*offset};
  186. }
  187. constexpr const_pointer_iterator operator-(const std::size_t offset) const
  188. {
  189. return const_pointer_iterator{data-sign*offset};
  190. }
  191. constexpr const_pointer_iterator operator-(const int offset)
  192. {
  193. return const_pointer_iterator{data-sign*offset};
  194. }
  195. constexpr difference_type operator-(const const_pointer_iterator& oth) const
  196. {
  197. return ((T*)data-(T*)oth.data)*sign;
  198. }
  199. constexpr bool operator==(const const_pointer_iterator oth) const
  200. {
  201. return data==oth.data;
  202. }
  203. constexpr bool operator!=(const_pointer_iterator oth) const
  204. {
  205. return data!=oth.data;
  206. }
  207. constexpr bool before_or_equal(const const_pointer_iterator oth) const
  208. {
  209. return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
  210. }
  211. constexpr bool after_or_equal(const const_pointer_iterator oth) const
  212. {
  213. return reinterpret_cast<std::intptr_t>(data) >= reinterpret_cast<std::intptr_t>(oth.data);
  214. }
  215. constexpr bool operator<=(const const_pointer_iterator oth) const
  216. {
  217. return before_or_equal(oth);
  218. }
  219. constexpr bool operator>=(const const_pointer_iterator oth) const
  220. {
  221. return after_or_equal(oth);
  222. }
  223. };
  224. }