]> git.lyx.org Git - lyx.git/blob - boost/boost/concept_archetype.hpp
complie fix
[lyx.git] / boost / boost / concept_archetype.hpp
1 //
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.
7 //
8 // Revision History:
9 //
10 //   17 July  2001: Added const to some member functions. (Jeremy Siek) 
11 //   05 May   2001: Removed static dummy_cons object. (Jeremy Siek)
12
13 #ifndef BOOST_CONCEPT_ARCHETYPES_HPP
14 #define BOOST_CONCEPT_ARCHETYPES_HPP
15
16 #include <boost/config.hpp>
17 #include <boost/iterator.hpp>
18 #include <functional>
19
20 namespace boost {
21
22   //===========================================================================
23   // Basic Archetype Classes
24
25   namespace detail {
26     class dummy_constructor { };
27   }
28
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 {
34   private:
35     null_archetype() { }
36     null_archetype(const null_archetype&) { }
37     null_archetype& operator=(const null_archetype&) { return *this; }
38   public:
39     null_archetype(detail::dummy_constructor) { }
40 #ifndef __MWERKS__
41     template <class TT>
42     friend void dummy_friend(); // just to avoid warnings
43 #endif
44   };
45
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
50   // changed.
51   template <class T>
52   class static_object {
53   public:
54     static T& get() {
55      static char d[sizeof(T)];
56       return *reinterpret_cast<T*>(d);
57     }
58   };
59
60   template <class Base = null_archetype<> >
61   class default_constructible_archetype : public Base {
62   public:
63     default_constructible_archetype() 
64       : Base(static_object<detail::dummy_constructor>::get()) { }
65     default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
66   };
67
68   template <class Base = null_archetype<> >
69   class assignable_archetype : public Base {
70     assignable_archetype() { }
71     assignable_archetype(const assignable_archetype&) { }
72   public:
73     assignable_archetype& operator=(const assignable_archetype&) {
74       return *this;
75     }
76     assignable_archetype(detail::dummy_constructor x) : Base(x) { }
77   };
78
79   template <class Base = null_archetype<> >
80   class copy_constructible_archetype : public Base {
81   public:
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) { }
87   };
88
89   template <class Base = null_archetype<> >
90   class sgi_assignable_archetype : public Base {
91   public:
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&) {
95       return *this;
96     }
97     sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
98   };
99
100   struct default_archetype_base {
101     default_archetype_base(detail::dummy_constructor) { }
102   };
103
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 {
109   private:
110     convertible_to_archetype() { }
111     convertible_to_archetype(const convertible_to_archetype& ) { }
112     convertible_to_archetype& operator=(const convertible_to_archetype&)
113       { return *this; }
114   public:
115     convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
116     operator const T&() const { return static_object<T>::get(); }
117   };
118
119   template <class T, class Base = default_archetype_base>
120   class convertible_from_archetype : public Base {
121   private:
122     convertible_from_archetype() { }
123     convertible_from_archetype(const convertible_from_archetype& ) { }
124     convertible_from_archetype& operator=(const convertible_from_archetype&)
125       { return *this; }
126   public:
127     convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
128     convertible_from_archetype(const T&) { }
129     convertible_from_archetype& operator=(const T&)
130       { return *this; }
131   };
132
133   class boolean_archetype {
134   public:
135     boolean_archetype(const boolean_archetype&) { }
136     operator bool() const { return true; }
137     boolean_archetype(detail::dummy_constructor) { }
138   private:
139     boolean_archetype() { }
140     boolean_archetype& operator=(const boolean_archetype&) { return *this; }
141   };
142   
143   template <class Base = null_archetype<> >
144   class equality_comparable_archetype : public Base {
145   public:
146     equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
147   };
148   template <class Base>
149   boolean_archetype
150   operator==(const equality_comparable_archetype<Base>&,
151              const equality_comparable_archetype<Base>&) 
152   { 
153     return boolean_archetype(static_object<detail::dummy_constructor>::get());
154   }
155   template <class Base>
156   boolean_archetype
157   operator!=(const equality_comparable_archetype<Base>&,
158              const equality_comparable_archetype<Base>&)
159   {
160     return boolean_archetype(static_object<detail::dummy_constructor>::get());
161   }
162
163
164   template <class Base = null_archetype<> >
165   class equality_comparable2_first_archetype : public Base {
166   public:
167     equality_comparable2_first_archetype(detail::dummy_constructor x) 
168       : Base(x) { }
169   };
170   template <class Base = null_archetype<> >
171   class equality_comparable2_second_archetype : public Base {
172   public:
173     equality_comparable2_second_archetype(detail::dummy_constructor x) 
174       : Base(x) { }
175   };
176   template <class Base1, class Base2>
177   boolean_archetype
178   operator==(const equality_comparable2_first_archetype<Base1>&,
179              const equality_comparable2_second_archetype<Base2>&) 
180   {
181     return boolean_archetype(static_object<detail::dummy_constructor>::get());
182   }
183   template <class Base1, class Base2>
184   boolean_archetype
185   operator!=(const equality_comparable2_first_archetype<Base1>&,
186              const equality_comparable2_second_archetype<Base2>&)
187   {
188     return boolean_archetype(static_object<detail::dummy_constructor>::get());
189   }
190
191
192   template <class Base = null_archetype<> >
193   class less_than_comparable_archetype : public Base {
194   public:
195     less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
196   };
197   template <class Base>
198   boolean_archetype
199   operator<(const less_than_comparable_archetype<Base>&,
200             const less_than_comparable_archetype<Base>&)
201   {
202     return boolean_archetype(static_object<detail::dummy_constructor>::get());
203   }
204
205
206
207   template <class Base = null_archetype<> >
208   class comparable_archetype : public Base {
209   public:
210     comparable_archetype(detail::dummy_constructor x) : Base(x) { }
211   };
212   template <class Base>
213   boolean_archetype
214   operator<(const comparable_archetype<Base>&,
215             const comparable_archetype<Base>&)
216   {
217     return boolean_archetype(static_object<detail::dummy_constructor>::get());
218   }
219   template <class Base>
220   boolean_archetype
221   operator<=(const comparable_archetype<Base>&,
222              const comparable_archetype<Base>&)
223   {
224     return boolean_archetype(static_object<detail::dummy_constructor>::get());
225   }
226   template <class Base>
227   boolean_archetype
228   operator>(const comparable_archetype<Base>&,
229             const comparable_archetype<Base>&)
230   {
231     return boolean_archetype(static_object<detail::dummy_constructor>::get());
232   }
233   template <class Base>
234   boolean_archetype
235   operator>=(const comparable_archetype<Base>&,
236              const comparable_archetype<Base>&)
237   {
238     return boolean_archetype(static_object<detail::dummy_constructor>::get());
239   }
240
241
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:
245   //
246   // A a; B b;
247   // a < b
248   // b < a
249   //
250   // without also allowing the combinations:
251   //
252   // a < a
253   // b < b
254   //
255   struct optag1 { };
256   struct optag2 { };
257   struct optag3 { };
258
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 { \
262   public: \
263     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
264   }; \
265   \
266   template <class Base = null_archetype<>, class Tag = optag1 > \
267   class NAME##_second_archetype : public Base { \
268   public: \
269     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
270   }; \
271   \
272   template <class BaseFirst, class BaseSecond, class Tag> \
273   boolean_archetype \
274   operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
275                const NAME##_second_archetype<BaseSecond, Tag>&) \
276   { \
277    return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
278   }
279
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)
286
287 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
288   template <class Base = null_archetype<> > \
289   class NAME##_archetype : public Base { \
290   public: \
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; } \
295   }; \
296   template <class Base> \
297   NAME##_archetype<Base> \
298   operator OP (const NAME##_archetype<Base>&,\
299                const NAME##_archetype<Base>&)  \
300   { \
301     return \
302      NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
303   }
304
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)
310
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 { \
316   public: \
317     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
318   }; \
319   \
320   template <class Return, class Base = null_archetype<> > \
321   class NAME##_second_archetype : public Base { \
322   public: \
323     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
324   }; \
325   \
326   template <class Return, class BaseFirst, class BaseSecond> \
327   Return \
328   operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
329                const NAME##_second_archetype<Return, BaseSecond>&) \
330   { \
331     return Return(static_object<detail::dummy_constructor>::get()); \
332   }
333
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)
339
340   //===========================================================================
341   // Function Object Archetype Classes
342
343   template <class Return>
344   class generator_archetype {
345   public:
346     const Return& operator()() {
347       return static_object<Return>::get(); 
348     }
349   };
350
351   class void_generator_archetype {
352   public:
353     void operator()() { }
354   };
355
356   template <class Arg, class Return>
357   class unary_function_archetype {
358   private:
359     unary_function_archetype() { }
360   public:
361     unary_function_archetype(detail::dummy_constructor) { }
362     const Return& operator()(const Arg&) const {
363       return static_object<Return>::get(); 
364     }
365   };
366
367   template <class Arg1, class Arg2, class Return>
368   class binary_function_archetype {
369   private:
370     binary_function_archetype() { }
371   public:
372     binary_function_archetype(detail::dummy_constructor) { }
373     const Return& operator()(const Arg1&, const Arg2&) const {
374       return static_object<Return>::get(); 
375     }
376   };
377
378   template <class Arg>
379   class unary_predicate_archetype {
380     typedef boolean_archetype Return;
381     unary_predicate_archetype() { }
382   public:
383     unary_predicate_archetype(detail::dummy_constructor) { }
384     const Return& operator()(const Arg&) const {
385       return static_object<Return>::get(); 
386     }
387   };
388
389   template <class Arg1, class Arg2, class Base = null_archetype<> >
390   class binary_predicate_archetype {
391     typedef boolean_archetype Return;
392     binary_predicate_archetype() { }
393   public:
394     binary_predicate_archetype(detail::dummy_constructor) { }
395     const Return& operator()(const Arg1&, const Arg2&) const {
396       return static_object<Return>::get(); 
397     }
398   };
399
400   //===========================================================================
401   // Iterator Archetype Classes
402
403   template <class T>
404   struct input_proxy {
405     operator const T&() { return static_object<T>::get(); }
406   };
407   template <class T>
408   class trivial_iterator_archetype
409   {
410     typedef trivial_iterator_archetype self;
411   public:
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;
418 #endif
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>(); }
424   };
425 } // namespace boost
426
427 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
428 namespace std {
429   template <class T>
430   struct iterator_traits< boost::trivial_iterator_archetype<T> >
431   {
432     typedef T value_type;
433   };
434 }
435 #endif
436
437 namespace boost {
438   template <class T>
439   struct input_output_proxy {
440     input_output_proxy<T>& operator=(const T&) { return *this; }
441     operator const T&() { return static_object<T>::get(); }
442   };
443   template <class T>
444   class mutable_trivial_iterator_archetype
445   {
446     typedef mutable_trivial_iterator_archetype self;
447   public:
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;
454 #endif
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>(); }
460   };
461 } // namespace boost
462
463 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
464 namespace std {
465   template <class T>
466   struct iterator_traits< boost::mutable_trivial_iterator_archetype<T> >
467   {
468     typedef T value_type;
469   };
470 }
471 #endif
472
473 namespace boost {
474
475   template <class T>
476   class input_iterator_archetype
477   {
478   public:
479     typedef input_iterator_archetype self;
480   public:
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; }
493   };
494
495  template <class T>
496   struct output_proxy {
497     output_proxy& operator=(const T&) { return *this; }
498   };
499
500   template <class T>
501   class output_iterator_archetype
502   {
503   public:
504     typedef output_iterator_archetype self;
505   public:
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; }
518   private:
519     output_iterator_archetype() { }
520   };
521
522   template <class T>
523   class forward_iterator_archetype
524   {
525   public:
526     typedef forward_iterator_archetype self;
527   public:
528     typedef std::forward_iterator_tag iterator_category;
529     typedef T value_type;
530     typedef const T& reference;
531     typedef T* pointer;
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; }
540   };
541
542   template <class T>
543   class mutable_forward_iterator_archetype
544   {
545   public:
546     typedef mutable_forward_iterator_archetype self;
547   public:
548     typedef std::forward_iterator_tag iterator_category;
549     typedef T value_type;
550     typedef T& reference;
551     typedef T* pointer;
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; }
560   };
561
562   template <class T>
563   class bidirectional_iterator_archetype
564   {
565   public:
566     typedef bidirectional_iterator_archetype self;
567   public:
568     typedef std::bidirectional_iterator_tag iterator_category;
569     typedef T value_type;
570     typedef const T& reference;
571     typedef T* pointer;
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; }
582   };
583
584   template <class T>
585   class mutable_bidirectional_iterator_archetype
586   {
587   public:
588     typedef mutable_bidirectional_iterator_archetype self;
589   public:
590     typedef std::bidirectional_iterator_tag iterator_category;
591     typedef T value_type;
592     typedef T& reference;
593     typedef T* pointer;
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; }
604   };
605
606   template <class T>
607   class random_access_iterator_archetype
608   {
609   public:
610     typedef random_access_iterator_archetype self;
611   public:
612     typedef std::random_access_iterator_tag iterator_category;
613     typedef T value_type;
614     typedef const T& reference;
615     typedef T* pointer;
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; }
638   };
639   template <class T>
640   random_access_iterator_archetype<T> 
641   operator+(typename random_access_iterator_archetype<T>::difference_type, 
642             const random_access_iterator_archetype<T>& x) 
643     { return x; }
644
645
646   template <class T>
647   class mutable_random_access_iterator_archetype
648   {
649   public:
650     typedef mutable_random_access_iterator_archetype self;
651   public:
652     typedef std::random_access_iterator_tag iterator_category;
653     typedef T value_type;
654     typedef T& reference;
655     typedef T* pointer;
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; }
678   };
679   template <class T>
680   mutable_random_access_iterator_archetype<T> 
681   operator+
682     (typename mutable_random_access_iterator_archetype<T>::difference_type, 
683      const mutable_random_access_iterator_archetype<T>& x) 
684     { return x; }
685
686 } // namespace boost
687
688 #endif // BOOST_CONCEPT_ARCHETYPES_H