You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2006/05/26 00:12:22 UTC
svn commit: r409484 - in /incubator/stdcxx/trunk/tests: include/21.strings.h
src/21.strings.cpp
Author: sebor
Date: Thu May 25 15:12:21 2006
New Revision: 409484
URL: http://svn.apache.org/viewvc?rev=409484&view=rev
Log:
2006-05-25 Martin Sebor <se...@roguewave.com>
* 21.strings.h (FuncId): Added members, increased to 6 bits.
(bit_member): New enumerator designating member functions.
(OverloadId): Added enumerator for operator+, operator==,
operator!=, and all relational operators.
* 21.strings.cpp (_rw_func_names): Added function names.
(_rw_class_name): New helper function to compute the name
of the basic_string class (string, wstring, or basic_string).
(_rw_sigcat): Used mnemonics instead of real function names
for name of options controlling operators (such as operator+).
Handled non-members correctly.
(_rw_uses_alloc): New helper to help determine whether a ctor
overload takes an allocator argument.
(_rw_setvars): Formatted ctors and non-members correctly.
Added formatting handlers for missing ctor overloads.
Added formatting handlers for non-member functions.
Modified:
incubator/stdcxx/trunk/tests/include/21.strings.h
incubator/stdcxx/trunk/tests/src/21.strings.cpp
Modified: incubator/stdcxx/trunk/tests/include/21.strings.h
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/include/21.strings.h?rev=409484&r1=409483&r2=409484&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/include/21.strings.h (original)
+++ incubator/stdcxx/trunk/tests/include/21.strings.h Thu May 25 15:12:21 2006
@@ -37,16 +37,16 @@
// identifiers for the charT template argument
enum CharId { Char, WChar, UChar };
- // identifiers for the Traits template argument
+ // identifiers for the Traits template argument
enum TraitsId { DefaultTraits, UserTraits };
- // identifiers for the Allocator template argument
+ // identifiers for the Allocator template argument
enum AllocId { DefaultAlloc, UserAlloc };
// identifies a set of overloaded member or non-member
// string functions
enum FuncId {
- // 5 bits, 32 functions max
+ // 6 bits, 64 functions max
/* 0 */ fid_append,
/* 1 */ fid_assign,
/* 2 */ fid_erase,
@@ -70,8 +70,15 @@
/* 18 */ fid_op_set,
/* 19 */ fid_swap,
/* 20 */ fid_push_back,
- /* -- */ fid_bits = 5,
- /* -- */ fid_mask = 31
+ /* 21 */ fid_op_plus,
+ /* 22 */ fid_op_equal,
+ /* 23 */ fid_op_not_equal,
+ /* 24 */ fid_op_less,
+ /* 25 */ fid_op_less_equal,
+ /* 26 */ fid_op_greater,
+ /* 27 */ fid_op_greater_equal,
+ /* -- */ fid_bits = 6,
+ /* -- */ fid_mask = 63
};
// identifies the type of a function argument, including
@@ -95,8 +102,16 @@
/* -- */ arg_mask = 15
};
+ enum {
+ // bit designating a member function
+ bit_member = 1 << fid_bits + 6 * arg_bits
+ };
+
+// FCAT() concatenates prefix, underscrore, and suffix
#define _FCAT(a, b) a ## b
#define FCAT(a, b) _FCAT (a ## _, b)
+
+// FID_N() constructs the name for an overload of a string function
#define FID_0(f) FCAT (f, void)
#define FID_1(f, a) FCAT (f, a)
#define FID_2(f, a, b) FID_1 (FCAT (f, a), b)
@@ -104,8 +119,10 @@
#define FID_4(f, a, b, c, d) FID_3 (FCAT (f, a), b, c, d)
#define FID_5(f, a, b, c, d, e) FID_4 (FCAT (f, a), b, c, d, e)
-#define ARG(a, N) ((arg_ ## a << (N << 2)) << 5)
+// ARG() creates a bitmap of an argument type at the given position
+#define ARG(a, N) ((arg_ ## a << (N * arg_bits)) << fid_bits)
+// SIG_N() creates an argument bitmap for the given function signature
#define SIG_0(f) fid_ ## f
#define SIG_1(f, a) SIG_0 (f) | ARG (a, 0)
#define SIG_2(f, a, b) SIG_1 (f, a) | ARG (b, 1)
@@ -118,17 +135,17 @@
// where the first argument encodes the constness of the member
// function (or the lack thereof)
#define MEMBER_0(f, self) \
- FID_0 (f) = SIG_1 (f, self)
+ FID_0 (f) = SIG_1 (f, self) | bit_member
#define MEMBER_1(f, self, a) \
- FID_1 (f, a) = SIG_2 (f, self, a)
+ FID_1 (f, a) = SIG_2 (f, self, a) | bit_member
#define MEMBER_2(f, self, a, b) \
- FID_2 (f, a, b) = SIG_3 (f, self, a, b)
+ FID_2 (f, a, b) = SIG_3 (f, self, a, b) | bit_member
#define MEMBER_3(f, self, a, b, c) \
- FID_3 (f, a, b, c) = SIG_4 (f, self, a, b, c)
+ FID_3 (f, a, b, c) = SIG_4 (f, self, a, b, c) | bit_member
#define MEMBER_4(f, self, a, b, c, d) \
- FID_4 (f, a, b, c, d) = SIG_5 (f, self, a, b, c, d)
+ FID_4 (f, a, b, c, d) = SIG_5 (f, self, a, b, c, d) | bit_member
#define MEMBER_5(f, self, a, b, c, d, e) \
- FID_5 (f, a, b, c, d, e) = SIG_6 (f, self, a, b, c, d, e)
+ FID_5 (f, a, b, c, d, e) = SIG_6 (f, self, a, b, c, d, e) | bit_member
// convenience macro to define non-member function overload id's
#define NON_MEMBER_0(f) \
@@ -145,6 +162,9 @@
FID_5 (f, a, b, c, d, e) = SIG_5 (f, a, b, c, d, e)
// unique identifiers for all overloads of each member function
+ // 6 bits for FuncId
+ // 6 * 4 bits for ArgId (at most 6 arguments including this)
+ // 1 bit for membership
enum OverloadId {
//////////////////////////////////////////////////////////////
// append (const_pointer)
@@ -420,7 +440,67 @@
//////////////////////////////////////////////////////////////
// push_back (value_type)
- MEMBER_1 (push_back, str, val)
+ MEMBER_1 (push_back, str, val),
+
+ //////////////////////////////////////////////////////////////
+ // operator+ (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_plus, cptr, cstr),
+ // operator+ (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_plus, cstr, cstr),
+ // operator+ (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_plus, cstr, cptr),
+ // operator+ (const basic_string&, value_type)
+ NON_MEMBER_2 (op_plus, cstr, val),
+ // operator+ (value_type, const basic_string&)
+ NON_MEMBER_2 (op_plus, val, cstr),
+
+ //////////////////////////////////////////////////////////////
+ // operator== (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_equal, cptr, cstr),
+ // operator== (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_equal, cstr, cstr),
+ // operator== (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_equal, cstr, cptr),
+
+ //////////////////////////////////////////////////////////////
+ // operator!= (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_not_equal, cptr, cstr),
+ // operator!= (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_not_equal, cstr, cstr),
+ // operator!= (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_not_equal, cstr, cptr),
+
+ //////////////////////////////////////////////////////////////
+ // operator< (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_less, cptr, cstr),
+ // operator< (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_less, cstr, cstr),
+ // operator< (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_less, cstr, cptr),
+
+ //////////////////////////////////////////////////////////////
+ // operator<= (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_less_equal, cptr, cstr),
+ // operator<= (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_less_equal, cstr, cstr),
+ // operator<= (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_less_equal, cstr, cptr),
+
+ //////////////////////////////////////////////////////////////
+ // operator> (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_greater, cptr, cstr),
+ // operator> (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_greater, cstr, cstr),
+ // operator> (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_greater, cstr, cptr),
+
+ //////////////////////////////////////////////////////////////
+ // operator>= (const_pointer, const basic_string&)
+ NON_MEMBER_2 (op_greater_equal, cptr, cstr),
+ // operator>= (const basic_string&, const basic_string&)
+ NON_MEMBER_2 (op_greater_equal, cstr, cstr),
+ // operator>= (const basic_string&, const_pointer)
+ NON_MEMBER_2 (op_greater_equal, cstr, cptr)
};
// clean up helper macros used above
Modified: incubator/stdcxx/trunk/tests/src/21.strings.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/src/21.strings.cpp?rev=409484&r1=409483&r2=409484&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/21.strings.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/21.strings.cpp Thu May 25 15:12:21 2006
@@ -71,7 +71,9 @@
"append", "assign", "erase", "insert", "replace", "operator+=", "find",
"rfind", "find_first_of", "find_last_of", "find_first_not_of",
"find_last_not_of", "compare", "substr", "operator[]", "at", "copy",
- "constructor", "operator=", "swap", "push_back"
+ 0 /* special handling for the ctor */, "operator=", "swap", "push_back",
+ "operator+", "operator==", "operator!=", "operator<", "operator<=",
+ "operator>", "operator>="
};
/**************************************************************************/
@@ -148,48 +150,140 @@
when);
}
+/**************************************************************************/
+
+static const char*
+_rw_class_name (const StringFunc &func)
+{
+ if ( StringIds::DefaultTraits == func.traits_id_
+ && StringIds::DefaultAlloc == func.alloc_id_) {
+
+ if (StringIds::Char == func.char_id_)
+ return "string";
+
+ if (StringIds::WChar == func.char_id_)
+ return "wstring";
+ }
+
+ return "basic_string";
+}
/**************************************************************************/
// appends the signature of the function specified by which
-// to the provided buffer; when brief is true, appends the
-// mnemonic representing the signature, including the name
-// of the function, instead
+// to the provided buffer; when the second argument is null,
+// appends the mnemonic representing the signature, including
+// the name of the function, as specified by the third argument
static void
_rw_sigcat (char **pbuf, size_t *pbufsize,
- StringIds::OverloadId which,
- bool brief = false)
+ const StringFunc *func,
+ StringIds::OverloadId which = StringIds::OverloadId ())
{
// for convenience
typedef StringIds Ids;
+ if (func)
+ which = func->which_;
+
+ // determine whether the function is a member function
+ const bool is_member = Ids::bit_member & which;
+
// get the bitmap describing the function's argument types
- int argmap = which >> Ids::fid_bits;
+ int argmap = (which & ~Ids::bit_member) >> Ids::fid_bits;
// determine whether the function is a const member function
- const bool is_const = Ids::arg_cstr == (argmap & Ids::arg_mask);
+ bool is_const_member =
+ is_member && Ids::arg_cstr == (argmap & Ids::arg_mask);
- // determine the string function name (for brief output)
- const size_t funcinx = which & StringIds::fid_mask;
- const size_t nfuncs = sizeof _rw_func_names / sizeof *_rw_func_names;
+ // remove the *this argument if the function is a member
+ if (is_member)
+ argmap >>= Ids::arg_bits;
+
+ const char* funcname = 0;
+
+ if (0 == func) {
+ const Ids::FuncId fid = Ids::FuncId (which & StringIds::fid_mask);
+
+ switch (fid) {
+ // translate names with funky characters to mnemonics
+ case Ids::fid_ctor: funcname = "ctor"; break;
+ case Ids::fid_op_plus_eq: funcname = "op_plus_eq"; break;
+ case Ids::fid_op_index: funcname = "op_index"; break;
+ case Ids::fid_op_set: funcname = "op_assign"; break;
+ case Ids::fid_op_plus: funcname = "op_plus"; break;
+ case Ids::fid_op_equal: funcname = "op_equal"; break;
+ case Ids::fid_op_not_equal: funcname = "op_not_equal"; break;
+ case Ids::fid_op_less: funcname = "op_less"; break;
+ case Ids::fid_op_less_equal: funcname = "op_less_equal"; break;
+ case Ids::fid_op_greater: funcname = "op_greater"; break;
+ case Ids::fid_op_greater_equal: funcname = "op_greater_equal"; break;
+
+ case Ids::fid_compare:
+ case Ids::fid_copy:
+ case Ids::fid_find:
+ case Ids::fid_find_first_not_of:
+ case Ids::fid_find_first_of:
+ case Ids::fid_find_last_not_of:
+ case Ids::fid_find_last_of:
+ case Ids::fid_rfind:
+ case Ids::fid_substr:
+ // prevent appending the "_const" bit to the mnemonics
+ // of member functions not overloaded on const
+ is_const_member = false;
+
+ // fall through
+
+ default: {
+ // determine the string function name (for brief output)
+ const size_t nfuncs =
+ sizeof _rw_func_names / sizeof *_rw_func_names;
- RW_ASSERT (funcinx < nfuncs);
+ RW_ASSERT (size_t (fid) < nfuncs);
- const char* const funcname = _rw_func_names [funcinx];
+ funcname = _rw_func_names [fid];
+ RW_ASSERT (0 != funcname);
+ break;
+ }
+ }
+ }
rw_asnprintf (pbuf, pbufsize, "%{+}%{?}%s%{?}_const%{;}%{:}(%{;}",
- brief, funcname, is_const);
+ 0 == func, funcname, is_const_member);
// iterate through the map of argument types one field at a time
// determining and formatting the type of each argument until
// void is reached
- for (size_t argno = 0; argmap >>= Ids::arg_bits; ++argno) {
+ for (size_t argno = 0; argmap; ++argno, argmap >>= Ids::arg_bits) {
+
+ const char* pfx = "";
+ const char* sfx = "";
const int argtype = argmap & Ids::arg_mask;
const char* tname = 0;
- if (brief) {
+ if (func) {
+ switch (argtype) {
+ case Ids::arg_size: tname = "size_type"; break;
+ case Ids::arg_val: tname = "value_type"; break;
+ case Ids::arg_ptr: tname = "pointer"; break;
+ case Ids::arg_cptr: tname = "const_pointer"; break;
+ case Ids::arg_ref: tname = "reference"; break;
+ case Ids::arg_cref: tname = "const_reference"; break;
+ case Ids::arg_iter: tname = "iterator"; break;
+ case Ids::arg_citer: tname = "const_iterator"; break;
+ case Ids::arg_range: tname = "InputIterator, InputIterator"; break;
+ case Ids::arg_alloc: tname = "const allocator_type&"; break;
+ case Ids::arg_cstr:
+ pfx = "const ";
+ // fall through
+ case Ids::arg_str:
+ tname = _rw_class_name (*func);
+ sfx = "&";
+ break;
+ }
+ }
+ else {
switch (argtype) {
case Ids::arg_size: tname = "size"; break;
case Ids::arg_val: tname = "val"; break;
@@ -200,39 +294,53 @@
case Ids::arg_iter: tname = "iter"; break;
case Ids::arg_citer: tname = "citer"; break;
case Ids::arg_range: tname = "range"; break;
+ case Ids::arg_alloc: tname = "alloc"; break;
case Ids::arg_str: tname = "str"; break;
case Ids::arg_cstr: tname = "cstr"; break;
- case Ids::arg_alloc: tname = "alloc"; break;
}
}
+
+ RW_ASSERT (0 != tname);
+
+ if ( 0 == func || is_member
+ || Ids::arg_str != argtype && Ids::arg_cstr != argtype) {
+ // append the name or mnemonic of the argument type
+ rw_asnprintf (pbuf, pbufsize, "%{+}%{?}_%{:}%{?}, %{;}%{;}%s%s%s",
+ 0 == func, 0 < argno, pfx, tname, sfx);
+ }
else {
- switch (argtype) {
- case Ids::arg_size: tname = "size_type"; break;
- case Ids::arg_val: tname = "value_type"; break;
- case Ids::arg_ptr: tname = "pointer"; break;
- case Ids::arg_cptr: tname = "const_pointer"; break;
- case Ids::arg_ref: tname = "reference"; break;
- case Ids::arg_cref: tname = "const_reference"; break;
- case Ids::arg_iter: tname = "iterator"; break;
- case Ids::arg_citer: tname = "const_iterator"; break;
- case Ids::arg_range: tname = "InputIterator, InputIterator"; break;
- case Ids::arg_str: tname = "basic_string&"; break;
- case Ids::arg_cstr: tname = "const basic_string&"; break;
- case Ids::arg_alloc: tname = "const allocator_type&"; break;
- }
+ // in non-member functions use ${CLASS} to format
+ // the basic_string argument in order to expand
+ // its template argument list
+ rw_asnprintf (pbuf, pbufsize,
+ "%{+}%{?}, %{;}%{?}const %{$CLASS}&%{;}",
+ 0 < argno, Ids::arg_cstr == argtype);
+
}
+ }
- RW_ASSERT (0 != tname);
+ if (func)
+ rw_asnprintf (pbuf, pbufsize, "%{+})%{?} const%{;}", is_const_member);
+}
+
+/**************************************************************************/
+
+static bool
+_rw_uses_alloc (StringIds::OverloadId which)
+{
+ // get the bitmap describing the function's argument types
+ int argmap = (which & ~StringIds::bit_member) >> StringIds::fid_bits;
- // append the name of the argument type
- rw_asnprintf (pbuf, pbufsize, "%{+}%{?}_%{:}%{?}, %{;}%{;}%s",
- brief, 0 < argno, tname);
+ for (; argmap; argmap >>= StringIds::arg_bits) {
+ if ((argmap & StringIds::arg_alloc) == StringIds::arg_alloc)
+ return true;
}
- if (!brief)
- rw_asnprintf (pbuf, pbufsize, "%{+})%{?} const%{;}", is_const);
+ return false;
}
+/**************************************************************************/
+
// sets the {CLASS}, {FUNC}, {FUNCSIG}, and optionally {FUNCALL}
// environment variables as follows:
// CLASS: the name of basic_string specialization
@@ -249,6 +357,8 @@
char* buf = 0;
size_t bufsize = 0;
+ const char* const class_name = _rw_class_name (func);
+
if (0 == pcase) {
// set the {charT}, {Traits}, and {Allocator} environment
// variables to the name of the character type and the
@@ -297,21 +407,29 @@
RW_ASSERT (funcinx < nfuncs);
- const char* const funcname = _rw_func_names [funcinx];
-
free (buf);
buf = 0;
bufsize = 0;
- // set the {FUNC} variable to the unqualified name
- // of the string function
- rw_asnprintf (&buf, &bufsize, "%s", funcname);
+ // get the undecorated function name; ctors are treated
+ // specially so that we can have string, wstring, or
+ // basic_string, depending on the template arguments
+ const char* const funcname = _rw_func_names [funcinx] ?
+ _rw_func_names [funcinx] : class_name;
+
+ // determine whether the function is a member function
+ const bool is_member = func.which_ & StringIds::bit_member;
+
+ // set the {FUNC} variable to the unqualified/undecorated
+ // name of the string function (member or otherwise)
+ rw_asnprintf (&buf, &bufsize, "%{?}std::%{;}%s",
+ !is_member, funcname);
rw_putenv ("FUNC=");
rw_fprintf (0, "%{$FUNC:=*}", buf);
// append the function signature
- _rw_sigcat (&buf, &bufsize, func.which_);
+ _rw_sigcat (&buf, &bufsize, &func);
rw_putenv ("FUNCSIG=");
rw_fprintf (0, "%{$FUNCSIG:=*}", buf);
@@ -342,15 +460,38 @@
else
arg = 0;
- // append the ctor argument(s) and the string function name
- rw_asnprintf (&buf, &bufsize,
- "%{$CLASS} (%{?}%{#*s}%{;}).%{$FUNC} ",
- str != 0, int (str_len), str);
+ // determine whether the function is a member function
+ const bool is_member = func.which_ & StringIds::bit_member;
+
+ // determine whether the function is a ctor
+ bool is_ctor = StringIds::fid_ctor == (func.which_ & StringIds::fid_mask);
+
+ if (is_ctor) {
+ // for ctors append just the class name here
+ // the class name will inserted below during argument
+ // formatting
+ rw_asnprintf (&buf, &bufsize, "%{$CLASS}::%s", class_name);
+ }
+ else if (is_member) {
+ // for other members append the ctor argument(s) followed
+ // by the string member function name
+ rw_asnprintf (&buf, &bufsize,
+ "%{$CLASS} (%{?}%{#*s}%{;}).%{$FUNC} ",
+ str != 0, int (str_len), str);
+ }
+ else {
+ // for non-members append just the function name here
+ // the class name will inserted below during argument
+ // formatting
+ rw_asnprintf (&buf, &bufsize, "%{$FUNC} ");
+ }
// compute the end offsets for convenience
const size_t range1_end = pcase->off + pcase->size;
const size_t range2_end = pcase->off2 + pcase->size2;
+ const bool use_alloc = _rw_uses_alloc (func.which_);
+
// format and append string function arguments abbreviating complex
// expressions as much as possible to make them easy to understand
switch (func.which_) {
@@ -364,12 +505,14 @@
case StringIds::find_first_not_of_cptr:
case StringIds::find_last_not_of_cptr:
case StringIds::compare_cptr:
- case StringIds::ctor_cptr:
case StringIds::op_set_cptr:
+ case StringIds::ctor_cptr:
+ case StringIds::ctor_cptr_alloc:
// format self-referential ptr argument without size as c_str()
rw_asnprintf (&buf, &bufsize,
- "%{+}(%{?}c_str()%{:}%{#*s}%{;})",
- self, int (arg_len), arg);
+ "%{+}(%{?}c_str()%{:}%{#*s}%{;}"
+ "%{?}, const allocator_type&%{;})",
+ self, int (arg_len), arg, use_alloc);
break;
case StringIds::append_cstr:
@@ -383,22 +526,26 @@
case StringIds::find_last_not_of_cstr:
case StringIds::compare_cstr:
case StringIds::ctor_cstr:
+ case StringIds::ctor_cstr_alloc:
case StringIds::op_set_cstr:
case StringIds::swap_str:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize,
- "%{+}(%{?}*this%{:}string(%{#*s})%{;})",
- self, int (arg_len), arg);
+ "%{+}(%{?}*this%{:}%s(%{#*s})%{;}"
+ "%{?}, const allocator_type&%{;})",
+ self, class_name, int (arg_len), arg, use_alloc);
break;
case StringIds::append_cptr_size:
case StringIds::assign_cptr_size:
case StringIds::copy_ptr_size:
case StringIds::ctor_cptr_size:
+ case StringIds::ctor_cptr_size_alloc:
// format self-referential ptr argument with size as data()
rw_asnprintf (&buf, &bufsize, "%{+}("
- "%{?}data()%{:}%{#*s}%{;}, %zu)",
- self, int (arg_len), arg, pcase->size);
+ "%{?}data()%{:}%{#*s}%{;}, %zu"
+ "%{?}, const allocator_type&%{;})",
+ self, int (arg_len), arg, pcase->size, use_alloc);
break;
case StringIds::find_cptr_size:
@@ -420,10 +567,13 @@
case StringIds::find_first_not_of_cstr_size:
case StringIds::find_last_not_of_cstr_size:
case StringIds::ctor_cstr_size:
+ case StringIds::ctor_cstr_size_alloc:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}("
- "%{?}*this%{:}string(%{#*s})%{;}, %zu)",
- self, int (arg_len), arg, pcase->off);
+ "%{?}*this%{:}%s(%{#*s})%{;}, %zu"
+ "%{?}, const allocator_type%{;})",
+ self, class_name, int (arg_len), arg, pcase->off,
+ use_alloc);
break;
case StringIds::find_cptr_size_size:
@@ -450,31 +600,37 @@
case StringIds::append_cstr_size_size:
case StringIds::assign_cstr_size_size:
case StringIds::ctor_cstr_size_size:
+ case StringIds::ctor_cstr_size_size_alloc:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}("
- "%{?}*this%{:}string(%{#*s})%{;}, %zu, %zu)",
- self, int (arg_len), arg,
- pcase->off, pcase->size);
+ "%{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu"
+ "%{?}, const allocator_type%{;})",
+ self, class_name, int (arg_len), arg,
+ pcase->off, pcase->size, use_alloc);
break;
case StringIds::append_size_val:
case StringIds::assign_size_val:
case StringIds::ctor_size_val:
+ case StringIds::ctor_size_val_alloc:
rw_asnprintf (&buf, &bufsize,
- "%{+}(%zu, %{#c})", pcase->size, pcase->val);
+ "%{+}(%zu, %{#c}%{?}, const allocator_type&%{;})",
+ pcase->size, pcase->val, use_alloc);
break;
case StringIds::append_range:
case StringIds::assign_range:
case StringIds::ctor_range:
+ case StringIds::ctor_range_alloc:
rw_asnprintf (&buf, &bufsize, "%{+}("
"%{?}begin()%{:}Iterator(%{#*s})%{;}"
"%{?} + %zu%{;}, "
"%{?}begin()%{:}Iterator(...)%{;}"
- "%{?} + %zu%{;})",
+ "%{?} + %zu%{;}"
+ "%{?}, const allocator_type&%{;})",
self, int (arg_len), arg,
0 != pcase->off, pcase->off,
- self, 0 != range1_end, range1_end);
+ self, 0 != range1_end, range1_end, use_alloc);
break;
case StringIds::insert_size_cptr:
@@ -487,8 +643,8 @@
case StringIds::insert_size_cstr:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize,
- "%{+}(%zu, %{?}*this%{:}string(%{#*s})%{;})",
- pcase->off, self, int (arg_len), arg);
+ "%{+}(%zu, %{?}*this%{:}%s(%{#*s})%{;})",
+ pcase->off, self, class_name, int (arg_len), arg);
break;
case StringIds::insert_size_cptr_size:
@@ -502,8 +658,8 @@
case StringIds::insert_size_cstr_size_size:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}("
- "%zu, %{?}*this%{:}string(%{#*s})%{;}, %zu, %zu)",
- pcase->off, self, int (arg_len), arg,
+ "%zu, %{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu)",
+ pcase->off, self, class_name, int (arg_len), arg,
pcase->off2, pcase->size2);
break;
@@ -549,8 +705,8 @@
case StringIds::compare_size_size_cstr:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}("
- "%zu, %zu, %{?}*this%{:}string(%{#*s})%{;})",
- pcase->off, pcase->size, self,
+ "%zu, %zu, %{?}*this%{:}%s(%{#*s})%{;})",
+ pcase->off, pcase->size, self, class_name,
int (arg_len), arg);
break;
@@ -567,9 +723,9 @@
case StringIds::compare_size_size_cstr_size_size:
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}(%zu, %zu, "
- "%{?}*this%{:}string(%{#*s})%{;}, %zu, %zu)",
- pcase->off, pcase->size, self,
- int (arg_len), arg,
+ "%{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu)",
+ pcase->off, pcase->size,
+ self, class_name, int (arg_len), arg,
pcase->off2, pcase->size2);
break;
@@ -593,10 +749,10 @@
// format self-referential str argument as *this
rw_asnprintf (&buf, &bufsize, "%{+}(begin()%{?} + %zu%{;}, "
"begin()%{?} + %zu%{;}, "
- "%{?}*this%{:}string(%{#*s})%{;})",
+ "%{?}*this%{:}%s(%{#*s})%{;})",
0 != pcase->off, pcase->off,
0 != range1_end, range1_end,
- self, int (arg_len), arg);
+ self, class_name, int (arg_len), arg);
break;
case StringIds::replace_iter_iter_cptr_size:
@@ -661,6 +817,11 @@
"%{+}()");
break;
+ case StringIds::ctor_alloc:
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(const allocator_type&)");
+ break;
+
case StringIds::erase_size:
case StringIds::substr_size:
case StringIds::op_index_size:
@@ -694,6 +855,60 @@
0 != range1_end, range1_end);
break;
+ case StringIds::op_plus_cptr_cstr:
+ case StringIds::op_equal_cptr_cstr:
+ case StringIds::op_not_equal_cptr_cstr:
+ case StringIds::op_less_cptr_cstr:
+ case StringIds::op_less_equal_cptr_cstr:
+ case StringIds::op_greater_cptr_cstr:
+ case StringIds::op_greater_equal_cptr_cstr:
+ // format zero ptr argument without size as arg.c_str()
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(%{?}arg2.c_str()%{:}%{#*s}%{;}, "
+ "%{$CLASS}(%{#*s}))",
+ 0 == str, int (str_len), str, int (arg_len), arg);
+ break;
+
+ case StringIds::op_plus_cstr_cptr:
+ case StringIds::op_equal_cstr_cptr:
+ case StringIds::op_not_equal_cstr_cptr:
+ case StringIds::op_less_cstr_cptr:
+ case StringIds::op_less_equal_cstr_cptr:
+ case StringIds::op_greater_cstr_cptr:
+ case StringIds::op_greater_equal_cstr_cptr:
+ // format zero ptr argument without size as arg.c_str()
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(%{$CLASS}(%{#*s}), "
+ "%{?}arg1.c_str()%{:}%{#*s}%{;})",
+ int (str_len), str, self, int (arg_len), arg);
+ break;
+
+ case StringIds::op_plus_cstr_cstr:
+ case StringIds::op_equal_cstr_cstr:
+ case StringIds::op_not_equal_cstr_cstr:
+ case StringIds::op_less_cstr_cstr:
+ case StringIds::op_less_equal_cstr_cstr:
+ case StringIds::op_greater_cstr_cstr:
+ case StringIds::op_greater_equal_cstr_cstr:
+ // format zero str argument without size as arg
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(%{?}arg2%{:}%{$CLASS}(%{#*s})%{;}, "
+ "%{?}arg1%{:}%{$CLASS}(%{#*s})%{;})",
+ 0 == str, int (str_len), str, self, int (arg_len), arg);
+ break;
+
+ case StringIds::op_plus_cstr_val:
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(%{$CLASS}(%{#*s}), %{#c})",
+ int (arg_len), arg, pcase->val);
+ break;
+
+ case StringIds::op_plus_val_cstr:
+ rw_asnprintf (&buf, &bufsize,
+ "%{+}(%{#c}, %{$CLASS}(%{#*s}))",
+ pcase->val, int (arg_len), arg);
+ break;
+
default:
RW_ASSERT (!"test logic error: unknown overload");
}
@@ -904,6 +1119,9 @@
// and the string function being exercised
_rw_setvars (func);
+ // determine whether the function is a member function
+ const bool is_member = StringIds::bit_member & test.which;
+
// compute the function overload's 0-based index
const size_t siginx = _rw_get_func_inx (test.which);
@@ -911,10 +1129,12 @@
// have been disabled
if (0 == rw_note (0 <= _rw_opt_func [siginx],
_rw_this_file, __LINE__,
- "%{$CLASS}::%{$FUNCSIG} tests disabled"))
+ "%{?%{$CLASS}::%{;}%{$FUNCSIG} "
+ "tests disabled", is_member))
continue;
- rw_info (0, 0, 0, "%{$CLASS}::%{$FUNCSIG}");
+ rw_info (0, 0, 0, "%{?}%{$CLASS}::%{;}%{$FUNCSIG}",
+ is_member);
const size_t case_count = test.case_count;
@@ -975,7 +1195,7 @@
// for each function append a command line option specification
// to allow to enable or disable it
rw_asnprintf (&optbuf, &optbufsize, "%{+}|-");
- _rw_sigcat (&optbuf, &optbufsize, tests [i].which, true);
+ _rw_sigcat (&optbuf, &optbufsize, 0, tests [i].which);
rw_asnprintf (&optbuf, &optbufsize, "%{+}~ ");
}