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.

239 lines
5.7 KiB

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