1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/stdcpp/tsrc/Stdcpp_test/stdcxx/include/alg_test.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1247 @@
1.4 +/***************************************************************************
1.5 + *
1.6 + * alg_test.h - common definitions for algorithms tests
1.7 + *
1.8 + * $Id: alg_test.h 349021 2005-11-25 20:32:27Z sebor $
1.9 + *
1.10 + ***************************************************************************
1.11 + *
1.12 + * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
1.13 + * Software division. Licensed under the Apache License, Version 2.0 (the
1.14 + * "License"); you may not use this file except in compliance with the
1.15 + * License. You may obtain a copy of the License at
1.16 + * http://www.apache.org/licenses/LICENSE-2.0. Unless required by
1.17 + * applicable law or agreed to in writing, software distributed under
1.18 + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
1.19 + * CONDITIONS OF ANY KIND, either express or implied. See the License
1.20 + * for the specific language governing permissions and limitations under
1.21 + * the License.
1.22 + *
1.23 + **************************************************************************/
1.24 +
1.25 +#ifndef _RWSTD_ALG_TEST_H_INCLUDED
1.26 +#define _RWSTD_ALG_TEST_H_INCLUDED
1.27 +
1.28 +#include <iterator>
1.29 +
1.30 +#include <cassert> // for assert()
1.31 +
1.32 +#include <testdefs.h>
1.33 +#include "rw/_defs.h"
1.34 +
1.35 +
1.36 +// defining macro for var
1.37 +#define n_total_op_assign_ (*Getn_total_op_assign_())
1.38 +#define n_total_op_eq_ (*Getn_total_op_eq_())
1.39 +#define gen_ (* Get_gen_())
1.40 +// objects of class X maintain a count of their instances in existence,
1.41 +// the number of defaut and copy ctor calls, assignment operators, and
1.42 +// the number of calls to operator==() and operator<()
1.43 +struct _TEST_EXPORT X
1.44 +{
1.45 + const int id_; // a unique non-zero id of the object
1.46 + int origin_; // id of the original object that this
1.47 + // is a (perhaps indirect) copy of (id_
1.48 + // when this is the original)
1.49 + int src_id_; // id of the object that this is a direct
1.50 + // copy of (id_ when this the original)
1.51 + int val_; // object's value
1.52 +
1.53 + // number of times the object has been copied into another object,
1.54 + // regardless of whether the operation threw an exception or not
1.55 + _RWSTD_SIZE_T n_copy_ctor_;
1.56 +
1.57 + // number of times the object's assignment operator has been invoked,
1.58 + // regardless of whether the operation threw an exception or not
1.59 + _RWSTD_SIZE_T n_op_assign_;
1.60 +
1.61 + // number of times the object's operator== was invoked
1.62 + // regardless of whether the operation threw an exception
1.63 + _RWSTD_SIZE_T n_op_eq_;
1.64 +
1.65 + // number of times the object's operator< was invoked
1.66 + // regardless of whether the operation threw an exception
1.67 + _RWSTD_SIZE_T n_op_lt_;
1.68 +
1.69 + static _RWSTD_SIZE_T count_; // number of objects in existence (>= 0)
1.70 + static int id_gen_; // generates a unique non-zero id
1.71 + _TEST_EXPORT static int (*_gen_)(); // extern "C++" int (*)()
1.72 +
1.73 + _TEST_EXPORT static _RWSTD_SIZE_T n_total_def_ctor_; // number of default ctor calls
1.74 + _TEST_EXPORT static _RWSTD_SIZE_T n_total_copy_ctor_; // ... copy ctors ...
1.75 + _TEST_EXPORT static _RWSTD_SIZE_T n_total_dtor_; // ... dtors ...
1.76 +//new chnage decl of member var
1.77 + _TEST_EXPORT static _RWSTD_SIZE_T _n_total_op_assign_; // ... assignment operators ...
1.78 + _TEST_EXPORT static _RWSTD_SIZE_T _n_total_op_eq_; // ... equality operators ...
1.79 + _TEST_EXPORT static _RWSTD_SIZE_T n_total_op_lt_; // ... operators <= ...
1.80 +
1.81 + // classes thrown from the respective functions
1.82 + struct Exception { int id_; };
1.83 + struct DefCtor: Exception { };
1.84 + struct CopyCtor: Exception { };
1.85 + struct Dtor: Exception { };
1.86 + struct OpAssign: Exception { };
1.87 + struct OpEq: Exception { };
1.88 + struct OpLt: Exception { };
1.89 +
1.90 + // throw object's `id' wrapped in the appropriate struct when the
1.91 + // corresponding n_total_xxx_ counter reaches the value pointed to
1.92 + // by the respective pointer below
1.93 + static _RWSTD_SIZE_T* def_ctor_throw_ptr_;
1.94 + static _RWSTD_SIZE_T* copy_ctor_throw_ptr_;
1.95 + static _RWSTD_SIZE_T* dtor_throw_ptr_;
1.96 + static _RWSTD_SIZE_T* op_assign_throw_ptr_;
1.97 + static _RWSTD_SIZE_T* op_eq_throw_ptr_;
1.98 + static _RWSTD_SIZE_T* op_lt_throw_ptr_;
1.99 +
1.100 + // objects to which the pointers above initally point
1.101 + static _RWSTD_SIZE_T def_ctor_throw_count_;
1.102 + static _RWSTD_SIZE_T copy_ctor_throw_count_;
1.103 + static _RWSTD_SIZE_T dtor_throw_count_;
1.104 + static _RWSTD_SIZE_T op_assign_throw_count_;
1.105 + static _RWSTD_SIZE_T op_eq_throw_count_;
1.106 + static _RWSTD_SIZE_T op_lt_throw_count_;
1.107 +
1.108 + _TEST_EXPORT X ();
1.109 +
1.110 + _TEST_EXPORT X (const X&);
1.111 +
1.112 + _TEST_EXPORT ~X ();
1.113 +
1.114 +_TEST_EXPORT X& operator= (const X&);
1.115 +
1.116 + _TEST_EXPORT bool operator== (const X&) const;
1.117 + _TEST_EXPORT bool operator< (const X&) const;
1.118 +
1.119 + // the following operators are not declared or defined in order
1.120 + // to detect any unwarranted assumptions made in algorithms
1.121 + // bool operator!= (const X &rhs) const;
1.122 + // bool operator> (const X &rhs) const;
1.123 + // bool operator>= (const X &rhs) const;
1.124 + // bool operator<= (const X &rhs) const;
1.125 + // X operator- () const;
1.126 + // X operator+ () const;
1.127 +
1.128 + _TEST_EXPORT bool
1.129 + is_count (_RWSTD_SIZE_T copy_ctor,
1.130 + _RWSTD_SIZE_T op_assign,
1.131 + _RWSTD_SIZE_T op_eq,
1.132 + _RWSTD_SIZE_T op_lt) const;
1.133 +
1.134 +_TEST_EXPORT static bool
1.135 + is_total (_RWSTD_SIZE_T count,
1.136 + _RWSTD_SIZE_T n_def_ctor,
1.137 + _RWSTD_SIZE_T n_copy_ctor,
1.138 + _RWSTD_SIZE_T n_op_assign,
1.139 + _RWSTD_SIZE_T n_op_eq,
1.140 + _RWSTD_SIZE_T n_op_lt);
1.141 +
1.142 +_TEST_EXPORT static void reset_totals ();
1.143 +
1.144 + // construct an array of objects of type X each initialized
1.145 + // from the corresponding element of the character array
1.146 + static X* from_char (const char*, _RWSTD_SIZE_T = ~0UL);
1.147 +
1.148 + // returns -1 when less, 0 when same, or +1 when the array
1.149 + // of X objects is greater than the character string
1.150 + static int compare (const X*, const char*, _RWSTD_SIZE_T = ~0UL);
1.151 + static int compare (const char*, const X*, _RWSTD_SIZE_T = ~0UL);
1.152 +
1.153 + // returns -1 when less, 0 when same, or +1 when the first
1.154 + // array of X objects is greater than the second array
1.155 + static int compare (const X*, const X*, _RWSTD_SIZE_T);
1.156 +};
1.157 +
1.158 +
1.159 +struct _TEST_EXPORT UnaryPredicate
1.160 +{
1.161 + // total number of times operator() was invoked
1.162 + static _RWSTD_SIZE_T n_total_op_fcall_;
1.163 +
1.164 + UnaryPredicate ();
1.165 +
1.166 + UnaryPredicate (const UnaryPredicate&);
1.167 +
1.168 + UnaryPredicate& operator= (const UnaryPredicate&);
1.169 +
1.170 + virtual ~UnaryPredicate ();
1.171 +
1.172 + virtual bool operator()(const X&) const;
1.173 +};
1.174 +
1.175 +
1.176 +struct _TEST_EXPORT BinaryPredicate
1.177 +{
1.178 + // total number of times operator() was invoked
1.179 + static _RWSTD_SIZE_T n_total_op_fcall_;
1.180 +
1.181 + bool ignore_case_;
1.182 +
1.183 + BinaryPredicate (bool = false);
1.184 +
1.185 + BinaryPredicate (const BinaryPredicate&);
1.186 +
1.187 + BinaryPredicate& operator= (const BinaryPredicate&);
1.188 +
1.189 + virtual ~BinaryPredicate ();
1.190 +
1.191 + virtual bool operator()(const X&, const X&) const;
1.192 +};
1.193 +
1.194 +
1.195 +class _TEST_EXPORT tempstr;
1.196 +
1.197 +// converts a sequence of objects of type X to a tempstr object
1.198 +// in the format "[%p0, %p1): { x0, >x1<, ..., xN - 1 } where N
1.199 +// is defined as: N = (X*)p1 - (X*)p0
1.200 +// the last argument, if non-negative, indicates the index of the
1.201 +// element enclosed in between the '>' and '<' characters
1.202 +_TEST_EXPORT void to_string (tempstr*, const X*, const X*, int = -1);
1.203 +
1.204 +
1.205 +// generate a unique sequential number starting from 0
1.206 +_TEST_EXPORT int gen_seq ();
1.207 +
1.208 +// generate numbers in the sequence 0, 0, 1, 1, 2, 2, 3, 3, etc...
1.209 +_TEST_EXPORT int gen_seq_2lists ();
1.210 +
1.211 +// generate a sequence of subsequences (i.e., 0, 1, 2, 3, 4, 0, 1, 2, etc...)
1.212 +_TEST_EXPORT int gen_subseq ();
1.213 +
1.214 +// wrapper around a (possibly) extern "C" int rand()
1.215 +// extern "C++"
1.216 +_TEST_EXPORT int gen_rnd ();
1.217 +
1.218 +
1.219 +// computes an integral log2
1.220 +inline unsigned ilog2 (unsigned long n)
1.221 +{
1.222 + unsigned result = 0;
1.223 + while (n >>= 1)
1.224 + ++result;
1.225 + return result;
1.226 +}
1.227 +
1.228 +
1.229 +// computes an integral log10
1.230 +inline unsigned ilog10 (unsigned long n)
1.231 +{
1.232 + unsigned result = 0;
1.233 + while (n /= 10)
1.234 + ++result;
1.235 + return result;
1.236 +}
1.237 +
1.238 +
1.239 +// returns true iff a sequence of (not necessarily unique) values
1.240 +// is sorted in an ascending order
1.241 +template <class InputIterator>
1.242 +inline bool is_sorted_lt (InputIterator first, InputIterator last)
1.243 +{
1.244 + if (first == last)
1.245 + return true;
1.246 +
1.247 + for (InputIterator prev (first); ++first != last; prev = first) {
1.248 + if (*first < *prev)
1.249 + return false;
1.250 + }
1.251 +
1.252 + return true;
1.253 +}
1.254 +
1.255 +
1.256 +// returns true iff a sequence of (not necessarily unique) values
1.257 +// is sorted in a descending order
1.258 +template <class InputIterator>
1.259 +inline bool is_sorted_gt (InputIterator first, InputIterator last)
1.260 +{
1.261 + if (first == last)
1.262 + return true;
1.263 +
1.264 + for (InputIterator prev (first); ++first != last; prev = first) {
1.265 + if (*prev < *first)
1.266 + return false;
1.267 + }
1.268 +
1.269 + return true;
1.270 +}
1.271 +
1.272 +
1.273 +// type used to exercise that algorithms do not apply operators
1.274 +// to function objects the latter are not required to define
1.275 +struct conv_to_bool {
1.276 +
1.277 + static conv_to_bool make (bool val) {
1.278 + conv_to_bool tmp;
1.279 + tmp.val_ = val;
1.280 + return tmp;
1.281 + }
1.282 +
1.283 + operator bool () const {
1.284 + return val_;
1.285 + }
1.286 +
1.287 +public:
1.288 + bool operator!() const
1.289 + {
1.290 + return val_ != 0;
1.291 + } // not defined
1.292 +
1.293 + bool val_;
1.294 +};
1.295 +
1.296 +// not defined
1.297 +void operator&& (const conv_to_bool&, bool);
1.298 +void operator&& (bool, const conv_to_bool&);
1.299 +void operator|| (const conv_to_bool&, bool);
1.300 +void operator|| (bool, const conv_to_bool&);
1.301 +
1.302 +// element-type prototypes to exercise container requirements
1.303 +
1.304 +
1.305 +// meets requirements listed at 25, p7
1.306 +template <class T>
1.307 +struct predicate {
1.308 + conv_to_bool operator() (const T &a) const {
1.309 + _RWSTD_UNUSED (a);
1.310 + return conv_to_bool::make (true);
1.311 + }
1.312 +};
1.313 +
1.314 +
1.315 +// meets requirements listed at 25, p8
1.316 +template <class T>
1.317 +struct binary_predicate {
1.318 + conv_to_bool operator() (const T &a, const T &b) const {
1.319 + _RWSTD_UNUSED (a);
1.320 + _RWSTD_UNUSED (b);
1.321 + return conv_to_bool::make (true);
1.322 + }
1.323 +};
1.324 +
1.325 +
1.326 +// meets requirements listed at 25.2.3, p2
1.327 +template <class T>
1.328 +struct func {
1.329 + typedef T argument_type;
1.330 + typedef argument_type& reference;
1.331 +
1.332 + reference operator() (const argument_type&) const {
1.333 + return _RWSTD_REINTERPRET_CAST (reference,
1.334 + _RWSTD_CONST_CAST (func*, this)->dummy);
1.335 + }
1.336 +
1.337 +private:
1.338 + char dummy;
1.339 +};
1.340 +
1.341 +
1.342 +// meets requirements listed at 25.2.3, p2
1.343 +template <class T>
1.344 +struct binary_func {
1.345 + typedef T argument_type;
1.346 + typedef argument_type& reference;
1.347 +
1.348 + reference operator() (const argument_type&,
1.349 + const argument_type&) const {
1.350 + return _RWSTD_REINTERPRET_CAST (reference,
1.351 + _RWSTD_CONST_CAST (binary_func*, this)->dummy);
1.352 + }
1.353 +
1.354 +private:
1.355 + char dummy;
1.356 +};
1.357 +
1.358 +
1.359 +// a base-class to extend the requirements classes from
1.360 +
1.361 +enum { no_ctor = 0, def_ctor = 1, cpy_ctor = 2 };
1.362 +
1.363 +template <int c = no_ctor>
1.364 +struct base;
1.365 +
1.366 +
1.367 +template<>
1.368 +struct base<no_ctor>
1.369 +{
1.370 +private:
1.371 + // struct s added to prevent gcc warning: base<no_ctor> has a private
1.372 + // constructor and no friends
1.373 + struct s { };
1.374 + friend struct s;
1.375 +
1.376 + base ();
1.377 + base (const base&);
1.378 + void operator= (base&);
1.379 +};
1.380 +
1.381 +
1.382 +template<>
1.383 +struct base<def_ctor>
1.384 +{
1.385 + base () : unused (0) { }
1.386 +
1.387 +private:
1.388 +
1.389 + void operator= (base&);
1.390 + base (const base&);
1.391 +
1.392 + // unused member prevents bogus HP aCC warnings (see Onyx #23561)
1.393 + int unused;
1.394 +};
1.395 +
1.396 +
1.397 +template<>
1.398 +struct base<cpy_ctor>
1.399 +{
1.400 + // explicitly specifying redundant template parameters to work
1.401 + // around a SunPro 5.2 bug (see Onyx #24260)
1.402 + base (const base<cpy_ctor> &rhs): unused (rhs.unused) { }
1.403 +
1.404 +private:
1.405 +
1.406 + base ();
1.407 + void operator= (base&);
1.408 +
1.409 + // unused member prevents bogus HP aCC warnings (see Onyx #23561)
1.410 + int unused;
1.411 +};
1.412 +
1.413 +
1.414 +template<>
1.415 +struct base<(def_ctor | cpy_ctor)>
1.416 +{
1.417 + base (): unused (0) { }
1.418 +
1.419 + // explicitly specifying redundant template parameters to work
1.420 + // around a SunPro 5.2 bug (see Onyx #24260)
1.421 + base (const base<(def_ctor | cpy_ctor)> &rhs): unused (rhs.unused) { }
1.422 +
1.423 +private:
1.424 +
1.425 + void operator= (base&);
1.426 +
1.427 + // unused member prevents bogus HP aCC warnings (see Onyx #23561)
1.428 + int unused;
1.429 +};
1.430 +
1.431 +
1.432 +template <class T>
1.433 +struct eq_comp: T { };
1.434 +
1.435 +
1.436 +template <class T>
1.437 +inline bool operator== (const eq_comp<T>&, const eq_comp<T>&)
1.438 +{
1.439 + return true;
1.440 +}
1.441 +
1.442 +
1.443 +template <class T>
1.444 +struct lt_comp: T { };
1.445 +
1.446 +
1.447 +template <class T>
1.448 +inline bool operator< (const lt_comp<T>&, const lt_comp<T>&)
1.449 +{
1.450 + return true;
1.451 +}
1.452 +
1.453 +
1.454 +// assignment
1.455 +
1.456 +template <class T>
1.457 +struct assign : T
1.458 +{
1.459 + assign& operator= (const assign& rhs) {
1.460 + unused = rhs.unused;
1.461 + return *this;
1.462 + }
1.463 +private:
1.464 + // unused member prevents bogus HP aCC warnings (see Onyx #23561)
1.465 + int unused;
1.466 +};
1.467 +
1.468 +
1.469 +// conversion structs
1.470 +
1.471 +// struct split into 2 to eliminate the following g++ 2.95.2 warning:
1.472 +// warning: choosing `convert<T>::operator U&()' over
1.473 +// `convert<T>::operator const U&() const'
1.474 +
1.475 +template <class T, class U>
1.476 +struct cvt : T
1.477 +{
1.478 + operator U& () {
1.479 + return _RWSTD_REINTERPRET_CAST (U&, *this);
1.480 + }
1.481 +};
1.482 +
1.483 +
1.484 +template <class T, class U>
1.485 +struct const_cvt : T
1.486 +{
1.487 + operator const U& () const {
1.488 + return _RWSTD_REINTERPRET_CAST (const U&, *this);
1.489 + }
1.490 +};
1.491 +
1.492 +
1.493 +#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
1.494 +
1.495 +struct DummyBase { };
1.496 +
1.497 +# define ITER_BASE(ign1, ign2, ign3, ign4, ign5) DummyBase
1.498 +#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
1.499 + // when partial specialization isn't supported
1.500 +# define ITER_BASE(Cat, T, Dist, Ptr, Ref) \
1.501 + std::iterator<Cat, T, Dist, Ptr, Ref >
1.502 +#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
1.503 +
1.504 +
1.505 +// satisfies the requirements in 24.1.1 [lib.input.iterators]
1.506 +template <class T>
1.507 +struct InputIter: ITER_BASE (std::input_iterator_tag, T, int, T*, T&)
1.508 +{
1.509 + typedef T value_type;
1.510 + typedef value_type* pointer;
1.511 + typedef value_type& reference;
1.512 + typedef int difference_type;
1.513 + typedef std::input_iterator_tag iterator_category;
1.514 +
1.515 + // body shared by all copies of the same InputIter specialization
1.516 + // to detect algorithms that pass through the same interator more
1.517 + // than once (disallowed by 24.1.1, p3)
1.518 + struct Shared {
1.519 + const value_type *cur_;
1.520 + const value_type *beg_;
1.521 + const value_type *end_;
1.522 + int ref_;
1.523 +
1.524 + Shared (const value_type *cur,
1.525 + const value_type *beg,
1.526 + const value_type *end)
1.527 + : cur_ (cur), beg_ (beg), end_ (end), ref_ (1) { }
1.528 +
1.529 + ~Shared () {
1.530 + cur_ = beg_ = end_ = 0;
1.531 + ref_ = -1;
1.532 + }
1.533 +
1.534 + private:
1.535 + Shared (const Shared&); // not defined
1.536 + void operator= (const Shared&); // not defined
1.537 +
1.538 + };
1.539 +
1.540 + // InputIterators are not default constructible
1.541 + InputIter (const value_type *cur,
1.542 + const value_type *beg,
1.543 + const value_type *end)
1.544 + : ptr_ (new Shared (cur, beg, end)), cur_ (cur) { }
1.545 +
1.546 + InputIter (const InputIter &rhs)
1.547 + : ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
1.548 + assert (0 != ptr_);
1.549 + ++ptr_->ref_;
1.550 + }
1.551 +
1.552 + ~InputIter () {
1.553 + assert (0 != ptr_);
1.554 +
1.555 + if (0 == --ptr_->ref_) // decrement the reference count
1.556 + delete ptr_;
1.557 + ptr_ = 0;
1.558 + cur_ = 0;
1.559 + }
1.560 +
1.561 + InputIter& operator= (const InputIter &rhs) {
1.562 + assert (rhs == rhs); // assert `rhs' is valid
1.563 +
1.564 + assert (0 != ptr_);
1.565 + if (0 == --ptr_->ref_)
1.566 + delete ptr_;
1.567 +
1.568 + ptr_ = rhs.ptr_;
1.569 +
1.570 + assert (0 != ptr_);
1.571 + ++ptr_->ref_;
1.572 +
1.573 + cur_ = rhs.cur_;
1.574 +
1.575 + return *this;
1.576 + }
1.577 +
1.578 + bool operator== (const InputIter &rhs) const {
1.579 + // assert that both arguments are in the domain of operator==()
1.580 + // i.e., that no copy of *this or `rhs' has been incremented
1.581 + // and that no copy passed through this value of the iterator
1.582 +
1.583 + assert (0 != ptr_);
1.584 + assert (cur_ == ptr_->cur_);
1.585 +
1.586 + assert (0 != rhs.ptr_);
1.587 + assert (rhs.cur_ == rhs.ptr_->cur_);
1.588 +
1.589 + return cur_ == rhs.cur_;
1.590 + }
1.591 +
1.592 + bool operator!= (const InputIter &rhs) const {
1.593 + return !(*this == rhs);
1.594 + }
1.595 +
1.596 + // returning const-reference rather than a value in order
1.597 + // not to impose the CopyConstructible requirement on T
1.598 + // and to disallow constructs like *InputIter<T>() = T()
1.599 + const value_type& operator* () const {
1.600 + assert (*this == *this); // assert *this is valid
1.601 + assert (cur_ < ptr_->end_); // assert *this is dereferenceable
1.602 + return *cur_;
1.603 + }
1.604 +
1.605 + _RWSTD_OPERATOR_ARROW(const value_type* operator-> () const);
1.606 +
1.607 + InputIter& operator++ () {
1.608 + assert (*this == *this); // assert *this is valid
1.609 + assert (cur_ < ptr_->end_); // assert *this is not past the end
1.610 +
1.611 + ptr_->cur_ = ++cur_;
1.612 +
1.613 + return *this;
1.614 + }
1.615 +
1.616 + InputIter operator++ (int) {
1.617 + return ++*this;
1.618 + }
1.619 +
1.620 +// private:
1.621 + Shared *ptr_;
1.622 + const value_type *cur_; // past-the-end
1.623 +};
1.624 +
1.625 +
1.626 +// satisfies the requirements in 24.1.2 [lib.output.iterators]
1.627 +template <class T>
1.628 +struct OutputIter: ITER_BASE (std::output_iterator_tag, T, int, T*, T&)
1.629 +{
1.630 + typedef T value_type;
1.631 + typedef value_type* pointer;
1.632 + typedef value_type& reference;
1.633 + typedef int difference_type;
1.634 + typedef std::output_iterator_tag iterator_category;
1.635 +
1.636 + // body shared by all copies of the same OutputIter specialization
1.637 + // to detect algorithms that pass through the same interator more
1.638 + // than once (disallowed by 24.1.2, p2)
1.639 + struct Shared {
1.640 + pointer cur_;
1.641 + pointer assign_;
1.642 + const value_type *begin_;
1.643 + const value_type *end_;
1.644 + int ref_;
1.645 +
1.646 + Shared (pointer cur, const value_type *end)
1.647 + : cur_ (cur), assign_ (cur), begin_ (cur), end_ (end), ref_ (1) { }
1.648 +
1.649 + ~Shared () {
1.650 + begin_ = end_ = cur_ = assign_ = 0;
1.651 + ref_ = -1;
1.652 + }
1.653 +
1.654 + private:
1.655 + Shared (const Shared&); // not defined
1.656 + void operator= (const Shared&); // not defined
1.657 +
1.658 + };
1.659 +
1.660 + // class whose objects are returned from OutputIter::operator*
1.661 + // to detect multiple assignments (disallowed by 24.1.2, p2)
1.662 + class Proxy {
1.663 + friend struct OutputIter;
1.664 +
1.665 + Shared* const ptr_;
1.666 +
1.667 + Proxy (Shared *ptr): ptr_ (ptr) { }
1.668 +
1.669 + public:
1.670 + void operator= (const value_type &rhs) {
1.671 + assert (0 != ptr_);
1.672 +
1.673 + // verify that the iterator is in the valid range
1.674 + assert (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ <= ptr_->end_);
1.675 +
1.676 + // verify that the assignment point is the same as the current
1.677 + // position `cur' within the sequence or immediately before it
1.678 + // (in order to allow the expression: *it++ = val)
1.679 + assert ( ptr_->assign_ == ptr_->cur_
1.680 + || ptr_->assign_ + 1 == ptr_->cur_);
1.681 +
1.682 + // assign and increment the assignment point
1.683 + *ptr_->assign_++ = rhs;
1.684 + }
1.685 + };
1.686 +
1.687 + // OutputIterators are not default constructible
1.688 + OutputIter (pointer cur,
1.689 + const value_type *,
1.690 + const value_type *end)
1.691 + : ptr_ (new Shared (cur, end)), cur_ (cur) { }
1.692 +
1.693 + OutputIter (const OutputIter &rhs)
1.694 + : ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
1.695 + ++ptr_->ref_; // increment the reference count
1.696 + }
1.697 +
1.698 + ~OutputIter () {
1.699 + if (0 == --ptr_->ref_) // decrement the reference count
1.700 + delete ptr_;
1.701 + ptr_ = 0;
1.702 + cur_ = 0;
1.703 + }
1.704 +
1.705 + OutputIter& operator= (const OutputIter &rhs) {
1.706 + if (0 == --ptr_->ref_)
1.707 + delete ptr_;
1.708 +
1.709 + ptr_ = rhs.ptr_;
1.710 + ++ptr_->ref_;
1.711 +
1.712 + cur_ = rhs.cur_;
1.713 +
1.714 + return *this;
1.715 + }
1.716 +
1.717 + void operator= (const value_type &rhs) const {
1.718 + **this = rhs;
1.719 + }
1.720 +
1.721 + // return a proxy in order to detect multiple assignments
1.722 + // through the iterator (disallowed by 24.1.2, p2))
1.723 + Proxy operator* () const {
1.724 + assert (0 != ptr_);
1.725 + assert (ptr_->assign_ && ptr_->assign_ != ptr_->end_);
1.726 +
1.727 + return Proxy (ptr_);
1.728 + }
1.729 +
1.730 + _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
1.731 +
1.732 + OutputIter& operator++ () {
1.733 + assert (cur_ == ptr_->cur_);
1.734 + assert (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ < ptr_->end_);
1.735 + cur_ = ++ptr_->cur_;
1.736 + return *this;
1.737 + }
1.738 +
1.739 + // returning a const value rather than a modifiable value
1.740 + // in order to verify the requirement in row 5 of Table 73
1.741 + const OutputIter operator++ (int) {
1.742 + OutputIter tmp (*this);
1.743 + return ++*this, tmp;
1.744 + }
1.745 +
1.746 +// private:
1.747 + Shared *ptr_;
1.748 + pointer cur_;
1.749 +};
1.750 +
1.751 +
1.752 +// satisfies the requirements in 24.1.3 [lib.forward.iterators]
1.753 +template <class T>
1.754 +struct FwdIter: ITER_BASE (std::forward_iterator_tag, T, int, T*, T&)
1.755 +{
1.756 + typedef T value_type;
1.757 + typedef value_type* pointer;
1.758 + typedef value_type& reference;
1.759 + typedef int difference_type;
1.760 + typedef std::forward_iterator_tag iterator_category;
1.761 +
1.762 + FwdIter (): cur_ (0), end_ (0) { }
1.763 +
1.764 + FwdIter (pointer cur,
1.765 + const value_type *,
1.766 + const value_type *end)
1.767 + : cur_ (cur), end_ (end) { }
1.768 +
1.769 + FwdIter (const FwdIter &rhs)
1.770 + : cur_ (rhs.cur_), end_ (rhs.end_) { }
1.771 +
1.772 + ~FwdIter () {
1.773 + end_ = cur_ = 0;
1.774 + }
1.775 +
1.776 + FwdIter& operator= (const FwdIter &rhs) {
1.777 + cur_ = rhs.cur_;
1.778 + end_ = rhs.end_;
1.779 + return *this;
1.780 + }
1.781 +
1.782 + bool operator== (const FwdIter &rhs) const {
1.783 + assert (cur_ != 0);
1.784 + return cur_ == rhs.cur_;
1.785 + }
1.786 +
1.787 + bool operator!= (const FwdIter &rhs) const {
1.788 + return !(*this == rhs);
1.789 + }
1.790 +
1.791 + reference operator* () const {
1.792 + assert (cur_ != 0 && cur_ != end_);
1.793 + return *cur_;
1.794 + }
1.795 +
1.796 + _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
1.797 +
1.798 + FwdIter& operator++ () {
1.799 + assert (cur_ != 0 && cur_ != end_);
1.800 + return ++cur_, *this;
1.801 + }
1.802 +
1.803 + FwdIter operator++ (int) {
1.804 + FwdIter tmp (*this);
1.805 + return ++*this, tmp;
1.806 + }
1.807 +
1.808 +// private:
1.809 + pointer cur_; // pointer to current element
1.810 + const value_type *end_; // past-the-end
1.811 +};
1.812 +
1.813 +
1.814 +template <class T>
1.815 +struct ConstFwdIter: FwdIter<T>
1.816 +{
1.817 + typedef T value_type;
1.818 + typedef FwdIter<value_type> Base;
1.819 +
1.820 + ConstFwdIter (): Base () { }
1.821 +
1.822 + ConstFwdIter (const value_type *cur,
1.823 + const value_type *begin,
1.824 + const value_type *end)
1.825 + : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
1.826 +
1.827 + const value_type& operator* () const {
1.828 + return Base::operator* ();
1.829 + }
1.830 +
1.831 + _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
1.832 +};
1.833 +
1.834 +
1.835 +// satisfies the requirements in 24.1.4 [lib.bidirectional.iterators]
1.836 +template <class T>
1.837 +struct BidirIter: ITER_BASE (std::bidirectional_iterator_tag, T, int, T*, T&)
1.838 +{
1.839 + typedef T value_type;
1.840 + typedef value_type* pointer;
1.841 + typedef value_type& reference;
1.842 + typedef int difference_type;
1.843 + typedef std::bidirectional_iterator_tag iterator_category;
1.844 +
1.845 + BidirIter (): cur_ (0), begin_ (0), end_ (0) { }
1.846 +
1.847 + BidirIter (pointer cur,
1.848 + const value_type *begin,
1.849 + const value_type *end)
1.850 + : cur_ (cur), begin_ (begin), end_ (end) { }
1.851 +
1.852 + BidirIter (const BidirIter &rhs)
1.853 + : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }
1.854 +
1.855 + ~BidirIter () {
1.856 + begin_ = end_ = cur_ = 0;
1.857 + }
1.858 +
1.859 + BidirIter& operator= (const BidirIter &rhs) {
1.860 + cur_ = rhs.cur_;
1.861 + end_ = rhs.end_;
1.862 + return *this;
1.863 + }
1.864 +
1.865 + bool operator== (const BidirIter &rhs) const {
1.866 + assert (cur_ != 0 && rhs.cur_ != 0);
1.867 + return cur_ == rhs.cur_;
1.868 + }
1.869 +
1.870 + bool operator!= (const BidirIter &rhs) const {
1.871 + return !(*this == rhs);
1.872 + }
1.873 +
1.874 + reference operator* () const {
1.875 + assert (cur_ != 0 && cur_ != end_);
1.876 + return *cur_;
1.877 + }
1.878 +
1.879 + _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
1.880 +
1.881 + BidirIter& operator++ () {
1.882 + assert (cur_ != 0 && cur_ != end_);
1.883 + return ++cur_, *this;
1.884 + }
1.885 +
1.886 + BidirIter operator++ (int) {
1.887 + BidirIter tmp (*this);
1.888 + return ++*this, tmp;
1.889 + }
1.890 +
1.891 + BidirIter& operator-- () {
1.892 + assert (cur_ != 0 && cur_ != begin_);
1.893 + return --cur_, *this;
1.894 + }
1.895 +
1.896 + BidirIter operator-- (int) {
1.897 + BidirIter tmp (*this);
1.898 + return --*this, tmp;
1.899 + }
1.900 +
1.901 +// private:
1.902 + pointer cur_; // pointer to current element
1.903 + const value_type *begin_; // first in range
1.904 + const value_type *end_; // past-the-end
1.905 +};
1.906 +
1.907 +
1.908 +template <class T>
1.909 +struct ConstBidirIter: BidirIter<T>
1.910 +{
1.911 + typedef T value_type;
1.912 + typedef BidirIter<value_type> Base;
1.913 +
1.914 + ConstBidirIter (): Base () { }
1.915 +
1.916 + ConstBidirIter (const value_type *cur,
1.917 + const value_type *begin,
1.918 + const value_type *end)
1.919 + : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
1.920 +
1.921 + const value_type& operator* () const {
1.922 + return Base::operator* ();
1.923 + }
1.924 +
1.925 + _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
1.926 +};
1.927 +
1.928 +
1.929 +// satisfies the requirements in 24.1.5 [lib.random.access.iterators]
1.930 +template <class T>
1.931 +struct RandomAccessIter
1.932 + : ITER_BASE (std::random_access_iterator_tag, T, int, T*, T&)
1.933 +{
1.934 + typedef T value_type;
1.935 + typedef value_type* pointer;
1.936 + typedef value_type& reference;
1.937 + typedef int difference_type;
1.938 + typedef std::random_access_iterator_tag iterator_category;
1.939 +
1.940 + RandomAccessIter (): cur_ (0), begin_ (0), end_ (0) { }
1.941 +
1.942 + RandomAccessIter (pointer cur,
1.943 + const value_type *begin,
1.944 + const value_type *end)
1.945 + : cur_ (cur), begin_ (begin), end_ (end) { }
1.946 +
1.947 + RandomAccessIter (const RandomAccessIter &rhs)
1.948 + : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }
1.949 +
1.950 + ~RandomAccessIter () {
1.951 + begin_ = end_ = cur_ = 0;
1.952 + }
1.953 +
1.954 + RandomAccessIter& operator= (const RandomAccessIter &rhs) {
1.955 + cur_ = rhs.cur_;
1.956 + begin_ = rhs.begin_;
1.957 + end_ = rhs.end_;
1.958 + return *this;
1.959 + }
1.960 +
1.961 + reference operator* () const {
1.962 + assert (cur_ != 0 && cur_ != end_);
1.963 + return *cur_;
1.964 + }
1.965 +
1.966 + _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
1.967 +
1.968 + RandomAccessIter& operator++ () {
1.969 + assert (cur_ != 0 && cur_ != end_);
1.970 + return ++cur_, *this;
1.971 + }
1.972 +
1.973 + RandomAccessIter operator++ (int) {
1.974 + RandomAccessIter tmp (*this);
1.975 + return ++*this, tmp;
1.976 + }
1.977 +
1.978 + RandomAccessIter& operator-- () {
1.979 + assert (cur_ != 0 && cur_ != begin_);
1.980 + return --cur_, *this;
1.981 + }
1.982 +
1.983 + RandomAccessIter operator-- (int) {
1.984 + RandomAccessIter tmp (*this);
1.985 + return --*this, tmp;
1.986 + }
1.987 +
1.988 + RandomAccessIter& operator+= (difference_type n) {
1.989 + assert ( cur_ != 0
1.990 + && (!end_ || cur_ + n <= end_)
1.991 + && (!begin_ || cur_ + n >= begin_));
1.992 + return cur_ += n, *this;
1.993 + }
1.994 + RandomAccessIter& operator-= (difference_type n) {
1.995 + return *this += -n;
1.996 + }
1.997 +
1.998 + RandomAccessIter operator+ (difference_type n) const {
1.999 + return RandomAccessIter (*this) += n;
1.1000 + }
1.1001 +
1.1002 + RandomAccessIter operator- (difference_type n) const {
1.1003 + return RandomAccessIter (*this) -= n;
1.1004 + }
1.1005 +
1.1006 + difference_type operator- (const RandomAccessIter &rhs) const {
1.1007 + assert (cur_ != 0 && rhs.cur_ != 0);
1.1008 + return cur_ - rhs.cur_;
1.1009 + }
1.1010 +
1.1011 + bool operator== (const RandomAccessIter &rhs) const {
1.1012 + assert (cur_ != 0 && rhs.cur_ != 0);
1.1013 + return cur_ == rhs.cur_;
1.1014 + }
1.1015 +
1.1016 + bool operator!= (const RandomAccessIter &rhs) const {
1.1017 + return !(*this == rhs);
1.1018 + }
1.1019 +
1.1020 + bool operator< (const RandomAccessIter &rhs) const {
1.1021 + assert (cur_ != 0 && rhs.cur_ != 0);
1.1022 + return cur_ < rhs.cur_;
1.1023 + };
1.1024 +
1.1025 + bool operator> (const RandomAccessIter &rhs) const {
1.1026 + return rhs < *this;
1.1027 + }
1.1028 +
1.1029 + bool operator<= (const RandomAccessIter &rhs) const {
1.1030 + return !(rhs < *this);
1.1031 + }
1.1032 +
1.1033 + bool operator>= (const RandomAccessIter &rhs) const {
1.1034 + return !(*this < rhs);
1.1035 + }
1.1036 +
1.1037 + reference operator[] (difference_type inx) const {
1.1038 + assert ( cur_ != 0
1.1039 + && (!end_ || cur_ + inx < end_)
1.1040 + && !(begin_ || cur_ + inx >= begin_));
1.1041 + return cur_ [inx];
1.1042 + }
1.1043 +
1.1044 +// private:
1.1045 + pointer cur_; // pointer to current element
1.1046 + const value_type *begin_; // first in range
1.1047 + const value_type *end_; // past-the-end
1.1048 +};
1.1049 +
1.1050 +
1.1051 +template <class T>
1.1052 +struct ConstRandomAccessIter: RandomAccessIter<T>
1.1053 +{
1.1054 + typedef T value_type;
1.1055 + typedef RandomAccessIter<value_type> Base;
1.1056 + typedef typename Base::difference_type difference_type;
1.1057 +
1.1058 + ConstRandomAccessIter (): Base () { }
1.1059 +
1.1060 + ConstRandomAccessIter (const value_type *cur,
1.1061 + const value_type *begin,
1.1062 + const value_type *end)
1.1063 + : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
1.1064 +
1.1065 + const value_type& operator* () const {
1.1066 + return Base::operator* ();
1.1067 + }
1.1068 +
1.1069 + _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
1.1070 +
1.1071 + const value_type& operator[] (difference_type inx) const {
1.1072 + return Base::operator[] (inx);
1.1073 + }
1.1074 +};
1.1075 +
1.1076 +
1.1077 +template <class T>
1.1078 +inline T*
1.1079 +make_iter (T *cur, const T*, const T*, T*)
1.1080 +{
1.1081 + return cur;
1.1082 +}
1.1083 +
1.1084 +template <class T>
1.1085 +inline T*
1.1086 +copy_iter (T *ptr, const T*)
1.1087 +{
1.1088 + return ptr;
1.1089 +}
1.1090 +
1.1091 +// dummy function argument provided to help broken compilers (PR #29835)
1.1092 +
1.1093 +template <class T>
1.1094 +inline InputIter<T>
1.1095 +make_iter (const T *cur, const T *begin, const T *end, const InputIter<T>&)
1.1096 +{
1.1097 + return InputIter<T>(cur, begin, end);
1.1098 +}
1.1099 +
1.1100 +template <class T>
1.1101 +inline InputIter<T>
1.1102 +copy_iter (const InputIter<T> &it, const T*)
1.1103 +{
1.1104 + return InputIter<T>(it.cur_, it.ptr_->beg_, it.ptr_->end_);
1.1105 +}
1.1106 +
1.1107 +template <class T>
1.1108 +inline const char* type_name (InputIter<T>, const T*)
1.1109 +{ return "InputIterator"; }
1.1110 +
1.1111 +
1.1112 +template <class T>
1.1113 +inline OutputIter<T>
1.1114 +make_iter (T *cur, const T *begin, const T *end, const OutputIter<T>&)
1.1115 +{
1.1116 + return OutputIter<T>(cur, begin, end);
1.1117 +}
1.1118 +
1.1119 +template <class T>
1.1120 +inline OutputIter<T>
1.1121 +copy_iter (const OutputIter<T> &it, const T*)
1.1122 +{
1.1123 + return OutputIter<T>(it.cur_, 0, it.ptr_->end);
1.1124 +}
1.1125 +
1.1126 +template <class T>
1.1127 +inline const char* type_name (OutputIter<T>, const T*)
1.1128 +{ return "OutputIterator"; }
1.1129 +
1.1130 +
1.1131 +template <class T>
1.1132 +inline FwdIter<T>
1.1133 +make_iter (T *cur, const T *begin, const T *end, FwdIter<T>)
1.1134 +{
1.1135 + return FwdIter<T>(cur, begin, end);
1.1136 +}
1.1137 +
1.1138 +template <class T>
1.1139 +inline FwdIter<T>
1.1140 +copy_iter (const FwdIter<T> &it, const T*)
1.1141 +{
1.1142 + return FwdIter<T>(it.cur_, 0, it.end_);
1.1143 +}
1.1144 +
1.1145 +template <class T>
1.1146 +inline const char* type_name (FwdIter<T>, const T*)
1.1147 +{ return "ForwardIterator"; }
1.1148 +
1.1149 +
1.1150 +template <class T>
1.1151 +inline ConstFwdIter<T>
1.1152 +make_iter (T *cur, const T *begin, const T *end, ConstFwdIter<T>)
1.1153 +{
1.1154 + return ConstFwdIter<T>(cur, begin, end);
1.1155 +}
1.1156 +
1.1157 +template <class T>
1.1158 +inline ConstFwdIter<T>
1.1159 +copy_iter (const ConstFwdIter<T> &it, const T*)
1.1160 +{
1.1161 + return ConstFwdIter<T>(it.cur_, 0, it.end_);
1.1162 +}
1.1163 +
1.1164 +template <class T>
1.1165 +inline const char* type_name (ConstFwdIter<T>, const T*)
1.1166 +{ return "ConstForwardIterator"; }
1.1167 +
1.1168 +
1.1169 +template <class T>
1.1170 +inline BidirIter<T>
1.1171 +make_iter (T *cur, const T *begin, const T *end, BidirIter<T>)
1.1172 +{
1.1173 + return BidirIter<T>(cur, begin, end);
1.1174 +}
1.1175 +
1.1176 +template <class T>
1.1177 +inline BidirIter<T>
1.1178 +copy_iter (const BidirIter<T> &it, const T*)
1.1179 +{
1.1180 + return BidirIter<T>(it.cur_, it.begin_, it.end_);
1.1181 +}
1.1182 +
1.1183 +template <class T>
1.1184 +inline const char* type_name (BidirIter<T>, const T*)
1.1185 +{ return "BidirectionalIterator"; }
1.1186 +
1.1187 +
1.1188 +template <class T>
1.1189 +inline ConstBidirIter<T>
1.1190 +make_iter (T *cur, const T *begin, const T *end, ConstBidirIter<T>)
1.1191 +{
1.1192 + return ConstBidirIter<T>(cur, begin, end);
1.1193 +}
1.1194 +
1.1195 +template <class T>
1.1196 +inline ConstBidirIter<T>
1.1197 +copy_iter (const ConstBidirIter<T> &it, const T*)
1.1198 +{
1.1199 + return ConstBidirIter<T>(it.cur_, it.begin_, it.end_);
1.1200 +}
1.1201 +
1.1202 +template <class T>
1.1203 +inline const char* type_name (ConstBidirIter<T>, const T*)
1.1204 +{ return "ConstBidirectionalIterator"; }
1.1205 +
1.1206 +
1.1207 +template <class T>
1.1208 +inline RandomAccessIter<T>
1.1209 +make_iter (T *cur, const T *begin, const T *end, RandomAccessIter<T>)
1.1210 +{
1.1211 + return RandomAccessIter<T>(cur, begin, end);
1.1212 +}
1.1213 +
1.1214 +template <class T>
1.1215 +inline RandomAccessIter<T>
1.1216 +copy_iter (const RandomAccessIter<T> &it, const T*)
1.1217 +{
1.1218 + return RandomAccessIter<T>(it.cur_, it.begin_, it.end_);
1.1219 +}
1.1220 +
1.1221 +template <class T>
1.1222 +inline const char* type_name (RandomAccessIter<T>, const T*)
1.1223 +{ return "RandomAccessIterator"; }
1.1224 +
1.1225 +
1.1226 +template <class T>
1.1227 +inline ConstRandomAccessIter<T>
1.1228 +make_iter (T *cur, const T *begin, const T *end, ConstRandomAccessIter<T>)
1.1229 +{
1.1230 + return ConstRandomAccessIter<T>(cur, begin, end);
1.1231 +}
1.1232 +
1.1233 +template <class T>
1.1234 +inline ConstRandomAccessIter<T>
1.1235 +copy_iter (const ConstRandomAccessIter<T> &it, const T*)
1.1236 +{
1.1237 + return ConstRandomAccessIter<T>(it.cur_, it.begin_, it.end_);
1.1238 +}
1.1239 +
1.1240 +template <class T>
1.1241 +inline const char* type_name (ConstRandomAccessIter<T>, const T*)
1.1242 +{ return "ConstRandomAccessIterator"; }
1.1243 +
1.1244 +typedef int (*fptr_gen_)();
1.1245 +
1.1246 +//exporting fun for exporting global var
1.1247 +_TEST_EXPORT _RWSTD_SIZE_T* Getn_total_op_assign_();
1.1248 +_TEST_EXPORT _RWSTD_SIZE_T* Getn_total_op_eq_();
1.1249 +_TEST_EXPORT fptr_gen_* Get_gen_();
1.1250 +#endif // _RWSTD_ALG_TEST_H_INCLUDED