/***************************************************************************
 *
 * alg_test.h - common definitions for algorithms tests
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2005 Rogue Wave Software.
 * 
 **************************************************************************/

#ifndef RW_ALG_TEST_H_INCLUDED
#define RW_ALG_TEST_H_INCLUDED

#include <rw/_iterbase.h>   // for iterator

#include <testdefs.h>

// generate a unique sequential number starting from 0
_TEST_EXPORT int gen_seq ();

// generate numbers in the sequence 0, 0, 1, 1, 2, 2, 3, 3, etc... 
_TEST_EXPORT int gen_seq_2lists ();

// generate a sequence of subsequences (i.e., 0, 1, 2, 3, 4, 0, 1, 2, etc...)
_TEST_EXPORT int gen_subseq ();

// wrapper around a (possibly) extern "C" int rand()
// extern "C++" 
_TEST_EXPORT int gen_rnd ();


// computes an integral log2
_TEST_EXPORT unsigned ilog2 (_RWSTD_SIZE_T);

// computes an integral log10
_TEST_EXPORT unsigned ilog10 (_RWSTD_SIZE_T);


template <class InputIterator, class Predicate>
inline bool
is_sorted (InputIterator first, InputIterator last, Predicate pred)
{
    if (first == last)
        return true;

    for (InputIterator prev (first); ++first != last; prev = first) {
        if (pred (*first, *prev))
            return false;
    }

    return true;
}

// returns true iff a sequence of (not necessarily unique) values
// is sorted in an ascending order
template <class InputIterator>
inline bool is_sorted_lt (InputIterator first, InputIterator last)
{
    if (first == last)
        return true;

    for (InputIterator prev (first); ++first != last; prev = first) {
        if (*first < *prev)
            return false;
    }

    return true;
}


// returns true iff a sequence of (not necessarily unique) values
// is sorted in a descending order
template <class InputIterator>
inline bool is_sorted_gt (InputIterator first, InputIterator last)
{
    if (first == last)
        return true;

    for (InputIterator prev (first); ++first != last; prev = first) {
        if (*prev < *first)
            return false;
    }

    return true;
}

/**************************************************************************/

// type used to exercise that algorithms do not apply operators
// to function objects the latter are not required to define
struct conv_to_bool
{
    static conv_to_bool make (bool val) {
        return conv_to_bool (val);
    }

#if !defined (_MSC_VER) || _MSC_VER > 1300
    // unique pointer not compatible with any other
    typedef bool conv_to_bool::*UniquePtr;

    // strictly convertible to a Boolean value testable
    // in the controlling expression of the if statement
    // as required in 25, p7
    operator UniquePtr () const {
        return val_ ? &conv_to_bool::val_ : UniquePtr (0);
    }
#else
    typedef const void* UniquePtr;

    operator UniquePtr () const {
        return val_ ? &val_ : UniquePtr (0);
    }
#endif

private:
    // not (publicly) Default-Constructible
    conv_to_bool (bool val): val_ (val) { }

    void operator= (conv_to_bool);   // not Assignable
    void operator!() const;          // not defined

    bool val_;
};

// not defined
void operator&& (const conv_to_bool&, bool);
void operator&& (bool, const conv_to_bool&);
void operator|| (const conv_to_bool&, bool);
void operator|| (bool, const conv_to_bool&);

// element-type prototypes to exercise container requirements


// meets requirements listed at 25, p7
template <class T>
struct predicate {
    conv_to_bool operator() (const T &a) const {
        _RWSTD_UNUSED (a);
        return conv_to_bool::make (true);
    }
};


// meets requirements listed at 25, p8
template <class T>
struct binary_predicate {
    conv_to_bool operator() (const T &a, const T &b) const {
        _RWSTD_UNUSED (a);
        _RWSTD_UNUSED (b);
        return conv_to_bool::make (true);
    }
};


// meets requirements listed at 25.2.3, p2
template <class T>
struct func {
    typedef T              argument_type;
    typedef argument_type& reference;

    reference operator() (const argument_type&) const {
        return _RWSTD_REINTERPRET_CAST (reference,
                   _RWSTD_CONST_CAST (func*, this)->dummy);
    }

private:
    char dummy;
};


