]> git.lyx.org Git - lyx.git/blob - boost/boost/concept_archetype.hpp
LFUN_ESCAPE gets ReadOnly (fix bug 1142)
[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 // See http://www.boost.org/libs/concept_check for documentation.
14
15 #ifndef BOOST_CONCEPT_ARCHETYPES_HPP
16 #define BOOST_CONCEPT_ARCHETYPES_HPP
17
18 #include <boost/config.hpp>
19 #include <boost/iterator.hpp>
20 #include <functional>
21
22 namespace 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   public:
56     static T& get() {
57      static char d[sizeof(T)];
58       return *reinterpret_cast<T*>(d);
59     }
60   };
61
62   template <class Base = null_archetype<> >
63   class default_constructible_archetype : public Base {
64   public:
65     default_constructible_archetype() 
66       : Base(static_object<detail::dummy_constructor>::get()) { }
67     default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
68   };
69
70   template <class Base = null_archetype<> >
71   class assignable_archetype : public Base {
72     assignable_archetype() { }
73     assignable_archetype(const assignable_archetype&) { }
74   public:
75     assignable_archetype& operator=(const assignable_archetype&) {
76       return *this;
77     }
78     assignable_archetype(detail::dummy_constructor x) : Base(x) { }
79   };
80
81   template <class Base = null_archetype<> >
82   class copy_constructible_archetype : public Base {
83   public:
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) { }
89   };
90
91   template <class Base = null_archetype<> >
92   class sgi_assignable_archetype : public Base {
93   public:
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&) {
97       return *this;
98     }
99     sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
100   };
101
102   struct default_archetype_base {
103     default_archetype_base(detail::dummy_constructor) { }
104   };
105
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 {
111   private:
112     convertible_to_archetype() { }
113     convertible_to_archetype(const convertible_to_archetype& ) { }
114     convertible_to_archetype& operator=(const convertible_to_archetype&)
115       { return *this; }
116   public:
117     convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
118     operator const T&() const { return static_object<T>::get(); }
119   };
120
121   template <class T, class Base = default_archetype_base>
122   class convertible_from_archetype : public Base {
123   private:
124     convertible_from_archetype() { }
125     convertible_from_archetype(const convertible_from_archetype& ) { }
126     convertible_from_archetype& operator=(const convertible_from_archetype&)
127       { return *this; }
128   public:
129     convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
130     convertible_from_archetype(const T&) { }
131     convertible_from_archetype& operator=(const T&)
132       { return *this; }
133   };
134
135   class boolean_archetype {
136   public:
137     boolean_archetype(const boolean_archetype&) { }
138     operator bool() const { return true; }
139     boolean_archetype(detail::dummy_constructor) { }
140   private:
141     boolean_archetype() { }
142     boolean_archetype& operator=(const boolean_archetype&) { return *this; }
143   };
144   
145   template <class Base = null_archetype<> >
146   class equality_comparable_archetype : public Base {
147   public:
148     equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
149   };
150   template <class Base>
151   boolean_archetype
152   operator==(const equality_comparable_archetype<Base>&,
153              const equality_comparable_archetype<Base>&) 
154   { 
155     return boolean_archetype(static_object<detail::dummy_constructor>::get());
156   }
157   template <class Base>
158   boolean_archetype
159   operator!=(const equality_comparable_archetype<Base>&,
160              const equality_comparable_archetype<Base>&)
161   {
162     return boolean_archetype(static_object<detail::dummy_constructor>::get());
163   }
164
165
166   template <class Base = null_archetype<> >
167   class equality_comparable2_first_archetype : public Base {
168   public:
169     equality_comparable2_first_archetype(detail::dummy_constructor x) 
170       : Base(x) { }
171   };
172   template <class Base = null_archetype<> >
173   class equality_comparable2_second_archetype : public Base {
174   public:
175     equality_comparable2_second_archetype(detail::dummy_constructor x) 
176       : Base(x) { }
177   };
178   template <class Base1, class Base2>
179   boolean_archetype
180   operator==(const equality_comparable2_first_archetype<Base1>&,
181              const equality_comparable2_second_archetype<Base2>&) 
182   {
183     return boolean_archetype(static_object<detail::dummy_constructor>::get());
184   }
185   template <class Base1, class Base2>
186   boolean_archetype
187   operator!=(const equality_comparable2_first_archetype<Base1>&,
188              const equality_comparable2_second_archetype<Base2>&)
189   {
190     return boolean_archetype(static_object<detail::dummy_constructor>::get());
191   }
192
193
194   template <class Base = null_archetype<> >
195   class less_than_comparable_archetype : public Base {
196   public:
197     less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
198   };
199   template <class Base>
200   boolean_archetype
201   operator<(const less_than_comparable_archetype<Base>&,
202             const less_than_comparable_archetype<Base>&)
203   {
204     return boolean_archetype(static_object<detail::dummy_constructor>::get());
205   }
206
207
208
209   template <class Base = null_archetype<> >
210   class comparable_archetype : public Base {
211   public:
212     comparable_archetype(detail::dummy_constructor x) : Base(x) { }
213   };
214   template <class Base>
215   boolean_archetype
216   operator<(const comparable_archetype<Base>&,
217             const comparable_archetype<Base>&)
218   {
219     return boolean_archetype(static_object<detail::dummy_constructor>::get());
220   }
221   template <class Base>
222   boolean_archetype
223   operator<=(const comparable_archetype<Base>&,
224              const comparable_archetype<Base>&)
225   {
226     return boolean_archetype(static_object<detail::dummy_constructor>::get());
227   }
228   template <class Base>
229   boolean_archetype
230   operator>(const comparable_archetype<Base>&,
231             const comparable_archetype<Base>&)
232   {
233     return boolean_archetype(static_object<detail::dummy_constructor>::get());
234   }
235   template <class Base>
236   boolean_archetype
237   operator>=(const comparable_archetype<Base>&,
238              const comparable_archetype<Base>&)
239   {
240     return boolean_archetype(static_object<detail::dummy_constructor>::get());
241   }
242
243
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:
247   //
248   // A a; B b;
249   // a < b
250   // b < a
251   //
252   // without also allowing the combinations:
253   //
254   // a < a
255   // b < b
256   //
257   struct optag1 { };
258   struct optag2 { };
259   struct optag3 { };
260
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 { \
264   public: \
265     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
266   }; \
267   \
268   template <class Base = null_archetype<>, class Tag = optag1 > \
269   class NAME##_second_archetype : public Base { \
270   public: \
271     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
272   }; \
273   \
274   template <class BaseFirst, class BaseSecond, class Tag> \
275   boolean_archetype \
276   operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
277                const NAME##_second_archetype<BaseSecond, Tag>&) \
278   { \
279    return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
280   }
281
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)
288
289 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
290   template <class Base = null_archetype<> > \
291   class NAME##_archetype : public Base { \
292   public: \
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; } \
297   }; \
298   template <class Base> \
299   NAME##_archetype<Base> \
300   operator OP (const NAME##_archetype<Base>&,\
301                const NAME##_archetype<Base>&)  \
302   { \
303     return \
304      NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
305   }
306
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)
312
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 { \
318   public: \
319     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
320   }; \
321   \
322   template <class Return, class Base = null_archetype<> > \
323   class NAME##_second_archetype : public Base { \
324   public: \
325     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
326   }; \
327   \
328   template <class Return, class BaseFirst, class BaseSecond> \
329   Return \
330   operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
331                const NAME##_second_archetype<Return, BaseSecond>&) \
332   { \
333     return Return(static_object<detail::dummy_constructor>::get()); \
334   }
335
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)
341
342   //===========================================================================
343   // Function Object Archetype Classes
344
345   template <class Return>
346   class generator_archetype {
347   public:
348     const Return& operator()() {
349       return static_object<Return>::get(); 
350     }
351   };
352
353   class void_generator_archetype {
354   public:
355     void operator()() { }
356   };
357
358   template <class Arg, class Return>
359   class unary_function_archetype {
360   private:
361     unary_function_archetype() { }
362   public:
363     unary_function_archetype(detail::dummy_constructor) { }
364     const Return& operator()(const Arg&) const {
365       return static_object<Return>::get(); 
366     }
367   };
368
369   template <class Arg1, class Arg2, class Return>
370   class binary_function_archetype {
371   private:
372     binary_function_archetype() { }
373   public:
374     binary_function_archetype(detail::dummy_constructor) { }
375     const Return& operator()(const Arg1&, const Arg2&) const {
376       return static_object<Return>::get(); 
377     }
378   };
379
380   template <class Arg>
381   class unary_predicate_archetype {
382     typedef boolean_archetype Return;
383     unary_predicate_archetype() { }
384   public:
385     unary_predicate_archetype(detail::dummy_constructor) { }
386     const Return& operator()(const Arg&) const {
387       return static_object<Return>::get(); 
388     }
389   };
390
391   template <class Arg1, class Arg2, class Base = null_archetype<> >
392   class binary_predicate_archetype {
393     typedef boolean_archetype Return;
394     binary_predicate_archetype() { }
395   public:
396     binary_predicate_archetype(detail::dummy_constructor) { }
397     const Return& operator()(const Arg1&, const Arg2&) const {
398       return static_object<Return>::get(); 
399     }
400   };
401
402   //===========================================================================
403   // Iterator Archetype Classes
404
405   template <class T>
406   struct input_proxy {
407     operator const T&() { return static_object<T>::get(); }
408   };
409   template <class T>
410   class trivial_iterator_archetype
411   {
412     typedef trivial_iterator_archetype self;
413   public:
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;
420 #endif
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>(); }
426   };
427 } // namespace boost
428
429 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
430 namespace std {
431   template <class T>
432   struct iterator_traits< boost::trivial_iterator_archetype<T> >
433   {
434     typedef T value_type;
435   };
436 }
437 #endif
438
439 namespace boost {
440   template <class T>
441   struct input_output_proxy {
442     input_output_proxy<T>& operator=(const T&) { return *this; }
443     operator const T&() { return static_object<T>::get(); }
444   };
445   template <class T>
446   class mutable_trivial_iterator_archetype
447   {
448     typedef mutable_trivial_iterator_archetype self;
449   public:
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;
456 #endif
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>(); }
462   };
463 } // namespace boost
464
465 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
466 namespace std {
467   template <class T>
468   struct iterator_traits< boost::mutable_trivial_iterator_archetype<T> >
469   {
470     typedef T value_type;
471   };
472 }
473 #endif
474
475 namespace boost {
476
477   template <class T>
478   class input_iterator_archetype
479   {
480   public:
481     typedef input_iterator_archetype self;
482   public:
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; }
495   };
496
497  template <class T>
498   struct output_proxy {
499     output_proxy& operator=(const T&) { return *this; }
500   };
501
502   template <class T>
503   class output_iterator_archetype
504   {
505   public:
506     typedef output_iterator_archetype self;
507   public:
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; }
521   private:
522     output_iterator_archetype() { }
523   };
524
525   template <class T>
526   class forward_iterator_archetype
527   {
528   public:
529     typedef forward_iterator_archetype self;
530   public:
531     typedef std::forward_iterator_tag iterator_category;
532     typedef T value_type;
533     typedef const T& reference;
534     typedef T* pointer;
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; }
543   };
544
545   template <class T>
546   class mutable_forward_iterator_archetype
547   {
548   public:
549     typedef mutable_forward_iterator_archetype self;
550   public:
551     typedef std::forward_iterator_tag iterator_category;
552     typedef T value_type;
553     typedef T& reference;
554     typedef T* pointer;
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; }
563   };
564
565   template <class T>
566   class bidirectional_iterator_archetype
567   {
568   public:
569     typedef bidirectional_iterator_archetype self;
570   public:
571     typedef std::bidirectional_iterator_tag iterator_category;
572     typedef T value_type;
573     typedef const T& reference;
574     typedef T* pointer;
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; }
585   };
586
587   template <class T>
588   class mutable_bidirectional_iterator_archetype
589   {
590   public:
591     typedef mutable_bidirectional_iterator_archetype self;
592   public:
593     typedef std::bidirectional_iterator_tag iterator_category;
594     typedef T value_type;
595     typedef T& reference;
596     typedef T* pointer;
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; }
607   };
608
609   template <class T>
610   class random_access_iterator_archetype
611   {
612   public:
613     typedef random_access_iterator_archetype self;
614   public:
615     typedef std::random_access_iterator_tag iterator_category;
616     typedef T value_type;
617     typedef const T& reference;
618     typedef T* pointer;
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; }
641   };
642   template <class T>
643   random_access_iterator_archetype<T> 
644   operator+(typename random_access_iterator_archetype<T>::difference_type, 
645             const random_access_iterator_archetype<T>& x) 
646     { return x; }
647
648
649   template <class T>
650   class mutable_random_access_iterator_archetype
651   {
652   public:
653     typedef mutable_random_access_iterator_archetype self;
654   public:
655     typedef std::random_access_iterator_tag iterator_category;
656     typedef T value_type;
657     typedef T& reference;
658     typedef T* pointer;
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; }
681   };
682   template <class T>
683   mutable_random_access_iterator_archetype<T> 
684   operator+
685     (typename mutable_random_access_iterator_archetype<T>::difference_type, 
686      const mutable_random_access_iterator_archetype<T>& x) 
687     { return x; }
688
689 } // namespace boost
690
691 #endif // BOOST_CONCEPT_ARCHETYPES_H