1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2015-2016. |
4 | // Distributed under the Boost Software License, Version 1.0. |
5 | // (See 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/libs/move for documentation. |
9 | // |
10 | ////////////////////////////////////////////////////////////////////////////// |
11 | |
12 | #ifndef BOOST_MOVE_TEST_ORDER_TYPE_HPP |
13 | #define BOOST_MOVE_TEST_ORDER_TYPE_HPP |
14 | |
15 | #include <boost/config.hpp> |
16 | #include <boost/move/core.hpp> |
17 | #include <boost/move/detail/iterator_traits.hpp> |
18 | #include <cstddef> |
19 | #include <cstdio> |
20 | |
21 | struct order_perf_type |
22 | { |
23 | public: |
24 | std::size_t key; |
25 | std::size_t val; |
26 | |
27 | order_perf_type() |
28 | : key(), val() |
29 | { |
30 | ++num_elements; |
31 | } |
32 | |
33 | order_perf_type(const order_perf_type& other) |
34 | : key(other.key), val(other.val) |
35 | { |
36 | ++num_elements; |
37 | ++num_copy; |
38 | } |
39 | |
40 | order_perf_type & operator=(const order_perf_type& other) |
41 | { |
42 | ++num_copy; |
43 | key = other.key; |
44 | val = other.val; |
45 | return *this; |
46 | } |
47 | |
48 | ~order_perf_type () |
49 | { |
50 | --num_elements; |
51 | } |
52 | |
53 | static void reset_stats() |
54 | { |
55 | num_compare=0; |
56 | num_copy=0; |
57 | } |
58 | |
59 | friend bool operator< (const order_perf_type& left, const order_perf_type& right) |
60 | { ++num_compare; return left.key < right.key; } |
61 | |
62 | static boost::ulong_long_type num_compare; |
63 | static boost::ulong_long_type num_copy; |
64 | static boost::ulong_long_type num_elements; |
65 | }; |
66 | |
67 | boost::ulong_long_type order_perf_type::num_compare = 0; |
68 | boost::ulong_long_type order_perf_type::num_copy = 0; |
69 | boost::ulong_long_type order_perf_type::num_elements = 0; |
70 | |
71 | |
72 | struct order_move_type |
73 | { |
74 | BOOST_MOVABLE_BUT_NOT_COPYABLE(order_move_type) |
75 | |
76 | public: |
77 | std::size_t key; |
78 | std::size_t val; |
79 | |
80 | static const std::size_t moved_constr_mark = std::size_t(-1); |
81 | static const std::size_t moved_assign_mark = std::size_t(-2); |
82 | |
83 | order_move_type() |
84 | : key(0u), val(0u) |
85 | {} |
86 | |
87 | order_move_type(BOOST_RV_REF(order_move_type) other) |
88 | : key(other.key), val(other.val) |
89 | { |
90 | assert(this != &other); |
91 | other.key = other.val = std::size_t(-1); |
92 | } |
93 | |
94 | order_move_type & operator=(BOOST_RV_REF(order_move_type) other) |
95 | { |
96 | assert(this != &other); |
97 | key = other.key; |
98 | val = other.val; |
99 | other.key = other.val = std::size_t(-2); |
100 | return *this; |
101 | } |
102 | |
103 | friend bool operator< (const order_move_type& left, const order_move_type& right) |
104 | { return left.key < right.key; } |
105 | |
106 | ~order_move_type () |
107 | { |
108 | key = val = std::size_t(-3); |
109 | } |
110 | }; |
111 | |
112 | struct order_type_less |
113 | { |
114 | template<class T, class U> |
115 | bool operator()(const T &a, U const &b) const |
116 | { return a < b; } |
117 | }; |
118 | |
119 | template<class T> |
120 | inline bool is_order_type_ordered(T *elements, std::size_t element_count, bool stable = true) |
121 | { |
122 | for(std::size_t i = 1; i < element_count; ++i){ |
123 | if(order_type_less()(elements[i], elements[i-1])){ |
124 | std::printf(format: "\n Ord KO !!!!" ); |
125 | return false; |
126 | } |
127 | if( stable && !(order_type_less()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){ |
128 | std::printf(format: "\n Stb KO !!!! " ); |
129 | return false; |
130 | } |
131 | } |
132 | return true; |
133 | } |
134 | |
135 | namespace boost { |
136 | namespace movelib { |
137 | |
138 | inline bool is_sorted(::order_perf_type *first, ::order_perf_type *last, ::order_type_less) |
139 | { |
140 | if (first != last) { |
141 | const order_perf_type *next = first, *cur(first); |
142 | while (++next != last) { |
143 | if (!(cur->key < next->key || (cur->key == next->key && cur->val < next->val))) |
144 | return false; |
145 | cur = next; |
146 | } |
147 | } |
148 | return true; |
149 | } |
150 | |
151 | inline bool is_sorted(::order_move_type* first, ::order_move_type* last, ::order_type_less) |
152 | { |
153 | if (first != last) { |
154 | const order_move_type* next = first, * cur(first); |
155 | while (++next != last) { |
156 | if (!(cur->key < next->key || (cur->key == next->key && cur->val < next->val))) |
157 | return false; |
158 | cur = next; |
159 | } |
160 | } |
161 | return true; |
162 | } |
163 | |
164 | }} //boost::movelib |
165 | |
166 | template<class T> |
167 | inline bool is_key(T *elements, std::size_t element_count) |
168 | { |
169 | for(std::size_t i = 1; i < element_count; ++i){ |
170 | if(elements[i].key >= element_count){ |
171 | std::printf(format: "\n Key.key KO !!!!" ); |
172 | return false; |
173 | } |
174 | if(elements[i].val != std::size_t(-1)){ |
175 | std::printf(format: "\n Key.val KO !!!!" ); |
176 | return false; |
177 | } |
178 | } |
179 | return true; |
180 | } |
181 | |
182 | template<class T> |
183 | inline bool is_buffer(T *elements, std::size_t element_count) |
184 | { |
185 | for(std::size_t i = 1; i < element_count; ++i){ |
186 | if(elements[i].key != std::size_t(-1)){ |
187 | std::printf(format: "\n Buf.key KO !!!!" ); |
188 | return false; |
189 | } |
190 | if(elements[i].val >= element_count){ |
191 | std::printf(format: "\n Buf.val KO !!!!" ); |
192 | return false; |
193 | } |
194 | } |
195 | return true; |
196 | } |
197 | |
198 | |
199 | //size_type iterator |
200 | template <class T, class D> |
201 | class randit |
202 | { |
203 | public: |
204 | typedef std::random_access_iterator_tag iterator_category; |
205 | typedef T value_type; |
206 | typedef D difference_type; |
207 | typedef T* pointer; |
208 | typedef T& reference; |
209 | |
210 | private: |
211 | T* m_ptr; |
212 | |
213 | public: |
214 | explicit randit(T* ptr) |
215 | : m_ptr(ptr) |
216 | {} |
217 | |
218 | public: |
219 | |
220 | //Constructors |
221 | randit() |
222 | : m_ptr() //Value initialization to achieve "null iterators" (N3644) |
223 | {} |
224 | |
225 | randit(const randit& other) |
226 | : m_ptr(other.m_ptr) |
227 | {} |
228 | |
229 | randit & operator=(const randit& other) |
230 | { m_ptr = other.m_ptr; return *this; } |
231 | |
232 | //T* like operators |
233 | reference operator*() const |
234 | { return *m_ptr; } |
235 | |
236 | pointer operator->() const |
237 | { return m_ptr; } |
238 | |
239 | reference operator[](difference_type off) const |
240 | { return m_ptr[off]; } |
241 | |
242 | //Increment / Decrement |
243 | randit& operator++() |
244 | { ++m_ptr; return *this; } |
245 | |
246 | randit operator++(int) |
247 | { return randit(m_ptr++); } |
248 | |
249 | randit& operator--() |
250 | { --m_ptr; return *this; } |
251 | |
252 | randit operator--(int) |
253 | { return randit(m_ptr--); } |
254 | |
255 | //Arithmetic |
256 | randit& operator+=(difference_type off) |
257 | { m_ptr += off; return *this; } |
258 | |
259 | randit& operator-=(difference_type off) |
260 | { m_ptr -= off; return *this; } |
261 | |
262 | friend randit operator+(const randit &x, difference_type off) |
263 | { return randit(x.m_ptr+off); } |
264 | |
265 | friend randit operator+(difference_type off, randit right) |
266 | { right.m_ptr += off; return right; } |
267 | |
268 | friend randit operator-(randit left, difference_type off) |
269 | { left.m_ptr -= off; return left; } |
270 | |
271 | friend difference_type operator-(const randit &left, const randit& right) |
272 | { return difference_type(left.m_ptr - right.m_ptr); } |
273 | |
274 | //Comparison operators |
275 | friend bool operator== (const randit& l, const randit& r) |
276 | { return l.m_ptr == r.m_ptr; } |
277 | |
278 | friend bool operator!= (const randit& l, const randit& r) |
279 | { return l.m_ptr != r.m_ptr; } |
280 | |
281 | friend bool operator< (const randit& l, const randit& r) |
282 | { return l.m_ptr < r.m_ptr; } |
283 | |
284 | friend bool operator<= (const randit& l, const randit& r) |
285 | { return l.m_ptr <= r.m_ptr; } |
286 | |
287 | friend bool operator> (const randit& l, const randit& r) |
288 | { return l.m_ptr > r.m_ptr; } |
289 | |
290 | friend bool operator>= (const randit& l, const randit& r) |
291 | { return l.m_ptr >= r.m_ptr; } |
292 | }; |
293 | |
294 | struct less_int |
295 | { |
296 | bool operator()(int l, int r) |
297 | { return l < r; } |
298 | }; |
299 | |
300 | |
301 | #endif //BOOST_MOVE_TEST_ORDER_TYPE_HPP |
302 | |