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