2 // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
3 // sell and distribute this software is granted provided this
4 // copyright notice appears in all copies. This software is provided
5 // "as is" without express or implied warranty, and with no claim as
6 // to its suitability for any purpose.
10 // 17 July 2001: Added const to some member functions. (Jeremy Siek)
11 // 05 May 2001: Removed static dummy_cons object. (Jeremy Siek)
13 // See http://www.boost.org/libs/concept_check for documentation.
15 #ifndef BOOST_CONCEPT_ARCHETYPES_HPP
16 #define BOOST_CONCEPT_ARCHETYPES_HPP
18 #include <boost/config.hpp>
19 #include <boost/iterator.hpp>
24 //===========================================================================
25 // Basic Archetype Classes
28 class dummy_constructor { };
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 {
38 null_archetype(const null_archetype&) { }
39 null_archetype& operator=(const null_archetype&) { return *this; }
41 null_archetype(detail::dummy_constructor) { }
44 friend void dummy_friend(); // just to avoid warnings
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
57 static char d[sizeof(T)];
58 return *reinterpret_cast<T*>(d);
62 template <class Base = null_archetype<> >
63 class default_constructible_archetype : public Base {
65 default_constructible_archetype()
66 : Base(static_object<detail::dummy_constructor>::get()) { }
67 default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
70 template <class Base = null_archetype<> >
71 class assignable_archetype : public Base {
72 assignable_archetype() { }
73 assignable_archetype(const assignable_archetype&) { }
75 assignable_archetype& operator=(const assignable_archetype&) {
78 assignable_archetype(detail::dummy_constructor x) : Base(x) { }
81 template <class Base = null_archetype<> >
82 class copy_constructible_archetype : public Base {
84 copy_constructible_archetype()
85 : Base(static_object<detail::dummy_constructor>::get()) { }
86 copy_constructible_archetype(const copy_constructible_archetype&)
87 : Base(static_object<detail::dummy_constructor>::get()) { }
88 copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
91 template <class Base = null_archetype<> >
92 class sgi_assignable_archetype : public Base {
94 sgi_assignable_archetype(const sgi_assignable_archetype&)
95 : Base(static_object<detail::dummy_constructor>::get()) { }
96 sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
99 sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
102 struct default_archetype_base {
103 default_archetype_base(detail::dummy_constructor) { }
106 // Careful, don't use same type for T and Base. That results in the
107 // conversion operator being invalid. Since T is often
108 // null_archetype, can't use null_archetype for Base.
109 template <class T, class Base = default_archetype_base>
110 class convertible_to_archetype : public Base {
112 convertible_to_archetype() { }
113 convertible_to_archetype(const convertible_to_archetype& ) { }
114 convertible_to_archetype& operator=(const convertible_to_archetype&)
117 convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
118 operator const T&() const { return static_object<T>::get(); }
121 template <class T, class Base = default_archetype_base>
122 class convertible_from_archetype : public Base {
124 convertible_from_archetype() { }
125 convertible_from_archetype(const convertible_from_archetype& ) { }
126 convertible_from_archetype& operator=(const convertible_from_archetype&)
129 convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
130 convertible_from_archetype(const T&) { }
131 convertible_from_archetype& operator=(const T&)
135 class boolean_archetype {
137 boolean_archetype(const boolean_archetype&) { }
138 operator bool() const { return true; }
139 boolean_archetype(detail::dummy_constructor) { }
141 boolean_archetype() { }
142 boolean_archetype& operator=(const boolean_archetype&) { return *this; }
145 template <class Base = null_archetype<> >
146 class equality_comparable_archetype : public Base {
148 equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
150 template <class Base>
152 operator==(const equality_comparable_archetype<Base>&,
153 const equality_comparable_archetype<Base>&)
155 return boolean_archetype(static_object<detail::dummy_constructor>::get());
157 template <class Base>
159 operator!=(const equality_comparable_archetype<Base>&,
160 const equality_comparable_archetype<Base>&)
162 return boolean_archetype(static_object<detail::dummy_constructor>::get());
166 template <class Base = null_archetype<> >
167 class equality_comparable2_first_archetype : public Base {
169 equality_comparable2_first_archetype(detail::dummy_constructor x)
172 template <class Base = null_archetype<> >
173 class equality_comparable2_second_archetype : public Base {
175 equality_comparable2_second_archetype(detail::dummy_constructor x)
178 template <class Base1, class Base2>
180 operator==(const equality_comparable2_first_archetype<Base1>&,
181 const equality_comparable2_second_archetype<Base2>&)
183 return boolean_archetype(static_object<detail::dummy_constructor>::get());
185 template <class Base1, class Base2>
187 operator!=(const equality_comparable2_first_archetype<Base1>&,
188 const equality_comparable2_second_archetype<Base2>&)
190 return boolean_archetype(static_object<detail::dummy_constructor>::get());
194 template <class Base = null_archetype<> >
195 class less_than_comparable_archetype : public Base {
197 less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
199 template <class Base>
201 operator<(const less_than_comparable_archetype<Base>&,
202 const less_than_comparable_archetype<Base>&)
204 return boolean_archetype(static_object<detail::dummy_constructor>::get());
209 template <class Base = null_archetype<> >
210 class comparable_archetype : public Base {
212 comparable_archetype(detail::dummy_constructor x) : Base(x) { }
214 template <class Base>
216 operator<(const comparable_archetype<Base>&,
217 const comparable_archetype<Base>&)
219 return boolean_archetype(static_object<detail::dummy_constructor>::get());
221 template <class Base>
223 operator<=(const comparable_archetype<Base>&,
224 const comparable_archetype<Base>&)
226 return boolean_archetype(static_object<detail::dummy_constructor>::get());
228 template <class Base>
230 operator>(const comparable_archetype<Base>&,
231 const comparable_archetype<Base>&)
233 return boolean_archetype(static_object<detail::dummy_constructor>::get());
235 template <class Base>
237 operator>=(const comparable_archetype<Base>&,
238 const comparable_archetype<Base>&)
240 return boolean_archetype(static_object<detail::dummy_constructor>::get());
244 // The purpose of the optags is so that one can specify
245 // exactly which types the operator< is defined between.
246 // This is useful for allowing the operations:
252 // without also allowing the combinations:
261 #define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
262 template <class Base = null_archetype<>, class Tag = optag1 > \
263 class NAME##_first_archetype : public Base { \
265 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
268 template <class Base = null_archetype<>, class Tag = optag1 > \
269 class NAME##_second_archetype : public Base { \
271 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
274 template <class BaseFirst, class BaseSecond, class Tag> \
276 operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
277 const NAME##_second_archetype<BaseSecond, Tag>&) \
279 return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
282 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
283 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
284 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
285 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
286 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
287 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
289 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
290 template <class Base = null_archetype<> > \
291 class NAME##_archetype : public Base { \
293 NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
294 NAME##_archetype(const NAME##_archetype&) \
295 : Base(static_object<detail::dummy_constructor>::get()) { } \
296 NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
298 template <class Base> \
299 NAME##_archetype<Base> \
300 operator OP (const NAME##_archetype<Base>&,\
301 const NAME##_archetype<Base>&) \
304 NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
307 BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
308 BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
309 BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
310 BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
311 BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
313 // As is, these are useless because of the return type.
314 // Need to invent a better way...
315 #define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
316 template <class Return, class Base = null_archetype<> > \
317 class NAME##_first_archetype : public Base { \
319 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
322 template <class Return, class Base = null_archetype<> > \
323 class NAME##_second_archetype : public Base { \
325 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
328 template <class Return, class BaseFirst, class BaseSecond> \
330 operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
331 const NAME##_second_archetype<Return, BaseSecond>&) \
333 return Return(static_object<detail::dummy_constructor>::get()); \
336 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
337 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
338 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
339 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
340 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
342 //===========================================================================
343 // Function Object Archetype Classes
345 template <class Return>
346 class generator_archetype {
348 const Return& operator()() {
349 return static_object<Return>::get();
353 class void_generator_archetype {
355 void operator()() { }
358 template <class Arg, class Return>
359 class unary_function_archetype {
361 unary_function_archetype() { }
363 unary_function_archetype(detail::dummy_constructor) { }
364 const Return& operator()(const Arg&) const {
365 return static_object<Return>::get();
369 template <class Arg1, class Arg2, class Return>
370 class binary_function_archetype {
372 binary_function_archetype() { }
374 binary_function_archetype(detail::dummy_constructor) { }
375 const Return& operator()(const Arg1&, const Arg2&) const {
376 return static_object<Return>::get();
381 class unary_predicate_archetype {
382 typedef boolean_archetype Return;
383 unary_predicate_archetype() { }
385 unary_predicate_archetype(detail::dummy_constructor) { }
386 const Return& operator()(const Arg&) const {
387 return static_object<Return>::get();
391 template <class Arg1, class Arg2, class Base = null_archetype<> >
392 class binary_predicate_archetype {
393 typedef boolean_archetype Return;
394 binary_predicate_archetype() { }
396 binary_predicate_archetype(detail::dummy_constructor) { }
397 const Return& operator()(const Arg1&, const Arg2&) const {
398 return static_object<Return>::get();
402 //===========================================================================
403 // Iterator Archetype Classes
407 operator const T&() { return static_object<T>::get(); }
410 class trivial_iterator_archetype
412 typedef trivial_iterator_archetype self;
414 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
415 typedef T value_type;
416 typedef void reference;
417 typedef void pointer;
418 typedef void difference_type;
419 typedef void iterator_category;
421 trivial_iterator_archetype() { }
422 self& operator=(const self&) { return *this; }
423 bool operator==(const self&) const { return true; }
424 bool operator!=(const self&) const { return true; }
425 input_proxy<T> operator*() const { return input_proxy<T>(); }
429 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
432 struct iterator_traits< boost::trivial_iterator_archetype<T> >
434 typedef T value_type;
441 struct input_output_proxy {
442 input_output_proxy<T>& operator=(const T&) { return *this; }
443 operator const T&() { return static_object<T>::get(); }
446 class mutable_trivial_iterator_archetype
448 typedef mutable_trivial_iterator_archetype self;
450 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
451 typedef T value_type;
452 typedef void reference;
453 typedef void pointer;
454 typedef void difference_type;
455 typedef void iterator_category;
457 mutable_trivial_iterator_archetype() { }
458 self& operator=(const self&) { return *this; }
459 bool operator==(const self&) const { return true; }
460 bool operator!=(const self&) const { return true; }
461 input_output_proxy<T> operator*() const { return input_output_proxy<T>(); }
465 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
468 struct iterator_traits< boost::mutable_trivial_iterator_archetype<T> >
470 typedef T value_type;
478 class input_iterator_archetype
481 typedef input_iterator_archetype self;
483 typedef std::input_iterator_tag iterator_category;
484 typedef T value_type;
485 typedef const T& reference;
486 typedef const T* pointer;
487 typedef std::ptrdiff_t difference_type;
488 input_iterator_archetype() { }
489 self& operator=(const self&) { return *this; }
490 bool operator==(const self&) const { return true; }
491 bool operator!=(const self&) const { return true; }
492 reference operator*() const { return static_object<T>::get(); }
493 self& operator++() { return *this; }
494 self operator++(int) { return *this; }
498 struct output_proxy {
499 output_proxy& operator=(const T&) { return *this; }
503 class output_iterator_archetype
506 typedef output_iterator_archetype self;
508 typedef std::output_iterator_tag iterator_category;
509 typedef output_proxy<T> value_type;
510 typedef output_proxy<T> reference;
511 typedef void pointer;
512 typedef void difference_type;
513 output_iterator_archetype(detail::dummy_constructor) { }
514 output_iterator_archetype(const self&) { }
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 output_proxy<T>(); }
519 self& operator++() { return *this; }
520 self operator++(int) { return *this; }
522 output_iterator_archetype() { }
526 class forward_iterator_archetype
529 typedef forward_iterator_archetype self;
531 typedef std::forward_iterator_tag iterator_category;
532 typedef T value_type;
533 typedef const T& reference;
535 typedef std::ptrdiff_t difference_type;
536 forward_iterator_archetype() { }
537 self& operator=(const self&) { return *this; }
538 bool operator==(const self&) const { return true; }
539 bool operator!=(const self&) const { return true; }
540 reference operator*() const { return static_object<T>::get(); }
541 self& operator++() { return *this; }
542 self operator++(int) { return *this; }
546 class mutable_forward_iterator_archetype
549 typedef mutable_forward_iterator_archetype self;
551 typedef std::forward_iterator_tag iterator_category;
552 typedef T value_type;
553 typedef T& reference;
555 typedef std::ptrdiff_t difference_type;
556 mutable_forward_iterator_archetype() { }
557 self& operator=(const self&) { return *this; }
558 bool operator==(const self&) const { return true; }
559 bool operator!=(const self&) const { return true; }
560 reference operator*() const { return static_object<T>::get(); }
561 self& operator++() { return *this; }
562 self operator++(int) { return *this; }
566 class bidirectional_iterator_archetype
569 typedef bidirectional_iterator_archetype self;
571 typedef std::bidirectional_iterator_tag iterator_category;
572 typedef T value_type;
573 typedef const T& reference;
575 typedef std::ptrdiff_t difference_type;
576 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; }
588 class mutable_bidirectional_iterator_archetype
591 typedef mutable_bidirectional_iterator_archetype self;
593 typedef std::bidirectional_iterator_tag iterator_category;
594 typedef T value_type;
595 typedef T& reference;
597 typedef std::ptrdiff_t difference_type;
598 mutable_bidirectional_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; }
610 class random_access_iterator_archetype
613 typedef random_access_iterator_archetype self;
615 typedef std::random_access_iterator_tag iterator_category;
616 typedef T value_type;
617 typedef const T& reference;
619 typedef std::ptrdiff_t difference_type;
620 random_access_iterator_archetype() { }
621 self& operator=(const self&) { return *this; }
622 bool operator==(const self&) const { return true; }
623 bool operator!=(const self&) const { return true; }
624 reference operator*() const { return static_object<T>::get(); }
625 self& operator++() { return *this; }
626 self operator++(int) { return *this; }
627 self& operator--() { return *this; }
628 self operator--(int) { return *this; }
629 reference operator[](difference_type) const
630 { return static_object<T>::get(); }
631 self& operator+=(difference_type) { return *this; }
632 self& operator-=(difference_type) { return *this; }
633 difference_type operator-(const self&) const
634 { return difference_type(); }
635 self operator+(difference_type) const { return *this; }
636 self operator-(difference_type) const { return *this; }
637 bool operator<(const self&) const { return true; }
638 bool operator<=(const self&) const { return true; }
639 bool operator>(const self&) const { return true; }
640 bool operator>=(const self&) const { return true; }
643 random_access_iterator_archetype<T>
644 operator+(typename random_access_iterator_archetype<T>::difference_type,
645 const random_access_iterator_archetype<T>& x)
650 class mutable_random_access_iterator_archetype
653 typedef mutable_random_access_iterator_archetype self;
655 typedef std::random_access_iterator_tag iterator_category;
656 typedef T value_type;
657 typedef T& reference;
659 typedef std::ptrdiff_t difference_type;
660 mutable_random_access_iterator_archetype() { }
661 self& operator=(const self&) { return *this; }
662 bool operator==(const self&) const { return true; }
663 bool operator!=(const self&) const { return true; }
664 reference operator*() const { return static_object<T>::get(); }
665 self& operator++() { return *this; }
666 self operator++(int) { return *this; }
667 self& operator--() { return *this; }
668 self operator--(int) { return *this; }
669 reference operator[](difference_type) const
670 { return static_object<T>::get(); }
671 self& operator+=(difference_type) { return *this; }
672 self& operator-=(difference_type) { return *this; }
673 difference_type operator-(const self&) const
674 { return difference_type(); }
675 self operator+(difference_type) const { return *this; }
676 self operator-(difference_type) const { return *this; }
677 bool operator<(const self&) const { return true; }
678 bool operator<=(const self&) const { return true; }
679 bool operator>(const self&) const { return true; }
680 bool operator>=(const self&) const { return true; }
683 mutable_random_access_iterator_archetype<T>
685 (typename mutable_random_access_iterator_archetype<T>::difference_type,
686 const mutable_random_access_iterator_archetype<T>& x)
691 #endif // BOOST_CONCEPT_ARCHETYPES_H