diff -r 000000000000 -r e4d67989cc36 stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/alg_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/alg_test.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,559 @@ +/************************************************************************ + * + * alg_test.cpp - definitions of class X members + * + * $Id: alg_test.cpp 349035 2005-11-25 23:17:58Z sebor $ + * + ************************************************************************ + * + * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave + * Software division. Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. Unless required by + * applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under + * the License. + * + **************************************************************************/ + +// expand _TEST_EXPORT macros +#define _RWSTD_TEST_SRC + +#include // for size_t +#include // for rand() +#include // for strlen() +#include // for toupper() + +#include + + +#ifdef _RWSTDDEBUG + // use own assertion mechanism for better diagnostic output +# undef assert +# define assert(expr) _RWSTD_ASSERT(expr) +#else +# include // for assert() +#endif // _RWSTDDEBUG + + +/* static */ size_t X::count_; +/* static */ int X::id_gen_; // generates unique non-zero ids +/* static */ int (*X::_gen_)() ; // extern "C++" int (*)() + +/* static */ size_t X::n_total_def_ctor_; +/* static */ size_t X::n_total_copy_ctor_; +/* static */ size_t X::n_total_dtor_; +/* static */ size_t X::_n_total_op_assign_ ; +/* static */ size_t X::_n_total_op_eq_; +/* static */ size_t X::n_total_op_lt_; + +// default values of pointers +/* static */ size_t* X::def_ctor_throw_ptr_ = &X::def_ctor_throw_count_; +/* static */ size_t* X::copy_ctor_throw_ptr_ = &X::copy_ctor_throw_count_; +/* static */ size_t* X::dtor_throw_ptr_ = &X::dtor_throw_count_; +/* static */ size_t* X::op_assign_throw_ptr_ = &X::op_assign_throw_count_; +/* static */ size_t* X::op_eq_throw_ptr_ = &X::op_eq_throw_count_; +/* static */ size_t* X::op_lt_throw_ptr_ = &X::op_lt_throw_count_; + +// exception throwing initially disabled +/* static */ size_t X::def_ctor_throw_count_ = size_t (-1); +/* static */ size_t X::copy_ctor_throw_count_ = size_t (-1); +/* static */ size_t X::dtor_throw_count_ = size_t (-1); +/* static */ size_t X::op_assign_throw_count_ = size_t (-1); +/* static */ size_t X::op_eq_throw_count_ = size_t (-1); +/* static */ size_t X::op_lt_throw_count_ = size_t (-1); + + +X::X () + : id_ (++id_gen_), origin_ (id_), src_id_ (id_), val_ (0), + n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0) +{ + // increment the total number of invocations of the default ctor + // (do so even if the function throws an exception below) + ++n_total_def_ctor_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + if (def_ctor_throw_ptr_ && n_total_def_ctor_ == *def_ctor_throw_ptr_) { + DefCtor ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + // initialize the object's value + if (_gen_) + val_ = _gen_ (); + + // increment the number of successfully constructed objects + ++count_; +} + + +X::X (const X &rhs) + : id_ (++id_gen_), origin_ (rhs.origin_), src_id_ (rhs.id_), + val_ (rhs.val_), + n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0) +{ + // verify id validity + assert (rhs.id_ && rhs.id_ < id_gen_); + + // increment the number of times `rhs' has been copied + // (do so even if the function throws an exception below) + ++_RWSTD_CONST_CAST (X*, &rhs)->n_copy_ctor_; + + // increment the total number of invocations of the copy ctor + // (do so even if the function throws an exception below) + ++n_total_copy_ctor_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + // throw an exception if the number of calls + // to the copy ctor reaches the given value + if (copy_ctor_throw_ptr_ && n_total_copy_ctor_ == *copy_ctor_throw_ptr_) { + CopyCtor ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + // increment the number of successfully constructed objects + ++count_; +} + + +X::~X () +{ + // verify id validity + assert (id_ && id_ <= id_gen_); + + // increment the total number of invocations of the dtor + // (do so even if the function throws an exception below) + ++n_total_dtor_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + // throw an exception if the number of calls + // to the class dtor reaches the given value + if (dtor_throw_ptr_ && n_total_dtor_ == *dtor_throw_ptr_) { + Dtor ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + // decrement the number of objects in existence + --count_; + + // invalidate id + _RWSTD_CONST_CAST (int&, this->id_) = 0; +} + + +X& +X::operator= (const X &rhs) +{ + // verify id validity and uniqueness + assert (id_ && id_ <= id_gen_); + assert (rhs.id_ && rhs.id_ <= id_gen_); + assert (this == &rhs || id_ != rhs.id_); + + // increment the total number of invocations of the operator + // (do so even if the function throws an exception below) + ++n_total_op_assign_; + + // increment the number of times the object has been assigned to + // (do so even if the function throws an exception below) + ++n_op_assign_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + // throw an exception if the number of calls to + // the assignment operator reaches the given value + + if (op_assign_throw_ptr_ && n_total_op_assign_ == *op_assign_throw_ptr_) { + OpAssign ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + // overwrite value and source id only when the operation + // is successful (i.e., only when it doesn't throw) + + origin_ = rhs.origin_; + src_id_ = rhs.id_; + val_ = rhs.val_; + + return *this; +} + + +bool +X::operator== (const X &rhs) const +{ + // verify id validity and uniqueness + assert (id_ && id_ <= id_gen_); + assert (rhs.id_ && rhs.id_ <= id_gen_); + assert (this == &rhs || id_ != rhs.id_); + + // increment the number of times each distinct object + // has been used as the argument to operator== + // (do so even if the function throws an exception below) + ++_RWSTD_CONST_CAST (X*, this)->n_op_eq_; + + if (this != &rhs) + ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_eq_; + + // increment the total number of invocations of the operator + // (do so even if the function throws an exception below) + ++n_total_op_eq_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + // throw an exception if the number of calls + // to operator== reaches the given value + + if (op_eq_throw_ptr_ && n_total_op_eq_ == *op_eq_throw_ptr_) { + OpEq ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + return val_ == rhs.val_; +} + + +bool +X::operator< (const X &rhs) const +{ + // verify id validity and uniqueness + assert (id_ && id_ <= id_gen_); + assert (rhs.id_ && rhs.id_ <= id_gen_); + assert (this == &rhs || id_ != rhs.id_); + + // increment the number of times each distinct object + // has been used as the argument to operator< + // (do so even if the function throws an exception below) + ++_RWSTD_CONST_CAST (X*, this)->n_op_lt_; + + if (this != &rhs) + ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_lt_; + + // increment the total number of invocations of the operator + // (do so even if the function throws an exception below) + ++n_total_op_lt_; + +#ifndef _RWSTD_NO_EXCEPTIONS + + // throw an exception if the number of calls + // to operator== reaches the given value + + if (op_lt_throw_ptr_ && n_total_op_lt_ == *op_lt_throw_ptr_) { + OpLt ex; + ex.id_ = id_; + throw ex; + } + +#endif // _RWSTD_NO_EXCEPTIONS + + return val_ < rhs.val_; +} + + +bool X:: +is_count (size_t n_copy_ctor, + size_t n_op_assign, + size_t n_op_eq, + size_t n_op_lt) const +{ + // verify id validity + assert (id_ && id_ <= id_gen_); + + return (size_t (-1) == n_copy_ctor || n_copy_ctor_ == n_copy_ctor) + && (size_t (-1) == n_op_assign || n_op_assign_ == n_op_assign) + && (size_t (-1) == n_op_eq || n_op_eq_ == n_op_eq) + && (size_t (-1) == n_op_lt || n_op_lt_ == n_op_lt); +} + + +/* static */ bool X:: +is_total (size_t cnt, + size_t n_def_ctor, + size_t n_copy_ctor, + size_t n_op_assign, + size_t n_op_eq, + size_t n_op_lt) +{ + return (size_t (-1) == cnt || count_ == cnt) + && (size_t (-1) == n_def_ctor || n_total_def_ctor_ == n_def_ctor) + && (size_t (-1) == n_copy_ctor || n_total_copy_ctor_ == n_copy_ctor) + && (size_t (-1) == n_op_assign || n_total_op_assign_ == n_op_assign) + && (size_t (-1) == n_op_eq || n_total_op_eq_ == n_op_eq) + && (size_t (-1) == n_op_lt || n_total_op_lt_ == n_op_lt); +} + + +/* static void +X::reset_totals () +{ + n_total_def_ctor_ = + n_total_copy_ctor_ = + n_total_dtor_ = + n_total_op_assign_ = + n_total_op_eq_ = + n_total_op_lt_ = 0; +}*/ + + +typedef unsigned char UChar; + +// used to initialize an array of objects of type X +static const char *xinit_begin; + +static int xinit () +{ + if (xinit_begin) + return UChar (*xinit_begin++); + + return 0; +} + + +/* static */ X* +X::from_char (const char *str, size_t len /* = -1 */) +{ + // handle null pointers + if (!str) + return 0; + + // compute the length of the character array if not specified + if (size_t (-1) == len) + len = strlen (str); + + // set the global pointer to point to the beginning of `str' + xinit_begin = str; + + // save the previous pointer to the initializer function + int (*gen_save)() = X::_gen_; + + // set the generating function + X::_gen_ = xinit; + + X *array = 0; + + _TRY { + // allocate and construct `len' elements, initializing + // each from the character array `str' (via `xinit') + array = new X [len]; + } + _CATCH (...) { + + // restore the original initializer function and rethrow + X::_gen_ = gen_save; + + _RETHROW; + } + + // restore the original initializer function + X::_gen_ = gen_save; + + return array; +} + +_TEST_EXPORT +/* static */ int +X::compare (const X *x, const char *str, size_t len /* = -1 */) +{ + if (!str) + return x == 0; + + if (size_t (-1) == len) + len = strlen (str); + + for (size_t i = 0; i != len; ++i) { + + const int val = UChar (str [i]); + + if (val != x [i].val_) + return x [i].val_ - val; + } + + return 0; +} + +_TEST_EXPORT +/* static */ int +X::compare (const char *str, const X *x, size_t len /* = -1 */) +{ + return -X::compare (x, str, len); +} + +_TEST_EXPORT +/* static */ int +X::compare (const X *x, const X *y, size_t count) +{ + for (size_t i = 0; i != count; ++i) { + if (x [i].val_ != y [i].val_) + return x [i].val_ - y [i].val_; + } + + return 0; +} + + +/* static */ size_t UnaryPredicate::n_total_op_fcall_; + +_TEST_EXPORT +UnaryPredicate:: +UnaryPredicate () +{ + // no-op +} + +_TEST_EXPORT +UnaryPredicate:: +UnaryPredicate (const UnaryPredicate&) +{ + // no-op +} + +_TEST_EXPORT +UnaryPredicate& UnaryPredicate:: +operator= (const UnaryPredicate&) +{ + return *this; +} + +_TEST_EXPORT +/* virtual */ UnaryPredicate::~UnaryPredicate () +{ + // no-op +} + +_TEST_EXPORT +/* virtual */ bool UnaryPredicate:: +operator()(const X&) const +{ + ++n_total_op_fcall_; + + return true; +} + + +/* static */ size_t BinaryPredicate::n_total_op_fcall_; + +_TEST_EXPORT + BinaryPredicate:: +BinaryPredicate (bool ignore_case) + : ignore_case_ (ignore_case) +{ + // no-op +} + + +BinaryPredicate:: +BinaryPredicate (const BinaryPredicate &rhs) + : ignore_case_ (rhs.ignore_case_) +{ + // no-op +} + + + _TEST_EXPORT BinaryPredicate& BinaryPredicate:: +operator= (const BinaryPredicate &rhs) +{ + ignore_case_ = rhs.ignore_case_; + return *this; +} + + +_TEST_EXPORT /* virtual */ BinaryPredicate::~BinaryPredicate () +{ + // no-op +} + + +_TEST_EXPORT /* virtual */ bool BinaryPredicate:: + operator()(const X &lhs, const X &rhs) const +{ + ++n_total_op_fcall_; + + if (lhs == rhs) + return true; + + if (ignore_case_) { + + const int lval = lhs.val_; + const int rval = rhs.val_; + + if ( lval < 0 || lval > int (_RWSTD_UCHAR_MAX) + || rval < 0 || rval > int (_RWSTD_UCHAR_MAX)) + return false; + + const int lup = toupper (lval); + const int rup = toupper (rval); + + return _RWSTD_EOF != lup && lup == rup; + } + + return false; +} + + +// generate a unique sequential number starting from 0 +_TEST_EXPORT int gen_seq () +{ + static int val; + + return ++val; +} + + +// generate numbers in the sequence 0, 0, 1, 1, 2, 2, 3, 3, etc... +_TEST_EXPORT int gen_seq_2lists () +{ + static int vals [2]; + + return vals [0] += ++vals [1] % 2; +} + + +// generate a sequence of subsequences (i.e., 0, 1, 2, 3, 4, 0, 1, 2, etc...) +_TEST_EXPORT int gen_subseq () +{ + static int val; + + return val++ % 5; +} + + +// wrapper around a (possibly) extern "C" int rand() +// extern "C++" +_TEST_EXPORT int gen_rnd () +{ + return rand (); +} +//defination of fun +_TEST_EXPORT _RWSTD_SIZE_T* Getn_total_op_assign_() + { + return &X::_n_total_op_assign_; + } + +_TEST_EXPORT _RWSTD_SIZE_T* Getn_total_op_eq_() + { + return &X::_n_total_op_eq_; + } +_TEST_EXPORT fptr_gen_* Get_gen_() + { + return &(X::_gen_) ; + }