/***************************************************************************
 *
 * 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 <rw_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
{
    typedef IntegralT IntegralType;

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