| // |
| // (C) Copyright Jeremy Siek 2000. |
| // Distributed under the Boost Software License, Version 1.0. (See |
| // accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // Revision History: |
| // |
| // 17 July 2001: Added const to some member functions. (Jeremy Siek) |
| // 05 May 2001: Removed static dummy_cons object. (Jeremy Siek) |
| |
| // See http://www.boost.org/libs/concept_check for documentation. |
| |
| #ifndef BOOST_CONCEPT_ARCHETYPES_HPP |
| #define BOOST_CONCEPT_ARCHETYPES_HPP |
| |
| #include <boost/config.hpp> |
| #include <boost/iterator.hpp> |
| #include <boost/mpl/identity.hpp> |
| #include <functional> |
| |
| namespace boost { |
| |
| //=========================================================================== |
| // Basic Archetype Classes |
| |
| namespace detail { |
| class dummy_constructor { }; |
| } |
| |
| // A type that models no concept. The template parameter |
| // is only there so that null_archetype types can be created |
| // that have different type. |
| template <class T = int> |
| class null_archetype { |
| private: |
| null_archetype() { } |
| null_archetype(const null_archetype&) { } |
| null_archetype& operator=(const null_archetype&) { return *this; } |
| public: |
| null_archetype(detail::dummy_constructor) { } |
| #ifndef __MWERKS__ |
| template <class TT> |
| friend void dummy_friend(); // just to avoid warnings |
| #endif |
| }; |
| |
| // This is a helper class that provides a way to get a reference to |
| // an object. The get() function will never be called at run-time |
| // (nothing in this file will) so this seemingly very bad function |
| // is really quite innocent. The name of this class needs to be |
| // changed. |
| template <class T> |
| class static_object |
| { |
| public: |
| static T& get() |
| { |
| #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
| return *reinterpret_cast<T*>(0); |
| #else |
| static char d[sizeof(T)]; |
| return *reinterpret_cast<T*>(d); |
| #endif |
| } |
| }; |
| |
| template <class Base = null_archetype<> > |
| class default_constructible_archetype : public Base { |
| public: |
| default_constructible_archetype() |
| : Base(static_object<detail::dummy_constructor>::get()) { } |
| default_constructible_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| |
| template <class Base = null_archetype<> > |
| class assignable_archetype : public Base { |
| assignable_archetype() { } |
| assignable_archetype(const assignable_archetype&) { } |
| public: |
| assignable_archetype& operator=(const assignable_archetype&) { |
| return *this; |
| } |
| assignable_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| |
| template <class Base = null_archetype<> > |
| class copy_constructible_archetype : public Base { |
| public: |
| copy_constructible_archetype() |
| : Base(static_object<detail::dummy_constructor>::get()) { } |
| copy_constructible_archetype(const copy_constructible_archetype&) |
| : Base(static_object<detail::dummy_constructor>::get()) { } |
| copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| |
| template <class Base = null_archetype<> > |
| class sgi_assignable_archetype : public Base { |
| public: |
| sgi_assignable_archetype(const sgi_assignable_archetype&) |
| : Base(static_object<detail::dummy_constructor>::get()) { } |
| sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) { |
| return *this; |
| } |
| sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { } |
| }; |
| |
| struct default_archetype_base { |
| default_archetype_base(detail::dummy_constructor) { } |
| }; |
| |
| // Careful, don't use same type for T and Base. That results in the |
| // conversion operator being invalid. Since T is often |
| // null_archetype, can't use null_archetype for Base. |
| template <class T, class Base = default_archetype_base> |
| class convertible_to_archetype : public Base { |
| private: |
| convertible_to_archetype() { } |
| convertible_to_archetype(const convertible_to_archetype& ) { } |
| convertible_to_archetype& operator=(const convertible_to_archetype&) |
| { return *this; } |
| public: |
| convertible_to_archetype(detail::dummy_constructor x) : Base(x) { } |
| operator const T&() const { return static_object<T>::get(); } |
| }; |
| |
| template <class T, class Base = default_archetype_base> |
| class convertible_from_archetype : public Base { |
| private: |
| convertible_from_archetype() { } |
| convertible_from_archetype(const convertible_from_archetype& ) { } |
| convertible_from_archetype& operator=(const convertible_from_archetype&) |
| { return *this; } |
| public: |
| convertible_from_archetype(detail::dummy_constructor x) : Base(x) { } |
| convertible_from_archetype(const T&) { } |
| convertible_from_archetype& operator=(const T&) |
| { return *this; } |
| }; |
| |
| class boolean_archetype { |
| public: |
| boolean_archetype(const boolean_archetype&) { } |
| operator bool() const { return true; } |
| boolean_archetype(detail::dummy_constructor) { } |
| private: |
| boolean_archetype() { } |
| boolean_archetype& operator=(const boolean_archetype&) { return *this; } |
| }; |
| |
| template <class Base = null_archetype<> > |
| class equality_comparable_archetype : public Base { |
| public: |
| equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| template <class Base> |
| boolean_archetype |
| operator==(const equality_comparable_archetype<Base>&, |
| const equality_comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| template <class Base> |
| boolean_archetype |
| operator!=(const equality_comparable_archetype<Base>&, |
| const equality_comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| |
| |
| template <class Base = null_archetype<> > |
| class equality_comparable2_first_archetype : public Base { |
| public: |
| equality_comparable2_first_archetype(detail::dummy_constructor x) |
| : Base(x) { } |
| }; |
| template <class Base = null_archetype<> > |
| class equality_comparable2_second_archetype : public Base { |
| public: |
| equality_comparable2_second_archetype(detail::dummy_constructor x) |
| : Base(x) { } |
| }; |
| template <class Base1, class Base2> |
| boolean_archetype |
| operator==(const equality_comparable2_first_archetype<Base1>&, |
| const equality_comparable2_second_archetype<Base2>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| template <class Base1, class Base2> |
| boolean_archetype |
| operator!=(const equality_comparable2_first_archetype<Base1>&, |
| const equality_comparable2_second_archetype<Base2>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| |
| |
| template <class Base = null_archetype<> > |
| class less_than_comparable_archetype : public Base { |
| public: |
| less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| template <class Base> |
| boolean_archetype |
| operator<(const less_than_comparable_archetype<Base>&, |
| const less_than_comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| |
| |
| |
| template <class Base = null_archetype<> > |
| class comparable_archetype : public Base { |
| public: |
| comparable_archetype(detail::dummy_constructor x) : Base(x) { } |
| }; |
| template <class Base> |
| boolean_archetype |
| operator<(const comparable_archetype<Base>&, |
| const comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| template <class Base> |
| boolean_archetype |
| operator<=(const comparable_archetype<Base>&, |
| const comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| template <class Base> |
| boolean_archetype |
| operator>(const comparable_archetype<Base>&, |
| const comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| template <class Base> |
| boolean_archetype |
| operator>=(const comparable_archetype<Base>&, |
| const comparable_archetype<Base>&) |
| { |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); |
| } |
| |
| |
| // The purpose of the optags is so that one can specify |
| // exactly which types the operator< is defined between. |
| // This is useful for allowing the operations: |
| // |
| // A a; B b; |
| // a < b |
| // b < a |
| // |
| // without also allowing the combinations: |
| // |
| // a < a |
| // b < b |
| // |
| struct optag1 { }; |
| struct optag2 { }; |
| struct optag3 { }; |
| |
| #define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \ |
| template <class Base = null_archetype<>, class Tag = optag1 > \ |
| class NAME##_first_archetype : public Base { \ |
| public: \ |
| NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \ |
| }; \ |
| \ |
| template <class Base = null_archetype<>, class Tag = optag1 > \ |
| class NAME##_second_archetype : public Base { \ |
| public: \ |
| NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \ |
| }; \ |
| \ |
| template <class BaseFirst, class BaseSecond, class Tag> \ |
| boolean_archetype \ |
| operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \ |
| const NAME##_second_archetype<BaseSecond, Tag>&) \ |
| { \ |
| return boolean_archetype(static_object<detail::dummy_constructor>::get()); \ |
| } |
| |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op) |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op) |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op) |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op) |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op) |
| BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op) |
| |
| #define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \ |
| template <class Base = null_archetype<> > \ |
| class NAME##_archetype : public Base { \ |
| public: \ |
| NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \ |
| NAME##_archetype(const NAME##_archetype&) \ |
| : Base(static_object<detail::dummy_constructor>::get()) { } \ |
| NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \ |
| }; \ |
| template <class Base> \ |
| NAME##_archetype<Base> \ |
| operator OP (const NAME##_archetype<Base>&,\ |
| const NAME##_archetype<Base>&) \ |
| { \ |
| return \ |
| NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \ |
| } |
| |
| BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable) |
| BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable) |
| BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable) |
| BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable) |
| BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable) |
| |
| // As is, these are useless because of the return type. |
| // Need to invent a better way... |
| #define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \ |
| template <class Return, class Base = null_archetype<> > \ |
| class NAME##_first_archetype : public Base { \ |
| public: \ |
| NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \ |
| }; \ |
| \ |
| template <class Return, class Base = null_archetype<> > \ |
| class NAME##_second_archetype : public Base { \ |
| public: \ |
| NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \ |
| }; \ |
| \ |
| template <class Return, class BaseFirst, class BaseSecond> \ |
| Return \ |
| operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \ |
| const NAME##_second_archetype<Return, BaseSecond>&) \ |
| { \ |
| return Return(static_object<detail::dummy_constructor>::get()); \ |
| } |
| |
| BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op) |
| BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op) |
| BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op) |
| BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op) |
| BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op) |
| |
| //=========================================================================== |
| // Function Object Archetype Classes |
| |
| template <class Return> |
| class generator_archetype { |
| public: |
| const Return& operator()() { |
| return static_object<Return>::get(); |
| } |
| }; |
| |
| class void_generator_archetype { |
| public: |
| void operator()() { } |
| }; |
| |
| template <class Arg, class Return> |
| class unary_function_archetype { |
| private: |
| unary_function_archetype() { } |
| public: |
| unary_function_archetype(detail::dummy_constructor) { } |
| const Return& operator()(const Arg&) const { |
| return static_object<Return>::get(); |
| } |
| }; |
| |
| template <class Arg1, class Arg2, class Return> |
| class binary_function_archetype { |
| private: |
| binary_function_archetype() { } |
| public: |
| binary_function_archetype(detail::dummy_constructor) { } |
| const Return& operator()(const Arg1&, const Arg2&) const { |
| return static_object<Return>::get(); |
| } |
| }; |
| |
| template <class Arg> |
| class unary_predicate_archetype { |
| typedef boolean_archetype Return; |
| unary_predicate_archetype() { } |
| public: |
| unary_predicate_archetype(detail::dummy_constructor) { } |
| const Return& operator()(const Arg&) const { |
| return static_object<Return>::get(); |
| } |
| }; |
| |
| template <class Arg1, class Arg2, class Base = null_archetype<> > |
| class binary_predicate_archetype { |
| typedef boolean_archetype Return; |
| binary_predicate_archetype() { } |
| public: |
| binary_predicate_archetype(detail::dummy_constructor) { } |
| const Return& operator()(const Arg1&, const Arg2&) const { |
| return static_object<Return>::get(); |
| } |
| }; |
| |
| //=========================================================================== |
| // Iterator Archetype Classes |
| |
| template <class T, int I = 0> |
| class input_iterator_archetype |
| { |
| private: |
| typedef input_iterator_archetype self; |
| public: |
| typedef std::input_iterator_tag iterator_category; |
| typedef T value_type; |
| struct reference { |
| operator const value_type&() const { return static_object<T>::get(); } |
| }; |
| typedef const T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return reference(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| }; |
| |
| template <class T> |
| class input_iterator_archetype_no_proxy |
| { |
| private: |
| typedef input_iterator_archetype_no_proxy self; |
| public: |
| typedef std::input_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef const T& reference; |
| typedef const T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| }; |
| |
| template <class T> |
| struct output_proxy { |
| output_proxy& operator=(const T&) { return *this; } |
| }; |
| |
| template <class T> |
| class output_iterator_archetype |
| { |
| public: |
| typedef output_iterator_archetype self; |
| public: |
| typedef std::output_iterator_tag iterator_category; |
| typedef output_proxy<T> value_type; |
| typedef output_proxy<T> reference; |
| typedef void pointer; |
| typedef void difference_type; |
| output_iterator_archetype(detail::dummy_constructor) { } |
| output_iterator_archetype(const self&) { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return output_proxy<T>(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| private: |
| output_iterator_archetype() { } |
| }; |
| |
| template <class T> |
| class input_output_iterator_archetype |
| { |
| private: |
| typedef input_output_iterator_archetype self; |
| struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { }; |
| public: |
| typedef in_out_tag iterator_category; |
| typedef T value_type; |
| struct reference { |
| reference& operator=(const T&) { return *this; } |
| operator value_type() { return static_object<T>::get(); } |
| }; |
| typedef const T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| input_output_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return reference(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| }; |
| |
| template <class T> |
| class forward_iterator_archetype |
| { |
| public: |
| typedef forward_iterator_archetype self; |
| public: |
| typedef std::forward_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef const T& reference; |
| typedef T const* pointer; |
| typedef std::ptrdiff_t difference_type; |
| forward_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| }; |
| |
| template <class T> |
| class mutable_forward_iterator_archetype |
| { |
| public: |
| typedef mutable_forward_iterator_archetype self; |
| public: |
| typedef std::forward_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef T& reference; |
| typedef T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| mutable_forward_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| }; |
| |
| template <class T> |
| class bidirectional_iterator_archetype |
| { |
| public: |
| typedef bidirectional_iterator_archetype self; |
| public: |
| typedef std::bidirectional_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef const T& reference; |
| typedef T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| bidirectional_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| self& operator--() { return *this; } |
| self operator--(int) { return *this; } |
| }; |
| |
| template <class T> |
| class mutable_bidirectional_iterator_archetype |
| { |
| public: |
| typedef mutable_bidirectional_iterator_archetype self; |
| public: |
| typedef std::bidirectional_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef T& reference; |
| typedef T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| mutable_bidirectional_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| self& operator--() { return *this; } |
| self operator--(int) { return *this; } |
| }; |
| |
| template <class T> |
| class random_access_iterator_archetype |
| { |
| public: |
| typedef random_access_iterator_archetype self; |
| public: |
| typedef std::random_access_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef const T& reference; |
| typedef T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| random_access_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| self& operator--() { return *this; } |
| self operator--(int) { return *this; } |
| reference operator[](difference_type) const |
| { return static_object<T>::get(); } |
| self& operator+=(difference_type) { return *this; } |
| self& operator-=(difference_type) { return *this; } |
| difference_type operator-(const self&) const |
| { return difference_type(); } |
| self operator+(difference_type) const { return *this; } |
| self operator-(difference_type) const { return *this; } |
| bool operator<(const self&) const { return true; } |
| bool operator<=(const self&) const { return true; } |
| bool operator>(const self&) const { return true; } |
| bool operator>=(const self&) const { return true; } |
| }; |
| template <class T> |
| random_access_iterator_archetype<T> |
| operator+(typename random_access_iterator_archetype<T>::difference_type, |
| const random_access_iterator_archetype<T>& x) |
| { return x; } |
| |
| |
| template <class T> |
| class mutable_random_access_iterator_archetype |
| { |
| public: |
| typedef mutable_random_access_iterator_archetype self; |
| public: |
| typedef std::random_access_iterator_tag iterator_category; |
| typedef T value_type; |
| typedef T& reference; |
| typedef T* pointer; |
| typedef std::ptrdiff_t difference_type; |
| mutable_random_access_iterator_archetype() { } |
| self& operator=(const self&) { return *this; } |
| bool operator==(const self&) const { return true; } |
| bool operator!=(const self&) const { return true; } |
| reference operator*() const { return static_object<T>::get(); } |
| self& operator++() { return *this; } |
| self operator++(int) { return *this; } |
| self& operator--() { return *this; } |
| self operator--(int) { return *this; } |
| reference operator[](difference_type) const |
| { return static_object<T>::get(); } |
| self& operator+=(difference_type) { return *this; } |
| self& operator-=(difference_type) { return *this; } |
| difference_type operator-(const self&) const |
| { return difference_type(); } |
| self operator+(difference_type) const { return *this; } |
| self operator-(difference_type) const { return *this; } |
| bool operator<(const self&) const { return true; } |
| bool operator<=(const self&) const { return true; } |
| bool operator>(const self&) const { return true; } |
| bool operator>=(const self&) const { return true; } |
| }; |
| template <class T> |
| mutable_random_access_iterator_archetype<T> |
| operator+ |
| (typename mutable_random_access_iterator_archetype<T>::difference_type, |
| const mutable_random_access_iterator_archetype<T>& x) |
| { return x; } |
| |
| } // namespace boost |
| |
| #endif // BOOST_CONCEPT_ARCHETYPES_H |