ChangeLog: * rw_value.h: struct X renamed to the struct UserClass; (struct UserPOD): New type for using in tests as POD type; (struct UserData): New structure to be used in UserPOD and UserClass. (_rw_user_class_fmat_init): New static variable to install the formatting collback function for UserClass type. * value.cpp: Use UserClass::data_.val_ instead of UserClass::val_; (__rw_from_char): new function to create array of the UserXXX type from string; (_rw_mismatch): new function compare the array of the UserXXX type and string.
Farid.
3c3 < * rw_value.h - defines a User Defined type --- > * rw_value.h - defines a User Defined Class type and User Defined POD type 35c35,74 < // objects of class X maintain a count of their instances in existence, --- > /**************************************************************************/ > > struct UserData > { > int val_; // object's value > }; > > /**************************************************************************/ > > struct _TEST_EXPORT UserPOD > { > UserData data_; > > static UserPOD > from_char (char c) > { > UserPOD x; > x.data_.val_ = c; > return x; > } > > // construct an array of objects of type UserPOD each initialized > // from the corresponding element of the character array > // when the last argument is true and the character array > // is not sorted in ascending order the function fails by > // returning 0 > static UserPOD* > from_char (const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX, > bool = false); > > // returns a pointer to the first element in the sequence of UserClass > // whose value is not equal to the corresponding element of > // the character string or 0 when no such element exists > static const UserPOD* mismatch (const UserPOD*, const char*, > _RWSTD_SIZE_T /* len */ = > _RWSTD_SIZE_MAX); > }; > > /**************************************************************************/ > > // objects of class UserClass maintain a count of their instances in > existence, 38c77 < struct _TEST_EXPORT X --- > struct _TEST_EXPORT UserClass 40,46c79,126 < const int id_; // a unique non-zero id of the object < int origin_; // id of the original object that this < // is a (perhaps indirect) copy of (id_ < // when this is the original) < int src_id_; // id of the object that this is a direct < // copy of (id_ when this the original) < int val_; // object's value --- > UserData data_; > > // temporary to not break the tests which uses struct X > struct UserVal > { > UserData& data_; > > UserVal (UserData& data) : data_ (data) { } > > operator int () const > { > return data_.val_; > } > > UserVal& operator= (int val) > { > data_.val_ = val; > return *this; > } > > UserVal& operator+= (int val) > { > data_.val_ += val; > return *this; > } > > UserVal& operator-= (int val) > { > data_.val_ -= val; > return *this; > } > > UserVal& operator*= (int val) > { > data_.val_ *= val; > return *this; > } > }; > > // temporary to not break the tests which uses struct X > UserVal val_; > > const int id_; // a unique non-zero id of the object > int origin_; // id of the original object that this > // is a (perhaps indirect) copy of (id_ > // when this is the original) > int src_id_; // id of the object that this is a direct > // copy of (id_ when this the original) 134c214 < X (); --- > UserClass (); 136c216 < X (const X&); --- > UserClass (const UserClass&); 138c218 < ~X (); --- > ~UserClass (); 140,144c220,224 < X& operator= (const X&); < X& operator+= (const X&); < X& operator-= (const X&); < X& operator*= (const X&); < X& operator/= (const X&); --- > UserClass& operator= (const UserClass&); > UserClass& operator+= (const UserClass&); > UserClass& operator-= (const UserClass&); > UserClass& operator*= (const UserClass&); > UserClass& operator/= (const UserClass&); 146,147c226,227 < bool operator== (const X&) const; < bool operator< (const X&) const; --- > bool operator== (const UserClass&) const; > bool operator< (const UserClass&) const; 151,156c231,236 < // bool operator!= (const X &rhs) const; < // bool operator> (const X &rhs) const; < // bool operator>= (const X &rhs) const; < // bool operator<= (const X &rhs) const; < // X operator- () const; < // X operator+ () const; --- > // bool operator!= (const UserClass &rhs) const; > // bool operator> (const UserClass &rhs) const; > // bool operator>= (const UserClass &rhs) const; > // bool operator<= (const UserClass &rhs) const; > // UserClass operator- () const; > // UserClass operator+ () const; 175,176c255,256 < static const X* < first_less (const X*, _RWSTD_SIZE_T); --- > static const UserClass* > first_less (const UserClass*, _RWSTD_SIZE_T); 180c260,268 < // construct an array of objects of type X each initialized --- > static UserClass > from_char (char c) > { > UserClass x; > x.data_.val_ = c; > return x; > } > > // construct an array of objects of type UserClass each initialized 185c273 < static X* --- > static UserClass* 190,192c278,282 < // of X objects is greater than the character string < static int compare (const X*, const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX); < static int compare (const char*, const X*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX); --- > // of UserClass objects is greater than the character string > static int compare (const UserClass*, const char*, > _RWSTD_SIZE_T = _RWSTD_SIZE_MAX); > static int compare (const char*, const UserClass*, > _RWSTD_SIZE_T = _RWSTD_SIZE_MAX); 195,196c285,286 < // array of X objects is greater than the second array < static int compare (const X*, const X*, _RWSTD_SIZE_T); --- > // array of UserClass objects is greater than the second array > static int compare (const UserClass*, const UserClass*, _RWSTD_SIZE_T); 198c288 < // returns a pointer to the first element in the sequence of X --- > // returns a pointer to the first element in the sequence of UserClass 201c291,292 < static const X* mismatch (const X*, const char*, _RWSTD_SIZE_T); --- > static const UserClass* mismatch (const UserClass*, const char*, > _RWSTD_SIZE_T); 212c303 < void assign (assign_op, const X&); --- > void assign (assign_op, const UserClass&); 214a306,308 > // temporary to not break tests which uses struct X > typedef UserClass X; > 230c324 < virtual conv_to_bool operator()(const X&) const; --- > virtual conv_to_bool operator()(const UserClass&) const; 252c346 < virtual conv_to_bool operator()(const X&, const X&) /* non-const */; --- > virtual conv_to_bool operator()(const UserClass&, const UserClass&) /* > non-const */; 263c357 < struct X::Less: BinaryPredicate --- > struct UserClass::Less: BinaryPredicate 269a364,368 > > > static const struct _TEST_EXPORT UserClassFmatInit { > UserClassFmatInit (); > } _rw_user_class_fmat_init;
3c3 < * value.cpp - defines a User Defined type --- > * value.cpp - definitions of UserClass and UserPOD class members 38a39 > #include <rw_char.h> // for rw_expand() 42,55c43,56 < /* 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_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_; --- > /* static */ size_t UserClass::count_; > /* static */ int UserClass::id_gen_; // generates unique non-zero ids > /* static */ int (*UserClass::gen_)(); // extern "C++" int (*)() > > /* static */ size_t UserClass::n_total_def_ctor_; > /* static */ size_t UserClass::n_total_copy_ctor_; > /* static */ size_t UserClass::n_total_dtor_; > /* static */ size_t UserClass::n_total_op_assign_; > /* static */ size_t UserClass::n_total_op_plus_assign_; > /* static */ size_t UserClass::n_total_op_minus_assign_; > /* static */ size_t UserClass::n_total_op_times_assign_; > /* static */ size_t UserClass::n_total_op_div_assign_; > /* static */ size_t UserClass::n_total_op_eq_; > /* static */ size_t UserClass::n_total_op_lt_; 58,77c59,78 < /* 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_; --- > /* static */ size_t* UserClass::def_ctor_throw_ptr_ = > &UserClass::def_ctor_throw_count_; > /* static */ size_t* UserClass::copy_ctor_throw_ptr_ = > &UserClass::copy_ctor_throw_count_; > /* static */ size_t* UserClass::dtor_throw_ptr_ = > &UserClass::dtor_throw_count_; > /* static */ size_t* UserClass::op_assign_throw_ptr_ = > &UserClass::op_assign_throw_count_; > /* static */ size_t* UserClass::op_plus_assign_throw_ptr_ = > &UserClass::op_plus_assign_throw_count_; > /* static */ size_t* UserClass::op_minus_assign_throw_ptr_ = > &UserClass::op_minus_assign_throw_count_; > /* static */ size_t* UserClass::op_times_assign_throw_ptr_ = > &UserClass::op_times_assign_throw_count_; > /* static */ size_t* UserClass::op_div_assign_throw_ptr_ = > &UserClass::op_div_assign_throw_count_; > /* static */ size_t* UserClass::op_eq_throw_ptr_ = > &UserClass::op_eq_throw_count_; > /* static */ size_t* UserClass::op_lt_throw_ptr_ = > &UserClass::op_lt_throw_count_; 80,89c81,90 < /* 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 */ size_t UserClass::def_ctor_throw_count_ = size_t (-1); > /* static */ size_t UserClass::copy_ctor_throw_count_ = size_t (-1); > /* static */ size_t UserClass::dtor_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_assign_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_plus_assign_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_minus_assign_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_times_assign_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_div_assign_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_eq_throw_count_ = size_t (-1); > /* static */ size_t UserClass::op_lt_throw_count_ = size_t (-1); 92,97c93,94 < static int < _rw_fmtxarray (char**, size_t*, const char*, ...); < < < X::X () < : id_ (++id_gen_), origin_ (id_), src_id_ (id_), val_ (0), --- > UserClass::UserClass () > : data_ (), val_ (data_), id_ (++id_gen_), origin_ (id_), src_id_ (id_), 100,105d96 < // push a new formatter function on top of the stack < // of user-defined formatting callbacks invoked by < // rw_printf() at al to process extended directives < static int format_init = rw_printf ("%{+!}", _rw_fmtxarray); < _RWSTD_UNUSED (format_init); < 122c113 < val_ = gen_ (); --- > data_.val_ = gen_ (); 129,131c120,122 < X::X (const X &rhs) < : id_ (++id_gen_), origin_ (rhs.origin_), src_id_ (rhs.id_), < val_ (rhs.val_), --- > UserClass::UserClass (const UserClass &rhs) > : data_ (rhs.data_), val_(data_), id_ (++id_gen_), origin_ (rhs.origin_), > src_id_ (rhs.id_), 139c130 < ++_RWSTD_CONST_CAST (X*, &rhs)->n_copy_ctor_; --- > ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_copy_ctor_; 162c153 < X::~X () --- > UserClass::~UserClass () 191,192c182,183 < void X:: < assign (assign_op which, const X &rhs) --- > void UserClass:: > assign (assign_op which, const UserClass &rhs) 222c213 < new_val = rhs.val_; --- > new_val = rhs.data_.val_; 230c221 < new_val = val_ + rhs.val_; --- > new_val = data_.val_ + rhs.data_.val_; 238c229 < new_val = val_ - rhs.val_; --- > new_val = data_.val_ - rhs.data_.val_; 246c237 < new_val = val_ * rhs.val_; --- > new_val = data_.val_ * rhs.data_.val_; 254c245 < new_val = val_ / rhs.val_; --- > new_val = data_.val_ / rhs.data_.val_; 281c272 < val_ = new_val; --- > data_.val_ = new_val; 285,286c276,277 < X& X:: < operator= (const X &rhs) --- > UserClass& UserClass:: > operator= (const UserClass &rhs) 294,295c285,286 < X& X:: < operator+= (const X &rhs) --- > UserClass& UserClass:: > operator+= (const UserClass &rhs) 303,304c294,295 < X& X:: < operator-= (const X &rhs) --- > UserClass& UserClass:: > operator-= (const UserClass &rhs) 312,313c303,304 < X& X:: < operator*= (const X &rhs) --- > UserClass& UserClass:: > operator*= (const UserClass &rhs) 321,322c312,313 < X& X:: < operator/= (const X &rhs) --- > UserClass& UserClass:: > operator/= (const UserClass &rhs) 331c322 < X::operator== (const X &rhs) const --- > UserClass::operator== (const UserClass &rhs) const 341c332 < ++_RWSTD_CONST_CAST (X*, this)->n_op_eq_; --- > ++_RWSTD_CONST_CAST (UserClass*, this)->n_op_eq_; 344c335 < ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_eq_; --- > ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_op_eq_; 363c354 < return val_ == rhs.val_; --- > return data_.val_ == rhs.data_.val_; 368c359 < X::operator< (const X &rhs) const --- > UserClass::operator< (const UserClass &rhs) const 378c369 < ++_RWSTD_CONST_CAST (X*, this)->n_op_lt_; --- > ++_RWSTD_CONST_CAST (UserClass*, this)->n_op_lt_; 381c372 < ++_RWSTD_CONST_CAST (X*, &rhs)->n_op_lt_; --- > ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_op_lt_; 400c391 < return val_ < rhs.val_; --- > return data_.val_ < rhs.data_.val_; 404c395 < bool X:: --- > bool UserClass:: 420c411 < /* static */ bool X:: --- > /* static */ bool UserClass:: 437,438c428,429 < /* static */ const X* < X::first_less (const X *xarray, size_t nelems) --- > /* static */ const UserClass* > UserClass::first_less (const UserClass *xarray, size_t nelems) 454c445 < X::reset_totals () --- > UserClass::reset_totals () 467c458 < // used to initialize an array of objects of type X --- > // used to initialize an array of objects of type UserClass 479,480c470,472 < /* static */ X* < X::from_char (const char *str, size_t len /* = -1 */, bool sorted /* = false */) --- > template <class T> > static T* > __rw_from_char (T*, const char *str, size_t len, bool sorted) 486,488c478,481 < // compute the length of the character array if not specified < if (size_t (-1) == len) < len = strlen (str); --- > // expand source string > char str_buf_ [256]; > size_t strlen_ = sizeof (str_buf_); > const char* const str_ = rw_expand (str_buf_, str, len, &strlen_); 492,493c485,488 < for (size_t i = 1; i < len; ++i) { < if (str [i] < str [i - 1]) { --- > for (size_t i = 1; i < strlen_; ++i) { > if (str_ [i] < str_ [i - 1]) { > if (str_buf_ != str_) > delete[] str_; 499,508c494 < // 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; --- > T*array = 0; 511,513c497 < // allocate and construct `len' elements, initializing < // each from the character array `str' (via `xinit') < array = new X [len]; --- > array = new T [strlen_]; 517,518c501,502 < // restore the original initializer function and rethrow < X::gen_ = gen_save; --- > if (str_buf_ != str_) > delete[] str_; 523,524c507,513 < // restore the original initializer function < X::gen_ = gen_save; --- > typedef unsigned char UChar; > > for (size_t i = 0; i < strlen_; ++i) > array [i].data_.val_ = UChar (str_ [i]); > > if (str_buf_ != str_) > delete[] str_; 530,531c519,521 < /* static */ const X* < X::mismatch (const X *xarray, const char *str, size_t len /* = -1 */) --- > template <class T> > static const T* > __rw_mismatch (const T *xarray, const char *str, size_t len) 543c533 < if (val != xarray [i].val_) --- > if (val != xarray [i].data_.val_) 550a541,556 > /* static */ UserClass* > UserClass::from_char (const char *str, size_t len /* = -1 */, > bool sorted /* = false */) > { > return __rw_from_char ((UserClass*)0, str, len, sorted); > } > > > /* static */ const UserClass* > UserClass::mismatch (const UserClass *xarray, const char *str, > size_t len /* = -1 */) > { > return __rw_mismatch (xarray, str, len); > } > > 552c558,559 < X::compare (const X *xarray, const char *str, size_t len /* = -1 */) --- > UserClass::compare (const UserClass *xarray, const char *str, > size_t len /* = -1 */) 554c561 < const X* const px = mismatch (xarray, str, len); --- > const UserClass* const px = mismatch (xarray, str, len); 559c566 < return px->val_ - int (UChar (str [px - xarray])); --- > return px->data_.val_ - int (UChar (str [px - xarray])); 567c574,575 < X::compare (const char *str, const X *xarray, size_t len /* = -1 */) --- > UserClass::compare (const char *str, const UserClass *xarray, > size_t len /* = -1 */) 569c577 < return -X::compare (xarray, str, len); --- > return -UserClass::compare (xarray, str, len); 574c582 < X::compare (const X *x, const X *y, size_t count) --- > UserClass::compare (const UserClass *x, const UserClass *y, size_t count) 577,578c585,586 < if (x [i].val_ != y [i].val_) < return x [i].val_ - y [i].val_; --- > if (x [i].data_.val_ != y [i].data_.val_) > return x [i].data_.val_ - y [i].data_.val_; 584a593,608 > /* static */ UserPOD* > UserPOD::from_char (const char *str, size_t len /* = -1 */, > bool sorted /* = false */) > { > return __rw_from_char ((UserPOD*)0, str, len, sorted); > } > > > /* static */ const UserPOD* > UserPOD::mismatch (const UserPOD *xarray, const char *str, > size_t len /* = -1 */) > { > return __rw_mismatch (xarray, str, len); > } > > 616c640 < operator()(const X&) const --- > operator()(const UserClass&) const 641c665 < operator()(const X &lhs, const X &rhs) /* non-const */ --- > operator()(const UserClass &lhs, const UserClass &rhs) /* non-const */ 648,653c672,677 < case op_equals: result = lhs.val_ == rhs.val_; break; < case op_not_equals: result = !(lhs.val_ == rhs.val_); break; < case op_less: result = lhs.val_ < rhs.val_; break; < case op_less_equal: result = !(rhs.val_ < lhs.val_); break; < case op_greater: result = rhs.val_ < lhs.val_; break; < case op_greater_equal: result = !(rhs.val_ < lhs.val_); break; --- > case op_equals: result = lhs.data_.val_ == rhs.data_.val_; break; > case op_not_equals: result = !(lhs.data_.val_ == rhs.data_.val_); > break; > case op_less: result = lhs.data_.val_ < rhs.data_.val_; break; > case op_less_equal: result = !(rhs.data_.val_ < lhs.data_.val_); break; > case op_greater: result = rhs.data_.val_ < lhs.data_.val_; break; > case op_greater_equal: result = !(rhs.data_.val_ < lhs.data_.val_); break; 674c698 < const X* pelem = 0; --- > const UserClass* pelem = 0; 679,681c703,705 < // '#' causes X::id_ to be included in output < // '+' forces X::val_ to be formatted as an integer (otherwise < // it is formatted as an (optionally escaped) character --- > // '#' causes UserClass::id_ to be included in output > // '+' forces UserClass::data_.val_ to be formatted as an integer ( > // otherwise it is formatted as an (optionally escaped) character 696c720 < // use numerical formatting for X::val_ --- > // use numerical formatting for UserClass::data_.val_ 702c726 < // include X::id_ in output --- > // include UserClass::id_ in output 751c775 < pelem = va_arg (*pva, X*); --- > pelem = va_arg (*pva, UserClass*); 771c795 < // extract a pointer to X from rw_snprintfa's variable argument --- > // extract a pointer to UserClass from rw_snprintfa's variable argument 773c797 < const X* const xbeg = va_arg (*pva, X*); --- > const UserClass* const xbeg = va_arg (*pva, UserClass*); 784c808 < const X** const pparam = va_arg (va, const X**); --- > const UserClass** const pparam = va_arg (va, const UserClass**); 802c826 < for (const X *px = xbeg; px != xbeg + nelems; ++px) { --- > for (const UserClass *px = xbeg; px != xbeg + nelems; ++px) { 811c835 < fl_plus, px->val_, // <val> --- > fl_plus, px->data_.val_, // <val> 813c837 < px->val_, // <val> --- > px->data_.val_, // <val> 846a871,880 > } > > > UserClassFmatInit:: > UserClassFmatInit () > { > // install the formatting callback function > static int format_init = rw_printf ("%{+!}", _rw_fmtxarray); > > _RWSTD_UNUSED (format_init);