stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/alg_test.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /************************************************************************
       
     2  *
       
     3  * alg_test.cpp - definitions of class X members
       
     4  *
       
     5  * $Id: alg_test.cpp 349035 2005-11-25 23:17:58Z 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 // expand _TEST_EXPORT macros
       
    23 #define _RWSTD_TEST_SRC
       
    24 
       
    25 #include <stddef.h>     // for size_t
       
    26 #include <stdlib.h>     // for rand()
       
    27 #include <string.h>     // for strlen()
       
    28 #include <ctype.h>      // for toupper()
       
    29 
       
    30 #include <alg_test.h>
       
    31 
       
    32 
       
    33 #ifdef _RWSTDDEBUG
       
    34    // use own assertion mechanism for better diagnostic output
       
    35 #  undef assert
       
    36 #  define assert(expr) _RWSTD_ASSERT(expr)
       
    37 #else
       
    38 #  include <assert.h>     // for assert()
       
    39 #endif   // _RWSTDDEBUG
       
    40 
       
    41 
       
    42 /* static */ size_t X::count_;
       
    43 /* static */ int    X::id_gen_;   // generates unique non-zero ids
       
    44 /* static */ int  (*X::_gen_)() ;   // extern "C++" int (*)()
       
    45 
       
    46 /* static */ size_t X::n_total_def_ctor_;
       
    47 /* static */ size_t X::n_total_copy_ctor_;
       
    48 /* static */ size_t X::n_total_dtor_;
       
    49 /* static */ size_t X::_n_total_op_assign_ ;
       
    50 /* static */ size_t X::_n_total_op_eq_;
       
    51 /* static */ size_t X::n_total_op_lt_;
       
    52 
       
    53 // default values of pointers
       
    54 /* static */ size_t* X::def_ctor_throw_ptr_  = &X::def_ctor_throw_count_;
       
    55 /* static */ size_t* X::copy_ctor_throw_ptr_ = &X::copy_ctor_throw_count_;
       
    56 /* static */ size_t* X::dtor_throw_ptr_      = &X::dtor_throw_count_;
       
    57 /* static */ size_t* X::op_assign_throw_ptr_ = &X::op_assign_throw_count_;
       
    58 /* static */ size_t* X::op_eq_throw_ptr_     = &X::op_eq_throw_count_;
       
    59 /* static */ size_t* X::op_lt_throw_ptr_     = &X::op_lt_throw_count_;
       
    60 
       
    61 // exception throwing initially disabled
       
    62 /* static */ size_t X::def_ctor_throw_count_  = size_t (-1);
       
    63 /* static */ size_t X::copy_ctor_throw_count_ = size_t (-1);
       
    64 /* static */ size_t X::dtor_throw_count_      = size_t (-1);
       
    65 /* static */ size_t X::op_assign_throw_count_ = size_t (-1);
       
    66 /* static */ size_t X::op_eq_throw_count_     = size_t (-1);
       
    67 /* static */ size_t X::op_lt_throw_count_     = size_t (-1);
       
    68 
       
    69 
       
    70 X::X ()
       
    71     : id_ (++id_gen_), origin_ (id_), src_id_ (id_), val_ (0),
       
    72       n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0)
       
    73 {
       
    74     // increment the total number of invocations of the default ctor
       
    75     // (do so even if the function throws an exception below)
       
    76     ++n_total_def_ctor_;
       
    77 
       
    78 #ifndef _RWSTD_NO_EXCEPTIONS
       
    79 
       
    80     if (def_ctor_throw_ptr_ && n_total_def_ctor_ == *def_ctor_throw_ptr_) {
       
    81         DefCtor ex;
       
    82         ex.id_ = id_;
       
    83         throw ex;
       
    84     }
       
    85 
       
    86 #endif   // _RWSTD_NO_EXCEPTIONS
       
    87 
       
    88     // initialize the object's value
       
    89     if (_gen_)
       
    90         val_ = _gen_ ();
       
    91 
       
    92     // increment the number of successfully constructed objects
       
    93     ++count_;
       
    94 }
       
    95 
       
    96 
       
    97 X::X (const X &rhs)
       
    98     : id_ (++id_gen_), origin_ (rhs.origin_), src_id_ (rhs.id_),
       
    99       val_ (rhs.val_),
       
   100       n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0)
       
   101 {
       
   102     // verify id validity
       
   103     assert (rhs.id_ && rhs.id_ < id_gen_);
       
   104 
       
   105     // increment the number of times `rhs' has been copied
       
   106     // (do so even if the function throws an exception below)
       
   107     ++_RWSTD_CONST_CAST (X*, &rhs)->n_copy_ctor_;
       
   108 
       
   109     // increment the total number of invocations of the copy ctor
       
   110     // (do so even if the function throws an exception below)
       
   111     ++n_total_copy_ctor_;
       
   112 
       
   113 #ifndef _RWSTD_NO_EXCEPTIONS
       
   114 
       
   115     // throw an exception if the number of calls
       
   116     // to the copy ctor reaches the given value
       
   117     if (copy_ctor_throw_ptr_ && n_total_copy_ctor_ == *copy_ctor_throw_ptr_) {
       
   118         CopyCtor ex;
       
   119         ex.id_ = id_;
       
   120         throw ex;
       
   121     }
       
   122 
       
   123 #endif   // _RWSTD_NO_EXCEPTIONS
       
   124 
       
   125     // increment the number of successfully constructed objects
       
   126     ++count_;
       
   127 }
       
   128 
       
   129 
       
   130 X::~X ()
       
   131 {
       
   132     // verify id validity
       
   133     assert (id_ && id_ <= id_gen_);
       
   134 
       
   135     // increment the total number of invocations of the dtor
       
   136     // (do so even if the function throws an exception below)
       
   137     ++n_total_dtor_;
       
   138 
       
   139 #ifndef _RWSTD_NO_EXCEPTIONS
       
   140 
       
   141     // throw an exception if the number of calls
       
   142     // to the class dtor reaches the given value
       
   143     if (dtor_throw_ptr_ && n_total_dtor_ == *dtor_throw_ptr_) {
       
   144         Dtor ex;
       
   145         ex.id_ = id_;
       
   146         throw ex;
       
   147     }
       
   148 
       
   149 #endif   // _RWSTD_NO_EXCEPTIONS
       
   150 
       
   151     // decrement the number of objects in existence
       
   152     --count_;
       
   153 
       
   154     // invalidate id
       
   155     _RWSTD_CONST_CAST (int&, this->id_) = 0;
       
   156 }
       
   157 
       
   158 
       
   159 X&
       
   160 X::operator= (const X &rhs)
       
   161 {
       
   162     // verify id validity and uniqueness
       
   163     assert (id_ && id_ <= id_gen_);
       
   164     assert (rhs.id_ && rhs.id_ <= id_gen_);
       
   165     assert (this == &rhs || id_ != rhs.id_);
       
   166 
       
   167     // increment the total number of invocations of the operator
       
   168     // (do so even if the function throws an exception below)
       
   169     ++n_total_op_assign_;
       
   170 
       
   171     // increment the number of times the object has been assigned to
       
   172     // (do so even if the function throws an exception below)
       
   173     ++n_op_assign_;
       
   174 
       
   175 #ifndef _RWSTD_NO_EXCEPTIONS
       
   176 
       
   177     // throw an exception if the number of calls to
       
   178     // the assignment operator reaches the given value
       
   179 
       
   180     if (op_assign_throw_ptr_ && n_total_op_assign_ == *op_assign_throw_ptr_) {
       
   181         OpAssign ex;
       
   182         ex.id_ = id_;
       
   183         throw ex;
       
   184     }
       
   185 
       
   186 #endif   // _RWSTD_NO_EXCEPTIONS
       
   187 
       
   188     // overwrite value and source id only when the operation
       
   189     // is successful (i.e., only when it doesn't throw)
       
   190 
       
   191     origin_ = rhs.origin_;
       
   192     src_id_ = rhs.id_;
       
   193     val_    = rhs.val_;
       
   194 
       
   195     return *this;
       
   196 }
       
   197 
       
   198 
       
   199 bool
       
   200 X::operator== (const X &rhs) const
       
   201 {
       
   202     // verify id validity and uniqueness
       
   203     assert (id_ && id_ <= id_gen_);
       
   204     assert (rhs.id_ && rhs.id_ <= id_gen_);
       
   205     assert (this == &rhs || id_ != rhs.id_);
       
   206 
       
   207     // increment the number of times each distinct object
       
   208     // has been used as the argument to operator==
       
   209     // (do so even if the function throws an exception below)
       
   210     ++_RWSTD_CONST_CAST (X*, this)->n_op_eq_;
       
   211 
       
   212     if (this != &rhs)
       
   213         ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_eq_;
       
   214 
       
   215     // increment the total number of invocations of the operator
       
   216     // (do so even if the function throws an exception below)
       
   217     ++n_total_op_eq_;
       
   218 
       
   219 #ifndef _RWSTD_NO_EXCEPTIONS
       
   220 
       
   221     // throw an exception if the number of calls
       
   222     // to operator== reaches the given value
       
   223 
       
   224     if (op_eq_throw_ptr_ && n_total_op_eq_ == *op_eq_throw_ptr_) {
       
   225         OpEq ex;
       
   226         ex.id_ = id_;
       
   227         throw ex;
       
   228     }
       
   229 
       
   230 #endif   // _RWSTD_NO_EXCEPTIONS
       
   231 
       
   232     return val_ == rhs.val_;
       
   233 }
       
   234 
       
   235 
       
   236 bool
       
   237 X::operator< (const X &rhs) const
       
   238 {
       
   239     // verify id validity and uniqueness
       
   240     assert (id_ && id_ <= id_gen_);
       
   241     assert (rhs.id_ && rhs.id_ <= id_gen_);
       
   242     assert (this == &rhs || id_ != rhs.id_);
       
   243 
       
   244     // increment the number of times each distinct object
       
   245     // has been used as the argument to operator<
       
   246     // (do so even if the function throws an exception below)
       
   247     ++_RWSTD_CONST_CAST (X*, this)->n_op_lt_;
       
   248 
       
   249     if (this != &rhs)
       
   250         ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_lt_;
       
   251 
       
   252     // increment the total number of invocations of the operator
       
   253     // (do so even if the function throws an exception below)
       
   254     ++n_total_op_lt_;
       
   255 
       
   256 #ifndef _RWSTD_NO_EXCEPTIONS
       
   257 
       
   258     // throw an exception if the number of calls
       
   259     // to operator== reaches the given value
       
   260 
       
   261     if (op_lt_throw_ptr_ && n_total_op_lt_ == *op_lt_throw_ptr_) {
       
   262         OpLt ex;
       
   263         ex.id_ = id_;
       
   264         throw ex;
       
   265     }
       
   266 
       
   267 #endif   // _RWSTD_NO_EXCEPTIONS
       
   268 
       
   269     return val_ < rhs.val_;
       
   270 }
       
   271 
       
   272 
       
   273 bool X::
       
   274 is_count (size_t n_copy_ctor,
       
   275           size_t n_op_assign,
       
   276           size_t n_op_eq,
       
   277           size_t n_op_lt) const
       
   278 {
       
   279     // verify id validity
       
   280     assert (id_ && id_ <= id_gen_);
       
   281 
       
   282     return    (size_t (-1) == n_copy_ctor || n_copy_ctor_ == n_copy_ctor)
       
   283            && (size_t (-1) == n_op_assign || n_op_assign_ == n_op_assign)
       
   284            && (size_t (-1) == n_op_eq     || n_op_eq_     == n_op_eq)
       
   285            && (size_t (-1) == n_op_lt     || n_op_lt_     == n_op_lt);
       
   286 }
       
   287 
       
   288 
       
   289 /* static */ bool X::
       
   290 is_total (size_t cnt,
       
   291           size_t n_def_ctor,
       
   292           size_t n_copy_ctor,
       
   293           size_t n_op_assign,
       
   294           size_t n_op_eq,
       
   295           size_t n_op_lt)
       
   296 {
       
   297     return    (size_t (-1) == cnt         || count_             == cnt)
       
   298            && (size_t (-1) == n_def_ctor  || n_total_def_ctor_  == n_def_ctor)
       
   299            && (size_t (-1) == n_copy_ctor || n_total_copy_ctor_ == n_copy_ctor)
       
   300            && (size_t (-1) == n_op_assign || n_total_op_assign_ == n_op_assign)
       
   301            && (size_t (-1) == n_op_eq     || n_total_op_eq_     == n_op_eq)
       
   302            && (size_t (-1) == n_op_lt     || n_total_op_lt_     == n_op_lt);
       
   303 }
       
   304 
       
   305 
       
   306 /* static  void
       
   307 X::reset_totals ()
       
   308 {
       
   309     n_total_def_ctor_  =
       
   310     n_total_copy_ctor_ =
       
   311     n_total_dtor_      =
       
   312     n_total_op_assign_ =
       
   313     n_total_op_eq_     =
       
   314     n_total_op_lt_     = 0;
       
   315 }*/
       
   316 
       
   317 
       
   318 typedef unsigned char UChar;
       
   319 
       
   320 // used to initialize an array of objects of type X
       
   321 static const char *xinit_begin;
       
   322 
       
   323 static int xinit ()
       
   324 {
       
   325     if (xinit_begin)
       
   326         return UChar (*xinit_begin++);
       
   327 
       
   328     return 0;
       
   329 }
       
   330 
       
   331 
       
   332 /* static */ X*
       
   333 X::from_char (const char *str, size_t len /* = -1 */)
       
   334 {
       
   335     // handle null pointers
       
   336     if (!str)
       
   337         return 0;
       
   338 
       
   339     // compute the length of the character array if not specified
       
   340     if (size_t (-1) == len)
       
   341         len = strlen (str);
       
   342 
       
   343     // set the global pointer to point to the beginning of `str'
       
   344     xinit_begin = str;
       
   345 
       
   346     // save the previous pointer to the initializer function
       
   347     int (*gen_save)() = X::_gen_;
       
   348 
       
   349     // set the generating function
       
   350     X::_gen_ = xinit;
       
   351 
       
   352     X *array = 0;
       
   353 
       
   354     _TRY {
       
   355         // allocate and construct `len' elements, initializing
       
   356         // each from the character array `str' (via `xinit')
       
   357         array = new X [len];
       
   358     }
       
   359     _CATCH (...) {
       
   360 
       
   361         // restore the original initializer function and rethrow
       
   362         X::_gen_ = gen_save;
       
   363 
       
   364         _RETHROW;
       
   365     }
       
   366 
       
   367     // restore the original initializer function
       
   368     X::_gen_ = gen_save;
       
   369 
       
   370     return array;
       
   371 }
       
   372 
       
   373 _TEST_EXPORT
       
   374 /* static */ int
       
   375 X::compare (const X *x, const char *str, size_t len /* = -1 */)
       
   376 {
       
   377     if (!str)
       
   378         return x == 0;
       
   379 
       
   380     if (size_t (-1) == len)
       
   381         len = strlen (str);
       
   382 
       
   383     for (size_t i = 0; i != len; ++i) {
       
   384 
       
   385         const int val = UChar (str [i]);
       
   386 
       
   387         if (val != x [i].val_)
       
   388             return x [i].val_ - val;
       
   389     }
       
   390 
       
   391     return 0;
       
   392 }
       
   393 
       
   394 _TEST_EXPORT
       
   395 /* static */ int
       
   396 X::compare (const char *str, const X *x, size_t len /* = -1 */)
       
   397 {
       
   398     return -X::compare (x, str, len);
       
   399 }
       
   400 
       
   401 _TEST_EXPORT
       
   402 /* static */ int
       
   403 X::compare (const X *x, const X *y, size_t count)
       
   404 {
       
   405     for (size_t i = 0; i != count; ++i) {
       
   406         if (x [i].val_ != y [i].val_)
       
   407             return x [i].val_ - y [i].val_;
       
   408     }
       
   409 
       
   410     return 0;
       
   411 }
       
   412 
       
   413 
       
   414 /* static */ size_t UnaryPredicate::n_total_op_fcall_;
       
   415 
       
   416 _TEST_EXPORT
       
   417 UnaryPredicate::
       
   418 UnaryPredicate ()
       
   419 {
       
   420     // no-op
       
   421 }
       
   422 
       
   423 _TEST_EXPORT
       
   424 UnaryPredicate::
       
   425 UnaryPredicate (const UnaryPredicate&)
       
   426 {
       
   427     // no-op
       
   428 }
       
   429 
       
   430 _TEST_EXPORT
       
   431 UnaryPredicate& UnaryPredicate::
       
   432 operator= (const UnaryPredicate&)
       
   433 {
       
   434     return *this;
       
   435 }
       
   436 
       
   437 _TEST_EXPORT
       
   438 /* virtual */ UnaryPredicate::~UnaryPredicate ()
       
   439 {
       
   440     // no-op
       
   441 }
       
   442 
       
   443 _TEST_EXPORT
       
   444 /* virtual */ bool UnaryPredicate::
       
   445 operator()(const X&) const
       
   446 {
       
   447     ++n_total_op_fcall_;
       
   448 
       
   449     return true;
       
   450 }
       
   451 
       
   452 
       
   453 /* static */ size_t BinaryPredicate::n_total_op_fcall_;
       
   454 
       
   455 _TEST_EXPORT
       
   456  BinaryPredicate::
       
   457 BinaryPredicate (bool ignore_case)
       
   458     : ignore_case_ (ignore_case)
       
   459 {
       
   460     // no-op
       
   461 }
       
   462 
       
   463 
       
   464 BinaryPredicate::
       
   465 BinaryPredicate (const BinaryPredicate &rhs)
       
   466     : ignore_case_ (rhs.ignore_case_)
       
   467 {
       
   468     // no-op
       
   469 }
       
   470 
       
   471 
       
   472  _TEST_EXPORT BinaryPredicate& BinaryPredicate::
       
   473 operator= (const BinaryPredicate &rhs)
       
   474 {
       
   475     ignore_case_ = rhs.ignore_case_;
       
   476     return *this;
       
   477 }
       
   478 
       
   479 
       
   480 _TEST_EXPORT /* virtual */ BinaryPredicate::~BinaryPredicate ()
       
   481 {
       
   482     // no-op
       
   483 }
       
   484 
       
   485 
       
   486 _TEST_EXPORT /* virtual */ bool BinaryPredicate::
       
   487  operator()(const X &lhs, const X &rhs) const
       
   488 {
       
   489     ++n_total_op_fcall_;
       
   490 
       
   491     if (lhs == rhs)
       
   492         return true;
       
   493 
       
   494     if (ignore_case_) {
       
   495 
       
   496         const int lval = lhs.val_;
       
   497         const int rval = rhs.val_;
       
   498 
       
   499         if (   lval < 0 || lval > int (_RWSTD_UCHAR_MAX)
       
   500             || rval < 0 || rval > int (_RWSTD_UCHAR_MAX))
       
   501             return false;
       
   502 
       
   503         const int lup = toupper (lval);
       
   504         const int rup = toupper (rval);
       
   505 
       
   506         return _RWSTD_EOF != lup && lup == rup;
       
   507     }
       
   508 
       
   509     return false;
       
   510 }
       
   511 
       
   512 
       
   513 // generate a unique sequential number starting from 0
       
   514 _TEST_EXPORT int gen_seq ()
       
   515 {
       
   516     static int val;
       
   517 
       
   518     return ++val;
       
   519 }
       
   520 
       
   521 
       
   522 // generate numbers in the sequence 0, 0, 1, 1, 2, 2, 3, 3, etc... 
       
   523 _TEST_EXPORT int gen_seq_2lists ()
       
   524 {
       
   525     static int vals [2];
       
   526 
       
   527     return vals [0] += ++vals [1] % 2;
       
   528 }
       
   529 
       
   530 
       
   531 // generate a sequence of subsequences (i.e., 0, 1, 2, 3, 4, 0, 1, 2, etc...)
       
   532 _TEST_EXPORT int gen_subseq ()
       
   533 {
       
   534     static int val;
       
   535 
       
   536     return val++ % 5;
       
   537 }
       
   538 
       
   539 
       
   540 // wrapper around a (possibly) extern "C" int rand()
       
   541 // extern "C++" 
       
   542 _TEST_EXPORT int gen_rnd ()
       
   543 {
       
   544     return rand ();
       
   545 }
       
   546 //defination of fun 
       
   547 _TEST_EXPORT    _RWSTD_SIZE_T* Getn_total_op_assign_()
       
   548 	{
       
   549 	return &X::_n_total_op_assign_;
       
   550 	}
       
   551 
       
   552 _TEST_EXPORT    _RWSTD_SIZE_T* Getn_total_op_eq_()
       
   553 	{
       
   554 	return &X::_n_total_op_eq_;
       
   555 	}
       
   556 _TEST_EXPORT    fptr_gen_*  Get_gen_()
       
   557 	{
       
   558 	return &(X::_gen_) ;
       
   559 	}