detail_iterator_adaptor_test.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // (C) Copyright Thomas Witt 2003.
  2. // (C) Copyright Hans Dembinski 2019.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org for most recent version including documentation.
  7. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/core/lightweight_test_trait.hpp>
  9. #include <boost/histogram/detail/detect.hpp>
  10. #include <boost/histogram/detail/iterator_adaptor.hpp>
  11. #include "std_ostream.hpp"
  12. #include "utility_iterator.hpp"
  13. #include <deque>
  14. #include <set>
  15. #include <vector>
  16. using namespace boost::histogram;
  17. using boost::histogram::detail::iterator_adaptor;
  18. typedef std::deque<int> storage;
  19. typedef std::deque<int*> pointer_deque;
  20. typedef std::set<storage::iterator> iterator_set;
  21. template <class T>
  22. struct foo;
  23. void blah(int) {}
  24. struct my_gen {
  25. typedef int result_type;
  26. my_gen() : n(0) {}
  27. int operator()() { return ++n; }
  28. int n;
  29. };
  30. template <class V>
  31. struct ptr_iterator : iterator_adaptor<ptr_iterator<V>, V*> {
  32. private:
  33. typedef iterator_adaptor<ptr_iterator<V>, V*> super_t;
  34. public:
  35. using base_type = typename super_t::base_type;
  36. ptr_iterator() {}
  37. ptr_iterator(V* d) : super_t(d) {}
  38. template <class V2, class = detail::requires_convertible<V2*, V*>>
  39. ptr_iterator(const ptr_iterator<V2>& x) : super_t(x.base()) {}
  40. V& operator*() const { return *(this->base()); }
  41. };
  42. template <class Iter>
  43. struct constant_iterator
  44. : iterator_adaptor<constant_iterator<Iter>, Iter,
  45. typename std::iterator_traits<Iter>::value_type const&> {
  46. typedef iterator_adaptor<constant_iterator<Iter>, Iter,
  47. typename std::iterator_traits<Iter>::value_type const&>
  48. base_t;
  49. constant_iterator() {}
  50. constant_iterator(Iter it) : base_t(it) {}
  51. typename std::iterator_traits<Iter>::value_type const& operator*() const {
  52. this->base().operator*();
  53. }
  54. };
  55. struct mutable_it : iterator_adaptor<mutable_it, int*> {
  56. typedef iterator_adaptor<mutable_it, int*> super_t;
  57. mutable_it();
  58. explicit mutable_it(int* p) : super_t(p) {}
  59. bool equal(mutable_it const& rhs) const { return this->base() == rhs.base(); }
  60. };
  61. struct constant_it : iterator_adaptor<constant_it, int const*> {
  62. typedef iterator_adaptor<constant_it, int const*> super_t;
  63. constant_it();
  64. explicit constant_it(int* p) : super_t(p) {}
  65. constant_it(mutable_it const& x) : super_t(x.base()) {}
  66. bool equal(constant_it const& rhs) const { return this->base() == rhs.base(); }
  67. };
  68. template <class T>
  69. class static_object {
  70. public:
  71. static T& get() {
  72. static char d[sizeof(T)];
  73. return *reinterpret_cast<T*>(d);
  74. }
  75. };
  76. int main() {
  77. dummyT array[] = {dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5)};
  78. const int N = sizeof(array) / sizeof(dummyT);
  79. // Test the iterator_adaptor
  80. {
  81. ptr_iterator<dummyT> i(array);
  82. using reference = typename std::iterator_traits<ptr_iterator<dummyT>>::reference;
  83. using pointer = typename std::iterator_traits<ptr_iterator<dummyT>>::pointer;
  84. BOOST_TEST_TRAIT_SAME(reference, dummyT&);
  85. BOOST_TEST_TRAIT_SAME(pointer, dummyT*);
  86. random_access_iterator_test(i, N, array);
  87. ptr_iterator<const dummyT> j(array);
  88. random_access_iterator_test(j, N, array);
  89. const_nonconst_iterator_test(i, ++j);
  90. }
  91. // Test the iterator_traits
  92. {
  93. // Test computation of defaults
  94. typedef ptr_iterator<int> Iter1;
  95. // don't use std::iterator_traits here to avoid VC++ problems
  96. BOOST_TEST_TRAIT_SAME(Iter1::value_type, int);
  97. BOOST_TEST_TRAIT_SAME(Iter1::reference, int&);
  98. BOOST_TEST_TRAIT_SAME(Iter1::pointer, int*);
  99. BOOST_TEST_TRAIT_SAME(Iter1::difference_type, std::ptrdiff_t);
  100. }
  101. {
  102. // Test computation of default when the Value is const
  103. typedef ptr_iterator<int const> Iter1;
  104. BOOST_TEST_TRAIT_SAME(Iter1::value_type, int);
  105. BOOST_TEST_TRAIT_SAME(Iter1::reference, const int&);
  106. BOOST_TEST_TRAIT_SAME(Iter1::pointer, int const*);
  107. }
  108. {
  109. // Test constant iterator idiom
  110. typedef ptr_iterator<int> BaseIter;
  111. typedef constant_iterator<BaseIter> Iter;
  112. BOOST_TEST_TRAIT_SAME(Iter::value_type, int);
  113. BOOST_TEST_TRAIT_SAME(Iter::reference, int const&);
  114. BOOST_TEST_TRAIT_SAME(Iter::pointer, int const*);
  115. }
  116. // Test the iterator_adaptor
  117. {
  118. ptr_iterator<dummyT> i(array);
  119. random_access_iterator_test(i, N, array);
  120. ptr_iterator<const dummyT> j(array);
  121. random_access_iterator_test(j, N, array);
  122. const_nonconst_iterator_test(i, ++j);
  123. }
  124. // check that base_type is correct
  125. {
  126. // Test constant iterator idiom
  127. typedef ptr_iterator<int> BaseIter;
  128. BOOST_TEST_TRAIT_SAME(BaseIter::base_type, int*);
  129. BOOST_TEST_TRAIT_SAME(constant_iterator<BaseIter>::base_type, BaseIter);
  130. }
  131. {
  132. int data[] = {49, 77};
  133. mutable_it i(data);
  134. constant_it j(data + 1);
  135. BOOST_TEST(i < j);
  136. BOOST_TEST(j > i);
  137. BOOST_TEST(i <= j);
  138. BOOST_TEST(j >= i);
  139. BOOST_TEST(j - i == 1);
  140. BOOST_TEST(i - j == -1);
  141. constant_it k = i;
  142. BOOST_TEST(!(i < k));
  143. BOOST_TEST(!(k > i));
  144. BOOST_TEST(i <= k);
  145. BOOST_TEST(k >= i);
  146. BOOST_TEST(k - i == 0);
  147. BOOST_TEST(i - k == 0);
  148. }
  149. return boost::report_errors();
  150. }