// meets requirements listed at 25.2.3, p2
template <class T>
struct binary_func {
    typedef T              argument_type;
    typedef argument_type& reference;

    reference operator() (const argument_type&, 
                          const argument_type&) const {
        return _RWSTD_REINTERPRET_CAST (reference,
                   _RWSTD_CONST_CAST (binary_func*, this)->dummy);
    }

private:
    char dummy;
};


// a base-class to extend the requirements classes from

enum { no_ctor = 0, def_ctor = 1, cpy_ctor = 2 };

template <int c = no_ctor>
struct base;


template<>
struct base<no_ctor>
{
private:
    // struct s added to prevent gcc warning: base<no_ctor> has a private
    // constructor and no friends
    struct s { };
    friend struct s;

    base ();
    base (const base&);
    void operator= (base&);
};


template<>
struct base<def_ctor>
{
    base () : unused (0) { }

private:

    void operator= (base&);
    base (const base&);

    // unused member prevents bogus HP aCC warnings (see Onyx #23561)
    int unused;
};


template<>
struct base<cpy_ctor>
{
    // explicitly specifying redundant template parameters to work
    // around a SunPro 5.2 bug (see Onyx #24260)
    base (const base<cpy_ctor> &rhs): unused (rhs.unused) { }

private:

    base ();
    void operator= (base&);

    // unused member prevents bogus HP aCC warnings (see Onyx #23561)
    int unused;
};


template<>
struct base<(def_ctor | cpy_ctor)>
{
    base (): unused (0) { }

    // explicitly specifying redundant template parameters to work
    // around a SunPro 5.2 bug (see Onyx #24260)
    base (const base<(def_ctor | cpy_ctor)> &rhs): unused (rhs.unused) { }

private:

    void operator= (base&);

    // unused member prevents bogus HP aCC warnings (see Onyx #23561)
    int unused;
};


template <class T>
struct eq_comp: T { };


template <class T>
inline bool operator== (const eq_comp<T>&, const eq_comp<T>&)
{
    return true;
}


template <class T>
struct lt_comp: T { };


template <class T>
inline bool operator< (const lt_comp<T>&, const lt_comp<T>&)
{
    return true;
}


// assignment

template <class T>
struct assign : T
{
    assign& operator= (const assign& rhs) {
        unused = rhs.unused;
        return *this;
    }
private:
    // unused member prevents bogus HP aCC warnings (see Onyx #23561)
    int unused;
};


// conversion structs

// struct split into 2 to eliminate the following g++ 2.95.2 warning:
// warning: choosing `convert<T>::operator U&()' over 
//                   `convert<T>::operator const U&() const'

template <class T, class U>
struct cvt : T 
{
    operator U& () {
        return _RWSTD_REINTERPRET_CAST (U&, *this);
    }
};


template <class T, class U>
struct const_cvt : T
{
    operator const U& () const {
        return _RWSTD_REINTERPRET_CAST (const U&, *this);
    }
};

/**************************************************************************/

// Size template argument to fill_n(), generate_n(), and search_n()
template <class IntegralT>
struct Size
{
    // dummy argument provided to prevent Size from being constructible
    // by conversion from IntegralT
    Size (IntegralT val, int /* dummy */ )
        : val_ (val) { /* empty */ }

    // Size must be convertible to an integral type
    operator IntegralT () const { return val_; }

private:

    void operator= (const Size&);   // not Assignable

    IntegralT val_;
};

/**************************************************************************/

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC

struct DummyBase { };

#  define ITER_BASE(ign1, ign2, ign3, ign4, ign5) DummyBase
#else   // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
   // when partial specialization isn't supported 
#  define ITER_BASE(Cat, T, Dist, Ptr, Ref) \
          std::iterator<Cat, T, Dist, Ptr, Ref >
#endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC


// satisfies the requirements in 24.1.1 [lib.input.iterators]
template <class T>
struct InputIter: ITER_BASE (std::input_iterator_tag, T, int, T*, T&)
{
    typedef T                       value_type;
    typedef value_type*             pointer;
    typedef value_type&             reference;
    typedef _RWSTD_PTRDIFF_T        difference_type;
    typedef std::input_iterator_tag iterator_category;

