1 | /////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/container for documentation. |
8 | // |
9 | /////////////////////////////////////////////////////////////////////////// |
10 | |
11 | #ifndef BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER |
12 | #define |
13 | |
14 | #include <boost/container/detail/config_begin.hpp> |
15 | #include <boost/container/detail/workaround.hpp> |
16 | #include <boost/move/utility_core.hpp> |
17 | #include <ostream> |
18 | #include <climits> |
19 | #include <boost/assert.hpp> |
20 | |
21 | namespace boost { |
22 | namespace container { |
23 | namespace test { |
24 | |
25 | template<class T> |
26 | struct is_copyable; |
27 | |
28 | template<> |
29 | struct is_copyable<int> |
30 | { |
31 | static const bool value = true; |
32 | }; |
33 | |
34 | template<class T> |
35 | struct is_move_assignable |
36 | { |
37 | static const bool value = true; |
38 | }; |
39 | |
40 | |
41 | |
42 | ///////////////////////// |
43 | // |
44 | // movable_int |
45 | // |
46 | ///////////////////////// |
47 | class movable_int |
48 | { |
49 | BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int) |
50 | |
51 | public: |
52 | |
53 | static unsigned int count; |
54 | |
55 | movable_int() |
56 | : m_int(0) |
57 | { ++count; } |
58 | |
59 | explicit movable_int(int a) |
60 | : m_int(a) |
61 | { |
62 | //Disallow INT_MIN |
63 | BOOST_ASSERT(this->m_int != INT_MIN); |
64 | ++count; |
65 | } |
66 | |
67 | movable_int(BOOST_RV_REF(movable_int) mmi) |
68 | : m_int(mmi.m_int) |
69 | { |
70 | BOOST_ASSERT(&mmi != this); |
71 | mmi.m_int = 0; ++count; |
72 | } |
73 | |
74 | movable_int & operator= (BOOST_RV_REF(movable_int) mmi) |
75 | { |
76 | BOOST_ASSERT(&mmi != this); |
77 | this->m_int = mmi.m_int; mmi.m_int = 0; return *this; |
78 | } |
79 | |
80 | movable_int & operator= (int i) |
81 | { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; } |
82 | |
83 | ~movable_int() |
84 | { |
85 | //Double destructor called |
86 | BOOST_ASSERT(this->m_int != INT_MIN); |
87 | this->m_int = INT_MIN; |
88 | --count; |
89 | } |
90 | |
91 | friend bool operator ==(const movable_int &l, const movable_int &r) |
92 | { return l.m_int == r.m_int; } |
93 | |
94 | friend bool operator !=(const movable_int &l, const movable_int &r) |
95 | { return l.m_int != r.m_int; } |
96 | |
97 | friend bool operator <(const movable_int &l, const movable_int &r) |
98 | { return l.m_int < r.m_int; } |
99 | |
100 | friend bool operator <=(const movable_int &l, const movable_int &r) |
101 | { return l.m_int <= r.m_int; } |
102 | |
103 | friend bool operator >=(const movable_int &l, const movable_int &r) |
104 | { return l.m_int >= r.m_int; } |
105 | |
106 | friend bool operator >(const movable_int &l, const movable_int &r) |
107 | { return l.m_int > r.m_int; } |
108 | |
109 | int get_int() const |
110 | { return m_int; } |
111 | |
112 | friend bool operator==(const movable_int &l, int r) |
113 | { return l.get_int() == r; } |
114 | |
115 | friend bool operator==(int l, const movable_int &r) |
116 | { return l == r.get_int(); } |
117 | |
118 | friend bool operator<(const movable_int &l, int r) |
119 | { return l.get_int() < r; } |
120 | |
121 | friend bool operator<(int l, const movable_int &r) |
122 | { return l < r.get_int(); } |
123 | |
124 | friend std::size_t hash_value(const movable_int &v) |
125 | { return (std::size_t)v.get_int(); } |
126 | |
127 | private: |
128 | int m_int; |
129 | }; |
130 | |
131 | unsigned int movable_int::count = 0; |
132 | |
133 | inline movable_int produce_movable_int() |
134 | { return movable_int(); } |
135 | |
136 | template<class E, class T> |
137 | std::basic_ostream<E, T> & operator<<(std::basic_ostream<E, T> & os, movable_int const & p) |
138 | { os << p.get_int(); return os; } |
139 | |
140 | template<> |
141 | struct is_copyable<movable_int> |
142 | { |
143 | static const bool value = false; |
144 | }; |
145 | |
146 | ///////////////////////// |
147 | // |
148 | // moveconstruct_int |
149 | // |
150 | ///////////////////////// |
151 | class moveconstruct_int |
152 | { |
153 | BOOST_MOVABLE_BUT_NOT_COPYABLE(moveconstruct_int) |
154 | |
155 | moveconstruct_int& operator= (BOOST_RV_REF(moveconstruct_int) mmi); |
156 | |
157 | public: |
158 | |
159 | static unsigned int count; |
160 | |
161 | moveconstruct_int() |
162 | : m_int(0) |
163 | { |
164 | ++count; |
165 | } |
166 | |
167 | explicit moveconstruct_int(int a) |
168 | : m_int(a) |
169 | { |
170 | //Disallow INT_MIN |
171 | BOOST_ASSERT(this->m_int != INT_MIN); |
172 | ++count; |
173 | } |
174 | |
175 | moveconstruct_int(BOOST_RV_REF(moveconstruct_int) mmi) |
176 | : m_int(mmi.m_int) |
177 | { |
178 | BOOST_ASSERT(&mmi != this); |
179 | mmi.m_int = 0; ++count; |
180 | } |
181 | |
182 | moveconstruct_int& operator= (int i) |
183 | { |
184 | this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; |
185 | } |
186 | |
187 | ~moveconstruct_int() |
188 | { |
189 | //Double destructor called |
190 | BOOST_ASSERT(this->m_int != INT_MIN); |
191 | this->m_int = INT_MIN; |
192 | --count; |
193 | } |
194 | |
195 | friend bool operator ==(const moveconstruct_int& l, const moveconstruct_int& r) |
196 | { |
197 | return l.m_int == r.m_int; |
198 | } |
199 | |
200 | friend bool operator !=(const moveconstruct_int& l, const moveconstruct_int& r) |
201 | { |
202 | return l.m_int != r.m_int; |
203 | } |
204 | |
205 | friend bool operator <(const moveconstruct_int& l, const moveconstruct_int& r) |
206 | { |
207 | return l.m_int < r.m_int; |
208 | } |
209 | |
210 | friend bool operator <=(const moveconstruct_int& l, const moveconstruct_int& r) |
211 | { |
212 | return l.m_int <= r.m_int; |
213 | } |
214 | |
215 | friend bool operator >=(const moveconstruct_int& l, const moveconstruct_int& r) |
216 | { |
217 | return l.m_int >= r.m_int; |
218 | } |
219 | |
220 | friend bool operator >(const moveconstruct_int& l, const moveconstruct_int& r) |
221 | { |
222 | return l.m_int > r.m_int; |
223 | } |
224 | |
225 | int get_int() const |
226 | { |
227 | return m_int; |
228 | } |
229 | |
230 | friend bool operator==(const moveconstruct_int& l, int r) |
231 | { |
232 | return l.get_int() == r; |
233 | } |
234 | |
235 | friend bool operator==(int l, const moveconstruct_int& r) |
236 | { |
237 | return l == r.get_int(); |
238 | } |
239 | |
240 | friend bool operator<(const moveconstruct_int& l, int r) |
241 | { |
242 | return l.get_int() < r; |
243 | } |
244 | |
245 | friend bool operator<(int l, const moveconstruct_int& r) |
246 | { |
247 | return l < r.get_int(); |
248 | } |
249 | |
250 | friend std::size_t hash_value(const moveconstruct_int& v) |
251 | { |
252 | return (std::size_t)v.get_int(); |
253 | } |
254 | |
255 | private: |
256 | int m_int; |
257 | }; |
258 | |
259 | unsigned int moveconstruct_int::count = 0; |
260 | |
261 | inline moveconstruct_int produce_movableconstruct_int() |
262 | { |
263 | return moveconstruct_int(); |
264 | } |
265 | |
266 | template<class E, class T> |
267 | std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& os, moveconstruct_int const& p) |
268 | { |
269 | os << p.get_int(); return os; |
270 | } |
271 | |
272 | template<> |
273 | struct is_copyable<moveconstruct_int> |
274 | { |
275 | static const bool value = false; |
276 | }; |
277 | |
278 | template<> |
279 | struct is_move_assignable<moveconstruct_int> |
280 | { |
281 | static const bool value = false; |
282 | }; |
283 | |
284 | |
285 | ///////////////////////// |
286 | // |
287 | // movable_and_copyable_int |
288 | // |
289 | ///////////////////////// |
290 | class movable_and_copyable_int |
291 | { |
292 | BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int) |
293 | |
294 | public: |
295 | |
296 | static unsigned int count; |
297 | |
298 | movable_and_copyable_int() |
299 | : m_int(0) |
300 | { ++count; } |
301 | |
302 | explicit movable_and_copyable_int(int a) |
303 | : m_int(a) |
304 | { |
305 | //Disallow INT_MIN |
306 | BOOST_ASSERT(this->m_int != INT_MIN); |
307 | ++count; |
308 | } |
309 | |
310 | movable_and_copyable_int(const movable_and_copyable_int& mmi) |
311 | : m_int(mmi.m_int) |
312 | { |
313 | BOOST_ASSERT(&mmi != this); |
314 | ++count; |
315 | } |
316 | |
317 | movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi) |
318 | : m_int(mmi.m_int) |
319 | { |
320 | BOOST_ASSERT(&mmi != this); |
321 | mmi.m_int = 0; ++count; |
322 | } |
323 | |
324 | ~movable_and_copyable_int() |
325 | { |
326 | //Double destructor called |
327 | BOOST_ASSERT(this->m_int != INT_MIN); |
328 | this->m_int = INT_MIN; |
329 | --count; |
330 | } |
331 | |
332 | movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi) |
333 | { this->m_int = mi.m_int; return *this; } |
334 | |
335 | movable_and_copyable_int & operator= (BOOST_RV_REF(movable_and_copyable_int) mmi) |
336 | { |
337 | BOOST_ASSERT(&mmi != this); |
338 | this->m_int = mmi.m_int; mmi.m_int = 0; return *this; |
339 | } |
340 | |
341 | movable_and_copyable_int & operator= (int i) |
342 | { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; } |
343 | |
344 | friend bool operator ==(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
345 | { return l.m_int == r.m_int; } |
346 | |
347 | friend bool operator !=(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
348 | { return l.m_int != r.m_int; } |
349 | |
350 | friend bool operator <(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
351 | { return l.m_int < r.m_int; } |
352 | |
353 | friend bool operator <=(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
354 | { return l.m_int <= r.m_int; } |
355 | |
356 | friend bool operator >=(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
357 | { return l.m_int >= r.m_int; } |
358 | |
359 | friend bool operator >(const movable_and_copyable_int &l, const movable_and_copyable_int &r) |
360 | { return l.m_int > r.m_int; } |
361 | |
362 | int get_int() const |
363 | { return m_int; } |
364 | |
365 | friend bool operator==(const movable_and_copyable_int &l, int r) |
366 | { return l.get_int() == r; } |
367 | |
368 | friend bool operator==(int l, const movable_and_copyable_int &r) |
369 | { return l == r.get_int(); } |
370 | |
371 | friend bool operator<(const movable_and_copyable_int &l, int r) |
372 | { return l.get_int() < r; } |
373 | |
374 | friend bool operator<(int l, const movable_and_copyable_int &r) |
375 | { return l < r.get_int(); } |
376 | |
377 | friend std::size_t hash_value(const movable_and_copyable_int &v) |
378 | { return (std::size_t)v.get_int(); } |
379 | |
380 | private: |
381 | int m_int; |
382 | }; |
383 | |
384 | unsigned int movable_and_copyable_int::count = 0; |
385 | |
386 | inline movable_and_copyable_int produce_movable_and_copyable_int() |
387 | { return movable_and_copyable_int(); } |
388 | |
389 | template<class E, class T> |
390 | std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, movable_and_copyable_int const & p) |
391 | { os << p.get_int(); return os; } |
392 | |
393 | template<> |
394 | struct is_copyable<movable_and_copyable_int> |
395 | { |
396 | static const bool value = true; |
397 | }; |
398 | |
399 | |
400 | ///////////////////////// |
401 | // |
402 | // copyable_int |
403 | // |
404 | ///////////////////////// |
405 | class copyable_int |
406 | { |
407 | public: |
408 | |
409 | static unsigned int count; |
410 | |
411 | copyable_int() |
412 | : m_int(0) |
413 | { ++count; } |
414 | |
415 | explicit copyable_int(int a) |
416 | : m_int(a) |
417 | { |
418 | //Disallow INT_MIN |
419 | BOOST_ASSERT(this->m_int != INT_MIN); |
420 | ++count; |
421 | } |
422 | |
423 | copyable_int(const copyable_int& mmi) |
424 | : m_int(mmi.m_int) |
425 | { ++count; } |
426 | |
427 | copyable_int & operator= (int i) |
428 | { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; } |
429 | |
430 | copyable_int & operator= (const copyable_int &ci) |
431 | { this->m_int = ci.m_int; BOOST_ASSERT(this->m_int != INT_MIN); return *this; } |
432 | |
433 | ~copyable_int() |
434 | { |
435 | //Double destructor called |
436 | BOOST_ASSERT(this->m_int != INT_MIN); |
437 | this->m_int = INT_MIN; |
438 | --count; |
439 | } |
440 | |
441 | friend bool operator ==(const copyable_int &l, const copyable_int &r) |
442 | { return l.m_int == r.m_int; } |
443 | |
444 | friend bool operator !=(const copyable_int &l, const copyable_int &r) |
445 | { return l.m_int != r.m_int; } |
446 | |
447 | friend bool operator <(const copyable_int &l, const copyable_int &r) |
448 | { return l.m_int < r.m_int; } |
449 | |
450 | friend bool operator <=(const copyable_int &l, const copyable_int &r) |
451 | { return l.m_int <= r.m_int; } |
452 | |
453 | friend bool operator >=(const copyable_int &l, const copyable_int &r) |
454 | { return l.m_int >= r.m_int; } |
455 | |
456 | friend bool operator >(const copyable_int &l, const copyable_int &r) |
457 | { return l.m_int > r.m_int; } |
458 | |
459 | int get_int() const |
460 | { return m_int; } |
461 | |
462 | friend bool operator==(const copyable_int &l, int r) |
463 | { return l.get_int() == r; } |
464 | |
465 | friend bool operator==(int l, const copyable_int &r) |
466 | { return l == r.get_int(); } |
467 | |
468 | friend bool operator<(const copyable_int &l, int r) |
469 | { return l.get_int() < r; } |
470 | |
471 | friend bool operator<(int l, const copyable_int &r) |
472 | { return l < r.get_int(); } |
473 | |
474 | friend std::size_t hash_value(const copyable_int &v) |
475 | { return (std::size_t)v.get_int(); } |
476 | |
477 | private: |
478 | int m_int; |
479 | }; |
480 | |
481 | unsigned int copyable_int::count = 0; |
482 | |
483 | inline copyable_int produce_copyable_int() |
484 | { return copyable_int(); } |
485 | |
486 | template<class E, class T> |
487 | std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, copyable_int const & p) |
488 | { os << p.get_int(); return os; } |
489 | |
490 | template<> |
491 | struct is_copyable<copyable_int> |
492 | { |
493 | static const bool value = true; |
494 | }; |
495 | |
496 | ///////////////////////// |
497 | // |
498 | // non_copymovable_int |
499 | // |
500 | ///////////////////////// |
501 | class non_copymovable_int |
502 | { |
503 | non_copymovable_int(const non_copymovable_int& mmi); |
504 | non_copymovable_int & operator= (const non_copymovable_int &mi); |
505 | |
506 | public: |
507 | |
508 | static unsigned int count; |
509 | |
510 | non_copymovable_int() |
511 | : m_int(0) |
512 | { ++count; } |
513 | |
514 | explicit non_copymovable_int(int a) |
515 | : m_int(a) |
516 | { ++count; } |
517 | |
518 | ~non_copymovable_int() |
519 | { m_int = 0; --count; } |
520 | |
521 | bool operator ==(const non_copymovable_int &mi) const |
522 | { return this->m_int == mi.m_int; } |
523 | |
524 | bool operator !=(const non_copymovable_int &mi) const |
525 | { return this->m_int != mi.m_int; } |
526 | |
527 | bool operator <(const non_copymovable_int &mi) const |
528 | { return this->m_int < mi.m_int; } |
529 | |
530 | bool operator <=(const non_copymovable_int &mi) const |
531 | { return this->m_int <= mi.m_int; } |
532 | |
533 | bool operator >=(const non_copymovable_int &mi) const |
534 | { return this->m_int >= mi.m_int; } |
535 | |
536 | bool operator >(const non_copymovable_int &mi) const |
537 | { return this->m_int > mi.m_int; } |
538 | |
539 | int get_int() const |
540 | { return m_int; } |
541 | |
542 | friend bool operator==(const non_copymovable_int &l, int r) |
543 | { return l.get_int() == r; } |
544 | |
545 | friend bool operator==(int l, const non_copymovable_int &r) |
546 | { return l == r.get_int(); } |
547 | |
548 | friend bool operator<(const non_copymovable_int &l, int r) |
549 | { return l.get_int() < r; } |
550 | |
551 | friend bool operator<(int l, const non_copymovable_int &r) |
552 | { return l < r.get_int(); } |
553 | |
554 | friend std::size_t hash_value(const non_copymovable_int &v) |
555 | { return (std::size_t)v.get_int(); } |
556 | |
557 | private: |
558 | int m_int; |
559 | }; |
560 | |
561 | unsigned int non_copymovable_int::count = 0; |
562 | |
563 | template<class T> |
564 | struct life_count |
565 | { |
566 | static bool check(unsigned) { return true; } |
567 | }; |
568 | |
569 | template<> |
570 | struct life_count< movable_int > |
571 | { |
572 | static bool check(unsigned c) |
573 | { return c == movable_int::count; } |
574 | }; |
575 | |
576 | template<> |
577 | struct life_count< copyable_int > |
578 | { |
579 | static bool check(unsigned c) |
580 | { return c == copyable_int::count; } |
581 | }; |
582 | |
583 | template<> |
584 | struct life_count< movable_and_copyable_int > |
585 | { |
586 | static bool check(unsigned c) |
587 | { return c == movable_and_copyable_int::count; } |
588 | }; |
589 | |
590 | template<> |
591 | struct life_count< non_copymovable_int > |
592 | { |
593 | static bool check(unsigned c) |
594 | { return c == non_copymovable_int::count; } |
595 | }; |
596 | |
597 | } //namespace test { |
598 | } //namespace container { |
599 | } //namespace boost { |
600 | |
601 | #include <boost/container/detail/config_end.hpp> |
602 | |
603 | #endif //#ifndef BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER |
604 | |