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