    // body shared by all copies of the same InputIter specialization
    // to detect algorithms that pass through the same interator more
    // than once (disallowed by 24.1.1, p3)
    struct Shared {
        const value_type *cur_;
        const value_type *beg_;
        const value_type *end_;
        int               ref_;

        Shared (const value_type *cur,
                const value_type *beg,
                const value_type *end)
            : cur_ (cur), beg_ (beg), end_ (end), ref_ (1) {
            RW_ASSERT (beg_ <= cur_ && cur_ <= end_);
        }

        ~Shared () {
            cur_ = beg_ = end_ = 0;
            ref_ = -1;
        }

    private:
        Shared (const Shared&);           // not defined
        void operator= (const Shared&);   // not defined

    };

    // InputIterators are not default constructible
    InputIter (const value_type* /* current */,
               const value_type* /* begin */,
               const value_type* /* end */);

    InputIter (const InputIter&);

    ~InputIter ();

    InputIter& operator= (const InputIter&);

    bool operator== (const InputIter&) const;

    bool operator!= (const InputIter &rhs) const {
        return !(*this == rhs);
    }

    // returning const-reference rather than a value in order
    // not to impose the CopyConstructible requirement on T
    // and to disallow constructs like *InputIter<T>() = T()
    const value_type& operator* () const {
        RW_ASSERT (*this == *this);      // assert *this is valid
        RW_ASSERT (cur_ < ptr_->end_);   // assert *this is dereferenceable
        return *cur_;
    }

    _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);

    InputIter& operator++ () {
        RW_ASSERT (*this == *this);      // assert *this is valid
        RW_ASSERT (cur_ < ptr_->end_);   // assert *this is not past the end

        ptr_->cur_ = ++cur_;

        return *this;
    }

    InputIter operator++ (int) {
        return ++*this;
    }

// private:
    Shared           *ptr_;
    const value_type *cur_;   // past-the-end
};


// "large" member functions outlined to prevent gcc -Winline warnings

template <class T>
InputIter<T>::
InputIter (const value_type *cur,
           const value_type *beg,
           const value_type *end)
    : ptr_ (new Shared (cur, beg, end)), cur_ (cur)
{
    // empty
}


template <class T>
InputIter<T>::
InputIter (const InputIter &rhs)
    : ptr_ (rhs.ptr_), cur_ (rhs.cur_)
{
    RW_ASSERT (0 != ptr_);
    ++ptr_->ref_;
}


template <class T>
InputIter<T>::
~InputIter ()
{
    RW_ASSERT (0 != ptr_);

    if (0 == --ptr_->ref_)   // decrement the reference count
        delete ptr_;

    ptr_ = 0;
    cur_ = 0;
}


template <class T>
InputIter<T>&
InputIter<T>::
operator= (const InputIter &rhs)
{
    RW_ASSERT (rhs == rhs);   // assert `rhs' is valid

    RW_ASSERT (0 != ptr_);
    if (0 == --ptr_->ref_)
        delete ptr_;

    ptr_ = rhs.ptr_;

    RW_ASSERT (0 != ptr_);
    ++ptr_->ref_;

    cur_ = rhs.cur_;

    return *this;
}


template <class T>
bool
InputIter<T>::
operator== (const InputIter &rhs) const
{
    // assert that both arguments are in the domain of operator==()
    // i.e., that no copy of *this or `rhs' has been incremented
    // and that no copy passed through this value of the iterator

    RW_ASSERT (0 != ptr_);
    RW_ASSERT (cur_ == ptr_->cur_);

    RW_ASSERT (0 != rhs.ptr_);
    RW_ASSERT (rhs.cur_ == rhs.ptr_->cur_);

    return cur_ == rhs.cur_;
}

/**************************************************************************/

// satisfies the requirements in 24.1.2 [lib.output.iterators]
template <class T>
struct OutputIter: ITER_BASE (std::output_iterator_tag, T, int, T*, T&)
{
    typedef T                        value_type;
    typedef value_type*              pointer;
    typedef value_type&              reference;
    typedef _RWSTD_PTRDIFF_T         difference_type;
    typedef std::output_iterator_tag iterator_category;

