os/ossrv/stdcpp/tsrc/Stdcpp_test/stdcxx/include/alg_test.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /***************************************************************************
     2  *
     3  * alg_test.h - common definitions for algorithms tests
     4  *
     5  * $Id: alg_test.h 349021 2005-11-25 20:32:27Z sebor $
     6  *
     7  ***************************************************************************
     8  *
     9  * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
    10  * Software division. Licensed under the Apache License, Version 2.0 (the
    11  * "License");  you may  not use this file except  in compliance with the
    12  * License.    You    may   obtain   a   copy   of    the   License    at
    13  * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
    14  * applicable law  or agreed to  in writing,  software  distributed under
    15  * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
    16  * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
    17  * for the specific language governing permissions  and limitations under
    18  * the License.
    19  * 
    20  **************************************************************************/
    21 
    22 #ifndef _RWSTD_ALG_TEST_H_INCLUDED
    23 #define _RWSTD_ALG_TEST_H_INCLUDED
    24 
    25 #include <iterator>
    26 
    27 #include <cassert>   // for assert()
    28 
    29 #include <testdefs.h>
    30 #include "rw/_defs.h"
    31 
    32 
    33 // defining macro for var
    34 #define n_total_op_assign_ (*Getn_total_op_assign_())
    35 #define n_total_op_eq_ (*Getn_total_op_eq_())
    36 #define gen_   (* Get_gen_())     
    37 // objects of class X maintain a count of their instances in existence,
    38 // the number of defaut and copy ctor calls, assignment operators, and
    39 // the number of calls to operator==() and operator<()
    40 struct _TEST_EXPORT X
    41 {
    42     const int id_;        // a unique non-zero id of the object
    43     int       origin_;    // id of the original object that this
    44                           // is a (perhaps indirect) copy of (id_
    45                           // when this is the original)
    46     int       src_id_;    // id of the object that this is a direct
    47                           // copy of (id_ when this the original)
    48     int       val_;       // object's value
    49 
    50     // number of times the object has been copied into another object,
    51     // regardless of whether the operation threw an exception or not
    52     _RWSTD_SIZE_T n_copy_ctor_;
    53 
    54     // number of times the object's assignment operator has been invoked,
    55     // regardless of whether the operation threw an exception or not
    56     _RWSTD_SIZE_T n_op_assign_;
    57 
    58     // number of times the object's operator== was invoked
    59     // regardless of whether the operation threw an exception
    60     _RWSTD_SIZE_T n_op_eq_;
    61 
    62     // number of times the object's operator< was invoked
    63     // regardless of whether the operation threw an exception
    64     _RWSTD_SIZE_T n_op_lt_;
    65 
    66     static _RWSTD_SIZE_T count_;   // number of objects in existence (>= 0)
    67     static int id_gen_;            // generates a unique non-zero id
    68     _TEST_EXPORT   static int (*_gen_)();          // extern "C++" int (*)()
    69 
    70  _TEST_EXPORT     static _RWSTD_SIZE_T n_total_def_ctor_;    // number of default ctor calls
    71   _TEST_EXPORT    static _RWSTD_SIZE_T n_total_copy_ctor_;   // ... copy ctors ...
    72   _TEST_EXPORT    static _RWSTD_SIZE_T n_total_dtor_;        // ... dtors ...
    73 //new chnage decl of member var
    74  _TEST_EXPORT     static _RWSTD_SIZE_T _n_total_op_assign_;   // ... assignment operators ...
    75  _TEST_EXPORT     static _RWSTD_SIZE_T _n_total_op_eq_;       // ... equality operators ...
    76   _TEST_EXPORT    static _RWSTD_SIZE_T n_total_op_lt_;       // ... operators <= ...
    77 	
    78     // classes thrown from the respective functions
    79     struct Exception { int id_; };
    80     struct DefCtor: Exception { };
    81     struct CopyCtor: Exception { };
    82     struct Dtor: Exception { };
    83     struct OpAssign: Exception { };
    84     struct OpEq: Exception { };
    85     struct OpLt: Exception { };
    86 
    87     // throw object's `id' wrapped in the appropriate struct when the
    88     // corresponding n_total_xxx_ counter reaches the value pointed to
    89     // by the respective pointer below
    90     static _RWSTD_SIZE_T* def_ctor_throw_ptr_;
    91     static _RWSTD_SIZE_T* copy_ctor_throw_ptr_;
    92     static _RWSTD_SIZE_T* dtor_throw_ptr_;
    93     static _RWSTD_SIZE_T* op_assign_throw_ptr_;
    94     static _RWSTD_SIZE_T* op_eq_throw_ptr_;
    95     static _RWSTD_SIZE_T* op_lt_throw_ptr_;
    96 
    97     // objects to which the pointers above initally point
    98     static _RWSTD_SIZE_T def_ctor_throw_count_;
    99     static _RWSTD_SIZE_T copy_ctor_throw_count_;
   100     static _RWSTD_SIZE_T dtor_throw_count_;
   101     static _RWSTD_SIZE_T op_assign_throw_count_;
   102     static _RWSTD_SIZE_T op_eq_throw_count_;
   103     static _RWSTD_SIZE_T op_lt_throw_count_;
   104 
   105  _TEST_EXPORT   X ();
   106 
   107  _TEST_EXPORT   X (const X&);
   108 
   109  _TEST_EXPORT   ~X ();
   110 
   111 _TEST_EXPORT    X& operator= (const X&);
   112 
   113  _TEST_EXPORT   bool operator== (const X&) const;
   114  _TEST_EXPORT   bool operator< (const X&) const;
   115 
   116     // the following operators are not declared or defined in order
   117     // to detect any unwarranted assumptions made in algorithms
   118     //    bool operator!= (const X &rhs) const;
   119     //    bool operator> (const X &rhs) const;
   120     //    bool operator>= (const X &rhs) const;
   121     //    bool operator<= (const X &rhs) const;
   122     //    X operator- () const;
   123     //    X operator+ () const;
   124     
   125  _TEST_EXPORT  bool
   126     is_count (_RWSTD_SIZE_T copy_ctor,
   127               _RWSTD_SIZE_T op_assign,
   128               _RWSTD_SIZE_T op_eq,
   129               _RWSTD_SIZE_T op_lt) const;
   130 
   131 _TEST_EXPORT    static bool
   132     is_total (_RWSTD_SIZE_T count,
   133               _RWSTD_SIZE_T n_def_ctor,
   134               _RWSTD_SIZE_T n_copy_ctor,
   135               _RWSTD_SIZE_T n_op_assign,
   136               _RWSTD_SIZE_T n_op_eq,
   137               _RWSTD_SIZE_T n_op_lt);
   138 
   139 _TEST_EXPORT    static void reset_totals ();										
   140 
   141     // construct an array of objects of type X each initialized
   142     // from the corresponding element of the character array
   143     static X* from_char (const char*, _RWSTD_SIZE_T = ~0UL);
   144 
   145     // returns -1 when less, 0 when same, or +1 when the array
   146     // of X objects is greater than the character string
   147     static int compare (const X*, const char*, _RWSTD_SIZE_T = ~0UL);
   148     static int compare (const char*, const X*, _RWSTD_SIZE_T = ~0UL);
   149 
   150     // returns -1 when less, 0 when same, or +1 when the first
   151     // array of X objects is greater than the second array
   152     static int compare (const X*, const X*, _RWSTD_SIZE_T);
   153 };
   154 
   155 
   156 struct _TEST_EXPORT UnaryPredicate
   157 {
   158     // total number of times operator() was invoked
   159     static _RWSTD_SIZE_T n_total_op_fcall_;
   160 
   161     UnaryPredicate ();
   162 
   163     UnaryPredicate (const UnaryPredicate&);
   164 
   165     UnaryPredicate& operator= (const UnaryPredicate&);
   166 
   167     virtual ~UnaryPredicate ();
   168 
   169     virtual bool operator()(const X&) const;
   170 };
   171 
   172 
   173 struct _TEST_EXPORT BinaryPredicate
   174 {
   175     // total number of times operator() was invoked
   176     static _RWSTD_SIZE_T n_total_op_fcall_;
   177 
   178     bool ignore_case_;
   179 
   180     BinaryPredicate (bool = false);
   181 
   182     BinaryPredicate (const BinaryPredicate&);
   183 
   184     BinaryPredicate& operator= (const BinaryPredicate&);
   185 
   186     virtual ~BinaryPredicate ();
   187 
   188     virtual bool operator()(const X&, const X&) const;
   189 };
   190 
   191 
   192 class _TEST_EXPORT tempstr;
   193 
   194 // converts a sequence of objects of type X to a tempstr object
   195 // in the format "[%p0, %p1): { x0, >x1<, ..., xN - 1 } where N
   196 // is defined as: N = (X*)p1 - (X*)p0
   197 // the last argument, if non-negative, indicates the index of the
   198 // element enclosed in between the '>' and '<' characters
   199 _TEST_EXPORT void to_string (tempstr*, const X*, const X*, int = -1);
   200 
   201 
   202 // generate a unique sequential number starting from 0
   203 _TEST_EXPORT int gen_seq ();
   204 
   205 // generate numbers in the sequence 0, 0, 1, 1, 2, 2, 3, 3, etc... 
   206 _TEST_EXPORT int gen_seq_2lists ();
   207 
   208 // generate a sequence of subsequences (i.e., 0, 1, 2, 3, 4, 0, 1, 2, etc...)
   209 _TEST_EXPORT int gen_subseq ();
   210 
   211 // wrapper around a (possibly) extern "C" int rand()
   212 // extern "C++" 
   213 _TEST_EXPORT  int gen_rnd ();
   214 
   215 
   216 // computes an integral log2
   217 inline unsigned ilog2 (unsigned long n)
   218 {
   219     unsigned result = 0;
   220     while (n >>= 1)
   221         ++result;
   222     return result;
   223 }
   224 
   225 
   226 // computes an integral log10
   227 inline unsigned ilog10 (unsigned long n)
   228 {
   229     unsigned result = 0;
   230     while (n /= 10)
   231         ++result;
   232     return result;
   233 }
   234 
   235 
   236 // returns true iff a sequence of (not necessarily unique) values
   237 // is sorted in an ascending order
   238 template <class InputIterator>
   239 inline bool is_sorted_lt (InputIterator first, InputIterator last)
   240 {
   241     if (first == last)
   242         return true;
   243 
   244     for (InputIterator prev (first); ++first != last; prev = first) {
   245         if (*first < *prev)
   246             return false;
   247     }
   248 
   249     return true;
   250 }
   251 
   252 
   253 // returns true iff a sequence of (not necessarily unique) values
   254 // is sorted in a descending order
   255 template <class InputIterator>
   256 inline bool is_sorted_gt (InputIterator first, InputIterator last)
   257 {
   258     if (first == last)
   259         return true;
   260 
   261     for (InputIterator prev (first); ++first != last; prev = first) {
   262         if (*prev < *first)
   263             return false;
   264     }
   265 
   266     return true;
   267 }
   268 
   269 
   270 // type used to exercise that algorithms do not apply operators
   271 // to function objects the latter are not required to define
   272 struct conv_to_bool {
   273 
   274     static conv_to_bool make (bool val) {
   275         conv_to_bool tmp;
   276         tmp.val_ = val;
   277         return tmp;
   278     }
   279 
   280     operator bool () const {
   281         return val_;
   282     }
   283 
   284 public:
   285     bool operator!() const
   286     	{
   287     	return val_ != 0;
   288     	}                  // not defined
   289 
   290     bool val_;
   291 };
   292 
   293 // not defined
   294 void operator&& (const conv_to_bool&, bool);
   295 void operator&& (bool, const conv_to_bool&);
   296 void operator|| (const conv_to_bool&, bool);
   297 void operator|| (bool, const conv_to_bool&);
   298 
   299 // element-type prototypes to exercise container requirements
   300 
   301 
   302 // meets requirements listed at 25, p7
   303 template <class T>
   304 struct predicate {
   305     conv_to_bool operator() (const T &a) const {
   306         _RWSTD_UNUSED (a);
   307         return conv_to_bool::make (true);
   308     }
   309 };
   310 
   311 
   312 // meets requirements listed at 25, p8
   313 template <class T>
   314 struct binary_predicate {
   315     conv_to_bool operator() (const T &a, const T &b) const {
   316         _RWSTD_UNUSED (a);
   317         _RWSTD_UNUSED (b);
   318         return conv_to_bool::make (true);
   319     }
   320 };
   321 
   322 
   323 // meets requirements listed at 25.2.3, p2
   324 template <class T>
   325 struct func {
   326     typedef T              argument_type;
   327     typedef argument_type& reference;
   328 
   329     reference operator() (const argument_type&) const {
   330         return _RWSTD_REINTERPRET_CAST (reference,
   331                    _RWSTD_CONST_CAST (func*, this)->dummy);
   332     }
   333 
   334 private:
   335     char dummy;
   336 };
   337 
   338 
   339 // meets requirements listed at 25.2.3, p2
   340 template <class T>
   341 struct binary_func {
   342     typedef T              argument_type;
   343     typedef argument_type& reference;
   344 
   345     reference operator() (const argument_type&, 
   346                           const argument_type&) const {
   347         return _RWSTD_REINTERPRET_CAST (reference,
   348                    _RWSTD_CONST_CAST (binary_func*, this)->dummy);
   349     }
   350 
   351 private:
   352     char dummy;
   353 };
   354 
   355 
   356 // a base-class to extend the requirements classes from
   357 
   358 enum { no_ctor = 0, def_ctor = 1, cpy_ctor = 2 };
   359 
   360 template <int c = no_ctor>
   361 struct base;
   362 
   363 
   364 template<>
   365 struct base<no_ctor>
   366 {
   367 private:
   368     // struct s added to prevent gcc warning: base<no_ctor> has a private
   369     // constructor and no friends
   370     struct s { };
   371     friend struct s;
   372 
   373     base ();
   374     base (const base&);
   375     void operator= (base&);
   376 };
   377 
   378 
   379 template<>
   380 struct base<def_ctor>
   381 {
   382     base () : unused (0) { }
   383 
   384 private:
   385 
   386     void operator= (base&);
   387     base (const base&);
   388 
   389     // unused member prevents bogus HP aCC warnings (see Onyx #23561)
   390     int unused;
   391 };
   392 
   393 
   394 template<>
   395 struct base<cpy_ctor>
   396 {
   397     // explicitly specifying redundant template parameters to work
   398     // around a SunPro 5.2 bug (see Onyx #24260)
   399     base (const base<cpy_ctor> &rhs): unused (rhs.unused) { }
   400 
   401 private:
   402 
   403     base ();
   404     void operator= (base&);
   405 
   406     // unused member prevents bogus HP aCC warnings (see Onyx #23561)
   407     int unused;
   408 };
   409 
   410 
   411 template<>
   412 struct base<(def_ctor | cpy_ctor)>
   413 {
   414     base (): unused (0) { }
   415 
   416     // explicitly specifying redundant template parameters to work
   417     // around a SunPro 5.2 bug (see Onyx #24260)
   418     base (const base<(def_ctor | cpy_ctor)> &rhs): unused (rhs.unused) { }
   419 
   420 private:
   421 
   422     void operator= (base&);
   423 
   424     // unused member prevents bogus HP aCC warnings (see Onyx #23561)
   425     int unused;
   426 };
   427 
   428 
   429 template <class T>
   430 struct eq_comp: T { };
   431 
   432 
   433 template <class T>
   434 inline bool operator== (const eq_comp<T>&, const eq_comp<T>&)
   435 {
   436     return true;
   437 }
   438 
   439 
   440 template <class T>
   441 struct lt_comp: T { };
   442 
   443 
   444 template <class T>
   445 inline bool operator< (const lt_comp<T>&, const lt_comp<T>&)
   446 {
   447     return true;
   448 }
   449 
   450 
   451 // assignment
   452 
   453 template <class T>
   454 struct assign : T
   455 {
   456     assign& operator= (const assign& rhs) {
   457         unused = rhs.unused;
   458         return *this;
   459     }
   460 private:
   461     // unused member prevents bogus HP aCC warnings (see Onyx #23561)
   462     int unused;
   463 };
   464 
   465 
   466 // conversion structs
   467 
   468 // struct split into 2 to eliminate the following g++ 2.95.2 warning:
   469 // warning: choosing `convert<T>::operator U&()' over 
   470 //                   `convert<T>::operator const U&() const'
   471 
   472 template <class T, class U>
   473 struct cvt : T 
   474 {
   475     operator U& () {
   476         return _RWSTD_REINTERPRET_CAST (U&, *this);
   477     }
   478 };
   479 
   480 
   481 template <class T, class U>
   482 struct const_cvt : T
   483 {
   484     operator const U& () const {
   485         return _RWSTD_REINTERPRET_CAST (const U&, *this);
   486     }
   487 };
   488 
   489 
   490 #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
   491 
   492 struct DummyBase { };
   493 
   494 #  define ITER_BASE(ign1, ign2, ign3, ign4, ign5) DummyBase
   495 #else   // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
   496    // when partial specialization isn't supported 
   497 #  define ITER_BASE(Cat, T, Dist, Ptr, Ref) \
   498           std::iterator<Cat, T, Dist, Ptr, Ref >
   499 #endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC
   500 
   501 
   502 // satisfies the requirements in 24.1.1 [lib.input.iterators]
   503 template <class T>
   504 struct InputIter: ITER_BASE (std::input_iterator_tag, T, int, T*, T&)
   505 {
   506     typedef T                       value_type;
   507     typedef value_type*             pointer;
   508     typedef value_type&             reference;
   509     typedef int                     difference_type;
   510     typedef std::input_iterator_tag iterator_category;
   511 
   512     // body shared by all copies of the same InputIter specialization
   513     // to detect algorithms that pass through the same interator more
   514     // than once (disallowed by 24.1.1, p3)
   515     struct Shared {
   516         const value_type *cur_;
   517         const value_type *beg_;
   518         const value_type *end_;
   519         int               ref_;
   520 
   521         Shared (const value_type *cur,
   522                 const value_type *beg,
   523                 const value_type *end)
   524             : cur_ (cur), beg_ (beg), end_ (end), ref_ (1) { }
   525 
   526         ~Shared () {
   527             cur_ = beg_ = end_ = 0;
   528             ref_ = -1;
   529         }
   530 
   531     private:
   532         Shared (const Shared&);           // not defined
   533         void operator= (const Shared&);   // not defined
   534 
   535     };
   536 
   537     // InputIterators are not default constructible
   538     InputIter (const value_type *cur,
   539                const value_type *beg,
   540                const value_type *end)
   541         : ptr_ (new Shared (cur, beg, end)), cur_ (cur) { }
   542 
   543     InputIter (const InputIter &rhs)
   544         : ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
   545         assert (0 != ptr_);
   546         ++ptr_->ref_;
   547     }
   548 
   549     ~InputIter () {
   550         assert (0 != ptr_);
   551 
   552         if (0 == --ptr_->ref_)   // decrement the reference count
   553             delete ptr_;
   554         ptr_ = 0;
   555         cur_ = 0;
   556     }
   557 
   558     InputIter& operator= (const InputIter &rhs) {
   559         assert (rhs == rhs);   // assert `rhs' is valid
   560 
   561         assert (0 != ptr_);
   562         if (0 == --ptr_->ref_)
   563             delete ptr_;
   564 
   565         ptr_ = rhs.ptr_;
   566 
   567         assert (0 != ptr_);
   568         ++ptr_->ref_;
   569 
   570         cur_ = rhs.cur_;
   571 
   572         return *this;
   573     }
   574 
   575     bool operator== (const InputIter &rhs) const {
   576         // assert that both arguments are in the domain of operator==()
   577         // i.e., that no copy of *this or `rhs' has been incremented
   578         // and that no copy passed through this value of the iterator
   579 
   580         assert (0 != ptr_);
   581         assert (cur_ == ptr_->cur_);
   582 
   583         assert (0 != rhs.ptr_);
   584         assert (rhs.cur_ == rhs.ptr_->cur_);
   585 
   586         return cur_ == rhs.cur_;
   587     }
   588 
   589     bool operator!= (const InputIter &rhs) const {
   590         return !(*this == rhs);
   591     }
   592 
   593     // returning const-reference rather than a value in order
   594     // not to impose the CopyConstructible requirement on T
   595     // and to disallow constructs like *InputIter<T>() = T()
   596     const value_type& operator* () const {
   597         assert (*this == *this);      // assert *this is valid
   598         assert (cur_ < ptr_->end_);   // assert *this is dereferenceable
   599         return *cur_;
   600     }
   601 
   602     _RWSTD_OPERATOR_ARROW(const value_type* operator-> () const);
   603 
   604     InputIter& operator++ () {
   605         assert (*this == *this);      // assert *this is valid
   606         assert (cur_ < ptr_->end_);   // assert *this is not past the end
   607 
   608         ptr_->cur_ = ++cur_;
   609 
   610         return *this;
   611     }
   612 
   613     InputIter operator++ (int) {
   614         return ++*this;
   615     }
   616 
   617 // private:
   618     Shared           *ptr_;
   619     const value_type *cur_;   // past-the-end
   620 };
   621 
   622 
   623 // satisfies the requirements in 24.1.2 [lib.output.iterators]
   624 template <class T>
   625 struct OutputIter: ITER_BASE (std::output_iterator_tag, T, int, T*, T&)
   626 {
   627     typedef T                        value_type;
   628     typedef value_type*              pointer;
   629     typedef value_type&              reference;
   630     typedef int                      difference_type;
   631     typedef std::output_iterator_tag iterator_category;
   632 
   633     // body shared by all copies of the same OutputIter specialization
   634     // to detect algorithms that pass through the same interator more
   635     // than once (disallowed by 24.1.2, p2)
   636     struct Shared {
   637         pointer           cur_;
   638         pointer           assign_;
   639         const value_type *begin_;
   640         const value_type *end_;
   641         int               ref_;
   642 
   643         Shared (pointer cur, const value_type *end)
   644             : cur_ (cur), assign_ (cur), begin_ (cur), end_ (end), ref_ (1) { }
   645 
   646         ~Shared () {
   647             begin_ = end_ = cur_ = assign_ = 0;
   648             ref_ = -1;
   649         }
   650 
   651     private:
   652         Shared (const Shared&);           // not defined
   653         void operator= (const Shared&);   // not defined
   654 
   655     };
   656 
   657     // class whose objects are returned from OutputIter::operator*
   658     // to detect multiple assignments (disallowed by 24.1.2, p2)
   659     class Proxy {
   660         friend struct OutputIter;
   661 
   662         Shared* const ptr_;
   663 
   664         Proxy (Shared *ptr): ptr_ (ptr) { }
   665 
   666     public:
   667         void operator= (const value_type &rhs) {
   668             assert (0 != ptr_);
   669 
   670             // verify that the iterator is in the valid range
   671             assert (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ <= ptr_->end_);
   672 
   673             // verify that the assignment point is the same as the current
   674             // position `cur' within the sequence or immediately before it
   675             // (in order to allow the expression: *it++ = val)
   676             assert (   ptr_->assign_ == ptr_->cur_
   677                     || ptr_->assign_ + 1 == ptr_->cur_);
   678 
   679             // assign and increment the assignment point
   680             *ptr_->assign_++ = rhs;
   681         }
   682     };
   683 
   684     // OutputIterators are not default constructible
   685     OutputIter (pointer           cur,
   686                 const value_type *,
   687                 const value_type *end)
   688         : ptr_ (new Shared (cur, end)), cur_ (cur) { }
   689 
   690     OutputIter (const OutputIter &rhs)
   691         : ptr_ (rhs.ptr_), cur_ (rhs.cur_) {
   692         ++ptr_->ref_;   // increment the reference count
   693     }
   694 
   695     ~OutputIter () {
   696         if (0 == --ptr_->ref_)   // decrement the reference count
   697             delete ptr_;
   698         ptr_ = 0;
   699         cur_ = 0;
   700     }
   701 
   702     OutputIter& operator= (const OutputIter &rhs) {
   703         if (0 == --ptr_->ref_)
   704             delete ptr_;
   705 
   706         ptr_ = rhs.ptr_;
   707         ++ptr_->ref_;
   708 
   709         cur_ = rhs.cur_;
   710 
   711         return *this;
   712     }
   713 
   714     void operator= (const value_type &rhs) const {
   715         **this = rhs;
   716     }
   717 
   718     // return a proxy in order to detect multiple assignments
   719     // through the iterator (disallowed by 24.1.2, p2))
   720     Proxy operator* () const {
   721         assert (0 != ptr_);
   722         assert (ptr_->assign_ && ptr_->assign_ != ptr_->end_);
   723 
   724         return Proxy (ptr_);
   725     }
   726 
   727     _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
   728 
   729     OutputIter& operator++ () {
   730         assert (cur_ == ptr_->cur_);
   731         assert (ptr_->cur_ >= ptr_->begin_ && ptr_->cur_ < ptr_->end_);
   732         cur_ = ++ptr_->cur_;
   733         return *this;
   734     }
   735 
   736     // returning a const value rather than a modifiable value
   737     // in order to verify the requirement in row 5 of Table 73
   738     const OutputIter operator++ (int) {
   739         OutputIter tmp (*this);
   740         return ++*this, tmp;
   741     }
   742 
   743 // private:
   744     Shared  *ptr_;
   745     pointer  cur_;
   746 };
   747 
   748 
   749 // satisfies the requirements in 24.1.3 [lib.forward.iterators]
   750 template <class T>
   751 struct FwdIter: ITER_BASE (std::forward_iterator_tag, T, int, T*, T&)
   752 {
   753     typedef T                         value_type;
   754     typedef value_type*               pointer;
   755     typedef value_type&               reference;
   756     typedef int                       difference_type;
   757     typedef std::forward_iterator_tag iterator_category;
   758 
   759     FwdIter (): cur_ (0), end_ (0) { }
   760 
   761     FwdIter (pointer           cur,
   762              const value_type *,
   763              const value_type *end)
   764         : cur_ (cur), end_ (end) { }
   765 
   766     FwdIter (const FwdIter &rhs)
   767         : cur_ (rhs.cur_), end_ (rhs.end_) { }
   768 
   769     ~FwdIter () {
   770         end_ = cur_ = 0;
   771     }
   772 
   773     FwdIter& operator= (const FwdIter &rhs) {
   774         cur_ = rhs.cur_;
   775         end_ = rhs.end_;
   776         return *this;
   777     }
   778 
   779     bool operator== (const FwdIter &rhs) const {
   780         assert (cur_ != 0);
   781         return cur_ == rhs.cur_;
   782     }
   783 
   784     bool operator!= (const FwdIter &rhs) const {
   785         return !(*this == rhs);
   786     }
   787 
   788     reference operator* () const {
   789         assert (cur_ != 0 && cur_ != end_);
   790         return *cur_;
   791     }
   792 
   793     _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
   794 
   795     FwdIter& operator++ () {
   796         assert (cur_ != 0 && cur_ != end_);
   797         return ++cur_, *this;
   798     }
   799 
   800     FwdIter operator++ (int) {
   801         FwdIter tmp (*this);
   802         return ++*this, tmp;
   803     }
   804 
   805 // private:
   806     pointer           cur_;   // pointer to current element
   807     const value_type *end_;   // past-the-end
   808 };
   809 
   810 
   811 template <class T>
   812 struct ConstFwdIter: FwdIter<T>
   813 {
   814     typedef T                   value_type;
   815     typedef FwdIter<value_type> Base;
   816 
   817     ConstFwdIter (): Base () { }
   818 
   819     ConstFwdIter (const value_type *cur,
   820                   const value_type *begin,
   821                   const value_type *end)
   822         : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
   823 
   824     const value_type& operator* () const {
   825         return Base::operator* ();
   826     }
   827 
   828     _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
   829 };
   830 
   831 
   832 // satisfies the requirements in 24.1.4 [lib.bidirectional.iterators]
   833 template <class T>
   834 struct BidirIter: ITER_BASE (std::bidirectional_iterator_tag, T, int, T*, T&)
   835 {
   836     typedef T                               value_type;
   837     typedef value_type*                     pointer;
   838     typedef value_type&                     reference;
   839     typedef int                             difference_type;
   840     typedef std::bidirectional_iterator_tag iterator_category;
   841 
   842     BidirIter (): cur_ (0), begin_ (0), end_ (0) { }
   843 
   844     BidirIter (pointer           cur,
   845                const value_type *begin,
   846                const value_type *end)
   847         : cur_ (cur), begin_ (begin), end_ (end) { }
   848 
   849     BidirIter (const BidirIter &rhs)
   850         : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }
   851 
   852     ~BidirIter () {
   853         begin_ = end_ = cur_ = 0;
   854     }
   855 
   856     BidirIter& operator= (const BidirIter &rhs) { 
   857         cur_ = rhs.cur_;
   858         end_ = rhs.end_;
   859         return *this; 
   860     }
   861 
   862     bool operator== (const BidirIter &rhs) const {
   863         assert (cur_ != 0 && rhs.cur_ != 0);
   864         return cur_ == rhs.cur_;
   865     }
   866 
   867     bool operator!= (const BidirIter &rhs) const {
   868         return !(*this == rhs);
   869     }
   870 
   871     reference operator* () const {
   872         assert (cur_ != 0 && cur_ != end_);
   873         return *cur_;
   874     }
   875 
   876     _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
   877 
   878     BidirIter& operator++ () {
   879         assert (cur_ != 0 && cur_ != end_);
   880         return ++cur_, *this;
   881     }
   882 
   883     BidirIter operator++ (int) {
   884         BidirIter tmp (*this);
   885         return ++*this, tmp;
   886     }
   887 
   888     BidirIter& operator-- () {
   889         assert (cur_ != 0 && cur_ != begin_);
   890         return --cur_, *this;
   891     }
   892 
   893     BidirIter operator-- (int) {
   894         BidirIter tmp (*this);
   895         return --*this, tmp;
   896     }
   897 
   898 // private:
   899     pointer           cur_;     // pointer to current element
   900     const value_type *begin_;   // first in range
   901     const value_type *end_;     // past-the-end
   902 };
   903 
   904 
   905 template <class T>
   906 struct ConstBidirIter: BidirIter<T>
   907 {
   908     typedef T                     value_type;
   909     typedef BidirIter<value_type> Base;
   910 
   911     ConstBidirIter (): Base () { }
   912 
   913     ConstBidirIter (const value_type *cur,
   914                     const value_type *begin,
   915                     const value_type *end)
   916         : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
   917 
   918     const value_type& operator* () const {
   919         return Base::operator* ();
   920     }
   921 
   922     _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
   923 };
   924 
   925 
   926 // satisfies the requirements in 24.1.5 [lib.random.access.iterators]
   927 template <class T>
   928 struct RandomAccessIter
   929     : ITER_BASE (std::random_access_iterator_tag, T, int, T*, T&)
   930 {
   931     typedef T                               value_type;
   932     typedef value_type*                     pointer;
   933     typedef value_type&                     reference;
   934     typedef int                             difference_type;
   935     typedef std::random_access_iterator_tag iterator_category;
   936 
   937     RandomAccessIter (): cur_ (0), begin_ (0), end_ (0) { }
   938 
   939     RandomAccessIter (pointer           cur,
   940                       const value_type *begin,
   941                       const value_type *end)
   942         : cur_ (cur), begin_ (begin), end_ (end) { }
   943 
   944     RandomAccessIter (const RandomAccessIter &rhs)
   945         : cur_ (rhs.cur_), begin_ (rhs.begin_), end_ (rhs.end_) { }
   946 
   947     ~RandomAccessIter () {
   948         begin_ = end_ = cur_ = 0;
   949     }
   950 
   951     RandomAccessIter& operator= (const RandomAccessIter &rhs) {
   952         cur_   = rhs.cur_;
   953         begin_ = rhs.begin_;
   954         end_   = rhs.end_;
   955         return *this; 
   956     }
   957 
   958     reference operator* () const {
   959         assert (cur_ != 0 && cur_ != end_);
   960         return *cur_;
   961     }
   962 
   963     _RWSTD_OPERATOR_ARROW (pointer operator-> () const);
   964 
   965     RandomAccessIter& operator++ () {
   966         assert (cur_ != 0 && cur_ != end_);
   967         return ++cur_, *this;
   968     }
   969 
   970     RandomAccessIter operator++ (int) {
   971         RandomAccessIter tmp (*this);
   972         return ++*this, tmp;
   973     }
   974 
   975     RandomAccessIter& operator-- () {
   976         assert (cur_ != 0 && cur_ != begin_);
   977         return --cur_, *this;
   978     }
   979 
   980     RandomAccessIter operator-- (int) {
   981         RandomAccessIter tmp (*this);
   982         return --*this, tmp;
   983     }
   984 
   985     RandomAccessIter& operator+= (difference_type n) {
   986         assert (   cur_ != 0
   987                 && (!end_ || cur_ + n <= end_)
   988                 && (!begin_ || cur_ + n >= begin_));
   989         return cur_ += n, *this;
   990     }
   991     RandomAccessIter& operator-= (difference_type n) {
   992         return *this += -n;
   993     }
   994 
   995     RandomAccessIter operator+ (difference_type n) const {
   996         return RandomAccessIter (*this) += n;
   997     }
   998 
   999     RandomAccessIter operator- (difference_type n) const {
  1000         return RandomAccessIter (*this) -= n;
  1001     }
  1002 
  1003     difference_type operator- (const RandomAccessIter &rhs) const { 
  1004         assert (cur_ != 0 && rhs.cur_ != 0);
  1005         return cur_ - rhs.cur_;
  1006     }
  1007 
  1008     bool operator== (const RandomAccessIter &rhs) const {
  1009         assert (cur_ != 0 && rhs.cur_ != 0);
  1010         return cur_ == rhs.cur_;
  1011     }
  1012 
  1013     bool operator!= (const RandomAccessIter &rhs) const {
  1014         return !(*this == rhs);
  1015     }
  1016 
  1017     bool operator< (const RandomAccessIter &rhs) const {
  1018         assert (cur_ != 0 && rhs.cur_ != 0);
  1019         return cur_ < rhs.cur_;
  1020     };
  1021 
  1022     bool operator> (const RandomAccessIter &rhs) const {
  1023         return rhs < *this;
  1024     }
  1025 
  1026     bool operator<= (const RandomAccessIter &rhs) const {
  1027         return !(rhs < *this);
  1028     }
  1029 
  1030     bool operator>= (const RandomAccessIter &rhs) const {
  1031         return !(*this < rhs);
  1032     }
  1033 
  1034     reference operator[] (difference_type inx) const { 
  1035         assert (   cur_ != 0
  1036                 && (!end_ || cur_ + inx < end_)
  1037                 && !(begin_ || cur_ + inx >= begin_));
  1038         return cur_ [inx];
  1039     }
  1040 
  1041 // private:
  1042     pointer           cur_;     // pointer to current element
  1043     const value_type *begin_;   // first in range
  1044     const value_type *end_;     // past-the-end
  1045 };
  1046 
  1047 
  1048 template <class T>
  1049 struct ConstRandomAccessIter: RandomAccessIter<T>
  1050 {
  1051     typedef T                              value_type;
  1052     typedef RandomAccessIter<value_type>   Base;
  1053     typedef typename Base::difference_type difference_type;
  1054 
  1055     ConstRandomAccessIter (): Base () { }
  1056 
  1057     ConstRandomAccessIter (const value_type *cur,
  1058                            const value_type *begin,
  1059                            const value_type *end)
  1060         : Base (_RWSTD_CONST_CAST (value_type*, cur), begin, end) { }
  1061 
  1062     const value_type& operator* () const {
  1063         return Base::operator* ();
  1064     }
  1065 
  1066     _RWSTD_OPERATOR_ARROW (const value_type* operator-> () const);
  1067 
  1068     const value_type& operator[] (difference_type inx) const {
  1069         return Base::operator[] (inx);
  1070     }
  1071 };
  1072 
  1073 
  1074 template <class T>
  1075 inline T*
  1076 make_iter (T *cur, const T*, const T*, T*)
  1077 {
  1078     return cur;
  1079 }
  1080 
  1081 template <class T>
  1082 inline T*
  1083 copy_iter (T *ptr, const T*)
  1084 {
  1085     return ptr;
  1086 }
  1087 
  1088 // dummy function argument provided to help broken compilers (PR #29835)
  1089 
  1090 template <class T>
  1091 inline InputIter<T>
  1092 make_iter (const T *cur, const T *begin, const T *end, const InputIter<T>&)
  1093 {
  1094     return InputIter<T>(cur, begin, end);
  1095 }
  1096 
  1097 template <class T>
  1098 inline InputIter<T>
  1099 copy_iter (const InputIter<T> &it, const T*)
  1100 {
  1101     return InputIter<T>(it.cur_, it.ptr_->beg_, it.ptr_->end_);
  1102 }
  1103 
  1104 template <class T>
  1105 inline const char* type_name (InputIter<T>, const T*)
  1106 { return "InputIterator"; }
  1107 
  1108 
  1109 template <class T>
  1110 inline OutputIter<T>
  1111 make_iter (T *cur, const T *begin, const T *end, const OutputIter<T>&)
  1112 {
  1113     return OutputIter<T>(cur, begin, end);
  1114 }
  1115 
  1116 template <class T>
  1117 inline OutputIter<T>
  1118 copy_iter (const OutputIter<T> &it, const T*)
  1119 {
  1120     return OutputIter<T>(it.cur_, 0, it.ptr_->end);
  1121 }
  1122 
  1123 template <class T>
  1124 inline const char* type_name (OutputIter<T>, const T*)
  1125 { return "OutputIterator"; }
  1126 
  1127 
  1128 template <class T>
  1129 inline FwdIter<T>
  1130 make_iter (T *cur, const T *begin, const T *end, FwdIter<T>)
  1131 {
  1132     return FwdIter<T>(cur, begin, end);
  1133 }
  1134 
  1135 template <class T>
  1136 inline FwdIter<T>
  1137 copy_iter (const FwdIter<T> &it, const T*)
  1138 {
  1139     return FwdIter<T>(it.cur_, 0, it.end_);
  1140 }
  1141 
  1142 template <class T>
  1143 inline const char* type_name (FwdIter<T>, const T*)
  1144 { return "ForwardIterator"; }
  1145 
  1146 
  1147 template <class T>
  1148 inline ConstFwdIter<T>
  1149 make_iter (T *cur, const T *begin, const T *end, ConstFwdIter<T>)
  1150 {
  1151     return ConstFwdIter<T>(cur, begin, end);
  1152 }
  1153 
  1154 template <class T>
  1155 inline ConstFwdIter<T>
  1156 copy_iter (const ConstFwdIter<T> &it, const T*)
  1157 {
  1158     return ConstFwdIter<T>(it.cur_, 0, it.end_);
  1159 }
  1160 
  1161 template <class T>
  1162 inline const char* type_name (ConstFwdIter<T>, const T*)
  1163 { return "ConstForwardIterator"; }
  1164 
  1165 
  1166 template <class T>
  1167 inline BidirIter<T>
  1168 make_iter (T *cur, const T *begin, const T *end, BidirIter<T>)
  1169 {
  1170     return BidirIter<T>(cur, begin, end);
  1171 }
  1172 
  1173 template <class T>
  1174 inline BidirIter<T>
  1175 copy_iter (const BidirIter<T> &it, const T*)
  1176 {
  1177     return BidirIter<T>(it.cur_, it.begin_, it.end_);
  1178 }
  1179 
  1180 template <class T>
  1181 inline const char* type_name (BidirIter<T>, const T*)
  1182 { return "BidirectionalIterator"; }
  1183 
  1184 
  1185 template <class T>
  1186 inline ConstBidirIter<T>
  1187 make_iter (T *cur, const T *begin, const T *end, ConstBidirIter<T>)
  1188 {
  1189     return ConstBidirIter<T>(cur, begin, end);
  1190 }
  1191 
  1192 template <class T>
  1193 inline ConstBidirIter<T>
  1194 copy_iter (const ConstBidirIter<T> &it, const T*)
  1195 {
  1196     return ConstBidirIter<T>(it.cur_, it.begin_, it.end_);
  1197 }
  1198 
  1199 template <class T>
  1200 inline const char* type_name (ConstBidirIter<T>, const T*)
  1201 { return "ConstBidirectionalIterator"; }
  1202 
  1203 
  1204 template <class T>
  1205 inline RandomAccessIter<T>
  1206 make_iter (T *cur, const T *begin, const T *end, RandomAccessIter<T>)
  1207 {
  1208     return RandomAccessIter<T>(cur, begin, end);
  1209 }
  1210 
  1211 template <class T>
  1212 inline RandomAccessIter<T>
  1213 copy_iter (const RandomAccessIter<T> &it, const T*)
  1214 {
  1215     return RandomAccessIter<T>(it.cur_, it.begin_, it.end_);
  1216 }
  1217 
  1218 template <class T>
  1219 inline const char* type_name (RandomAccessIter<T>, const T*)
  1220 { return "RandomAccessIterator"; }
  1221 
  1222 
  1223 template <class T>
  1224 inline ConstRandomAccessIter<T>
  1225 make_iter (T *cur, const T *begin, const T *end, ConstRandomAccessIter<T>)
  1226 {
  1227     return ConstRandomAccessIter<T>(cur, begin, end);
  1228 }
  1229 
  1230 template <class T>
  1231 inline ConstRandomAccessIter<T>
  1232 copy_iter (const ConstRandomAccessIter<T> &it, const T*)
  1233 {
  1234     return ConstRandomAccessIter<T>(it.cur_, it.begin_, it.end_);
  1235 }
  1236 
  1237 template <class T>
  1238 inline const char* type_name (ConstRandomAccessIter<T>, const T*)
  1239 { return "ConstRandomAccessIterator"; }
  1240 
  1241 typedef int (*fptr_gen_)();
  1242 
  1243 //exporting fun for exporting global var
  1244 _TEST_EXPORT    _RWSTD_SIZE_T* Getn_total_op_assign_();
  1245 _TEST_EXPORT    _RWSTD_SIZE_T* Getn_total_op_eq_();
  1246 _TEST_EXPORT      fptr_gen_* Get_gen_();
  1247 #endif   // _RWSTD_ALG_TEST_H_INCLUDED