Boost logo

Boost :

From: Dave Abrahams (abrahams_at_[hidden])
Date: 2000-04-21 09:33:34


Here is the header I intended to post.
-Dave

// Boost operators.hpp header file ---------------------------------
--------//

// (C) Copyright David Abrahams 1999. Permission to copy, use,
modify, sell and
// distribute this software is granted provided this copyright
notice appears
// in all copies. This software is provided "as is" without express
or implied
// warranty, and with no claim as to its suitability for any purpose.

// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

// See http://www.boost.org for most recent version including
documentation.

// Revision History
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
// 18 Nov 99 Change name "divideable" to "dividable", remove
unnecessary
// specializations of dividable, subtractable, modable (Ed
Brey)
// 17 Nov 99 Add comments (Beman Dawes)
// Remove unnecessary specialization of operators<> (Ed
Brey)
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for
first two
// operators.(Beman Dawes)
// 12 Nov 99 Add operators templates (Ed Brey)
// 11 Nov 99 Add single template parameter version for compilers
without
// partial specialization (Beman Dawes)
// 10 Nov 99 Initial version

#ifndef BOOST_OPERATORS_HPP
#define BOOST_OPERATORS_HPP

#include <boost/config.hpp>
#include <iterator>

#if defined(__sgi) && !defined(__GNUC__)
#pragma set woff 1234
#endif

#if defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
# define BOOST_REPLICATED_TYPE_PARAMETER(T)
#else
# define BOOST_REPLICATED_TYPE_PARAMETER(T) <T, T>
#endif