    // body shared by all copies of the same OutputIter specialization
    // to detect algorithms that pass through the same interator more
    // than once (disallowed by 24.1.2, p2)
    struct Shared {
        pointer           cur_;
        pointer           assign_;
        const value_type *begin_;
        const value_type *end_;
        int               ref_;

        Shared (pointer cur, const value_type *end)
            : cur_ (cur), assign_ (cur), begin_ (cur), end_ (end), ref_ (1) { }

        ~Shared () {
            begin_ = end_ = cur_ = assign_ = 0;
            ref_ = -1;
        }

    private:
        Shared (const Shared&);           // not defined
        void operator= (const Shared&);   // not defined

    };

    // class whose objects are returned from OutputIter::operator*
    // to detect multiple assignments (disallowed by 24.1.2, p2)
    class Proxy {
        friend struct OutputIter;

        Shared* const ptr_;

        Proxy (Shared *ptr): ptr_ (ptr) { }

    public:
        void operator= (const value_type &rhs) {
            RW_ASSERT (0 != ptr_);

            // verify that the iterator is in the valid range
            RW_ASSERT (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ <= ptr_->end_);

            // verify that the assignment point is the same as the current
            // position `cur' within the sequence or immediately before it
            // (in order to allow the expression: *it++ = val)
            RW_ASSERT (   ptr_->assign_ == ptr_->cur_
                       || ptr_->assign_ + 1 == ptr_->cur_);

            // assign and increment the assignment point
            *ptr_->assign_++ = rhs;
        }
    };

    // OutputIterators are not default constructible
    OutputIter (pointer           cur,
                const value_type *,
                const value_type *end)
        : ptr_ (new Shared (cur, end)), cur_ (cur) { }

    OutputIter (const OutputIter &rhs)
        : ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
        ++ptr_->ref_;   // increment the reference count
    }

    ~OutputIter ();

    OutputIter& operator= (const OutputIter&);

    void operator= (const value_type &rhs) const {
        **this = rhs;
    }

    // return a proxy in order to detect multiple assignments
    // through the iterator (disallowed by 24.1.2, p2))
    Proxy operator* () const {
        RW_ASSERT (0 != ptr_);
        RW_ASSERT (ptr_->assign_ && ptr_->assign_ != ptr_->end_);

        return Proxy (ptr_);
    }

    _RWSTD_OPERATOR_ARROW (pointer operator-> () const);

    OutputIter& operator++ () {
        RW_ASSERT (cur_ == ptr_->cur_);
        RW_ASSERT (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ < ptr_->end_);
        cur_ = ++ptr_->cur_;
        return *this;
    }

    // returning a const value rather than a modifiable value
    // in order to verify the requirement in row 5 of Table 73
    const OutputIter operator++ (int) {
        OutputIter tmp (*this);
        return ++*this, tmp;
    }

// private:
    Shared  *ptr_;
    pointer  cur_;
};


// "large" member functions outlined to prevent gcc -Winline warnings

template <class T>
OutputIter<T>::
~OutputIter ()
{
    RW_ASSERT (0 != ptr_);

    if (0 == --ptr_->ref_)   // decrement the reference count
        delete ptr_;

    ptr_ = 0;
    cur_ = 0;
}


template <class T>
OutputIter<T>&
OutputIter<T>::
operator= (const OutputIter &rhs)
{
    RW_ASSERT (0 != ptr_);

    if (0 == --ptr_->ref_)
        delete ptr_;

    ptr_ = rhs.ptr_;
    ++ptr_->ref_;

    cur_ = rhs.cur_;

    return *this;
}

/**************************************************************************/

// satisfies the requirements in 24.1.3 [lib.forward.iterators]
template <class T>
struct FwdIter: ITER_BASE (std::forward_iterator_tag, T, int, T*, T&)
{
    typedef T                         value_type;
    typedef value_type*               pointer;
    typedef value_type&               reference;
    typedef _RWSTD_PTRDIFF_T          difference_type;
    typedef std::forward_iterator_tag iterator_category;

    FwdIter (): cur_ (0), end_ (0) { }

    FwdIter (pointer           cur,
             const value_type *,
             const value_type *end)
        : cur_ (cur), end_ (end) { }

    FwdIter (const FwdIter &rhs)
        : cur_ (rhs.cur_), end_ (rhs.end_) { }

