• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright Thomas Witt 2003.
2 //  (C) Copyright Hans Dembinski 2019.
3 
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 
8 //  See http://www.boost.org for most recent version including documentation.
9 
10 #include <boost/core/lightweight_test.hpp>
11 #include <boost/core/lightweight_test_trait.hpp>
12 #include <boost/histogram/detail/iterator_adaptor.hpp>
13 #include <deque>
14 #include <set>
15 #include <type_traits>
16 #include <vector>
17 #include "std_ostream.hpp"
18 #include "utility_iterator.hpp"
19 
20 using namespace boost::histogram;
21 using boost::histogram::detail::iterator_adaptor;
22 
23 typedef std::deque<int> storage;
24 typedef std::deque<int*> pointer_deque;
25 typedef std::set<storage::iterator> iterator_set;
26 
27 template <class T>
28 struct foo;
29 
blah(int)30 void blah(int) {}
31 
32 struct my_gen {
33   typedef int result_type;
my_genmy_gen34   my_gen() : n(0) {}
operator ()my_gen35   int operator()() { return ++n; }
36   int n;
37 };
38 
39 template <class V>
40 struct ptr_iterator : iterator_adaptor<ptr_iterator<V>, V*> {
41 private:
42   typedef iterator_adaptor<ptr_iterator<V>, V*> super_t;
43 
44 public:
45   using base_type = typename super_t::base_type;
46 
ptr_iteratorptr_iterator47   ptr_iterator() {}
ptr_iteratorptr_iterator48   ptr_iterator(V* d) : super_t(d) {}
49 
50   template <class V2, class = std::enable_if_t<std::is_convertible<V2*, V*>::value>>
ptr_iteratorptr_iterator51   ptr_iterator(const ptr_iterator<V2>& x) : super_t(x.base()) {}
52 
operator *ptr_iterator53   V& operator*() const { return *(this->base()); }
54 };
55 
56 template <class Iter>
57 struct constant_iterator
58     : iterator_adaptor<constant_iterator<Iter>, Iter,
59                        typename std::iterator_traits<Iter>::value_type const&> {
60   typedef iterator_adaptor<constant_iterator<Iter>, Iter,
61                            typename std::iterator_traits<Iter>::value_type const&>
62       base_t;
63 
constant_iteratorconstant_iterator64   constant_iterator() {}
constant_iteratorconstant_iterator65   constant_iterator(Iter it) : base_t(it) {}
66 
operator *constant_iterator67   typename std::iterator_traits<Iter>::value_type const& operator*() const {
68     this->base().operator*();
69   }
70 };
71 
72 struct mutable_it : iterator_adaptor<mutable_it, int*> {
73   typedef iterator_adaptor<mutable_it, int*> super_t;
74 
75   mutable_it();
mutable_itmutable_it76   explicit mutable_it(int* p) : super_t(p) {}
77 
equalmutable_it78   bool equal(mutable_it const& rhs) const { return this->base() == rhs.base(); }
79 };
80 
81 struct constant_it : iterator_adaptor<constant_it, int const*> {
82   typedef iterator_adaptor<constant_it, int const*> super_t;
83 
84   constant_it();
constant_itconstant_it85   explicit constant_it(int* p) : super_t(p) {}
constant_itconstant_it86   constant_it(mutable_it const& x) : super_t(x.base()) {}
87 
equalconstant_it88   bool equal(constant_it const& rhs) const { return this->base() == rhs.base(); }
89 };
90 
91 template <class T>
92 class static_object {
93 public:
get()94   static T& get() {
95     static char d[sizeof(T)];
96     return *reinterpret_cast<T*>(d);
97   }
98 };
99 
main()100 int main() {
101   dummyT array[] = {dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5)};
102   const int N = sizeof(array) / sizeof(dummyT);
103 
104   // Test the iterator_adaptor
105   {
106     ptr_iterator<dummyT> i(array);
107     using reference = typename std::iterator_traits<ptr_iterator<dummyT>>::reference;
108     using pointer = typename std::iterator_traits<ptr_iterator<dummyT>>::pointer;
109     BOOST_TEST_TRAIT_SAME(reference, dummyT&);
110     BOOST_TEST_TRAIT_SAME(pointer, dummyT*);
111 
112     random_access_iterator_test(i, N, array);
113 
114     ptr_iterator<const dummyT> j(array);
115     random_access_iterator_test(j, N, array);
116     const_nonconst_iterator_test(i, ++j);
117   }
118 
119   // Test the iterator_traits
120   {
121     // Test computation of defaults
122     typedef ptr_iterator<int> Iter1;
123     // don't use std::iterator_traits here to avoid VC++ problems
124     BOOST_TEST_TRAIT_SAME(Iter1::value_type, int);
125     BOOST_TEST_TRAIT_SAME(Iter1::reference, int&);
126     BOOST_TEST_TRAIT_SAME(Iter1::pointer, int*);
127     BOOST_TEST_TRAIT_SAME(Iter1::difference_type, std::ptrdiff_t);
128   }
129 
130   {
131     // Test computation of default when the Value is const
132     typedef ptr_iterator<int const> Iter1;
133     BOOST_TEST_TRAIT_SAME(Iter1::value_type, int);
134     BOOST_TEST_TRAIT_SAME(Iter1::reference, const int&);
135     BOOST_TEST_TRAIT_SAME(Iter1::pointer, int const*);
136   }
137 
138   {
139     // Test constant iterator idiom
140     typedef ptr_iterator<int> BaseIter;
141     typedef constant_iterator<BaseIter> Iter;
142 
143     BOOST_TEST_TRAIT_SAME(Iter::value_type, int);
144     BOOST_TEST_TRAIT_SAME(Iter::reference, int const&);
145     BOOST_TEST_TRAIT_SAME(Iter::pointer, int const*);
146   }
147 
148   // Test the iterator_adaptor
149   {
150     ptr_iterator<dummyT> i(array);
151     random_access_iterator_test(i, N, array);
152 
153     ptr_iterator<const dummyT> j(array);
154     random_access_iterator_test(j, N, array);
155     const_nonconst_iterator_test(i, ++j);
156   }
157 
158   // check that base_type is correct
159   {
160     // Test constant iterator idiom
161     typedef ptr_iterator<int> BaseIter;
162 
163     BOOST_TEST_TRAIT_SAME(BaseIter::base_type, int*);
164     BOOST_TEST_TRAIT_SAME(constant_iterator<BaseIter>::base_type, BaseIter);
165   }
166 
167   {
168     int data[] = {49, 77};
169 
170     mutable_it i(data);
171     constant_it j(data + 1);
172     BOOST_TEST(i < j);
173     BOOST_TEST(j > i);
174     BOOST_TEST(i <= j);
175     BOOST_TEST(j >= i);
176     BOOST_TEST(j - i == 1);
177     BOOST_TEST(i - j == -1);
178 
179     constant_it k = i;
180 
181     BOOST_TEST(!(i < k));
182     BOOST_TEST(!(k > i));
183     BOOST_TEST(i <= k);
184     BOOST_TEST(k >= i);
185     BOOST_TEST(k - i == 0);
186     BOOST_TEST(i - k == 0);
187   }
188 
189   return boost::report_errors();
190 }
191