Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 60320 invoked from network); 17 Nov 2005 19:25:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 17 Nov 2005 19:25:09 -0000 Received: (qmail 41114 invoked by uid 500); 17 Nov 2005 19:25:08 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 41094 invoked by uid 500); 17 Nov 2005 19:25:08 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 41083 invoked by uid 500); 17 Nov 2005 19:25:08 -0000 Delivered-To: apmail-incubator-stdcxx-cvs@incubator.apache.org Received: (qmail 41080 invoked by uid 99); 17 Nov 2005 19:25:08 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 17 Nov 2005 11:25:07 -0800 Received: (qmail 60220 invoked by uid 65534); 17 Nov 2005 19:24:47 -0000 Message-ID: <20051117192447.60214.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r345310 - /incubator/stdcxx/trunk/tests/include/alg_test.h Date: Thu, 17 Nov 2005 19:24:46 -0000 To: stdcxx-cvs@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: sebor Date: Thu Nov 17 11:24:42 2005 New Revision: 345310 URL: http://svn.apache.org/viewcvs?rev=345310&view=rev Log: 2005-11-17 Martin Sebor STDCXX-3 * alg_test.h: New header with definitions of helpers used by algorithm tests. Added: incubator/stdcxx/trunk/tests/include/alg_test.h (with props) Added: incubator/stdcxx/trunk/tests/include/alg_test.h URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/include/alg_test.h?rev=345310&view=auto ============================================================================== --- incubator/stdcxx/trunk/tests/include/alg_test.h (added) +++ incubator/stdcxx/trunk/tests/include/alg_test.h Thu Nov 17 11:24:42 2005 @@ -0,0 +1,1230 @@ +/*************************************************************************** + * + * alg_test.h - common definitions for algorithms tests + * + * $Id$ + * + *************************************************************************** + * + * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave + * Software division. Licensed 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. + * + **************************************************************************/ + +#ifndef _RWSTD_ALG_TEST_H_INCLUDED +#define _RWSTD_ALG_TEST_H_INCLUDED + +#include + +#include // for assert() + +#include +#include + + +// objects of class X maintain a count of their instances in existence, +// the number of defaut and copy ctor calls, assignment operators, and +// the number of calls to operator==() and operator<() +struct _TEST_EXPORT X +{ + const int id_; // a unique non-zero id of the object + int origin_; // id of the original object that this + // is a (perhaps indirect) copy of (id_ + // when this is the original) + int src_id_; // id of the object that this is a direct + // copy of (id_ when this the original) + int val_; // object's value + + // number of times the object has been copied into another object, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_copy_ctor_; + + // number of times the object's assignment operator has been invoked, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_op_assign_; + + // number of times the object's operator== was invoked + // regardless of whether the operation threw an exception + _RWSTD_SIZE_T n_op_eq_; + + // number of times the object's operator< was invoked + // regardless of whether the operation threw an exception + _RWSTD_SIZE_T n_op_lt_; + + static _RWSTD_SIZE_T count_; // number of objects in existence (>= 0) + static int id_gen_; // generates a unique non-zero id + static int (*gen_)(); // extern "C++" int (*)() + + static _RWSTD_SIZE_T n_total_def_ctor_; // number of default ctor calls + static _RWSTD_SIZE_T n_total_copy_ctor_; // ... copy ctors ... + static _RWSTD_SIZE_T n_total_dtor_; // ... dtors ... + static _RWSTD_SIZE_T n_total_op_assign_; // ... assignment operators ... + static _RWSTD_SIZE_T n_total_op_eq_; // ... equality operators ... + static _RWSTD_SIZE_T n_total_op_lt_; // ... operators <= ... + + // classes thrown from the respective functions + struct Exception { int id_; }; + struct DefCtor: Exception { }; + struct CopyCtor: Exception { }; + struct Dtor: Exception { }; + struct OpAssign: Exception { }; + struct OpEq: Exception { }; + struct OpLt: Exception { }; + + // throw object's `id' wrapped in the appropriate struct when the + // corresponding n_total_xxx_ counter reaches the value pointed to + // by the respective pointer below + static _RWSTD_SIZE_T* def_ctor_throw_ptr_; + static _RWSTD_SIZE_T* copy_ctor_throw_ptr_; + static _RWSTD_SIZE_T* dtor_throw_ptr_; + static _RWSTD_SIZE_T* op_assign_throw_ptr_; + static _RWSTD_SIZE_T* op_eq_throw_ptr_; + static _RWSTD_SIZE_T* op_lt_throw_ptr_; + + // objects to which the pointers above initally point + static _RWSTD_SIZE_T def_ctor_throw_count_; + static _RWSTD_SIZE_T copy_ctor_throw_count_; + static _RWSTD_SIZE_T dtor_throw_count_; + static _RWSTD_SIZE_T op_assign_throw_count_; + static _RWSTD_SIZE_T op_eq_throw_count_; + static _RWSTD_SIZE_T op_lt_throw_count_; + + X (); + + X (const X&); + + ~X (); + + X& operator= (const X&); + + bool operator== (const X&) const; + bool operator< (const X&) const; + + // the following operators are not declared or defined in order + // to detect any unwarranted assumptions made in algorithms + // bool operator!= (const X &rhs) const; + // bool operator> (const X &rhs) const; + // bool operator>= (const X &rhs) const; + // bool operator<= (const X &rhs) const; + // X operator- () const; + // X operator+ () const; + + bool + is_count (_RWSTD_SIZE_T copy_ctor, + _RWSTD_SIZE_T op_assign, + _RWSTD_SIZE_T op_eq, + _RWSTD_SIZE_T op_lt) const; + + static bool + is_total (_RWSTD_SIZE_T count, + _RWSTD_SIZE_T n_def_ctor, + _RWSTD_SIZE_T n_copy_ctor, + _RWSTD_SIZE_T n_op_assign, + _RWSTD_SIZE_T n_op_eq, + _RWSTD_SIZE_T n_op_lt); + + static void reset_totals (); + + // construct an array of objects of type X each initialized + // from the corresponding element of the character array + static X* from_char (const char*, _RWSTD_SIZE_T = ~0UL); + + // returns -1 when less, 0 when same, or +1 when the array + // of X objects is greater than the character string + static int compare (const X*, const char*, _RWSTD_SIZE_T = ~0UL); + static int compare (const char*, const X*, _RWSTD_SIZE_T = ~0UL); + + // returns -1 when less, 0 when same, or +1 when the first + // array of X objects is greater than the second array + static int compare (const X*, const X*, _RWSTD_SIZE_T); +}; + + +struct _TEST_EXPORT UnaryPredicate +{ + // total number of times operator() was invoked + static _RWSTD_SIZE_T n_total_op_fcall_; + + UnaryPredicate (); + + UnaryPredicate (const UnaryPredicate&); + + UnaryPredicate& operator= (const UnaryPredicate&); + + virtual ~UnaryPredicate (); + + virtual bool operator()(const X&) const; +}; + + +struct _TEST_EXPORT BinaryPredicate +{ + // total number of times operator() was invoked + static _RWSTD_SIZE_T n_total_op_fcall_; + + bool ignore_case_; + + BinaryPredicate (bool = false); + + BinaryPredicate (const BinaryPredicate&); + + BinaryPredicate& operator= (const BinaryPredicate&); + + virtual ~BinaryPredicate (); + + virtual bool operator()(const X&, const X&) const; +}; + + +class _TEST_EXPORT tempstr; + +// converts a sequence of objects of type X to a tempstr object +// in the format "[%p0, %p1): { x0, >x1<, ..., xN - 1 } where N +// is defined as: N = (X*)p1 - (X*)p0 +// the last argument, if non-negative, indicates the index of the +// element enclosed in between the '>' and '<' characters +_TEST_EXPORT void to_string (tempstr*, const X*, const X*, int = -1); + + +// 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 +inline unsigned ilog2 (unsigned long n) +{ + unsigned result = 0; + while (n >>= 1) + ++result; + return result; +} + + +// computes an integral log10 +inline unsigned ilog10 (unsigned long n) +{ + unsigned result = 0; + while (n /= 10) + ++result; + return result; +} + + +// returns true iff a sequence of (not necessarily unique) values +// is sorted in an ascending order +template +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 +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) { + conv_to_bool tmp; + tmp.val_ = val; + return tmp; + } + + operator bool () const { + return val_; + } + +private: + 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 +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 +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 +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 +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 +struct base; + + +template<> +struct base +{ +private: + // struct s added to prevent gcc warning: base has a private + // constructor and no friends + struct s { }; + friend struct s; + + base (); + base (const base&); + void operator= (base&); +}; + + +template<> +struct base +{ + 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 +{ + // explicitly specifying redundant template parameters to work + // around a SunPro 5.2 bug (see Onyx #24260) + base (const base &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 +struct eq_comp: T { }; + + +template +inline bool operator== (const eq_comp&, const eq_comp&) +{ + return true; +} + + +template +struct lt_comp: T { }; + + +template +inline bool operator< (const lt_comp&, const lt_comp&) +{ + return true; +} + + +// assignment + +template +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::operator U&()' over +// `convert::operator const U&() const' + +template +struct cvt : T +{ + operator U& () { + return _RWSTD_REINTERPRET_CAST (U&, *this); + } +}; + + +template +struct const_cvt : T +{ + operator const U& () const { + return _RWSTD_REINTERPRET_CAST (const U&, *this); + } +}; + + +#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 +#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC + + +// satisfies the requirements in 24.1.1 [lib.input.iterators] +template +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 int 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) { } + + ~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 *cur, + const value_type *beg, + const value_type *end) + : ptr_ (new Shared (cur, beg, end)), cur_ (cur) { } + + InputIter (const InputIter &rhs) + : ptr_ (rhs.ptr_), cur_ (rhs.cur_) { + assert (0 != ptr_); + ++ptr_->ref_; + } + + ~InputIter () { + assert (0 != ptr_); + + if (0 == --ptr_->ref_) // decrement the reference count + delete ptr_; + ptr_ = 0; + cur_ = 0; + } + + InputIter& operator= (const InputIter &rhs) { + assert (rhs == rhs); // assert `rhs' is valid + + assert (0 != ptr_); + if (0 == --ptr_->ref_) + delete ptr_; + + ptr_ = rhs.ptr_; + + assert (0 != ptr_); + ++ptr_->ref_; + + cur_ = rhs.cur_; + + return *this; + } + + bool 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 + + assert (0 != ptr_); + assert (cur_ == ptr_->cur_); + + assert (0 != rhs.ptr_); + assert (rhs.cur_ == rhs.ptr_->cur_); + + return cur_ == rhs.cur_; + } + + 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() + const value_type& operator* () const { + assert (*this == *this); // assert *this is valid + assert (cur_ < ptr_->end_); // assert *this is dereferenceable + return *cur_; + } + + _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const); + + InputIter& operator++ () { + assert (*this == *this); // assert *this is valid + 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 +}; + + +// satisfies the requirements in 24.1.2 [lib.output.iterators] +template +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 int 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) { + assert (0 != ptr_); + + // verify that the iterator is in the valid range + 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) + 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 () { + if (0 == --ptr_->ref_) // decrement the reference count + delete ptr_; + ptr_ = 0; + cur_ = 0; + } + + OutputIter& operator= (const OutputIter &rhs) { + if (0 == --ptr_->ref_) + delete ptr_; + + ptr_ = rhs.ptr_; + ++ptr_->ref_; + + cur_ = rhs.cur_; + + return *this; + } + + 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 { + assert (0 != ptr_); + assert (ptr_->assign_ && ptr_->assign_ != ptr_->end_); + + return Proxy (ptr_); + } + + _RWSTD_OPERATOR_ARROW (pointer operator-> () const); + + OutputIter& operator++ () { + assert (cur_ == ptr_->cur_); + 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_; +}; + + +// satisfies the requirements in 24.1.3 [lib.forward.iterators] +template +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 int 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 { + assert (cur_ != 0); + return cur_ == rhs.cur_; + } + + bool operator!= (const FwdIter &rhs) const { + return !(*this == rhs); + } + + reference operator* () const { + assert (cur_ != 0 && cur_ != end_); + return *cur_; + } + + _RWSTD_OPERATOR_ARROW (pointer operator-> () const); + + FwdIter& operator++ () { + 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 +struct ConstFwdIter: FwdIter +{ + typedef T value_type; + typedef FwdIter Base; + + ConstFwdIter (): Base () { } + + ConstFwdIter (const value_type *cur, + const value_type *, + const value_type *end) + : Base (_RWSTD_CONST_CAST (value_type*, cur), 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 +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 int 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 { + assert (cur_ != 0 && rhs.cur_ != 0); + return cur_ == rhs.cur_; + } + + bool operator!= (const BidirIter &rhs) const { + return !(*this == rhs); + } + + reference operator* () const { + assert (cur_ != 0 && cur_ != end_); + return *cur_; + } + + _RWSTD_OPERATOR_ARROW (pointer operator-> () const); + + BidirIter& operator++ () { + assert (cur_ != 0 && cur_ != end_); + return ++cur_, *this; + } + + BidirIter operator++ (int) { + BidirIter tmp (*this); + return ++*this, tmp; + } + + BidirIter& operator-- () { + 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 +struct ConstBidirIter: BidirIter +{ + typedef T value_type; + typedef BidirIter Base; + + ConstBidirIter (): Base () { } + + ConstBidirIter (const value_type *cur, + const value_type *begin, + const value_type *end) + : Base (_RWSTD_CONST_CAST (value_type*, 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 +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 int 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 { + assert (cur_ != 0 && cur_ != end_); + return *cur_; + } + + _RWSTD_OPERATOR_ARROW (pointer operator-> () const); + + RandomAccessIter& operator++ () { + assert (cur_ != 0 && cur_ != end_); + return ++cur_, *this; + } + + RandomAccessIter operator++ (int) { + RandomAccessIter tmp (*this); + return ++*this, tmp; + } + + RandomAccessIter& operator-- () { + assert (cur_ != 0 && cur_ != begin_); + return --cur_, *this; + } + + RandomAccessIter operator-- (int) { + RandomAccessIter tmp (*this); + return --*this, tmp; + } + + RandomAccessIter& operator+= (difference_type n) { + 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 { + assert (cur_ != 0 && rhs.cur_ != 0); + return cur_ - rhs.cur_; + } + + bool operator== (const RandomAccessIter &rhs) const { + 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 { + 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 i) const { + assert ( cur_ != 0 + && (!end_ || cur_ + i < end_) + && !(begin_ || cur_ + i >= begin_)); + return cur_ [i]; + } + +// private: + pointer cur_; // pointer to current element + const value_type *begin_; // first in range + const value_type *end_; // past-the-end +}; + + +template +struct ConstRandomAccessIter: RandomAccessIter +{ + typedef T value_type; + typedef RandomAccessIter Base; + + ConstRandomAccessIter (): Base () { } + + ConstRandomAccessIter (const value_type *cur, + const value_type *begin, + const value_type *end) + : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { } + + const value_type& operator* () const { + return Base::operator* (); + } + + _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const); +}; + + +template +inline T* +make_iter (T *cur, const T*, const T*, T*) +{ + return cur; +} + +template +inline T* +copy_iter (T *ptr, const T*) +{ + return ptr; +} + +// dummy function argument provided to help broken compilers (PR #29835) + +template +inline InputIter +make_iter (const T *cur, const T *begin, const T *end, const InputIter&) +{ + return InputIter(cur, begin, end); +} + +template +inline InputIter +copy_iter (const InputIter &it, const T*) +{ + return InputIter(it.cur_, it.ptr_->beg_, it.ptr_->end_); +} + +template +inline const char* type_name (InputIter, const T*) +{ return "InputIterator"; } + + +template +inline OutputIter +make_iter (T *cur, const T *begin, const T *end, const OutputIter&) +{ + return OutputIter(cur, begin, end); +} + +template +inline OutputIter +copy_iter (const OutputIter &it, const T*) +{ + return OutputIter(it.cur_, 0, it.ptr_->end); +} + +template +inline const char* type_name (OutputIter, const T*) +{ return "OutputIterator"; } + + +template +inline FwdIter +make_iter (T *cur, const T *begin, const T *end, FwdIter) +{ + return FwdIter(cur, begin, end); +} + +template +inline FwdIter +copy_iter (const FwdIter &it, const T*) +{ + return FwdIter(it.cur_, 0, it.end_); +} + +template +inline const char* type_name (FwdIter, const T*) +{ return "ForwardIterator"; } + + +template +inline ConstFwdIter +make_iter (T *cur, const T *begin, const T *end, ConstFwdIter) +{ + return ConstFwdIter(cur, begin, end); +} + +template +inline ConstFwdIter +copy_iter (const ConstFwdIter &it, const T*) +{ + return ConstFwdIter(it.cur_, 0, it.end_); +} + +template +inline const char* type_name (ConstFwdIter, const T*) +{ return "ConstForwardIterator"; } + + +template +inline BidirIter +make_iter (T *cur, const T *begin, const T *end, BidirIter) +{ + return BidirIter(cur, begin, end); +} + +template +inline BidirIter +copy_iter (const BidirIter &it, const T*) +{ + return BidirIter(it.cur_, it.begin_, it.end_); +} + +template +inline const char* type_name (BidirIter, const T*) +{ return "BidirectionalIterator"; } + + +template +inline ConstBidirIter +make_iter (T *cur, const T *begin, const T *end, ConstBidirIter) +{ + return ConstBidirIter(cur, begin, end); +} + +template +inline ConstBidirIter +copy_iter (const ConstBidirIter &it, const T*) +{ + return ConstBidirIter(it.cur_, it.begin_, it.end_); +} + +template +inline const char* type_name (ConstBidirIter, const T*) +{ return "ConstBidirectionalIterator"; } + + +template +inline RandomAccessIter +make_iter (T *cur, const T *begin, const T *end, RandomAccessIter) +{ + return RandomAccessIter(cur, begin, end); +} + +template +inline RandomAccessIter +copy_iter (const RandomAccessIter &it, const T*) +{ + return RandomAccessIter(it.cur_, it.begin_, it.end_); +} + +template +inline const char* type_name (RandomAccessIter, const T*) +{ return "RandomAccessIterator"; } + + +template +inline ConstRandomAccessIter +make_iter (T *cur, const T *begin, const T *end, ConstRandomAccessIter) +{ + return ConstRandomAccessIter(cur, begin, end); +} + +template +inline ConstRandomAccessIter +copy_iter (const ConstRandomAccessIter &it, const T*) +{ + return ConstRandomAccessIter(it.cur_, it.begin_, it.end_); +} + +template +inline const char* type_name (ConstRandomAccessIter, const T*) +{ return "ConstRandomAccessIterator"; } + + + +#endif // _RWSTD_ALG_TEST_H_INCLUDED Propchange: incubator/stdcxx/trunk/tests/include/alg_test.h ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/stdcxx/trunk/tests/include/alg_test.h ------------------------------------------------------------------------------ svn:keywords = Id