    ~FwdIter () {
        end_ = cur_ = 0;
    }

    FwdIter& operator= (const FwdIter &rhs) {
        cur_ = rhs.cur_;
        end_ = rhs.end_;
        return *this;
    }

    bool operator== (const FwdIter &rhs) const {
        RW_ASSERT (cur_ != 0);
        return cur_ == rhs.cur_;
    }

    bool operator!= (const FwdIter &rhs) const {
        return !(*this == rhs);
    }

    reference operator* () const {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return *cur_;
    }

    _RWSTD_OPERATOR_ARROW (pointer operator-> () const);

    FwdIter& operator++ () {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return ++cur_, *this;
    }

    FwdIter operator++ (int) {
        FwdIter tmp (*this);
        return ++*this, tmp;
    }

// private:
    pointer           cur_;   // pointer to current element
    const value_type *end_;   // past-the-end
};


template <class T>
struct ConstFwdIter: FwdIter<const T>
{
    typedef T                         value_type;
    typedef FwdIter<const value_type> Base;

    ConstFwdIter (): Base () { }

    ConstFwdIter (const value_type *cur,
                  const value_type *begin,
                  const value_type *end)
        : Base (cur, begin, end) { }

    const value_type& operator* () const {
        return Base::operator* ();
    }

    _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
};

/**************************************************************************/

// satisfies the requirements in 24.1.4 [lib.bidirectional.iterators]
template <class T>
struct BidirIter: ITER_BASE (std::bidirectional_iterator_tag, T, int, T*, T&)
{
    typedef T                               value_type;
    typedef value_type*                     pointer;
    typedef value_type&                     reference;
    typedef _RWSTD_PTRDIFF_T                difference_type;
    typedef std::bidirectional_iterator_tag iterator_category;

    BidirIter (): cur_ (0), begin_ (0), end_ (0) { }

    BidirIter (pointer           cur,
               const value_type *begin,
               const value_type *end)
        : cur_ (cur), begin_ (begin), end_ (end) { }

    BidirIter (const BidirIter &rhs)
        : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }

    ~BidirIter () {
        begin_ = end_ = cur_ = 0;
    }

    BidirIter& operator= (const BidirIter &rhs) { 
        cur_ = rhs.cur_;
        end_ = rhs.end_;
        return *this; 
    }

    bool operator== (const BidirIter &rhs) const {
        RW_ASSERT (cur_ != 0 && rhs.cur_ != 0);
        return cur_ == rhs.cur_;
    }

    bool operator!= (const BidirIter &rhs) const {
        return !(*this == rhs);
    }

    reference operator* () const {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return *cur_;
    }

    _RWSTD_OPERATOR_ARROW (pointer operator-> () const);

    BidirIter& operator++ () {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return ++cur_, *this;
    }

    BidirIter operator++ (int) {
        BidirIter tmp (*this);
        return ++*this, tmp;
    }

    BidirIter& operator-- () {
        RW_ASSERT (cur_ != 0 && cur_ != begin_);
        return --cur_, *this;
    }

    BidirIter operator-- (int) {
        BidirIter tmp (*this);
        return --*this, tmp;
    }

// private:
    pointer           cur_;     // pointer to current element
    const value_type *begin_;   // first in range
    const value_type *end_;     // past-the-end
};


template <class T>
struct ConstBidirIter: BidirIter<const T>
{
    typedef T                           value_type;
    typedef BidirIter<const value_type> Base;

    ConstBidirIter (): Base () { }

    ConstBidirIter (const value_type *cur,
                    const value_type *begin,
                    const value_type *end)
        : Base (cur, begin, end) { }

    const value_type& operator* () const {
        return Base::operator* ();
    }

    _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
};

/**************************************************************************/

