]> git.lyx.org Git - lyx.git/blob - boost/boost/concept_archetype.hpp
64-bit fix to boost::format.
[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 <boost/mpl/identity.hpp>
21 #include <functional>
22
23 namespace boost {
24
25   //===========================================================================
26   // Basic Archetype Classes
27
28   namespace detail {
29     class dummy_constructor { };
30   }
31
32   // A type that models no concept. The template parameter 
33   // is only there so that null_archetype types can be created
34   // that have different type.
35   template <class T = int>
36   class null_archetype {
37   private:
38     null_archetype() { }
39     null_archetype(const null_archetype&) { }
40     null_archetype& operator=(const null_archetype&) { return *this; }
41   public:
42     null_archetype(detail::dummy_constructor) { }
43 #ifndef __MWERKS__
44     template <class TT>
45     friend void dummy_friend(); // just to avoid warnings
46 #endif
47   };
48
49   // This is a helper class that provides a way to get a reference to
50   // an object. The get() function will never be called at run-time
51   // (nothing in this file will) so this seemingly very bad function
52   // is really quite innocent. The name of this class needs to be
53   // changed.
54   template <class T>
55   class static_object
56   {
57   public:
58       static T& get()
59       {
60 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
61           return *reinterpret_cast<T*>(0);
62 #else 
63           static char d[sizeof(T)];
64           return *reinterpret_cast<T*>(d);
65 #endif 
66       }
67   };
68
69   template <class Base = null_archetype<> >
70   class default_constructible_archetype : public Base {
71   public:
72     default_constructible_archetype() 
73       : Base(static_object<detail::dummy_constructor>::get()) { }
74     default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
75   };
76
77   template <class Base = null_archetype<> >
78   class assignable_archetype : public Base {
79     assignable_archetype() { }
80     assignable_archetype(const assignable_archetype&) { }
81   public:
82     assignable_archetype& operator=(const assignable_archetype&) {
83       return *this;
84     }
85     assignable_archetype(detail::dummy_constructor x) : Base(x) { }
86   };
87
88   template <class Base = null_archetype<> >
89   class copy_constructible_archetype : public Base {
90   public:
91     copy_constructible_archetype() 
92       : Base(static_object<detail::dummy_constructor>::get()) { }
93     copy_constructible_archetype(const copy_constructible_archetype&)
94       : Base(static_object<detail::dummy_constructor>::get()) { }
95     copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
96   };
97
98   template <class Base = null_archetype<> >
99   class sgi_assignable_archetype : public Base {
100   public:
101     sgi_assignable_archetype(const sgi_assignable_archetype&)
102       : Base(static_object<detail::dummy_constructor>::get()) { }
103     sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
104       return *this;
105     }
106     sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
107   };
108
109   struct default_archetype_base {
110     default_archetype_base(detail::dummy_constructor) { }
111   };
112
113   // Careful, don't use same type for T and Base. That results in the
114   // conversion operator being invalid.  Since T is often
115   // null_archetype, can't use null_archetype for Base.
116   template <class T, class Base = default_archetype_base>
117   class convertible_to_archetype : public Base {
118   private:
119     convertible_to_archetype() { }
120     convertible_to_archetype(const convertible_to_archetype& ) { }
121     convertible_to_archetype& operator=(const convertible_to_archetype&)
122       { return *this; }
123   public:
124     convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
125     operator const T&() const { return static_object<T>::get(); }
126   };
127
128   template <class T, class Base = default_archetype_base>
129   class convertible_from_archetype : public Base {
130   private:
131     convertible_from_archetype() { }
132     convertible_from_archetype(const convertible_from_archetype& ) { }
133     convertible_from_archetype& operator=(const convertible_from_archetype&)
134       { return *this; }
135   public:
136     convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
137     convertible_from_archetype(const T&) { }
138     convertible_from_archetype& operator=(const T&)
139       { return *this; }
140   };
141
142   class boolean_archetype {
143   public:
144     boolean_archetype(const boolean_archetype&) { }
145     operator bool() const { return true; }
146     boolean_archetype(detail::dummy_constructor) { }
147   private:
148     boolean_archetype() { }
149     boolean_archetype& operator=(const boolean_archetype&) { return *this; }
150   };
151   
152   template <class Base = null_archetype<> >
153   class equality_comparable_archetype : public Base {
154   public:
155     equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
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   template <class Base>
165   boolean_archetype
166   operator!=(const equality_comparable_archetype<Base>&,
167              const equality_comparable_archetype<Base>&)
168   {
169     return boolean_archetype(static_object<detail::dummy_constructor>::get());
170   }
171
172
173   template <class Base = null_archetype<> >
174   class equality_comparable2_first_archetype : public Base {
175   public:
176     equality_comparable2_first_archetype(detail::dummy_constructor x) 
177       : Base(x) { }
178   };
179   template <class Base = null_archetype<> >
180   class equality_comparable2_second_archetype : public Base {
181   public:
182     equality_comparable2_second_archetype(detail::dummy_constructor x) 
183       : Base(x) { }
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   template <class Base1, class Base2>
193   boolean_archetype
194   operator!=(const equality_comparable2_first_archetype<Base1>&,
195              const equality_comparable2_second_archetype<Base2>&)
196   {
197     return boolean_archetype(static_object<detail::dummy_constructor>::get());
198   }
199
200
201   template <class Base = null_archetype<> >
202   class less_than_comparable_archetype : public Base {
203   public:
204     less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
205   };
206   template <class Base>
207   boolean_archetype
208   operator<(const less_than_comparable_archetype<Base>&,
209             const less_than_comparable_archetype<Base>&)
210   {
211     return boolean_archetype(static_object<detail::dummy_constructor>::get());
212   }
213
214
215
216   template <class Base = null_archetype<> >
217   class comparable_archetype : public Base {
218   public:
219     comparable_archetype(detail::dummy_constructor x) : Base(x) { }
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   template <class Base>
243   boolean_archetype
244   operator>=(const comparable_archetype<Base>&,
245              const comparable_archetype<Base>&)
246   {
247     return boolean_archetype(static_object<detail::dummy_constructor>::get());
248   }
249
250
251   // The purpose of the optags is so that one can specify
252   // exactly which types the operator< is defined between.
253   // This is useful for allowing the operations:
254   //
255   // A a; B b;
256   // a < b
257   // b < a
258   //
259   // without also allowing the combinations:
260   //
261   // a < a
262   // b < b
263   //
264   struct optag1 { };
265   struct optag2 { };
266   struct optag3 { };
267
268 #define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME)                       \
269   template <class Base = null_archetype<>, class Tag = optag1 >                 \
270   class NAME##_first_archetype : public Base {                                  \
271   public:                                                                       \
272     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { }           \
273   };                                                                            \
274                                                                                 \
275   template <class Base = null_archetype<>, class Tag = optag1 >                 \
276   class NAME##_second_archetype : public Base {                                 \
277   public:                                                                       \
278     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { }          \
279   };                                                                            \
280                                                                                 \
281   template <class BaseFirst, class BaseSecond, class Tag>                       \
282   boolean_archetype                                                             \
283   operator OP (const NAME##_first_archetype<BaseFirst, Tag>&,                   \
284                const NAME##_second_archetype<BaseSecond, Tag>&)                 \
285   {                                                                             \
286    return boolean_archetype(static_object<detail::dummy_constructor>::get());   \
287   }
288
289   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
290   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
291   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
292   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
293   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
294   BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
295
296 #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
297   template <class Base = null_archetype<> > \
298   class NAME##_archetype : public Base { \
299   public: \
300     NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
301     NAME##_archetype(const NAME##_archetype&)  \
302       : Base(static_object<detail::dummy_constructor>::get()) { } \
303     NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
304   }; \
305   template <class Base> \
306   NAME##_archetype<Base> \
307   operator OP (const NAME##_archetype<Base>&,\
308                const NAME##_archetype<Base>&)  \
309   { \
310     return \
311      NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
312   }
313
314   BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
315   BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
316   BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
317   BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
318   BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
319
320   // As is, these are useless because of the return type.
321   // Need to invent a better way...
322 #define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
323   template <class Return, class Base = null_archetype<> > \
324   class NAME##_first_archetype : public Base { \
325   public: \
326     NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
327   }; \
328   \
329   template <class Return, class Base = null_archetype<> > \
330   class NAME##_second_archetype : public Base { \
331   public: \
332     NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
333   }; \
334   \
335   template <class Return, class BaseFirst, class BaseSecond> \
336   Return \
337   operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
338                const NAME##_second_archetype<Return, BaseSecond>&) \
339   { \
340     return Return(static_object<detail::dummy_constructor>::get()); \
341   }
342
343   BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
344   BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
345   BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
346   BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
347   BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
348
349   //===========================================================================
350   // Function Object Archetype Classes
351
352   template <class Return>
353   class generator_archetype {
354   public:
355     const Return& operator()() {
356       return static_object<Return>::get(); 
357     }
358   };
359
360   class void_generator_archetype {
361   public:
362     void operator()() { }
363   };
364
365   template <class Arg, class Return>
366   class unary_function_archetype {
367   private:
368     unary_function_archetype() { }
369   public:
370     unary_function_archetype(detail::dummy_constructor) { }
371     const Return& operator()(const Arg&) const {
372       return static_object<Return>::get(); 
373     }
374   };
375
376   template <class Arg1, class Arg2, class Return>
377   class binary_function_archetype {
378   private:
379     binary_function_archetype() { }
380   public:
381     binary_function_archetype(detail::dummy_constructor) { }
382     const Return& operator()(const Arg1&, const Arg2&) const {
383       return static_object<Return>::get(); 
384     }
385   };
386
387   template <class Arg>
388   class unary_predicate_archetype {
389     typedef boolean_archetype Return;
390     unary_predicate_archetype() { }
391   public:
392     unary_predicate_archetype(detail::dummy_constructor) { }
393     const Return& operator()(const Arg&) const {
394       return static_object<Return>::get(); 
395     }
396   };
397
398   template <class Arg1, class Arg2, class Base = null_archetype<> >
399   class binary_predicate_archetype {
400     typedef boolean_archetype Return;
401     binary_predicate_archetype() { }
402   public:
403     binary_predicate_archetype(detail::dummy_constructor) { }
404     const Return& operator()(const Arg1&, const Arg2&) const {
405       return static_object<Return>::get(); 
406     }
407   };
408
409   //===========================================================================
410   // Iterator Archetype Classes
411
412   template <class T>
413   class input_iterator_archetype
414   {
415   private:
416     typedef input_iterator_archetype self;
417   public:
418     typedef std::input_iterator_tag iterator_category;
419     typedef T value_type;
420     struct reference {
421       operator value_type() const { return static_object<T>::get(); }
422     };
423     typedef const T* pointer;
424     typedef std::ptrdiff_t difference_type;
425     self& operator=(const self&) { return *this;  }
426     bool operator==(const self&) const { return true; }
427     bool operator!=(const self&) const { return true; }
428     reference operator*() const { return reference(); }
429     self& operator++() { return *this; }
430     self operator++(int) { return *this; }
431   };
432
433   template <class T>
434   class input_iterator_archetype_no_proxy
435   {
436   private:
437     typedef input_iterator_archetype_no_proxy self;
438   public:
439     typedef std::input_iterator_tag iterator_category;
440     typedef T value_type;
441     typedef const T& reference;
442     typedef const T* pointer;
443     typedef std::ptrdiff_t difference_type;
444     self& operator=(const self&) { return *this;  }
445     bool operator==(const self&) const { return true; }
446     bool operator!=(const self&) const { return true; }
447     reference operator*() const { return static_object<T>::get(); }
448     self& operator++() { return *this; }
449     self operator++(int) { return *this; }
450   };
451
452   template <class T>
453   struct output_proxy {
454     output_proxy& operator=(const T&) { return *this; }
455   };
456
457   template <class T>
458   class output_iterator_archetype
459   {
460   public:
461     typedef output_iterator_archetype self;
462   public:
463     typedef std::output_iterator_tag iterator_category;
464     typedef output_proxy<T> value_type;
465     typedef output_proxy<T> reference;
466     typedef void pointer;
467     typedef void difference_type;
468     output_iterator_archetype(detail::dummy_constructor) { }
469     output_iterator_archetype(const self&) { }
470     self& operator=(const self&) { return *this; }
471     bool operator==(const self&) const { return true; }
472     bool operator!=(const self&) const { return true; }
473     reference operator*() const { return output_proxy<T>(); }
474     self& operator++() { return *this; }
475     self operator++(int) { return *this; }
476   private:
477     output_iterator_archetype() { }
478   };
479
480   template <class T>
481   class input_output_iterator_archetype
482   {
483   private:
484     typedef input_output_iterator_archetype self;
485     struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { };
486   public:
487     typedef in_out_tag iterator_category;
488     typedef T value_type;
489     struct reference {
490       reference& operator=(const T&) { return *this; }
491       operator value_type() { return static_object<T>::get(); }
492     };
493     typedef const T* pointer;
494     typedef std::ptrdiff_t difference_type;
495     input_output_iterator_archetype() { }
496     self& operator=(const self&) { return *this;  }
497     bool operator==(const self&) const { return true; }
498     bool operator!=(const self&) const { return true; }
499     reference operator*() const { return reference(); }
500     self& operator++() { return *this; }
501     self operator++(int) { return *this; }
502   };
503
504   template <class T>
505   class forward_iterator_archetype
506   {
507   public:
508     typedef forward_iterator_archetype self;
509   public:
510     typedef std::forward_iterator_tag iterator_category;
511     typedef T value_type;
512     typedef const T& reference;
513     typedef T const* pointer;
514     typedef std::ptrdiff_t difference_type;
515     forward_iterator_archetype() { }
516     self& operator=(const self&) { return *this;  }
517     bool operator==(const self&) const { return true; }
518     bool operator!=(const self&) const { return true; }
519     reference operator*() const { return static_object<T>::get(); }
520     self& operator++() { return *this; }
521     self operator++(int) { return *this; }
522   };
523
524   template <class T>
525   class mutable_forward_iterator_archetype
526   {
527   public:
528     typedef mutable_forward_iterator_archetype self;
529   public:
530     typedef std::forward_iterator_tag iterator_category;
531     typedef T value_type;
532     typedef T& reference;
533     typedef T* pointer;
534     typedef std::ptrdiff_t difference_type;
535     mutable_forward_iterator_archetype() { }
536     self& operator=(const self&) { return *this;  }
537     bool operator==(const self&) const { return true; }
538     bool operator!=(const self&) const { return true; }
539     reference operator*() const { return static_object<T>::get(); }
540     self& operator++() { return *this; }
541     self operator++(int) { return *this; }
542   };
543
544   template <class T>
545   class bidirectional_iterator_archetype
546   {
547   public:
548     typedef bidirectional_iterator_archetype self;
549   public:
550     typedef std::bidirectional_iterator_tag iterator_category;
551     typedef T value_type;
552     typedef const T& reference;
553     typedef T* pointer;
554     typedef std::ptrdiff_t difference_type;
555     bidirectional_iterator_archetype() { }
556     self& operator=(const self&) { return *this;  }
557     bool operator==(const self&) const { return true; }
558     bool operator!=(const self&) const { return true; }
559     reference operator*() const { return static_object<T>::get(); }
560     self& operator++() { return *this; }
561     self operator++(int) { return *this; }
562     self& operator--() { return *this; }
563     self operator--(int) { return *this; }
564   };
565
566   template <class T>
567   class mutable_bidirectional_iterator_archetype
568   {
569   public:
570     typedef mutable_bidirectional_iterator_archetype self;
571   public:
572     typedef std::bidirectional_iterator_tag iterator_category;
573     typedef T value_type;
574     typedef T& reference;
575     typedef T* pointer;
576     typedef std::ptrdiff_t difference_type;
577     mutable_bidirectional_iterator_archetype() { }
578     self& operator=(const self&) { return *this;  }
579     bool operator==(const self&) const { return true; }
580     bool operator!=(const self&) const { return true; }
581     reference operator*() const { return static_object<T>::get(); }
582     self& operator++() { return *this; }
583     self operator++(int) { return *this; }
584     self& operator--() { return *this; }
585     self operator--(int) { return *this; }
586   };
587
588   template <class T>
589   class random_access_iterator_archetype
590   {
591   public:
592     typedef random_access_iterator_archetype self;
593   public:
594     typedef std::random_access_iterator_tag iterator_category;
595     typedef T value_type;
596     typedef const T& reference;
597     typedef T* pointer;
598     typedef std::ptrdiff_t difference_type;
599     random_access_iterator_archetype() { }
600     self& operator=(const self&) { return *this;  }
601     bool operator==(const self&) const { return true; }
602     bool operator!=(const self&) const { return true; }
603     reference operator*() const { return static_object<T>::get(); }
604     self& operator++() { return *this; }
605     self operator++(int) { return *this; }
606     self& operator--() { return *this; }
607     self operator--(int) { return *this; }
608     reference operator[](difference_type) const
609       { return static_object<T>::get(); }
610     self& operator+=(difference_type) { return *this; }
611     self& operator-=(difference_type) { return *this; }
612     difference_type operator-(const self&) const
613       { return difference_type(); }
614     self operator+(difference_type) const { return *this; }
615     self operator-(difference_type) const { return *this; }
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     bool operator>=(const self&) const { return true; }
620   };
621   template <class T>
622   random_access_iterator_archetype<T> 
623   operator+(typename random_access_iterator_archetype<T>::difference_type, 
624             const random_access_iterator_archetype<T>& x) 
625     { return x; }
626
627
628   template <class T>
629   class mutable_random_access_iterator_archetype
630   {
631   public:
632     typedef mutable_random_access_iterator_archetype self;
633   public:
634     typedef std::random_access_iterator_tag iterator_category;
635     typedef T value_type;
636     typedef T& reference;
637     typedef T* pointer;
638     typedef std::ptrdiff_t difference_type;
639     mutable_random_access_iterator_archetype() { }
640     self& operator=(const self&) { return *this;  }
641     bool operator==(const self&) const { return true; }
642     bool operator!=(const self&) const { return true; }
643     reference operator*() const { return static_object<T>::get(); }
644     self& operator++() { return *this; }
645     self operator++(int) { return *this; }
646     self& operator--() { return *this; }
647     self operator--(int) { return *this; }
648     reference operator[](difference_type) const
649       { return static_object<T>::get(); }
650     self& operator+=(difference_type) { return *this; }
651     self& operator-=(difference_type) { return *this; }
652     difference_type operator-(const self&) const
653       { return difference_type(); }
654     self operator+(difference_type) const { return *this; }
655     self operator-(difference_type) const { return *this; }
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     bool operator>=(const self&) const { return true; }
660   };
661   template <class T>
662   mutable_random_access_iterator_archetype<T> 
663   operator+
664     (typename mutable_random_access_iterator_archetype<T>::difference_type, 
665      const mutable_random_access_iterator_archetype<T>& x) 
666     { return x; }
667
668 } // namespace boost
669
670 #endif // BOOST_CONCEPT_ARCHETYPES_H