Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 54288 invoked from network); 20 Feb 2007 17:12:46 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 20 Feb 2007 17:12:46 -0000 Received: (qmail 43732 invoked by uid 500); 20 Feb 2007 17:12:54 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 43719 invoked by uid 500); 20 Feb 2007 17:12:54 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 43708 invoked by uid 99); 20 Feb 2007 17:12:53 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Feb 2007 09:12:53 -0800 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (herse.apache.org: local policy) Received: from [212.82.213.172] (HELO exkiv.kyiv.vdiweb.com) (212.82.213.172) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Feb 2007 09:12:42 -0800 Received: from [10.11.37.198] ([10.11.37.198]) by exkiv.kyiv.vdiweb.com with Microsoft SMTPSVC(6.0.3790.1830); Tue, 20 Feb 2007 19:12:18 +0200 Message-ID: <45DB2BE7.1060504@kyiv.vdiweb.com> Date: Tue, 20 Feb 2007 19:12:07 +0200 From: Farid Zaripov User-Agent: Thunderbird 1.5.0.9 (Windows/20061207) MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: [PATCH] introducing rw_value.h and value.cpp Content-Type: multipart/mixed; boundary="------------030008020000080702070204" X-OriginalArrivalTime: 20 Feb 2007 17:12:18.0332 (UTC) FILETIME=[4676EDC0:01C75512] X-Virus-Checked: Checked by ClamAV on apache.org --------------030008020000080702070204 Content-Type: text/plain; charset=KOI8-R; format=flowed Content-Transfer-Encoding: 7bit Hi All. Attached is a first small patch from the splitted big patch. ChangeLog: * alg_test.h (struct X, struct UnaryPredicate, struct BinaryPredicate): Declarations moved from here ... * rw_value.h: ... to here (new header file). * alg_test.cpp: Updated copyright notice; (struct X, struct UnaryPredicate, struct BinaryPredicate, _rw_fmtxarrayv, _rw_fmtxarray): Definitions moved from here ... * value.cpp: ... to here (new source file). Farid. --------------030008020000080702070204 Content-Type: text/plain; name="patch1.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch1.diff" Index: include/alg_test.h =================================================================== --- include/alg_test.h (revision 509624) +++ include/alg_test.h (working copy) @@ -33,188 +33,6 @@ #include -// objects of class X maintain a count of their instances in existence, -// the number of defaut and copy ctor calls, assignment operators, and -// the number of calls to operator==() and operator<() -struct _TEST_EXPORT X -{ - 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 - - // number of times the object has been copied into another object, - // regardless of whether the operation threw an exception or not - _RWSTD_SIZE_T n_copy_ctor_; - - // number of times the object's assignment operator has been invoked, - // 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_; - - // number of times the object's operator< was invoked - // regardless of whether the operation threw an exception - _RWSTD_SIZE_T n_op_lt_; - - static _RWSTD_SIZE_T count_; // number of objects in existence (>= 0) - static int id_gen_; // generates a unique non-zero id - static int (*gen_)(); // extern "C++" int (*)() - - static _RWSTD_SIZE_T n_total_def_ctor_; // number of default ctor calls - 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 <= ... - - // classes thrown from the respective functions - struct Exception { int id_; }; - struct DefCtor: Exception { }; - 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 { }; - - // throw object's `id' wrapped in the appropriate struct when the - // corresponding n_total_xxx_ counter reaches the value pointed to - // by the respective pointer below - static _RWSTD_SIZE_T* def_ctor_throw_ptr_; - 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_; - - // objects to which the pointers above initally point - static _RWSTD_SIZE_T def_ctor_throw_count_; - 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_; - - X (); - - X (const X&); - - ~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; - - // the following operators are not declared or defined in order - // to detect any unwarranted assumptions made in algorithms - // 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 - is_count (_RWSTD_SIZE_T copy_ctor, - _RWSTD_SIZE_T op_assign, - _RWSTD_SIZE_T op_eq, - _RWSTD_SIZE_T op_lt) const; - - static bool - is_total (_RWSTD_SIZE_T count, - _RWSTD_SIZE_T n_def_ctor, - _RWSTD_SIZE_T n_copy_ctor, - _RWSTD_SIZE_T n_op_assign, - _RWSTD_SIZE_T n_op_eq, - _RWSTD_SIZE_T n_op_lt); - - // returns a pointer to the first element in the sequence whose value - // is less than the value of the immediately preceding element, or 0 - // when no such element exists - static const X* - first_less (const X*, _RWSTD_SIZE_T); - - static void reset_totals (); - - // construct an array of objects of type X 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 X* - from_char (const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX, - bool = false); - - // returns -1 when less, 0 when same, or +1 when the array - // 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); - - // 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); - - // returns a pointer to the first element in the sequence of X - // whose value is not equal to the corresponding element of - // the character string or 0 when no such element exists - static const X* mismatch (const X*, const char*, _RWSTD_SIZE_T); - - struct Less; - -private: - - enum assign_op { - op_assign, op_plus_assign, op_minus_assign, - op_times_assign, op_div_assign - }; - - void assign (assign_op, const X&); -}; - -/**************************************************************************/ - // generate a unique sequential number starting from 0 _TEST_EXPORT int gen_seq (); @@ -520,62 +338,6 @@ /**************************************************************************/ -struct _TEST_EXPORT UnaryPredicate -{ - // total number of times operator() was invoked - static _RWSTD_SIZE_T n_total_op_fcall_; - - UnaryPredicate (); - - UnaryPredicate (const UnaryPredicate&); - - UnaryPredicate& operator= (const UnaryPredicate&); - - virtual ~UnaryPredicate (); - - virtual conv_to_bool operator()(const X&) const; -}; - - -struct _TEST_EXPORT BinaryPredicate -{ - // total number of times operator() was invoked - static _RWSTD_SIZE_T n_total_op_fcall_; - - enum binary_op { - op_equals, - op_not_equals, - op_less, - op_less_equal, - op_greater, - op_greater_equal - }; - - BinaryPredicate (binary_op); - - virtual ~BinaryPredicate (); - - virtual conv_to_bool operator()(const X&, const X&) /* non-const */; - -private: - - // not assignable - void operator= (const BinaryPredicate&); - - binary_op op_; -}; - - -struct X::Less: BinaryPredicate -{ - // dummy arguments provided to prevent the class from being - // default constructible and implicit conversion from int - Less (int /* dummy */, int /* dummy */) - : BinaryPredicate (BinaryPredicate::op_less) { /* no-op */ } -}; - -/**************************************************************************/ - // Size template argument to fill_n(), generate_n(), and search_n() template struct Size @@ -1357,5 +1119,7 @@ { return "ConstRandomAccessIterator"; } +// temporary to not break the tests which uses struct X +#include #endif // RW_ALG_TEST_H_INCLUDED Index: include/rw_value.h =================================================================== --- include/rw_value.h (revision 0) +++ include/rw_value.h (revision 0) @@ -0,0 +1,272 @@ +/*************************************************************************** + * + * rw_value.h - defines a User Defined type + * + * $Id$ + * + *************************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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. + * + * Copyright 1994-2005 Rogue Wave Software. + * + **************************************************************************/ + +#ifndef RW_VALUE_H_INCLUDED +#define RW_VALUE_H_INCLUDED + +#include +#include // for conv_to_bool + +// objects of class X maintain a count of their instances in existence, +// the number of defaut and copy ctor calls, assignment operators, and +// the number of calls to operator==() and operator<() +struct _TEST_EXPORT X +{ + 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 + + // number of times the object has been copied into another object, + // regardless of whether the operation threw an exception or not + _RWSTD_SIZE_T n_copy_ctor_; + + // number of times the object's assignment operator has been invoked, + // 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_; + + // number of times the object's operator< was invoked + // regardless of whether the operation threw an exception + _RWSTD_SIZE_T n_op_lt_; + + static _RWSTD_SIZE_T count_; // number of objects in existence (>= 0) + static int id_gen_; // generates a unique non-zero id + static int (*gen_)(); // extern "C++" int (*)() + + static _RWSTD_SIZE_T n_total_def_ctor_; // number of default ctor calls + 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 <= ... + + // classes thrown from the respective functions + struct Exception { int id_; }; + struct DefCtor: Exception { }; + 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 { }; + + // throw object's `id' wrapped in the appropriate struct when the + // corresponding n_total_xxx_ counter reaches the value pointed to + // by the respective pointer below + static _RWSTD_SIZE_T* def_ctor_throw_ptr_; + 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_; + + // objects to which the pointers above initally point + static _RWSTD_SIZE_T def_ctor_throw_count_; + 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_; + + X (); + + X (const X&); + + ~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; + + // the following operators are not declared or defined in order + // to detect any unwarranted assumptions made in algorithms + // 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 + is_count (_RWSTD_SIZE_T copy_ctor, + _RWSTD_SIZE_T op_assign, + _RWSTD_SIZE_T op_eq, + _RWSTD_SIZE_T op_lt) const; + + static bool + is_total (_RWSTD_SIZE_T count, + _RWSTD_SIZE_T n_def_ctor, + _RWSTD_SIZE_T n_copy_ctor, + _RWSTD_SIZE_T n_op_assign, + _RWSTD_SIZE_T n_op_eq, + _RWSTD_SIZE_T n_op_lt); + + // returns a pointer to the first element in the sequence whose value + // is less than the value of the immediately preceding element, or 0 + // when no such element exists + static const X* + first_less (const X*, _RWSTD_SIZE_T); + + static void reset_totals (); + + // construct an array of objects of type X 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 X* + from_char (const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX, + bool = false); + + // returns -1 when less, 0 when same, or +1 when the array + // 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); + + // 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); + + // returns a pointer to the first element in the sequence of X + // whose value is not equal to the corresponding element of + // the character string or 0 when no such element exists + static const X* mismatch (const X*, const char*, _RWSTD_SIZE_T); + + struct Less; + +private: + + enum assign_op { + op_assign, op_plus_assign, op_minus_assign, + op_times_assign, op_div_assign + }; + + void assign (assign_op, const X&); +}; + +/**************************************************************************/ + +struct _TEST_EXPORT UnaryPredicate +{ + // total number of times operator() was invoked + static _RWSTD_SIZE_T n_total_op_fcall_; + + UnaryPredicate (); + + UnaryPredicate (const UnaryPredicate&); + + UnaryPredicate& operator= (const UnaryPredicate&); + + virtual ~UnaryPredicate (); + + virtual conv_to_bool operator()(const X&) const; +}; + + +struct _TEST_EXPORT BinaryPredicate +{ + // total number of times operator() was invoked + static _RWSTD_SIZE_T n_total_op_fcall_; + + enum binary_op { + op_equals, + op_not_equals, + op_less, + op_less_equal, + op_greater, + op_greater_equal + }; + + BinaryPredicate (binary_op); + + virtual ~BinaryPredicate (); + + virtual conv_to_bool operator()(const X&, const X&) /* non-const */; + +private: + + // not assignable + void operator= (const BinaryPredicate&); + + binary_op op_; +}; + + +struct X::Less: BinaryPredicate +{ + // dummy arguments provided to prevent the class from being + // default constructible and implicit conversion from int + Less (int /* dummy */, int /* dummy */) + : BinaryPredicate (BinaryPredicate::op_less) { /* no-op */ } +}; + + +#endif // RW_VALUE_H_INCLUDED Property changes on: include\rw_value.h ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/alg_test.cpp =================================================================== --- src/alg_test.cpp (revision 509624) +++ src/alg_test.cpp (working copy) @@ -6,650 +6,35 @@ * ************************************************************************ * - * 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. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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. + * + * Copyright 1994-2005 Rogue Wave Software. * **************************************************************************/ // expand _TEST_EXPORT macros #define _RWSTD_TEST_SRC -#include // for isdigit(), toupper() -#include // for va_arg, va_list, ... -#include // for rand(), strtol() -#include // for size_t, strlen() +#include // for rand() #include -#include -/* 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_; - -// 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_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_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 -_rw_fmtxarray (char**, size_t*, const char*, ...); - - -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) -{ - // 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); - - // 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 - RW_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 - RW_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; -} - - -void X:: -assign (assign_op which, const X &rhs) -{ - // 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_); - - 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 invocations of the operator - // (do so even if the function throws an exception below) - - ++*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 (p_throw && *p_throw == *p_total_op) { - pex->id_ = id_; - throw *pex; - } - -#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_ = 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; -} - - -bool -X::operator== (const X &rhs) const -{ - // verify id validity and uniqueness - RW_ASSERT (id_ && id_ <= id_gen_); - RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_); - RW_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 - RW_ASSERT (id_ && id_ <= id_gen_); - RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_); - RW_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 - RW_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 */ const X* -X::first_less (const X *xarray, size_t nelems) -{ - size_t inx = nelems; - - if (1 < nelems) { - for (inx = 1; inx != nelems; ++inx) { - if (xarray [inx] < xarray [inx - 1]) - break; - } - } - - return inx < nelems ? xarray + inx : 0; -} - - -/* 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 */, bool sorted /* = false */) -{ - // 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); - - if (sorted) { - // verify that the sequence is sorted - for (size_t i = 1; i < len; ++i) { - if (str [i] < str [i - 1]) { - return 0; - } - } - } - - // 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; -} - - -/* static */ const X* -X::mismatch (const X *xarray, const char *str, size_t len /* = -1 */) -{ - if (!str) - return xarray; - - if (size_t (-1) == len) - len = strlen (str); - - for (size_t i = 0; i != len; ++i) { - - const int val = UChar (str [i]); - - if (val != xarray [i].val_) - return xarray + i; - } - - return 0; -} - - -/* static */ int -X::compare (const X *xarray, const char *str, size_t len /* = -1 */) -{ - const X* const px = mismatch (xarray, str, len); - - if (px) { - RW_ASSERT (size_t (px - xarray) < len); - - return px->val_ - int (UChar (str [px - xarray])); - } - - return 0; -} - - -/* static */ int -X::compare (const char *str, const X *xarray, size_t len /* = -1 */) -{ - return -X::compare (xarray, str, len); -} - - -/* 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_; - - -UnaryPredicate:: -UnaryPredicate () -{ - // no-op -} - - -UnaryPredicate:: -UnaryPredicate (const UnaryPredicate&) -{ - // no-op -} - - -UnaryPredicate& UnaryPredicate:: -operator= (const UnaryPredicate&) -{ - return *this; -} - - -/* virtual */ UnaryPredicate::~UnaryPredicate () -{ - // no-op -} - - -/* virtual */ conv_to_bool UnaryPredicate:: -operator()(const X&) const -{ - ++n_total_op_fcall_; - - return conv_to_bool::make (true); -} - - -/* static */ size_t BinaryPredicate::n_total_op_fcall_; - - -BinaryPredicate:: -BinaryPredicate (binary_op op): op_ (op) -{ - // no-op -} - - -/* virtual */ BinaryPredicate::~BinaryPredicate () -{ - // no-op -} - - -/* virtual */ conv_to_bool BinaryPredicate:: -operator()(const X &lhs, const X &rhs) /* non-const */ -{ - ++n_total_op_fcall_; - - bool result; - - switch (op_) { - 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; - } - - return conv_to_bool::make (result); -} - - // generate a unique sequential number starting from 0 _TEST_EXPORT int gen_seq () { @@ -707,193 +92,3 @@ return result; } - - -static int -_rw_fmtxarrayv (char **pbuf, size_t *pbufsize, const char *fmt, va_list va) -{ - RW_ASSERT (0 != pbuf); - RW_ASSERT (0 != pbufsize); - 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; - - const X* pelem = 0; - - // directive syntax: - // "X=" [ '#' ] [ '+' ] [ '*' | ] [ '.' [ '*' | '@' | ] ] - // where - // '#' 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 - // '*' or is the number of elements in the sequence (the - // first occurrence) - // '*', is the offset of the cursor within the sequence - // (where the cursor is a pair of pointy brackets - // surrounding the element, e.g., >123<) - // '@' is the pointer to the element to be surrended by the - // pair of pointy brackets - - if ('X' != fmt [0] || '=' != fmt [1]) - return _RWSTD_INT_MIN; - - 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; - } - - if ('*' == *fmt) { - // process width - pva = va_arg (va, va_list*); - - RW_ASSERT (0 != pva); - - // extract the width from rw_snprintfa's variable argument - // list pass through to us by the caller - nelems = va_arg (*pva, int); - ++fmt; - } - else if (isdigit (*fmt)) { - // process positional parameter or width - char* end = 0; - const int arg = strtol (fmt, &end, 10); - if ('$' == *end) - paramno = arg; - else - nelems = arg; - - fmt = end; - } - - if ('.' == *fmt) { - // process precision (cursor) - if ('*' == *++fmt) { - if (0 == pva) - pva = va_arg (va, va_list*); - - RW_ASSERT (0 != pva); - - // extract the width from rw_snprintfa's variable argument - // list passed through to us by the caller - cursor = va_arg (*pva, int); - ++fmt; - } - else if ('@' == *fmt) { - if (0 == pva) - pva = va_arg (va, va_list*); - - RW_ASSERT (0 != pva); - - // extract the pointer from rw_snprintfa's variable argument - // list passed through to us by the caller - pelem = va_arg (*pva, X*); - - ++fmt; - } - else if (isdigit (*fmt)) { - char* end = 0; - cursor = strtol (fmt, &end, 10); - - fmt = end; - } - } - - RW_ASSERT ('\0' == *fmt); - - // extract the address of the caller's variable argument list - if (0 == pva) - pva = va_arg (va, va_list*); - - RW_ASSERT (0 != pva); - - // extract a pointer to X from rw_snprintfa's variable argument - // list pass through to us by the caller - const X* const xbeg = va_arg (*pva, X*); - - if (-1 != cursor) { - RW_ASSERT (-1 < cursor); - RW_ASSERT (0 == pelem); - - pelem = xbeg + cursor; - } - - // extract the address where to store the extracted argument - // for use by any subsequent positional paramaters - const X** const pparam = va_arg (va, const X**); - - RW_ASSERT (0 != pparam); - - // store the extracted argument - *pparam = xbeg; - - // compute the length of the buffer formatted so far - const size_t buflen_0 = *pbuf ? strlen (*pbuf) : 0; - - int nbytes = 0; - - ////////////////////////////////////////////////////////////////// - // invoke rw_asnprintf() recursively to format our arguments - // and append the result to the end of the buffer; pass the - // value returned from rw_asnprintf() (i.e., the number of - // bytes appended) back to the caller - - for (const X *px = xbeg; px != xbeg + nelems; ++px) { - const int n = - rw_asnprintf (pbuf, pbufsize, - "%{+}%{?}>%{;}" - "%{?}%d:%{;}" - "%{?}%d%{?},%{;}%{:}%{lc}%{;}" - "%{?}<%{;}", - px == pelem, // '>' - fl_pound, px->id_, // ":" - fl_plus, px->val_, // - px + 1 < xbeg + nelems, // ',' - px->val_, // - px == pelem); // '<' - if (n < 0) - return n; - - nbytes += n; - } - - ////////////////////////////////////////////////////////////////// - - // compute the new length of the buffer - const size_t buflen_1 = *pbuf ? strlen (*pbuf) : 0; - - // assert that the function really appended as many characters - // as it said it did (assumes no NULs embedded in the output) - // and that it didn't write past the end of the buffer - RW_ASSERT (buflen_1 == buflen_0 + nbytes); - RW_ASSERT (buflen_1 < *pbufsize); - - return nbytes; -} - - -static int -_rw_fmtxarray (char **pbuf, size_t *pbufsize, const char *fmt, ...) -{ - va_list va; - va_start (va, fmt); - - const int nbytes = _rw_fmtxarrayv (pbuf, pbufsize, fmt, va); - - va_end (va); - - return nbytes; -} Index: src/value.cpp =================================================================== --- src/value.cpp (revision 0) +++ src/value.cpp (revision 0) @@ -0,0 +1,847 @@ +/************************************************************************ + * + * value.cpp - defines a User Defined type + * + * $Id$ + * + ************************************************************************ + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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. + * + * Copyright 1994-2005 Rogue Wave Software. + * + **************************************************************************/ + +// expand _TEST_EXPORT macros +#define _RWSTD_TEST_SRC + +#include // for isdigit() +#include // for va_arg, va_list, ... +#include // for strtol() +#include // for size_t, strlen() + + +#include +#include + + +/* 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_; + +// 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_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_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 +_rw_fmtxarray (char**, size_t*, const char*, ...); + + +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) +{ + // 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); + + // 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 + RW_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 + RW_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; +} + + +void X:: +assign (assign_op which, const X &rhs) +{ + // 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_); + + 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 invocations of the operator + // (do so even if the function throws an exception below) + + ++*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 (p_throw && *p_throw == *p_total_op) { + pex->id_ = id_; + throw *pex; + } + +#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_ = 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; +} + + +bool +X::operator== (const X &rhs) const +{ + // verify id validity and uniqueness + RW_ASSERT (id_ && id_ <= id_gen_); + RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_); + RW_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 + RW_ASSERT (id_ && id_ <= id_gen_); + RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_); + RW_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 + RW_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 */ const X* +X::first_less (const X *xarray, size_t nelems) +{ + size_t inx = nelems; + + if (1 < nelems) { + for (inx = 1; inx != nelems; ++inx) { + if (xarray [inx] < xarray [inx - 1]) + break; + } + } + + return inx < nelems ? xarray + inx : 0; +} + + +/* 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 */, bool sorted /* = false */) +{ + // 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); + + if (sorted) { + // verify that the sequence is sorted + for (size_t i = 1; i < len; ++i) { + if (str [i] < str [i - 1]) { + return 0; + } + } + } + + // 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; +} + + +/* static */ const X* +X::mismatch (const X *xarray, const char *str, size_t len /* = -1 */) +{ + if (!str) + return xarray; + + if (size_t (-1) == len) + len = strlen (str); + + for (size_t i = 0; i != len; ++i) { + + const int val = UChar (str [i]); + + if (val != xarray [i].val_) + return xarray + i; + } + + return 0; +} + + +/* static */ int +X::compare (const X *xarray, const char *str, size_t len /* = -1 */) +{ + const X* const px = mismatch (xarray, str, len); + + if (px) { + RW_ASSERT (size_t (px - xarray) < len); + + return px->val_ - int (UChar (str [px - xarray])); + } + + return 0; +} + + +/* static */ int +X::compare (const char *str, const X *xarray, size_t len /* = -1 */) +{ + return -X::compare (xarray, str, len); +} + + +/* 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_; + + +UnaryPredicate:: +UnaryPredicate () +{ + // no-op +} + + +UnaryPredicate:: +UnaryPredicate (const UnaryPredicate&) +{ + // no-op +} + + +UnaryPredicate& UnaryPredicate:: +operator= (const UnaryPredicate&) +{ + return *this; +} + + +/* virtual */ UnaryPredicate::~UnaryPredicate () +{ + // no-op +} + + +/* virtual */ conv_to_bool UnaryPredicate:: +operator()(const X&) const +{ + ++n_total_op_fcall_; + + return conv_to_bool::make (true); +} + + +/* static */ size_t BinaryPredicate::n_total_op_fcall_; + + +BinaryPredicate:: +BinaryPredicate (binary_op op): op_ (op) +{ + // no-op +} + + +/* virtual */ BinaryPredicate::~BinaryPredicate () +{ + // no-op +} + + +/* virtual */ conv_to_bool BinaryPredicate:: +operator()(const X &lhs, const X &rhs) /* non-const */ +{ + ++n_total_op_fcall_; + + bool result; + + switch (op_) { + 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; + } + + return conv_to_bool::make (result); +} + + +static int +_rw_fmtxarrayv (char **pbuf, size_t *pbufsize, const char *fmt, va_list va) +{ + RW_ASSERT (0 != pbuf); + RW_ASSERT (0 != pbufsize); + 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; + + const X* pelem = 0; + + // directive syntax: + // "X=" [ '#' ] [ '+' ] [ '*' | ] [ '.' [ '*' | '@' | ] ] + // where + // '#' 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 + // '*' or is the number of elements in the sequence (the + // first occurrence) + // '*', is the offset of the cursor within the sequence + // (where the cursor is a pair of pointy brackets + // surrounding the element, e.g., >123<) + // '@' is the pointer to the element to be surrended by the + // pair of pointy brackets + + if ('X' != fmt [0] || '=' != fmt [1]) + return _RWSTD_INT_MIN; + + 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; + } + + if ('*' == *fmt) { + // process width + pva = va_arg (va, va_list*); + + RW_ASSERT (0 != pva); + + // extract the width from rw_snprintfa's variable argument + // list pass through to us by the caller + nelems = va_arg (*pva, int); + ++fmt; + } + else if (isdigit (*fmt)) { + // process positional parameter or width + char* end = 0; + const int arg = strtol (fmt, &end, 10); + if ('$' == *end) + paramno = arg; + else + nelems = arg; + + fmt = end; + } + + if ('.' == *fmt) { + // process precision (cursor) + if ('*' == *++fmt) { + if (0 == pva) + pva = va_arg (va, va_list*); + + RW_ASSERT (0 != pva); + + // extract the width from rw_snprintfa's variable argument + // list passed through to us by the caller + cursor = va_arg (*pva, int); + ++fmt; + } + else if ('@' == *fmt) { + if (0 == pva) + pva = va_arg (va, va_list*); + + RW_ASSERT (0 != pva); + + // extract the pointer from rw_snprintfa's variable argument + // list passed through to us by the caller + pelem = va_arg (*pva, X*); + + ++fmt; + } + else if (isdigit (*fmt)) { + char* end = 0; + cursor = strtol (fmt, &end, 10); + + fmt = end; + } + } + + RW_ASSERT ('\0' == *fmt); + + // extract the address of the caller's variable argument list + if (0 == pva) + pva = va_arg (va, va_list*); + + RW_ASSERT (0 != pva); + + // extract a pointer to X from rw_snprintfa's variable argument + // list pass through to us by the caller + const X* const xbeg = va_arg (*pva, X*); + + if (-1 != cursor) { + RW_ASSERT (-1 < cursor); + RW_ASSERT (0 == pelem); + + pelem = xbeg + cursor; + } + + // extract the address where to store the extracted argument + // for use by any subsequent positional paramaters + const X** const pparam = va_arg (va, const X**); + + RW_ASSERT (0 != pparam); + + // store the extracted argument + *pparam = xbeg; + + // compute the length of the buffer formatted so far + const size_t buflen_0 = *pbuf ? strlen (*pbuf) : 0; + + int nbytes = 0; + + ////////////////////////////////////////////////////////////////// + // invoke rw_asnprintf() recursively to format our arguments + // and append the result to the end of the buffer; pass the + // value returned from rw_asnprintf() (i.e., the number of + // bytes appended) back to the caller + + for (const X *px = xbeg; px != xbeg + nelems; ++px) { + const int n = + rw_asnprintf (pbuf, pbufsize, + "%{+}%{?}>%{;}" + "%{?}%d:%{;}" + "%{?}%d%{?},%{;}%{:}%{lc}%{;}" + "%{?}<%{;}", + px == pelem, // '>' + fl_pound, px->id_, // ":" + fl_plus, px->val_, // + px + 1 < xbeg + nelems, // ',' + px->val_, // + px == pelem); // '<' + if (n < 0) + return n; + + nbytes += n; + } + + ////////////////////////////////////////////////////////////////// + + // compute the new length of the buffer + const size_t buflen_1 = *pbuf ? strlen (*pbuf) : 0; + + // assert that the function really appended as many characters + // as it said it did (assumes no NULs embedded in the output) + // and that it didn't write past the end of the buffer + RW_ASSERT (buflen_1 == buflen_0 + nbytes); + RW_ASSERT (buflen_1 < *pbufsize); + + return nbytes; +} + + +static int +_rw_fmtxarray (char **pbuf, size_t *pbufsize, const char *fmt, ...) +{ + va_list va; + va_start (va, fmt); + + const int nbytes = _rw_fmtxarrayv (pbuf, pbufsize, fmt, va); + + va_end (va); + + return nbytes; +} Property changes on: src\value.cpp ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native --------------030008020000080702070204--