//
// (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
