1//
2// (C) Copyright Jeremy Siek 2000.
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//
7// Revision History:
8//
9// 17 July 2001: Added const to some member functions. (Jeremy Siek)
10// 05 May 2001: Removed static dummy_cons object. (Jeremy Siek)
11
12// See http://www.boost.org/libs/concept_check for documentation.
13
14#ifndef BOOST_CONCEPT_ARCHETYPES_HPP
15#define BOOST_CONCEPT_ARCHETYPES_HPP
16
17#include <boost/config.hpp>
18#include <boost/iterator.hpp>
19#include <boost/mpl/identity.hpp>
20#include <functional>
21
22namespace boost {
23
24 //===========================================================================
25 // Basic Archetype Classes
26
27 namespace detail {
28 class dummy_constructor { };
29 }
30
31 // A type that models no concept. The template parameter
32 // is only there so that null_archetype types can be created
33 // that have different type.
34 template <class T = int>
35 class null_archetype {
36 private:
37 null_archetype() { }
38 null_archetype(const null_archetype&) { }
39 null_archetype& operator=(const null_archetype&) { return *this; }
40 public:
41 null_archetype(detail::dummy_constructor) { }
42#ifndef __MWERKS__
43 template <class TT>
44 friend void dummy_friend(); // just to avoid warnings
45#endif
46 };
47
48 // This is a helper class that provides a way to get a reference to
49 // an object. The get() function will never be called at run-time
50 // (nothing in this file will) so this seemingly very bad function
51 // is really quite innocent. The name of this class needs to be
52 // changed.
53 template <class T>
54 class static_object
55 {
56 public:
57 static T& get()
58 {
59#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
60 return *reinterpret_cast<T*>(0);
61#else
62 static char d[sizeof(T)];
63 return *reinterpret_cast<T*>(d);
64#endif
65 }
66 };
67
68 template <class Base = null_archetype<> >
69 class default_constructible_archetype : public Base {
70 public:
71 default_constructible_archetype()
72 : Base(static_object<detail::dummy_constructor>::get()) { }
73 default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
74 };
75
76 template <class Base = null_archetype<> >
77 class assignable_archetype : public Base {
78 assignable_archetype() { }
79 assignable_archetype(const assignable_archetype&) { }
80 public:
81 assignable_archetype& operator=(const assignable_archetype&) {
82 return *this;
83 }
84 assignable_archetype(detail::dummy_constructor x) : Base(x) { }
85 };
86
87 template <class Base = null_archetype<> >
88 class copy_constructible_archetype : public Base {
89 public:
90 copy_constructible_archetype()
91 : Base(static_object<detail::dummy_constructor>::get()) { }
92 copy_constructible_archetype(const copy_constructible_archetype&)
93 : Base(static_object<detail::dummy_constructor>::get()) { }
94 copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
95 };
96
97 template <class Base = null_archetype<> >
98 class sgi_assignable_archetype : public Base {
99 public:
100 sgi_assignable_archetype(const sgi_assignable_archetype&)
101 : Base(static_object<detail::dummy_constructor>::get()) { }
102 sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
103 return *this;
104 }
105 sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
106 };
107
108 struct default_archetype_base {
109 default_archetype_base(detail::dummy_constructor) { }
110 };
111
112 // Careful, don't use same type for T and Base. That results in the
113 // conversion operator being invalid. Since T is often
114 // null_archetype, can't use null_archetype for Base.
115 template <class T, class Base = default_archetype_base>
116 class convertible_to_archetype : public Base {
117 private:
118 convertible_to_archetype() { }
119 convertible_to_archetype(const convertible_to_archetype& ) { }
120 convertible_to_archetype& operator=(const convertible_to_archetype&)
121 { return *this; }
122 public:
123 convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
124 operator const T&() const { return static_object<T>::get(); }
125 };
126
127 template <class T, class Base = default_archetype_base>
128 class convertible_from_archetype : public Base {
129 private:
130 convertible_from_archetype() { }
131 convertible_from_archetype(const convertible_from_archetype& ) { }
132 convertible_from_archetype& operator=(const convertible_from_archetype&)
133 { return *this; }
134 public:
135 convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
136 convertible_from_archetype(const T&) { }
137 convertible_from_archetype& operator=(const T&)
138 { return *this; }
139 };
140
141 class boolean_archetype {
142 public:
143 boolean_archetype(const boolean_archetype&) { }
144 operator bool() const { return true; }
145 boolean_archetype(detail::dummy_constructor) { }
146 private:
147 boolean_archetype() { }
148 boolean_archetype& operator=(const boolean_archetype&) { return *this; }
149 };
150
151 template <class Base = null_archetype<> >
152 class equality_comparable_archetype : public Base {
153 public:
154 equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
155 };
156 template <class Base>
157 boolean_archetype
158 operator==(const equality_comparable_archetype<Base>&,
159 const equality_comparable_archetype<Base>&)
160 {
161 return boolean_archetype(static_object<detail::dummy_constructor>::get());
162 }
163 template <class Base>
164 boolean_archetype
165 operator!=(const equality_comparable_archetype<Base>&,
166 const equality_comparable_archetype<Base>&)
167 {
168 return boolean_archetype(static_object<detail::dummy_constructor>::get());
169 }
170
171
172 template <class Base = null_archetype<> >
173 class equality_comparable2_first_archetype : public Base {
174 public:
175 equality_comparable2_first_archetype(detail::dummy_constructor x)
176 : Base(x) { }
177 };
178 template <class Base = null_archetype<> >
179 class equality_comparable2_second_archetype : public Base {
180 public:
181 equality_comparable2_second_archetype(detail::dummy_constructor x)
182 : Base(x) { }
183 };
184 template <class Base1, class Base2>
185 boolean_archetype
186 operator==(const equality_comparable2_first_archetype<Base1>&,
187 const equality_comparable2_second_archetype<Base2>&)
188 {
189 return boolean_archetype(static_object<detail::dummy_constructor>::get());
190 }
191 template <class Base1, class Base2>
192 boolean_archetype
193 operator!=(const equality_comparable2_first_archetype<Base1>&,
194 const equality_comparable2_second_archetype<Base2>&)
195 {
196 return boolean_archetype(static_object<detail::dummy_constructor>::get());
197 }
198
199
200 template <class Base = null_archetype<> >
201 class less_than_comparable_archetype : public Base {
202 public:
203 less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
204 };
205 template <class Base>
206 boolean_archetype
207 operator<(const less_than_comparable_archetype<Base>&,
208 const less_than_comparable_archetype<Base>&)
209 {
210 return boolean_archetype(static_object<detail::dummy_constructor>::get());
211 }
212
213
214
215 template <class Base = null_archetype<> >
216 class comparable_archetype : public Base {
217 public:
218 comparable_archetype(detail::dummy_constructor x) : Base(x) { }
219 };
220 template <class Base>
221 boolean_archetype
222 operator<(const comparable_archetype<Base>&,
223 const comparable_archetype<Base>&)
224 {
225 return boolean_archetype(static_object<detail::dummy_constructor>::get());
226 }
227 template <class Base>
228 boolean_archetype
229 operator<=(const comparable_archetype<Base>&,
230 const comparable_archetype<Base>&)
231 {
232 return boolean_archetype(static_object<detail::dummy_constructor>::get());
233 }
234 template <class Base>
235 boolean_archetype
236 operator>(const comparable_archetype<Base>&,
237 const comparable_archetype<Base>&)
238 {
239 return boolean_archetype(static_object<detail::dummy_constructor>::get());
240 }
241 template <class Base>
242 boolean_archetype
243 operator>=(const comparable_archetype<Base>&,
244 const comparable_archetype<Base>&)
245 {
246 return boolean_archetype(static_object<detail::dummy_constructor>::get());
247 }
248
249
250 // The purpose of the optags is so that one can specify
251 // exactly which types the operator< is defined between.
252 // This is useful for allowing the operations:
253 //
254 // A a; B b;
255 // a < b
256 // b < a
257 //
258 // without also allowing the combinations:
259 //
260 // a < a
261 // b < b
262 //
263 struct optag1 { };
264 struct optag2 { };
265 struct optag3 { };
266
267#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
268 template <class Base = null_archetype<>, class Tag = optag1 > \
269 class NAME##_first_archetype : public Base { \
270 public: \
271 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
272 }; \
273 \
274 template <class Base = null_archetype<>, class Tag = optag1 > \
275 class NAME##_second_archetype : public Base { \
276 public: \
277 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
278 }; \
279 \
280 template <class BaseFirst, class BaseSecond, class Tag> \
281 boolean_archetype \
282 operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
283 const NAME##_second_archetype<BaseSecond, Tag>&) \
284 { \
285 return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
286 }
287
288 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
289 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
290 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
291 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
292 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
293 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
294
295#define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
296 template <class Base = null_archetype<> > \
297 class NAME##_archetype : public Base { \
298 public: \
299 NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
300 NAME##_archetype(const NAME##_archetype&) \
301 : Base(static_object<detail::dummy_constructor>::get()) { } \
302 NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
303 }; \
304 template <class Base> \
305 NAME##_archetype<Base> \
306 operator OP (const NAME##_archetype<Base>&,\
307 const NAME##_archetype<Base>&) \
308 { \
309 return \
310 NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
311 }
312
313 BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
314 BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
315 BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
316 BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
317 BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
318
319 // As is, these are useless because of the return type.
320 // Need to invent a better way...
321#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
322 template <class Return, class Base = null_archetype<> > \
323 class NAME##_first_archetype : public Base { \
324 public: \
325 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
326 }; \
327 \
328 template <class Return, class Base = null_archetype<> > \
329 class NAME##_second_archetype : public Base { \
330 public: \
331 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
332 }; \
333 \
334 template <class Return, class BaseFirst, class BaseSecond> \
335 Return \
336 operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
337 const NAME##_second_archetype<Return, BaseSecond>&) \
338 { \
339 return Return(static_object<detail::dummy_constructor>::get()); \
340 }
341
342 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
343 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
344 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
345 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
346 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
347
348 //===========================================================================
349 // Function Object Archetype Classes
350
351 template <class Return>
352 class generator_archetype {
353 public:
354 const Return& operator()() {
355 return static_object<Return>::get();
356 }
357 };
358
359 class void_generator_archetype {
360 public:
361 void operator()() { }
362 };
363
364 template <class Arg, class Return>
365 class unary_function_archetype {
366 private:
367 unary_function_archetype() { }
368 public:
369 unary_function_archetype(detail::dummy_constructor) { }
370 const Return& operator()(const Arg&) const {
371 return static_object<Return>::get();
372 }
373 };
374
375 template <class Arg1, class Arg2, class Return>
376 class binary_function_archetype {
377 private:
378 binary_function_archetype() { }
379 public:
380 binary_function_archetype(detail::dummy_constructor) { }
381 const Return& operator()(const Arg1&, const Arg2&) const {
382 return static_object<Return>::get();
383 }
384 };
385
386 template <class Arg>
387 class unary_predicate_archetype {
388 typedef boolean_archetype Return;
389 unary_predicate_archetype() { }
390 public:
391 unary_predicate_archetype(detail::dummy_constructor) { }
392 const Return& operator()(const Arg&) const {
393 return static_object<Return>::get();
394 }
395 };
396
397 template <class Arg1, class Arg2, class Base = null_archetype<> >
398 class binary_predicate_archetype {
399 typedef boolean_archetype Return;
400 binary_predicate_archetype() { }
401 public:
402 binary_predicate_archetype(detail::dummy_constructor) { }
403 const Return& operator()(const Arg1&, const Arg2&) const {
404 return static_object<Return>::get();
405 }
406 };
407
408 //===========================================================================
409 // Iterator Archetype Classes
410
411 template <class T, int I = 0>
412 class input_iterator_archetype
413 {
414 private:
415 typedef input_iterator_archetype self;
416 public:
417 typedef std::input_iterator_tag iterator_category;
418 typedef T value_type;
419 struct reference {
420 operator const value_type&() const { return static_object<T>::get(); }
421 };
422 typedef const T* pointer;
423 typedef std::ptrdiff_t difference_type;
424 self& operator=(const self&) { return *this; }
425 bool operator==(const self&) const { return true; }
426 bool operator!=(const self&) const { return true; }
427 reference operator*() const { return reference(); }
428 self& operator++() { return *this; }
429 self operator++(int) { return *this; }
430 };
431
432 template <class T>
433 class input_iterator_archetype_no_proxy
434 {
435 private:
436 typedef input_iterator_archetype_no_proxy self;
437 public:
438 typedef std::input_iterator_tag iterator_category;
439 typedef T value_type;
440 typedef const T& reference;
441 typedef const T* pointer;
442 typedef std::ptrdiff_t difference_type;
443 self& operator=(const self&) { return *this; }
444 bool operator==(const self&) const { return true; }
445 bool operator!=(const self&) const { return true; }
446 reference operator*() const { return static_object<T>::get(); }
447 self& operator++() { return *this; }
448 self operator++(int) { return *this; }
449 };
450
451 template <class T>
452 struct output_proxy {
453 output_proxy& operator=(const T&) { return *this; }
454 };
455
456 template <class T>
457 class output_iterator_archetype
458 {
459 public:
460 typedef output_iterator_archetype self;
461 public:
462 typedef std::output_iterator_tag iterator_category;
463 typedef output_proxy<T> value_type;
464 typedef output_proxy<T> reference;
465 typedef void pointer;
466 typedef void difference_type;
467 output_iterator_archetype(detail::dummy_constructor) { }
468 output_iterator_archetype(const self&) { }
469 self& operator=(const self&) { return *this; }
470 bool operator==(const self&) const { return true; }
471 bool operator!=(const self&) const { return true; }
472 reference operator*() const { return output_proxy<T>(); }
473 self& operator++() { return *this; }
474 self operator++(int) { return *this; }
475 private:
476 output_iterator_archetype() { }
477 };
478
479 template <class T>
480 class input_output_iterator_archetype
481 {
482 private:
483 typedef input_output_iterator_archetype self;
484 struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { };
485 public:
486 typedef in_out_tag iterator_category;
487 typedef T value_type;
488 struct reference {
489 reference& operator=(const T&) { return *this; }
490 operator value_type() { return static_object<T>::get(); }
491 };
492 typedef const T* pointer;
493 typedef std::ptrdiff_t difference_type;
494 input_output_iterator_archetype() { }
495 self& operator=(const self&) { return *this; }
496 bool operator==(const self&) const { return true; }
497 bool operator!=(const self&) const { return true; }
498 reference operator*() const { return reference(); }
499 self& operator++() { return *this; }
500 self operator++(int) { return *this; }
501 };
502
503 template <class T>
504 class forward_iterator_archetype
505 {
506 public:
507 typedef forward_iterator_archetype self;
508 public:
509 typedef std::forward_iterator_tag iterator_category;
510 typedef T value_type;
511 typedef const T& reference;
512 typedef T const* pointer;
513 typedef std::ptrdiff_t difference_type;
514 forward_iterator_archetype() { }
515 self& operator=(const self&) { return *this; }
516 bool operator==(const self&) const { return true; }
517 bool operator!=(const self&) const { return true; }
518 reference operator*() const { return static_object<T>::get(); }
519 self& operator++() { return *this; }
520 self operator++(int) { return *this; }
521 };
522
523 template <class T>
524 class mutable_forward_iterator_archetype
525 {
526 public:
527 typedef mutable_forward_iterator_archetype self;
528 public:
529 typedef std::forward_iterator_tag iterator_category;
530 typedef T value_type;
531 typedef T& reference;
532 typedef T* pointer;
533 typedef std::ptrdiff_t difference_type;
534 mutable_forward_iterator_archetype() { }
535 self& operator=(const self&) { return *this; }
536 bool operator==(const self&) const { return true; }
537 bool operator!=(const self&) const { return true; }
538 reference operator*() const { return static_object<T>::get(); }
539 self& operator++() { return *this; }
540 self operator++(int) { return *this; }
541 };
542
543 template <class T>
544 class bidirectional_iterator_archetype
545 {
546 public:
547 typedef bidirectional_iterator_archetype self;
548 public:
549 typedef std::bidirectional_iterator_tag iterator_category;
550 typedef T value_type;
551 typedef const T& reference;
552 typedef T* pointer;
553 typedef std::ptrdiff_t difference_type;
554 bidirectional_iterator_archetype() { }
555 self& operator=(const self&) { return *this; }
556 bool operator==(const self&) const { return true; }
557 bool operator!=(const self&) const { return true; }
558 reference operator*() const { return static_object<T>::get(); }
559 self& operator++() { return *this; }
560 self operator++(int) { return *this; }
561 self& operator--() { return *this; }
562 self operator--(int) { return *this; }
563 };
564
565 template <class T>
566 class mutable_bidirectional_iterator_archetype
567 {
568 public:
569 typedef mutable_bidirectional_iterator_archetype self;
570 public:
571 typedef std::bidirectional_iterator_tag iterator_category;
572 typedef T value_type;
573 typedef T& reference;
574 typedef T* pointer;
575 typedef std::ptrdiff_t difference_type;
576 mutable_bidirectional_iterator_archetype() { }
577 self& operator=(const self&) { return *this; }
578 bool operator==(const self&) const { return true; }
579 bool operator!=(const self&) const { return true; }
580 reference operator*() const { return static_object<T>::get(); }
581 self& operator++() { return *this; }
582 self operator++(int) { return *this; }
583 self& operator--() { return *this; }
584 self operator--(int) { return *this; }
585 };
586
587 template <class T>
588 class random_access_iterator_archetype
589 {
590 public:
591 typedef random_access_iterator_archetype self;
592 public:
593 typedef std::random_access_iterator_tag iterator_category;
594 typedef T value_type;
595 typedef const T& reference;
596 typedef T* pointer;
597 typedef std::ptrdiff_t difference_type;
598 random_access_iterator_archetype() { }
599 self& operator=(const self&) { return *this; }
600 bool operator==(const self&) const { return true; }
601 bool operator!=(const self&) const { return true; }
602 reference operator*() const { return static_object<T>::get(); }
603 self& operator++() { return *this; }
604 self operator++(int) { return *this; }
605 self& operator--() { return *this; }
606 self operator--(int) { return *this; }
607 reference operator[](difference_type) const
608 { return static_object<T>::get(); }
609 self& operator+=(difference_type) { return *this; }
610 self& operator-=(difference_type) { return *this; }
611 difference_type operator-(const self&) const
612 { return difference_type(); }
613 self operator+(difference_type) const { return *this; }
614 self operator-(difference_type) const { return *this; }
615 bool operator<(const self&) const { return true; }
616 bool operator<=(const self&) const { return true; }
617 bool operator>(const self&) const { return true; }
618 bool operator>=(const self&) const { return true; }
619 };
620 template <class T>
621 random_access_iterator_archetype<T>
622 operator+(typename random_access_iterator_archetype<T>::difference_type,
623 const random_access_iterator_archetype<T>& x)
624 { return x; }
625
626
627 template <class T>
628 class mutable_random_access_iterator_archetype
629 {
630 public:
631 typedef mutable_random_access_iterator_archetype self;
632 public:
633 typedef std::random_access_iterator_tag iterator_category;
634 typedef T value_type;
635 typedef T& reference;
636 typedef T* pointer;
637 typedef std::ptrdiff_t difference_type;
638 mutable_random_access_iterator_archetype() { }
639 self& operator=(const self&) { return *this; }
640 bool operator==(const self&) const { return true; }
641 bool operator!=(const self&) const { return true; }
642 reference operator*() const { return static_object<T>::get(); }
643 self& operator++() { return *this; }
644 self operator++(int) { return *this; }
645 self& operator--() { return *this; }
646 self operator--(int) { return *this; }
647 reference operator[](difference_type) const
648 { return static_object<T>::get(); }
649 self& operator+=(difference_type) { return *this; }
650 self& operator-=(difference_type) { return *this; }
651 difference_type operator-(const self&) const
652 { return difference_type(); }
653 self operator+(difference_type) const { return *this; }
654 self operator-(difference_type) const { return *this; }
655 bool operator<(const self&) const { return true; }
656 bool operator<=(const self&) const { return true; }
657 bool operator>(const self&) const { return true; }
658 bool operator>=(const self&) const { return true; }
659 };
660 template <class T>
661 mutable_random_access_iterator_archetype<T>
662 operator+
663 (typename mutable_random_access_iterator_archetype<T>::difference_type,
664 const mutable_random_access_iterator_archetype<T>& x)
665 { return x; }
666
667} // namespace boost
668
669#endif // BOOST_CONCEPT_ARCHETYPES_H
670

source code of boost/boost/concept_archetype.hpp