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 <[EMAIL PROTECTED]>
* 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=" [ '#' ] [ '*' | <n> ] [ '.' [ '*' | <n> ] ]
+ // "X=" [ '#' ] [ '+' ] [ '*' | <n> ] [ '.' [ '*' | <n> ] ]
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_, // "<id>:"
- px->val_, // <val>
- px - xbeg == cursor); // '<'
+ "%{+}%{?}>%{;}"
+ "%{?}%d:%{;}"
+ "%{?}%d%{?},%{;}%{:}%{lc}%{;}"
+ "%{?}<%{;}",
+ px - xbeg == cursor, // '>'
+ fl_pound, px->id_, // "<id>:"
+ fl_plus, px->val_, // <val>
+ px + 1 < xbeg + nelems, // ','
+ px->val_, // <val>
+ px - xbeg == cursor); // '<'
if (n < 0)
return n;