Author: sebor Date: Mon Feb 27 16:48:26 2006 New Revision: 381511 URL: http://svn.apache.org/viewcvs?rev=381511&view=rev Log: 2006-02-27 Martin Sebor * alg_test.h: Added support for arithmetic self-assignment operators to allow class X to be used in tests for numeric algorithms. * alg_test.cpp: Definitions of the above. (_rw_fmtxarrayv): Recognized and handled the '+' flag to force only numeric formatting. Modified: incubator/stdcxx/trunk/tests/include/alg_test.h incubator/stdcxx/trunk/tests/src/alg_test.cpp Modified: incubator/stdcxx/trunk/tests/include/alg_test.h URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/include/alg_test.h?rev=381511&r1=381510&r2=381511&view=diff ============================================================================== --- incubator/stdcxx/trunk/tests/include/alg_test.h (original) +++ incubator/stdcxx/trunk/tests/include/alg_test.h Mon Feb 27 16:48:26 2006 @@ -47,6 +47,22 @@ // regardless of whether the operation threw an exception or not _RWSTD_SIZE_T n_op_assign_; + // number of times the object's operator+=() has been invoked, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_op_plus_assign_; + + // number of times the object's operator-=() has been invoked, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_op_minus_assign_; + + // number of times the object's operator*=() has been invoked, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_op_times_assign_; + + // number of times the object's operator/=() has been invoked, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_op_div_assign_; + // number of times the object's operator== was invoked // regardless of whether the operation threw an exception _RWSTD_SIZE_T n_op_eq_; @@ -63,6 +79,10 @@ static _RWSTD_SIZE_T n_total_copy_ctor_; // ... copy ctors ... static _RWSTD_SIZE_T n_total_dtor_; // ... dtors ... static _RWSTD_SIZE_T n_total_op_assign_; // ... assignment operators ... + static _RWSTD_SIZE_T n_total_op_plus_assign_; // ... operator+= + static _RWSTD_SIZE_T n_total_op_minus_assign_; // ... operator-= + static _RWSTD_SIZE_T n_total_op_times_assign_; // ... operator*= + static _RWSTD_SIZE_T n_total_op_div_assign_; // ... operator/= static _RWSTD_SIZE_T n_total_op_eq_; // ... equality operators ... static _RWSTD_SIZE_T n_total_op_lt_; // ... operators <= ... @@ -72,6 +92,10 @@ struct CopyCtor: Exception { }; struct Dtor: Exception { }; struct OpAssign: Exception { }; + struct OpPlusAssign: Exception { }; + struct OpMinusAssign: Exception { }; + struct OpTimesAssign: Exception { }; + struct OpDivAssign: Exception { }; struct OpEq: Exception { }; struct OpLt: Exception { }; @@ -82,6 +106,10 @@ static _RWSTD_SIZE_T* copy_ctor_throw_ptr_; static _RWSTD_SIZE_T* dtor_throw_ptr_; static _RWSTD_SIZE_T* op_assign_throw_ptr_; + static _RWSTD_SIZE_T* op_plus_assign_throw_ptr_; + static _RWSTD_SIZE_T* op_minus_assign_throw_ptr_; + static _RWSTD_SIZE_T* op_times_assign_throw_ptr_; + static _RWSTD_SIZE_T* op_div_assign_throw_ptr_; static _RWSTD_SIZE_T* op_eq_throw_ptr_; static _RWSTD_SIZE_T* op_lt_throw_ptr_; @@ -90,6 +118,10 @@ static _RWSTD_SIZE_T copy_ctor_throw_count_; static _RWSTD_SIZE_T dtor_throw_count_; static _RWSTD_SIZE_T op_assign_throw_count_; + static _RWSTD_SIZE_T op_plus_assign_throw_count_; + static _RWSTD_SIZE_T op_minus_assign_throw_count_; + static _RWSTD_SIZE_T op_times_assign_throw_count_; + static _RWSTD_SIZE_T op_div_assign_throw_count_; static _RWSTD_SIZE_T op_eq_throw_count_; static _RWSTD_SIZE_T op_lt_throw_count_; @@ -100,6 +132,10 @@ ~X (); X& operator= (const X&); + X& operator+= (const X&); + X& operator-= (const X&); + X& operator*= (const X&); + X& operator/= (const X&); bool operator== (const X&) const; bool operator< (const X&) const; @@ -152,6 +188,15 @@ // returns -1 when less, 0 when same, or +1 when the first // array of X objects is greater than the second array static int compare (const X*, const X*, _RWSTD_SIZE_T); + +private: + + enum assign_op { + op_assign, op_plus_assign, op_minus_assign, + op_times_assign, op_div_assign + }; + + void assign (assign_op, const X&); }; /**************************************************************************/ Modified: incubator/stdcxx/trunk/tests/src/alg_test.cpp URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/src/alg_test.cpp?rev=381511&r1=381510&r2=381511&view=diff ============================================================================== --- incubator/stdcxx/trunk/tests/src/alg_test.cpp (original) +++ incubator/stdcxx/trunk/tests/src/alg_test.cpp Mon Feb 27 16:48:26 2006 @@ -40,24 +40,46 @@ /* 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_plus_assign_; +/* static */ size_t X::n_total_op_minus_assign_; +/* static */ size_t X::n_total_op_times_assign_; +/* static */ size_t X::n_total_op_div_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_; +/* 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_plus_assign_throw_ptr_ = + &X::op_plus_assign_throw_count_; +/* static */ size_t* X::op_minus_assign_throw_ptr_ = + &X::op_minus_assign_throw_count_; +/* static */ size_t* X::op_times_assign_throw_ptr_ = + &X::op_times_assign_throw_count_; +/* static */ size_t* X::op_div_assign_throw_ptr_ = + &X::op_div_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); +/* 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_plus_assign_throw_count_ = size_t (-1); +/* static */ size_t X::op_minus_assign_throw_count_ = size_t (-1); +/* static */ size_t X::op_times_assign_throw_count_ = size_t (-1); +/* static */ size_t X::op_div_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); static int @@ -159,31 +181,87 @@ } -X& -X::operator= (const X &rhs) +void X:: +assign (assign_op which, const X &rhs) { - // verify id validity and uniqueness + // verify id validity and uniqueness: + // a valid id is non-zero (dtor resets) RW_ASSERT (id_ && id_ <= id_gen_); RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_); + + // no two id's have the same value RW_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_; + size_t *p_total_op = 0; + size_t *p_op = 0; + size_t *p_throw = 0; + + Exception *pex = 0; + + OpAssign ex_assign; + OpPlusAssign ex_plus_assign; + OpMinusAssign ex_minus_assign; + OpTimesAssign ex_times_assign; + OpDivAssign ex_div_assign; + + int new_val; + + switch (which) { + case op_assign: + p_total_op = &n_total_op_assign_; + p_op = &n_op_assign_; + p_throw = op_assign_throw_ptr_; + pex = &ex_assign; + new_val = rhs.val_; + break; + + case op_plus_assign: + p_total_op = &n_total_op_plus_assign_; + p_op = &n_op_plus_assign_; + p_throw = op_plus_assign_throw_ptr_; + pex = &ex_plus_assign; + new_val = val_ + rhs.val_; + break; + + case op_minus_assign: + p_total_op = &n_total_op_minus_assign_; + p_op = &n_op_minus_assign_; + p_throw = op_minus_assign_throw_ptr_; + pex = &ex_minus_assign; + new_val = val_ - rhs.val_; + break; + + case op_times_assign: + p_total_op = &n_total_op_times_assign_; + p_op = &n_op_times_assign_; + p_throw = op_times_assign_throw_ptr_; + pex = &ex_times_assign; + new_val = val_ * rhs.val_; + break; + + case op_div_assign: + p_total_op = &n_total_op_div_assign_; + p_op = &n_op_div_assign_; + p_throw = op_div_assign_throw_ptr_; + pex = &ex_div_assign; + new_val = val_ / rhs.val_; + break; + } - // increment the number of times the object has been assigned to + // increment the number of invocations of the operator // (do so even if the function throws an exception below) - ++n_op_assign_; + + ++*p_total_op; + ++*p_op; #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; + if (p_throw && *p_throw == *p_total_op) { + pex->id_ = id_; + throw *pex; } #endif // _RWSTD_NO_EXCEPTIONS @@ -193,7 +271,50 @@ origin_ = rhs.origin_; src_id_ = rhs.id_; - val_ = rhs.val_; + val_ = new_val; +} + + +X& X:: +operator= (const X &rhs) +{ + assign (op_assign, rhs); + + return *this; +} + + +X& X:: +operator+= (const X &rhs) +{ + assign (op_plus_assign, rhs); + + return *this; +} + + +X& X:: +operator-= (const X &rhs) +{ + assign (op_minus_assign, rhs); + + return *this; +} + + +X& X:: +operator*= (const X &rhs) +{ + assign (op_times_assign, rhs); + + return *this; +} + + +X& X:: +operator/= (const X &rhs) +{ + assign (op_div_assign, rhs); return *this; } @@ -605,13 +726,14 @@ RW_ASSERT (0 != fmt); va_list* pva = 0; + bool fl_plus = false; bool fl_pound = false; int nelems = -1; int paramno = -1; int cursor = -1; // directive syntax: - // "X=" [ '#' ] [ '*' | ] [ '.' [ '*' | ] ] + // "X=" [ '#' ] [ '+' ] [ '*' | ] [ '.' [ '*' | ] ] if ('X' != fmt [0] || '=' != fmt [1]) @@ -619,7 +741,14 @@ fmt += 2; + if ('+' == *fmt) { + // use numerical formatting for X::val_ + fl_plus = true; + ++fmt; + } + if ('#' == *fmt) { + // include X::id_ in output fl_pound = true; ++fmt; } @@ -703,11 +832,16 @@ for (const X *px = xbeg; px != xbeg + nelems; ++px) { const int n = rw_asnprintf (pbuf, pbufsize, - "%{+}%{?}>%{;}%{?}%d:%{;}%{lc}%{?}<%{;}", - px - xbeg == cursor, // '>' - fl_pound, px->id_, // ":" - px->val_, // - px - xbeg == cursor); // '<' + "%{+}%{?}>%{;}" + "%{?}%d:%{;}" + "%{?}%d%{?},%{;}%{:}%{lc}%{;}" + "%{?}<%{;}", + px - xbeg == cursor, // '>' + fl_pound, px->id_, // ":" + fl_plus, px->val_, // + px + 1 < xbeg + nelems, // ',' + px->val_, // + px - xbeg == cursor); // '<' if (n < 0) return n;