array_range_impl.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  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_IMPL_H_
  28. #define RTTR_ARRAY_RANGE_IMPL_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/property.h"
  31. #include "rttr/type.h"
  32. #include <memory>
  33. namespace rttr
  34. {
  35. /////////////////////////////////////////////////////////////////////////////////////////
  36. template<typename T, typename Predicate>
  37. RTTR_INLINE array_range<T, Predicate>::array_range(const T* begin, size_type size, const Predicate& pred)
  38. : m_begin(begin),
  39. m_end(begin + size),
  40. m_pred(pred)
  41. {
  42. }
  43. /////////////////////////////////////////////////////////////////////////////////////////
  44. template<typename T, typename Predicate>
  45. RTTR_INLINE array_range<T, Predicate>::array_range()
  46. : m_begin(nullptr),
  47. m_end(nullptr)
  48. {
  49. }
  50. /////////////////////////////////////////////////////////////////////////////////////////
  51. template<typename T, typename Predicate>
  52. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::begin()
  53. {
  54. if (empty_())
  55. {
  56. return {m_end, this};
  57. }
  58. else
  59. {
  60. const_iterator itr(m_begin, this);
  61. if (m_pred(*itr))
  62. return itr;
  63. next(itr);
  64. return itr;
  65. }
  66. }
  67. /////////////////////////////////////////////////////////////////////////////////////////
  68. template<typename T, typename Predicate>
  69. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::end()
  70. {
  71. return {m_end, this};
  72. }
  73. /////////////////////////////////////////////////////////////////////////////////////////
  74. template<typename T, typename Predicate>
  75. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::begin() const
  76. {
  77. if (empty_())
  78. {
  79. return {m_end, this};
  80. }
  81. else
  82. {
  83. const_iterator itr(m_begin, this);
  84. if (m_pred(*itr))
  85. return itr;
  86. next(itr);
  87. return itr;
  88. }
  89. }
  90. /////////////////////////////////////////////////////////////////////////////////////////
  91. template<typename T, typename Predicate>
  92. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::end() const
  93. {
  94. return {m_end, this};
  95. }
  96. /////////////////////////////////////////////////////////////////////////////////////////
  97. template<typename T, typename Predicate>
  98. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::cbegin() const
  99. {
  100. if (empty_())
  101. {
  102. return {m_end, this};
  103. }
  104. else
  105. {
  106. const_iterator itr(m_begin, this);
  107. if (m_pred(*itr))
  108. return itr;
  109. next(itr);
  110. return itr;
  111. }
  112. }
  113. /////////////////////////////////////////////////////////////////////////////////////////
  114. template<typename T, typename Predicate>
  115. RTTR_INLINE typename array_range<T, Predicate>::const_iterator array_range<T, Predicate>::cend() const
  116. {
  117. return {m_end, this};
  118. }
  119. /////////////////////////////////////////////////////////////////////////////////////////
  120. template<typename T, typename Predicate>
  121. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::rbegin()
  122. {
  123. if (empty_())
  124. {
  125. return {m_end, this};
  126. }
  127. else
  128. {
  129. const_reverse_iterator itr(m_end, this);
  130. if (m_pred(*itr))
  131. return itr;
  132. prev(itr);
  133. return itr;
  134. }
  135. }
  136. /////////////////////////////////////////////////////////////////////////////////////////
  137. template<typename T, typename Predicate>
  138. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::rend()
  139. {
  140. return const_reverse_iterator{m_begin, this};
  141. }
  142. /////////////////////////////////////////////////////////////////////////////////////////
  143. template<typename T, typename Predicate>
  144. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::rbegin() const
  145. {
  146. if (empty_())
  147. {
  148. return {m_end, this};
  149. }
  150. else
  151. {
  152. const_reverse_iterator itr(m_end, this);
  153. if (m_pred(*itr))
  154. return itr;
  155. prev(itr);
  156. return itr;
  157. }
  158. }
  159. /////////////////////////////////////////////////////////////////////////////////////////
  160. template<typename T, typename Predicate>
  161. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::rend() const
  162. {
  163. return const_reverse_iterator{m_begin, this};
  164. }
  165. /////////////////////////////////////////////////////////////////////////////////////////
  166. template<typename T, typename Predicate>
  167. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::crbegin() const
  168. {
  169. if (empty_())
  170. {
  171. return {m_end, this};
  172. }
  173. else
  174. {
  175. const_reverse_iterator itr(m_end, this);
  176. if (m_pred(*itr))
  177. return itr;
  178. prev(itr);
  179. return itr;
  180. }
  181. }
  182. /////////////////////////////////////////////////////////////////////////////////////////
  183. template<typename T, typename Predicate>
  184. RTTR_INLINE typename array_range<T, Predicate>::const_reverse_iterator array_range<T, Predicate>::crend() const
  185. {
  186. return const_reverse_iterator{m_begin, this};
  187. }
  188. /////////////////////////////////////////////////////////////////////////////////////////
  189. template<typename T, typename Predicate>
  190. RTTR_INLINE size_t array_range<T, Predicate>::size() const
  191. {
  192. std::size_t result = 0;
  193. const_iterator itr{m_begin, this};
  194. while(itr != cend())
  195. {
  196. if (m_pred(*itr.m_ptr))
  197. ++result;
  198. ++itr.m_ptr;
  199. }
  200. return result;
  201. }
  202. /////////////////////////////////////////////////////////////////////////////////////////
  203. template<typename T, typename Predicate>
  204. RTTR_INLINE bool array_range<T, Predicate>::empty() const
  205. {
  206. if (m_begin == m_end)
  207. return true;
  208. const_iterator itr{m_begin, this};
  209. if (m_pred(*itr))
  210. return false;
  211. ++itr.m_ptr;
  212. while(itr.m_ptr != m_end && !m_pred(*itr.m_ptr))
  213. {
  214. ++itr.m_ptr;
  215. }
  216. return (itr == cend());
  217. }
  218. /////////////////////////////////////////////////////////////////////////////////////////
  219. template<typename T, typename Predicate>
  220. RTTR_INLINE bool array_range<T, Predicate>::empty_() const
  221. {
  222. return (m_begin == m_end);
  223. }
  224. /////////////////////////////////////////////////////////////////////////////////////////
  225. template<typename T, typename Predicate>
  226. template<typename DataType>
  227. RTTR_INLINE void array_range<T, Predicate>::next(array_iterator<DataType>& itr) const
  228. {
  229. ++itr.m_ptr;
  230. while(itr.m_ptr != m_end && !m_pred(*itr.m_ptr))
  231. {
  232. ++itr.m_ptr;
  233. }
  234. }
  235. /////////////////////////////////////////////////////////////////////////////////////////
  236. template<typename T, typename Predicate>
  237. template<typename DataType>
  238. RTTR_INLINE void array_range<T, Predicate>::prev(array_reverse_iterator<DataType>& itr) const
  239. {
  240. --itr.m_ptr;
  241. while(itr.m_ptr != (m_begin - 1) && !m_pred(*itr.m_ptr))
  242. {
  243. --itr.m_ptr;
  244. }
  245. }
  246. /////////////////////////////////////////////////////////////////////////////////////////
  247. /////////////////////////////////////////////////////////////////////////////////////////
  248. /////////////////////////////////////////////////////////////////////////////////////////
  249. template<typename T, typename Predicate>
  250. template<typename DataType>
  251. RTTR_INLINE
  252. array_range<T, Predicate>::array_iterator_base<DataType>::array_iterator_base()
  253. : m_ptr(nullptr)
  254. {
  255. }
  256. /////////////////////////////////////////////////////////////////////////////////////////
  257. template<typename T, typename Predicate>
  258. template<typename DataType>
  259. RTTR_INLINE
  260. array_range<T, Predicate>::array_iterator_base<DataType>::array_iterator_base(typename array_iterator_base<DataType>::pointer ptr,
  261. const array_range<T, Predicate>* const range)
  262. : m_ptr(ptr),
  263. m_range(range)
  264. {
  265. }
  266. /////////////////////////////////////////////////////////////////////////////////////////
  267. template<typename T, typename Predicate>
  268. template<typename DataType>
  269. RTTR_INLINE bool array_range<T, Predicate>::array_iterator_base<DataType>::operator==(const self_type& rhs) const
  270. {
  271. return (m_ptr == rhs.m_ptr);
  272. }
  273. /////////////////////////////////////////////////////////////////////////////////////////
  274. template<typename T, typename Predicate>
  275. template<typename DataType>
  276. RTTR_INLINE bool array_range<T, Predicate>::array_iterator_base<DataType>::operator!=(const self_type& rhs) const
  277. {
  278. return (m_ptr != rhs.m_ptr);
  279. }
  280. /////////////////////////////////////////////////////////////////////////////////////////
  281. template<typename T, typename Predicate>
  282. template<typename DataType>
  283. RTTR_INLINE typename array_range<T, Predicate>::template array_iterator_base<DataType>::self_type&
  284. array_range<T, Predicate>::array_iterator_base<DataType>::operator=(const self_type& other)
  285. {
  286. m_ptr = other.m_ptr;
  287. return *this;
  288. }
  289. /////////////////////////////////////////////////////////////////////////////////////////
  290. /////////////////////////////////////////////////////////////////////////////////////////
  291. /////////////////////////////////////////////////////////////////////////////////////////
  292. template<typename T, typename Predicate>
  293. template<typename DataType>
  294. RTTR_INLINE array_range<T, Predicate>::array_iterator<DataType>::array_iterator()
  295. {
  296. }
  297. /////////////////////////////////////////////////////////////////////////////////////////
  298. template<typename T, typename Predicate>
  299. template<typename DataType>
  300. RTTR_INLINE array_range<T, Predicate>::array_iterator<DataType>::array_iterator(const array_iterator<DataType>& other)
  301. : array_iterator_base<DataType>(other.m_ptr, other.m_range)
  302. {
  303. }
  304. /////////////////////////////////////////////////////////////////////////////////////////
  305. template<typename T, typename Predicate>
  306. template<typename DataType>
  307. RTTR_INLINE array_range<T, Predicate>::array_iterator<DataType>::array_iterator(typename array_iterator_base<DataType>::pointer ptr,
  308. const array_range<T, Predicate>* const range)
  309. : array_iterator_base<DataType>(ptr, range)
  310. {
  311. }
  312. /////////////////////////////////////////////////////////////////////////////////////////
  313. template<typename T, typename Predicate>
  314. template<typename DataType>
  315. RTTR_INLINE typename array_range<T, Predicate>::template array_iterator<DataType>::reference
  316. array_range<T, Predicate>::array_iterator<DataType>::operator*() const
  317. {
  318. return *this->m_ptr;
  319. }
  320. /////////////////////////////////////////////////////////////////////////////////////////
  321. template<typename T, typename Predicate>
  322. template<typename DataType>
  323. RTTR_INLINE typename array_range<T, Predicate>::template array_iterator<DataType>::pointer
  324. array_range<T, Predicate>::array_iterator<DataType>::operator->()
  325. {
  326. return this->m_ptr;
  327. }
  328. /////////////////////////////////////////////////////////////////////////////////////////
  329. template<typename T, typename Predicate>
  330. template<typename DataType>
  331. RTTR_INLINE typename array_range<T, Predicate>::template array_iterator<DataType>::self_type&
  332. array_range<T, Predicate>::array_iterator<DataType>::operator++()
  333. {
  334. this->m_range->next(*this);
  335. return *this;
  336. }
  337. /////////////////////////////////////////////////////////////////////////////////////////
  338. template<typename T, typename Predicate>
  339. template<typename DataType>
  340. RTTR_INLINE typename array_range<T, Predicate>::template array_iterator<DataType>::self_type
  341. array_range<T, Predicate>::array_iterator<DataType>::operator++(int index)
  342. {
  343. auto old_itr = *this;
  344. this->m_range->next(*this);
  345. return old_itr;
  346. }
  347. /////////////////////////////////////////////////////////////////////////////////////////
  348. /////////////////////////////////////////////////////////////////////////////////////////
  349. /////////////////////////////////////////////////////////////////////////////////////////
  350. template<typename T, typename Predicate>
  351. template<typename DataType>
  352. RTTR_INLINE array_range<T, Predicate>::array_reverse_iterator<DataType>::array_reverse_iterator()
  353. {
  354. }
  355. /////////////////////////////////////////////////////////////////////////////////////////
  356. template<typename T, typename Predicate>
  357. template<typename DataType>
  358. RTTR_INLINE array_range<T, Predicate>::array_reverse_iterator<DataType>::array_reverse_iterator(const array_reverse_iterator<DataType>& other)
  359. : array_iterator_base<DataType>(other.m_ptr, other.m_range)
  360. {
  361. }
  362. /////////////////////////////////////////////////////////////////////////////////////////
  363. template<typename T, typename Predicate>
  364. template<typename DataType>
  365. RTTR_INLINE array_range<T, Predicate>::array_reverse_iterator<DataType>::array_reverse_iterator(typename array_iterator_base<DataType>::pointer ptr,
  366. const array_range<T, Predicate>* const range)
  367. : array_iterator_base<DataType>(ptr, range)
  368. {
  369. }
  370. /////////////////////////////////////////////////////////////////////////////////////////
  371. template<typename T, typename Predicate>
  372. template<typename DataType>
  373. RTTR_INLINE typename array_range<T, Predicate>::template array_reverse_iterator<DataType>::reference
  374. array_range<T, Predicate>::array_reverse_iterator<DataType>::operator*() const
  375. {
  376. auto tmp = this->m_ptr;
  377. return (*--tmp);
  378. }
  379. /////////////////////////////////////////////////////////////////////////////////////////
  380. template<typename T, typename Predicate>
  381. template<typename DataType>
  382. RTTR_INLINE typename array_range<T, Predicate>::template array_reverse_iterator<DataType>::pointer
  383. array_range<T, Predicate>::array_reverse_iterator<DataType>::operator->()
  384. {
  385. auto tmp = this->m_ptr;
  386. return --tmp;
  387. }
  388. ////////////////////////////////////////////////////////////////////////////////////////////
  389. template<typename T, typename Predicate>
  390. template<typename DataType>
  391. RTTR_INLINE typename array_range<T, Predicate>::template array_reverse_iterator<DataType>::self_type&
  392. array_range<T, Predicate>::array_reverse_iterator<DataType>::operator++()
  393. {
  394. this->m_range->prev(*this);
  395. return *this;
  396. }
  397. /////////////////////////////////////////////////////////////////////////////////////////
  398. template<typename T, typename Predicate>
  399. template<typename DataType>
  400. RTTR_INLINE typename array_range<T, Predicate>::template array_reverse_iterator<DataType>::self_type
  401. array_range<T, Predicate>::array_reverse_iterator<DataType>::operator++(int index)
  402. {
  403. auto old_itr = *this;
  404. this->m_range->prev(*this);
  405. return old_itr;
  406. }
  407. /////////////////////////////////////////////////////////////////////////////////////////
  408. namespace detail
  409. {
  410. template<typename T>
  411. struct default_predicate
  412. {
  413. RTTR_FORCE_INLINE default_predicate() {}
  414. RTTR_FORCE_INLINE default_predicate(std::function<bool(const T&)> func) : m_func(std::move(func)) {}
  415. RTTR_FORCE_INLINE bool operator()(const T& obj) const { return (m_func ? m_func(obj) : true); }
  416. std::function<bool(const T&)> m_func;
  417. };
  418. /////////////////////////////////////////////////////////////////////////////////////////
  419. } // end namespace detail
  420. } // end namespace rttr
  421. #endif // RTTR_ITEM_RANGE_IMPL_H_