// satisfies the requirements in 24.1.5 [lib.random.access.iterators]
template <class T>
struct RandomAccessIter
    : ITER_BASE (std::random_access_iterator_tag, T, int, T*, T&)
{
    typedef T                               value_type;
    typedef value_type*                     pointer;
    typedef value_type&                     reference;
    typedef _RWSTD_PTRDIFF_T                difference_type;
    typedef std::random_access_iterator_tag iterator_category;

    RandomAccessIter (): cur_ (0), begin_ (0), end_ (0) { }

    RandomAccessIter (pointer           cur,
                      const value_type *begin,
                      const value_type *end)
        : cur_ (cur), begin_ (begin), end_ (end) { }

    RandomAccessIter (const RandomAccessIter &rhs)
        : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }

    ~RandomAccessIter () {
        begin_ = end_ = cur_ = 0;
    }

    RandomAccessIter& operator= (const RandomAccessIter &rhs) {
        cur_   = rhs.cur_;
        begin_ = rhs.begin_;
        end_   = rhs.end_;
        return *this; 
    }

    reference operator* () const {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return *cur_;
    }

    _RWSTD_OPERATOR_ARROW (pointer operator-> () const);

    RandomAccessIter& operator++ () {
        RW_ASSERT (cur_ != 0 && cur_ != end_);
        return ++cur_, *this;
    }

    RandomAccessIter operator++ (int) {
        RandomAccessIter tmp (*this);
        return ++*this, tmp;
    }

    RandomAccessIter& operator-- () {
        RW_ASSERT (cur_ != 0 && cur_ != begin_);
        return --cur_, *this;
    }

    RandomAccessIter operator-- (int) {
        RandomAccessIter tmp (*this);
        return --*this, tmp;
    }

    RandomAccessIter& operator+= (difference_type n) {
        RW_ASSERT (   cur_ != 0
                   && (!end_ || cur_ + n <= end_)
                   && (!begin_ || cur_ + n >= begin_));
        return cur_ += n, *this;
    }
    RandomAccessIter& operator-= (difference_type n) {
        return *this += -n;
    }

    RandomAccessIter operator+ (difference_type n) const {
        return RandomAccessIter (*this) += n;
    }

    RandomAccessIter operator- (difference_type n) const {
        return RandomAccessIter (*this) -= n;
    }

    difference_type operator- (const RandomAccessIter &rhs) const { 
        RW_ASSERT (cur_ != 0 && rhs.cur_ != 0);
        return cur_ - rhs.cur_;
    }

    bool operator== (const RandomAccessIter &rhs) const {
        RW_ASSERT (cur_ != 0 && rhs.cur_ != 0);
        return cur_ == rhs.cur_;
    }

    bool operator!= (const RandomAccessIter &rhs) const {
        return !(*this == rhs);
    }

    bool operator< (const RandomAccessIter &rhs) const {
        RW_ASSERT (cur_ != 0 && rhs.cur_ != 0);
        return cur_ < rhs.cur_;
    };

    bool operator> (const RandomAccessIter &rhs) const {
        return rhs < *this;
    }

    bool operator<= (const RandomAccessIter &rhs) const {
        return !(rhs < *this);
    }

    bool operator>= (const RandomAccessIter &rhs) const {
        return !(*this < rhs);
    }

    reference operator[] (difference_type inx) const { 
        RW_ASSERT (   cur_ != 0
                   && (!end_ || cur_ + inx < end_)
                   && !(begin_ || cur_ + inx >= begin_));
        return cur_ [inx];
    }

// private:
    pointer           cur_;     // pointer to current element
    const value_type *begin_;   // first in range
    const value_type *end_;     // past-the-end
};

/**************************************************************************/

template <class T>
struct ConstRandomAccessIter: RandomAccessIter<const T>
{
    typedef T                                  value_type;
    typedef RandomAccessIter<const value_type> Base;
    typedef typename Base::difference_type     difference_type;

    ConstRandomAccessIter (): Base () { }

    ConstRandomAccessIter (const value_type *cur,
                           const value_type *begin,
                           const value_type *end)
        : Base (cur, begin, end) { }

    const value_type& operator* () const {
        return Base::operator* ();
    }

    _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);

    const value_type& operator[] (difference_type inx) const {
        return Base::operator[] (inx);
    }
};

/**************************************************************************/

template <class T>
inline T*
make_iter (T *cur, const T*, const T*, T*)
{
    return cur;
}

template <class T>
inline T*
copy_iter (T *ptr, const T*)
{
    return ptr;
}

// dummy function argument provided to help broken compilers (PR #29835)