#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost
{
#endif

// Basic operator classes (contributed by Dave Abrahams ) -----------
--------//

// Preferred version -----------------------------------------------
--------//

// Note that friend functions defined in a class are implicitly
inline.
// See the C++ std, 11.4 [class.friend] paragraph 5

// The two-type version requires that T implement
// bool operator<( const U& ) const, bool operator>( const U& ) const
template <class T, class U>
class less_than_comparable2
{
     friend bool operator<=( const T& x, const U& y ) { return !(x >
y); }
     friend bool operator>=( const T& x, const U& y ) { return !(x <
y); }
     friend bool operator>( const U& x, const T& y ) { return y <
x; }
     friend bool operator<( const U& x, const T& y ) { return y >
x; }
     friend bool operator<=( const U& x, const T& y ) { return !(y <
x); }
     friend bool operator>=( const U& x, const T& y ) { return !(y >
x); }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T> // = T really is needed; not a
coding error
class less_than_comparable : less_than_comparable2<T, U>
{};
#endif

// This partial specialization requires only that T implement
// bool operator<( const T& ) const
template <class T>
class less_than_comparable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend bool operator>( const T& x, const T& y ) { return y <
x; }
     friend bool operator<=( const T& x, const T& y ) { return !(y <
x); }
     friend bool operator>=( const T& x, const T& y ) { return !(x <
y); }
};

template <class T, class U>
class equality_comparable2
{
     friend bool operator==( const U& y, const T& x ) { return x ==
y; }
     friend bool operator!=( const U& y, const T& x ) { return !(x ==
y); }
     friend bool operator!=( const T& y, const U& x ) { return !(y ==
x); }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class equality_comparable : equality_comparable2<T, U>
{};
#endif

template <class T>
class equality_comparable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend bool operator!=( const T& x, const T& y ) { return !(x ==
y); }
};

template <class T, class U = T>
class multipliable2
{
     friend T operator*( T x, const U& y ) { return x *= y; }
     friend T operator*( const U& y, T x ) { return x *= y; }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class multipliable : multipliable2<T, U>
{};
#endif

template <class T>
class multipliable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend T operator*( T x, const T& y ) { return x *= y; }
};

template <class T, class U>
class addable2
{
     friend T operator+( T x, const U& y ) { return x += y; }
     friend T operator+( const U& y, T x ) { return x += y; }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class addable : addable2<T, U>
{};
#endif

template <class T>
class addable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend T operator+( T x, const T& y ) { return x += y; }
};

template <class T, class U>
class subtractable2
{
     friend T operator-( T x, const U& y ) { return x -= y; }
};

template <class T, class U = T>
class subtractable : subtractable2<T, U>
{};

template <class T, class U>
class dividable2
{
     friend T operator/( T x, const U& y ) { return x /= y; }
};

template <class T, class U = T>
class dividable : dividable2<T, U>
{};

template <class T, class U>
class modable2
{
     friend T operator%( T x, const U& y ) { return x %= y; }
};

template <class T, class U = T>
class modable : modable2<T, U>
{};

template <class T, class U>
class xorable2
{
     friend T operator^( T x, const U& y ) { return x ^= y; }
     friend T operator^( const U& y, T x ) { return x ^= y; }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class xorable : xorable2<T, U>
{};
#endif

template <class T>
class xorable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend T operator^( T x, const T& y ) { return x ^= y; }
};

template <class T, class U>
class andable2
{
     friend T operator&( T x, const U& y ) { return x &= y; }
     friend T operator&( const U& y, T x ) { return x &= y; }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class andable : andable2<T, U>
{};
#endif

template <class T>
class andable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend T operator&( T x, const T& y ) { return x &= y; }
};

template <class T, class U>
class orable2
{
     friend T operator|( T x, const U& y ) { return x |= y; }
     friend T operator|( const U& y, T x ) { return x |= y; }
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class orable : orable2<T, U>
{};
#endif

template <class T>
class orable BOOST_REPLICATED_TYPE_PARAMETER(T)
{
     friend T operator|( T x, const T& y ) { return x |= y; }
};

// incrementable and decrementable contributed by Jeremy Siek)
template <class T>
struct incrementable
{
  friend T operator++(T& x, int)
  {
    T tmp(x);
    ++x;
    return tmp;
  }
};
  

template <class T>
struct decrementable
{
  friend T operator--(T& x, int)
  {
    T tmp(x);
    --x;
    return tmp;
  }
};

#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} // namespace boost
#else
namespace boost {
  using ::orable;
  using ::andable;
  using ::less_than_comparable;
  using ::equality_comparable;
  using ::multipliable;
  using ::addable;
  using ::subtractable;
  using ::dividable;
  using ::modable;
  using ::xorable;
  using ::incrementable;
  using ::decrementable;
}
#endif

namespace boost {
    // The following 'operators' classes are of questionable utility,
but
    // remain here for backward compatibility.
    // (these can be safely declared directly in boost, even on GCC
2.95.2
template <class T, class U>
class operators2 :
    less_than_comparable2<T,U>,
    equality_comparable2<T,U>,
    addable2<T,U>,
    subtractable2<T,U>,
    multipliable2<T,U>,
    dividable2<T,U>,
    modable2<T,U>,
    orable2<T,U>,
    andable2<T,U>,
    xorable2<T,U> {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
class operators : operators2<T, U>
    {};
#endif

template <class T>
class operators BOOST_REPLICATED_TYPE_PARAMETER(T) :
    less_than_comparable<T>,
    equality_comparable<T>,
    addable<T>,
    subtractable<T>,
    multipliable<T>,
    dividable<T>,
    modable<T>,
    orable<T>,
    andable<T>,
    xorable<T>,
    incrementable<T>,
    decrementable<T> {};

}

// Iterator operator classes (contributed by Jeremy Siek ) ----------
--------//

#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost
{
#endif

template <class T, class V>
struct dereferenceable
{
  V* operator->() const
  {
    return &*static_cast<const T&>(*this);
  }
};

template <class T, class D, class R>
struct indexable
{
  R operator[](D n) const
  {
    return *(static_cast<const T&>(*this) + n);
  }
};

// Iterator helper classes (contributed by Jeremy Siek ) ------------
--------//

#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ > 95 || defined
(__SGI_STL)
template <class T,
          class V,
          class D = std::iterator_traits<char*>::difference_type,
          class P = V*,
          class R = V&>
struct forward_iterator_helper :
  equality_comparable<T>,
  incrementable<T>,
  dereferenceable<T,V>,
  std::iterator<std::forward_iterator_tag, V, D> { };

template <class T,
          class V,
          class D = std::iterator_traits<char*>::difference_type,
          class P = V*,
          class R = V&>
struct bidirectional_iterator_helper :
  equality_comparable<T>,
  incrementable<T>,
  decrementable<T>,
  dereferenceable<T,V>,
  std::iterator<std::bidirectional_iterator_tag, V, D> { };

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T,
          class V,
          class D = std::iterator_traits<char*>::difference_type,
          class P = V*,
          class R = V&>
struct random_access_iterator_helper :
  equality_comparable<T>,
  less_than_comparable<T>,
  incrementable<T>,
  decrementable<T>,
  dereferenceable<T,V>,
  addable<T,D>,
  subtractable<T,D>,
  indexable<T,D,R>,
  std::iterator<std::random_access_iterator_tag, V, D>
{
  friend D requires_difference_operator(const T& x, const T& y) {
    return x - y;
  }
}; // random_access_iterator_helper
#else
template <class T,
          class V,
          class D = ptrdiff_t,
          class P = V*,
          class R = V&>
struct random_access_iterator_helper :
  equality_comparable<T>,
  less_than_comparable<T>,
  incrementable<T>,
  decrementable<T>,
  dereferenceable<T,V>,
  addable2<T,D>,
  subtractable2<T,D>,
  indexable<T,D,R>,
  std::iterator<std::random_access_iterator_tag, V, D>
{
  friend D requires_difference_operator(const T& x, const T& y) {
    return x - y;
  }
}; // random_access_iterator_helper
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // Disabled when working with broken default GCC library

#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} // namespace boost
#else

namespace boost {
  using ::incrementable;
  using ::decrementable;
  using ::dereferenceable;
  using ::indexable;
#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ > 95 || defined
(__SGI_STL)
  using ::forward_iterator_helper;
  using ::bidirectional_iterator_helper;
  using ::random_access_iterator_helper;
#endif // Disabled when working with broken default GCC library
}
#endif

#undef BOOST_REPLICATED_TYPE_PARAMETER

#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif

#endif // BOOST_OPERATORS_HPP


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk