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 #ifndef BOOST_CONCEPT_ARCHETYPES_HPP
14 #define BOOST_CONCEPT_ARCHETYPES_HPP
16 #include <boost/config.hpp>
17 #include <boost/iterator.hpp>
22 //===========================================================================
23 // Basic Archetype Classes
26 class dummy_constructor { };
29 // A type that models no concept. The template parameter
30 // is only there so that null_archetype types can be created
31 // that have different type.
32 template <class T = int>
33 class null_archetype {
36 null_archetype(const null_archetype&) { }
37 null_archetype& operator=(const null_archetype&) { return *this; }
39 null_archetype(detail::dummy_constructor) { }
42 friend void dummy_friend(); // just to avoid warnings
46 // This is a helper class that provides a way to get a reference to
47 // an object. The get() function will never be called at run-time
48 // (nothing in this file will) so this seemingly very bad function
49 // is really quite innocent. The name of this class needs to be
55 static char d[sizeof(T)];
56 return *reinterpret_cast<T*>(d);
60 template <class Base = null_archetype<> >
61 class default_constructible_archetype : public Base {
63 default_constructible_archetype()
64 : Base(static_object<detail::dummy_constructor>::get()) { }
65 default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
68 template <class Base = null_archetype<> >
69 class assignable_archetype : public Base {
70 assignable_archetype() { }
71 assignable_archetype(const assignable_archetype&) { }
73 assignable_archetype& operator=(const assignable_archetype&) {
76 assignable_archetype(detail::dummy_constructor x) : Base(x) { }
79 template <class Base = null_archetype<> >
80 class copy_constructible_archetype : public Base {
82 copy_constructible_archetype()
83 : Base(static_object<detail::dummy_constructor>::get()) { }
84 copy_constructible_archetype(const copy_constructible_archetype&)
85 : Base(static_object<detail::dummy_constructor>::get()) { }
86 copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
89 template <class Base = null_archetype<> >
90 class sgi_assignable_archetype : public Base {
92 sgi_assignable_archetype(const sgi_assignable_archetype&)
93 : Base(static_object<detail::dummy_constructor>::get()) { }
94 sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
97 sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
100 struct default_archetype_base {
101 default_archetype_base(detail::dummy_constructor) { }
104 // Careful, don't use same type for T and Base. That results in the
105 // conversion operator being invalid. Since T is often
106 // null_archetype, can't use null_archetype for Base.
107 template <class T, class Base = default_archetype_base>
108 class convertible_to_archetype : public Base {
110 convertible_to_archetype() { }
111 convertible_to_archetype(const convertible_to_archetype& ) { }
112 convertible_to_archetype& operator=(const convertible_to_archetype&)
115 convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
116 operator const T&() const { return static_object<T>::get(); }
119 template <class T, class Base = default_archetype_base>
120 class convertible_from_archetype : public Base {
122 convertible_from_archetype() { }
123 convertible_from_archetype(const convertible_from_archetype& ) { }
124 convertible_from_archetype& operator=(const convertible_from_archetype&)
127 convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
128 convertible_from_archetype(const T&) { }
129 convertible_from_archetype& operator=(const T&)
133 class boolean_archetype {
135 boolean_archetype(const boolean_archetype&) { }
136 operator bool() const { return true; }
137 boolean_archetype(detail::dummy_constructor) { }
139 boolean_archetype() { }
140 boolean_archetype& operator=(const boolean_archetype&) { return *this; }
143 template <class Base = null_archetype<> >
144 class equality_comparable_archetype : public Base {
146 equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
148 template <class Base>
150 operator==(const equality_comparable_archetype<Base>&,
151 const equality_comparable_archetype<Base>&)
153 return boolean_archetype(static_object<detail::dummy_constructor>::get());
155 template <class Base>
157 operator!=(const equality_comparable_archetype<Base>&,
158 const equality_comparable_archetype<Base>&)
160 return boolean_archetype(static_object<detail::dummy_constructor>::get());
164 template <class Base = null_archetype<> >
165 class equality_comparable2_first_archetype : public Base {
167 equality_comparable2_first_archetype(detail::dummy_constructor x)
170 template <class Base = null_archetype<> >
171 class equality_comparable2_second_archetype : public Base {
173 equality_comparable2_second_archetype(detail::dummy_constructor x)
176 template <class Base1, class Base2>
178 operator==(const equality_comparable2_first_archetype<Base1>&,
179 const equality_comparable2_second_archetype<Base2>&)
181 return boolean_archetype(static_object<detail::dummy_constructor>::get());
183 template <class Base1, class Base2>
185 operator!=(const equality_comparable2_first_archetype<Base1>&,
186 const equality_comparable2_second_archetype<Base2>&)
188 return boolean_archetype(static_object<detail::dummy_constructor>::get());
192 template <class Base = null_archetype<> >
193 class less_than_comparable_archetype : public Base {
195 less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
197 template <class Base>
199 operator<(const less_than_comparable_archetype<Base>&,
200 const less_than_comparable_archetype<Base>&)
202 return boolean_archetype(static_object<detail::dummy_constructor>::get());
207 template <class Base = null_archetype<> >
208 class comparable_archetype : public Base {
210 comparable_archetype(detail::dummy_constructor x) : Base(x) { }
212 template <class Base>
214 operator<(const comparable_archetype<Base>&,
215 const comparable_archetype<Base>&)
217 return boolean_archetype(static_object<detail::dummy_constructor>::get());
219 template <class Base>
221 operator<=(const comparable_archetype<Base>&,
222 const comparable_archetype<Base>&)
224 return boolean_archetype(static_object<detail::dummy_constructor>::get());
226 template <class Base>
228 operator>(const comparable_archetype<Base>&,
229 const comparable_archetype<Base>&)
231 return boolean_archetype(static_object<detail::dummy_constructor>::get());
233 template <class Base>
235 operator>=(const comparable_archetype<Base>&,
236 const comparable_archetype<Base>&)
238 return boolean_archetype(static_object<detail::dummy_constructor>::get());
242 // The purpose of the optags is so that one can specify
243 // exactly which types the operator< is defined between.
244 // This is useful for allowing the operations:
250 // without also allowing the combinations:
259 #define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
260 template <class Base = null_archetype<>, class Tag = optag1 > \
261 class NAME##_first_archetype : public Base { \
263 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
266 template <class Base = null_archetype<>, class Tag = optag1 > \
267 class NAME##_second_archetype : public Base { \
269 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
272 template <class BaseFirst, class BaseSecond, class Tag> \
274 operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
275 const NAME##_second_archetype<BaseSecond, Tag>&) \
277 return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
280 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
281 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
282 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
283 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
284 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
285 BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
287 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
288 template <class Base = null_archetype<> > \
289 class NAME##_archetype : public Base { \
291 NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
292 NAME##_archetype(const NAME##_archetype&) \
293 : Base(static_object<detail::dummy_constructor>::get()) { } \
294 NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
296 template <class Base> \
297 NAME##_archetype<Base> \
298 operator OP (const NAME##_archetype<Base>&,\
299 const NAME##_archetype<Base>&) \
302 NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
305 BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
306 BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
307 BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
308 BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
309 BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
311 // As is, these are useless because of the return type.
312 // Need to invent a better way...
313 #define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
314 template <class Return, class Base = null_archetype<> > \
315 class NAME##_first_archetype : public Base { \
317 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
320 template <class Return, class Base = null_archetype<> > \
321 class NAME##_second_archetype : public Base { \
323 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
326 template <class Return, class BaseFirst, class BaseSecond> \
328 operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
329 const NAME##_second_archetype<Return, BaseSecond>&) \
331 return Return(static_object<detail::dummy_constructor>::get()); \
334 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
335 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
336 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
337 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
338 BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
340 //===========================================================================
341 // Function Object Archetype Classes
343 template <class Return>
344 class generator_archetype {
346 const Return& operator()() {
347 return static_object<Return>::get();
351 class void_generator_archetype {
353 void operator()() { }
356 template <class Arg, class Return>
357 class unary_function_archetype {
359 unary_function_archetype() { }
361 unary_function_archetype(detail::dummy_constructor) { }
362 const Return& operator()(const Arg&) const {
363 return static_object<Return>::get();
367 template <class Arg1, class Arg2, class Return>
368 class binary_function_archetype {
370 binary_function_archetype() { }
372 binary_function_archetype(detail::dummy_constructor) { }
373 const Return& operator()(const Arg1&, const Arg2&) const {
374 return static_object<Return>::get();
379 class unary_predicate_archetype {
380 typedef boolean_archetype Return;
381 unary_predicate_archetype() { }
383 unary_predicate_archetype(detail::dummy_constructor) { }
384 const Return& operator()(const Arg&) const {
385 return static_object<Return>::get();
389 template <class Arg1, class Arg2, class Base = null_archetype<> >
390 class binary_predicate_archetype {
391 typedef boolean_archetype Return;
392 binary_predicate_archetype() { }
394 binary_predicate_archetype(detail::dummy_constructor) { }
395 const Return& operator()(const Arg1&, const Arg2&) const {
396 return static_object<Return>::get();
400 //===========================================================================
401 // Iterator Archetype Classes
405 operator const T&() { return static_object<T>::get(); }
408 class trivial_iterator_archetype
410 typedef trivial_iterator_archetype self;
412 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
413 typedef T value_type;
414 typedef void reference;
415 typedef void pointer;
416 typedef void difference_type;
417 typedef void iterator_category;
419 trivial_iterator_archetype() { }
420 self& operator=(const self&) { return *this; }
421 bool operator==(const self&) const { return true; }
422 bool operator!=(const self&) const { return true; }
423 input_proxy<T> operator*() const { return input_proxy<T>(); }
427 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
430 struct iterator_traits< boost::trivial_iterator_archetype<T> >
432 typedef T value_type;
439 struct input_output_proxy {
440 input_output_proxy<T>& operator=(const T&) { return *this; }
441 operator const T&() { return static_object<T>::get(); }
444 class mutable_trivial_iterator_archetype
446 typedef mutable_trivial_iterator_archetype self;
448 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
449 typedef T value_type;
450 typedef void reference;
451 typedef void pointer;
452 typedef void difference_type;
453 typedef void iterator_category;
455 mutable_trivial_iterator_archetype() { }
456 self& operator=(const self&) { return *this; }
457 bool operator==(const self&) const { return true; }
458 bool operator!=(const self&) const { return true; }
459 input_output_proxy<T> operator*() const { return input_output_proxy<T>(); }
463 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
466 struct iterator_traits< boost::mutable_trivial_iterator_archetype<T> >
468 typedef T value_type;
476 class input_iterator_archetype
479 typedef input_iterator_archetype self;
481 typedef std::input_iterator_tag iterator_category;
482 typedef T value_type;
483 typedef const T& reference;
484 typedef const T* pointer;
485 typedef std::ptrdiff_t difference_type;
486 input_iterator_archetype() { }
487 self& operator=(const self&) { return *this; }
488 bool operator==(const self&) const { return true; }
489 bool operator!=(const self&) const { return true; }
490 reference operator*() const { return static_object<T>::get(); }
491 self& operator++() { return *this; }
492 self operator++(int) { return *this; }
496 struct output_proxy {
497 output_proxy& operator=(const T&) { return *this; }
501 class output_iterator_archetype
504 typedef output_iterator_archetype self;
506 typedef std::output_iterator_tag iterator_category;
507 typedef output_proxy<T> value_type;
508 typedef output_proxy<T> reference;
509 typedef void pointer;
510 typedef void difference_type;
511 output_iterator_archetype(const self&) { }
512 self& operator=(const self&) { return *this; }
513 bool operator==(const self&) const { return true; }
514 bool operator!=(const self&) const { return true; }
515 reference operator*() const { return output_proxy<T>(); }
516 self& operator++() { return *this; }
517 self operator++(int) { return *this; }
519 output_iterator_archetype() { }
523 class forward_iterator_archetype
526 typedef forward_iterator_archetype self;
528 typedef std::forward_iterator_tag iterator_category;
529 typedef T value_type;
530 typedef const T& reference;
532 typedef std::ptrdiff_t difference_type;
533 forward_iterator_archetype() { }
534 self& operator=(const self&) { return *this; }
535 bool operator==(const self&) const { return true; }
536 bool operator!=(const self&) const { return true; }
537 reference operator*() const { return static_object<T>::get(); }
538 self& operator++() { return *this; }
539 self operator++(int) { return *this; }
543 class mutable_forward_iterator_archetype
546 typedef mutable_forward_iterator_archetype self;
548 typedef std::forward_iterator_tag iterator_category;
549 typedef T value_type;
550 typedef T& reference;
552 typedef std::ptrdiff_t difference_type;
553 mutable_forward_iterator_archetype() { }
554 self& operator=(const self&) { return *this; }
555 bool operator==(const self&) const { return true; }
556 bool operator!=(const self&) const { return true; }
557 reference operator*() const { return static_object<T>::get(); }
558 self& operator++() { return *this; }
559 self operator++(int) { return *this; }
563 class bidirectional_iterator_archetype
566 typedef bidirectional_iterator_archetype self;
568 typedef std::bidirectional_iterator_tag iterator_category;
569 typedef T value_type;
570 typedef const T& reference;
572 typedef std::ptrdiff_t difference_type;
573 bidirectional_iterator_archetype() { }
574 self& operator=(const self&) { return *this; }
575 bool operator==(const self&) const { return true; }
576 bool operator!=(const self&) const { return true; }
577 reference operator*() const { return static_object<T>::get(); }
578 self& operator++() { return *this; }
579 self operator++(int) { return *this; }
580 self& operator--() { return *this; }
581 self operator--(int) { return *this; }
585 class mutable_bidirectional_iterator_archetype
588 typedef mutable_bidirectional_iterator_archetype self;
590 typedef std::bidirectional_iterator_tag iterator_category;
591 typedef T value_type;
592 typedef T& reference;
594 typedef std::ptrdiff_t difference_type;
595 mutable_bidirectional_iterator_archetype() { }
596 self& operator=(const self&) { return *this; }
597 bool operator==(const self&) const { return true; }
598 bool operator!=(const self&) const { return true; }
599 reference operator*() const { return static_object<T>::get(); }
600 self& operator++() { return *this; }
601 self operator++(int) { return *this; }
602 self& operator--() { return *this; }
603 self operator--(int) { return *this; }
607 class random_access_iterator_archetype
610 typedef random_access_iterator_archetype self;
612 typedef std::random_access_iterator_tag iterator_category;
613 typedef T value_type;
614 typedef const T& reference;
616 typedef std::ptrdiff_t difference_type;
617 random_access_iterator_archetype() { }
618 self& operator=(const self&) { return *this; }
619 bool operator==(const self&) const { return true; }
620 bool operator!=(const self&) const { return true; }
621 reference operator*() const { return static_object<T>::get(); }
622 self& operator++() { return *this; }
623 self operator++(int) { return *this; }
624 self& operator--() { return *this; }
625 self operator--(int) { return *this; }
626 reference operator[](difference_type) const
627 { return static_object<T>::get(); }
628 self& operator+=(difference_type) { return *this; }
629 self& operator-=(difference_type) { return *this; }
630 difference_type operator-(const self&) const
631 { return difference_type(); }
632 self operator+(difference_type) const { return *this; }
633 self operator-(difference_type) const { return *this; }
634 bool operator<(const self&) const { return true; }
635 bool operator<=(const self&) const { return true; }
636 bool operator>(const self&) const { return true; }
637 bool operator>=(const self&) const { return true; }
640 random_access_iterator_archetype<T>
641 operator+(typename random_access_iterator_archetype<T>::difference_type,
642 const random_access_iterator_archetype<T>& x)
647 class mutable_random_access_iterator_archetype
650 typedef mutable_random_access_iterator_archetype self;
652 typedef std::random_access_iterator_tag iterator_category;
653 typedef T value_type;
654 typedef T& reference;
656 typedef std::ptrdiff_t difference_type;
657 mutable_random_access_iterator_archetype() { }
658 self& operator=(const self&) { return *this; }
659 bool operator==(const self&) const { return true; }
660 bool operator!=(const self&) const { return true; }
661 reference operator*() const { return static_object<T>::get(); }
662 self& operator++() { return *this; }
663 self operator++(int) { return *this; }
664 self& operator--() { return *this; }
665 self operator--(int) { return *this; }
666 reference operator[](difference_type) const
667 { return static_object<T>::get(); }
668 self& operator+=(difference_type) { return *this; }
669 self& operator-=(difference_type) { return *this; }
670 difference_type operator-(const self&) const
671 { return difference_type(); }
672 self operator+(difference_type) const { return *this; }
673 self operator-(difference_type) const { return *this; }
674 bool operator<(const self&) const { return true; }
675 bool operator<=(const self&) const { return true; }
676 bool operator>(const self&) const { return true; }
677 bool operator>=(const self&) const { return true; }
680 mutable_random_access_iterator_archetype<T>
682 (typename mutable_random_access_iterator_archetype<T>::difference_type,
683 const mutable_random_access_iterator_archetype<T>& x)
688 #endif // BOOST_CONCEPT_ARCHETYPES_H