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)
9 // 17 July 2001: Added const to some member functions. (Jeremy Siek)
10 // 05 May 2001: Removed static dummy_cons object. (Jeremy Siek)
12 // See http://www.boost.org/libs/concept_check for documentation.
14 #ifndef BOOST_CONCEPT_ARCHETYPES_HPP
15 #define BOOST_CONCEPT_ARCHETYPES_HPP
17 #include <boost/config.hpp>
18 #include <boost/iterator.hpp>
19 #include <boost/mpl/identity.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
59 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
60 return *reinterpret_cast<T
*>(0);
62 static char d
[sizeof(T
)];
63 return *reinterpret_cast<T
*>(d
);
68 template <class Base
= null_archetype
<> >
69 class default_constructible_archetype
: public Base
{
71 default_constructible_archetype()
72 : Base(static_object
<detail::dummy_constructor
>::get()) { }
73 default_constructible_archetype(detail::dummy_constructor x
) : Base(x
) { }
76 template <class Base
= null_archetype
<> >
77 class assignable_archetype
: public Base
{
78 assignable_archetype() { }
79 assignable_archetype(const assignable_archetype
&) { }
81 assignable_archetype
& operator=(const assignable_archetype
&) {
84 assignable_archetype(detail::dummy_constructor x
) : Base(x
) { }
87 template <class Base
= null_archetype
<> >
88 class copy_constructible_archetype
: public Base
{
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
) { }
97 template <class Base
= null_archetype
<> >
98 class sgi_assignable_archetype
: public Base
{
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
&) {
105 sgi_assignable_archetype(const detail::dummy_constructor
& x
) : Base(x
) { }
108 struct default_archetype_base
{
109 default_archetype_base(detail::dummy_constructor
) { }
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
{
118 convertible_to_archetype() { }
119 convertible_to_archetype(const convertible_to_archetype
& ) { }
120 convertible_to_archetype
& operator=(const convertible_to_archetype
&)
123 convertible_to_archetype(detail::dummy_constructor x
) : Base(x
) { }
124 operator const T
&() const { return static_object
<T
>::get(); }
127 template <class T
, class Base
= default_archetype_base
>
128 class convertible_from_archetype
: public Base
{
130 convertible_from_archetype() { }
131 convertible_from_archetype(const convertible_from_archetype
& ) { }
132 convertible_from_archetype
& operator=(const convertible_from_archetype
&)
135 convertible_from_archetype(detail::dummy_constructor x
) : Base(x
) { }
136 convertible_from_archetype(const T
&) { }
137 convertible_from_archetype
& operator=(const T
&)
141 class boolean_archetype
{
143 boolean_archetype(const boolean_archetype
&) { }
144 operator bool() const { return true; }
145 boolean_archetype(detail::dummy_constructor
) { }
147 boolean_archetype() { }
148 boolean_archetype
& operator=(const boolean_archetype
&) { return *this; }
151 template <class Base
= null_archetype
<> >
152 class equality_comparable_archetype
: public Base
{
154 equality_comparable_archetype(detail::dummy_constructor x
) : Base(x
) { }
156 template <class Base
>
158 operator==(const equality_comparable_archetype
<Base
>&,
159 const equality_comparable_archetype
<Base
>&)
161 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
163 template <class Base
>
165 operator!=(const equality_comparable_archetype
<Base
>&,
166 const equality_comparable_archetype
<Base
>&)
168 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
172 template <class Base
= null_archetype
<> >
173 class equality_comparable2_first_archetype
: public Base
{
175 equality_comparable2_first_archetype(detail::dummy_constructor x
)
178 template <class Base
= null_archetype
<> >
179 class equality_comparable2_second_archetype
: public Base
{
181 equality_comparable2_second_archetype(detail::dummy_constructor x
)
184 template <class Base1
, class Base2
>
186 operator==(const equality_comparable2_first_archetype
<Base1
>&,
187 const equality_comparable2_second_archetype
<Base2
>&)
189 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
191 template <class Base1
, class Base2
>
193 operator!=(const equality_comparable2_first_archetype
<Base1
>&,
194 const equality_comparable2_second_archetype
<Base2
>&)
196 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
200 template <class Base
= null_archetype
<> >
201 class less_than_comparable_archetype
: public Base
{
203 less_than_comparable_archetype(detail::dummy_constructor x
) : Base(x
) { }
205 template <class Base
>
207 operator<(const less_than_comparable_archetype
<Base
>&,
208 const less_than_comparable_archetype
<Base
>&)
210 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
215 template <class Base
= null_archetype
<> >
216 class comparable_archetype
: public Base
{
218 comparable_archetype(detail::dummy_constructor x
) : Base(x
) { }
220 template <class Base
>
222 operator<(const comparable_archetype
<Base
>&,
223 const comparable_archetype
<Base
>&)
225 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
227 template <class Base
>
229 operator<=(const comparable_archetype
<Base
>&,
230 const comparable_archetype
<Base
>&)
232 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
234 template <class Base
>
236 operator>(const comparable_archetype
<Base
>&,
237 const comparable_archetype
<Base
>&)
239 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
241 template <class Base
>
243 operator>=(const comparable_archetype
<Base
>&,
244 const comparable_archetype
<Base
>&)
246 return boolean_archetype(static_object
<detail::dummy_constructor
>::get());
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:
258 // without also allowing the combinations:
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 { \
271 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
274 template <class Base = null_archetype<>, class Tag = optag1 > \
275 class NAME##_second_archetype : public Base { \
277 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
280 template <class BaseFirst, class BaseSecond, class Tag> \
282 operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
283 const NAME##_second_archetype<BaseSecond, Tag>&) \
285 return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
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
)
295 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
296 template <class Base = null_archetype<> > \
297 class NAME##_archetype : public Base { \
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; } \
304 template <class Base> \
305 NAME##_archetype<Base> \
306 operator OP (const NAME##_archetype<Base>&,\
307 const NAME##_archetype<Base>&) \
310 NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
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
)
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 { \
325 NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
328 template <class Return, class Base = null_archetype<> > \
329 class NAME##_second_archetype : public Base { \
331 NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
334 template <class Return, class BaseFirst, class BaseSecond> \
336 operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
337 const NAME##_second_archetype<Return, BaseSecond>&) \
339 return Return(static_object<detail::dummy_constructor>::get()); \
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
)
348 //===========================================================================
349 // Function Object Archetype Classes
351 template <class Return
>
352 class generator_archetype
{
354 const Return
& operator()() {
355 return static_object
<Return
>::get();
359 class void_generator_archetype
{
361 void operator()() { }
364 template <class Arg
, class Return
>
365 class unary_function_archetype
{
367 unary_function_archetype() { }
369 unary_function_archetype(detail::dummy_constructor
) { }
370 const Return
& operator()(const Arg
&) const {
371 return static_object
<Return
>::get();
375 template <class Arg1
, class Arg2
, class Return
>
376 class binary_function_archetype
{
378 binary_function_archetype() { }
380 binary_function_archetype(detail::dummy_constructor
) { }
381 const Return
& operator()(const Arg1
&, const Arg2
&) const {
382 return static_object
<Return
>::get();
387 class unary_predicate_archetype
{
388 typedef boolean_archetype Return
;
389 unary_predicate_archetype() { }
391 unary_predicate_archetype(detail::dummy_constructor
) { }
392 const Return
& operator()(const Arg
&) const {
393 return static_object
<Return
>::get();
397 template <class Arg1
, class Arg2
, class Base
= null_archetype
<> >
398 class binary_predicate_archetype
{
399 typedef boolean_archetype Return
;
400 binary_predicate_archetype() { }
402 binary_predicate_archetype(detail::dummy_constructor
) { }
403 const Return
& operator()(const Arg1
&, const Arg2
&) const {
404 return static_object
<Return
>::get();
408 //===========================================================================
409 // Iterator Archetype Classes
411 template <class T
, int I
= 0>
412 class input_iterator_archetype
415 typedef input_iterator_archetype self
;
417 typedef std::input_iterator_tag iterator_category
;
418 typedef T value_type
;
420 operator const value_type
&() const { return static_object
<T
>::get(); }
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; }
433 class input_iterator_archetype_no_proxy
436 typedef input_iterator_archetype_no_proxy self
;
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; }
452 struct output_proxy
{
453 output_proxy
& operator=(const T
&) { return *this; }
457 class output_iterator_archetype
460 typedef output_iterator_archetype self
;
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; }
476 output_iterator_archetype() { }
480 class input_output_iterator_archetype
483 typedef input_output_iterator_archetype self
;
484 struct in_out_tag
: public std::input_iterator_tag
, public std::output_iterator_tag
{ };
486 typedef in_out_tag iterator_category
;
487 typedef T value_type
;
489 reference
& operator=(const T
&) { return *this; }
490 operator value_type() { return static_object
<T
>::get(); }
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; }
504 class forward_iterator_archetype
507 typedef forward_iterator_archetype self
;
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; }
524 class mutable_forward_iterator_archetype
527 typedef mutable_forward_iterator_archetype self
;
529 typedef std::forward_iterator_tag iterator_category
;
530 typedef T value_type
;
531 typedef T
& reference
;
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; }
544 class bidirectional_iterator_archetype
547 typedef bidirectional_iterator_archetype self
;
549 typedef std::bidirectional_iterator_tag iterator_category
;
550 typedef T value_type
;
551 typedef const T
& reference
;
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; }
566 class mutable_bidirectional_iterator_archetype
569 typedef mutable_bidirectional_iterator_archetype self
;
571 typedef std::bidirectional_iterator_tag iterator_category
;
572 typedef T value_type
;
573 typedef T
& reference
;
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; }
588 class random_access_iterator_archetype
591 typedef random_access_iterator_archetype self
;
593 typedef std::random_access_iterator_tag iterator_category
;
594 typedef T value_type
;
595 typedef const T
& reference
;
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; }
621 random_access_iterator_archetype
<T
>
622 operator+(typename random_access_iterator_archetype
<T
>::difference_type
,
623 const random_access_iterator_archetype
<T
>& x
)
628 class mutable_random_access_iterator_archetype
631 typedef mutable_random_access_iterator_archetype self
;
633 typedef std::random_access_iterator_tag iterator_category
;
634 typedef T value_type
;
635 typedef T
& reference
;
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; }
661 mutable_random_access_iterator_archetype
<T
>
663 (typename mutable_random_access_iterator_archetype
<T
>::difference_type
,
664 const mutable_random_access_iterator_archetype
<T
>& x
)
669 #endif // BOOST_CONCEPT_ARCHETYPES_H