template <class T>
inline InputIter<T>
make_iter (const T *cur, const T *begin, const T *end, const InputIter<T>&)
{
    return InputIter<T>(cur, begin, end);
}

template <class T>
inline InputIter<T>
copy_iter (const InputIter<T> &it, const T*)
{
    return InputIter<T>(it.cur_, it.ptr_->beg_, it.ptr_->end_);
}

template <class T>
inline const char* type_name (InputIter<T>, const T*)
{ return "InputIterator"; }


template <class T>
inline OutputIter<T>
make_iter (T *cur, const T *begin, const T *end, const OutputIter<T>&)
{
    return OutputIter<T>(cur, begin, end);
}

template <class T>
inline OutputIter<T>
copy_iter (const OutputIter<T> &it, const T*)
{
    return OutputIter<T>(it.cur_, 0, it.ptr_->end);
}

template <class T>
inline const char* type_name (OutputIter<T>, const T*)
{ return "OutputIterator"; }


template <class T>
inline FwdIter<T>
make_iter (T *cur, const T *begin, const T *end, const FwdIter<T>&)
{
    return FwdIter<T>(cur, begin, end);
}

template <class T>
inline FwdIter<T>
copy_iter (const FwdIter<T> &it, const T*)
{
    return FwdIter<T>(it.cur_, 0, it.end_);
}

template <class T>
inline const char* type_name (FwdIter<T>, const T*)
{ return "ForwardIterator"; }


template <class T>
inline ConstFwdIter<T>
make_iter (const T *cur, const T *begin, const T *end, const ConstFwdIter<T>&)
{
    return ConstFwdIter<T>(cur, begin, end);
}

template <class T>
inline ConstFwdIter<T>
copy_iter (const ConstFwdIter<T> &it, const T*)
{
    return ConstFwdIter<T>(it.cur_, 0, it.end_);
}

template <class T>
inline const char* type_name (ConstFwdIter<T>, const T*)
{ return "ConstForwardIterator"; }


template <class T>
inline BidirIter<T>
make_iter (T *cur, const T *begin, const T *end, const BidirIter<T>&)
{
    return BidirIter<T>(cur, begin, end);
}

template <class T>
inline BidirIter<T>
copy_iter (const BidirIter<T> &it, const T*)
{
    return BidirIter<T>(it.cur_, it.begin_, it.end_);
}

template <class T>
inline const char* type_name (BidirIter<T>, const T*)
{ return "BidirectionalIterator"; }


template <class T>
inline ConstBidirIter<T>
make_iter (const T *cur, const T *begin, const T *end, const ConstBidirIter<T>&)
{
    return ConstBidirIter<T>(cur, begin, end);
}

template <class T>
inline ConstBidirIter<T>
copy_iter (const ConstBidirIter<T> &it, const T*)
{
    return ConstBidirIter<T>(it.cur_, it.begin_, it.end_);
}

template <class T>
inline const char* type_name (ConstBidirIter<T>, const T*)
{ return "ConstBidirectionalIterator"; }


template <class T>
inline RandomAccessIter<T>
make_iter (T *cur, const T *begin, const T *end, const RandomAccessIter<T>&)
{
    return RandomAccessIter<T>(cur, begin, end);
}

template <class T>
inline RandomAccessIter<T>
copy_iter (const RandomAccessIter<T> &it, const T*)
{
    return RandomAccessIter<T>(it.cur_, it.begin_, it.end_);
}

template <class T>
inline const char* type_name (RandomAccessIter<T>, const T*)
{ return "RandomAccessIterator"; }


template <class T>
inline ConstRandomAccessIter<T>
make_iter (const T *cur, const T *begin, const T *end,
           const ConstRandomAccessIter<T>&)
{
    return ConstRandomAccessIter<T>(cur, begin, end);
}

template <class T>
inline ConstRandomAccessIter<T>
copy_iter (const ConstRandomAccessIter<T> &it, const T*)
{
    return ConstRandomAccessIter<T>(it.cur_, it.begin_, it.end_);
}

template <class T>
inline const char* type_name (ConstRandomAccessIter<T>, const T*)
{ return "ConstRandomAccessIterator"; }


// temporary to not break the tests which uses struct X
#include <rw_value.h>

#endif   // RW_ALG_TEST_H_INCLUDED
