source: NonGTP/Boost/boost/concept_archetype.hpp @ 857

Revision 857, 23.8 KB checked in by igarcia, 18 years ago (diff)
Line 
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
Note: See TracBrowser for help on using the repository browser.