| /************************************************************************ |
| * |
| * 21.strings.h - definitions of helpers used in clause 21 tests |
| * |
| * $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. |
| * |
| **************************************************************************/ |
| |
| #ifndef RW_21_STRINGS_H_INCLUDED |
| #define RW_21_STRINGS_H_INCLUDED |
| |
| #include <rw_char.h> // for rw_expand() |
| #include <testdefs.h> |
| #include <23.containers.h> // for ContainerIds |
| |
| /**************************************************************************/ |
| |
| // defines enumerations identifying basic_string template arguments, |
| // sets of overloaded functions, member types used in the declarations |
| // of their signatures, and specific overloads of such member functions |
| struct StringIds: ContainerIds { |
| |
| // identifiers for the charT template argument |
| enum CharId { Char, WChar, UChar }; |
| |
| // identifiers for the Traits template argument |
| enum TraitsId { DefaultTraits, UserTraits }; |
| |
| // identifies a set of overloaded member or non-member |
| // string functions |
| enum FuncId { |
| // 6 bits, 64 functions max |
| /* 0 */ fid_append, |
| /* 1 */ fid_assign, |
| /* 2 */ fid_erase, |
| /* 3 */ fid_insert, |
| /* 4 */ fid_replace, |
| /* 5 */ fid_op_plus_eq, |
| /* 6 */ fid_find, |
| /* 7 */ fid_rfind, |
| /* 8 */ fid_find_first_of, |
| /* 9 */ fid_find_last_of, |
| /* 10 */ fid_find_first_not_of, |
| /* 11 */ fid_find_last_not_of, |
| /* 12 */ fid_compare, |
| /* 13 */ fid_substr, |
| /* 14 */ fid_op_index, |
| /* */ fid_op_index_const = fid_op_index, |
| /* 15 */ fid_at, |
| /* */ fid_at_const = fid_at, |
| /* 16 */ fid_copy, |
| /* 17 */ fid_ctor, |
| /* 18 */ fid_op_set, |
| /* 19 */ fid_swap, |
| /* 20 */ fid_push_back, |
| /* 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, |
| /* 28 */ fid_size, |
| /* 29 */ fid_length, |
| /* 30 */ fid_max_size, |
| /* 31 */ fid_resize, |
| /* 32 */ fid_capacity, |
| /* 33 */ fid_reserve, |
| /* 34 */ fid_clear, |
| /* 35 */ fid_empty, |
| /* 36 */ fid_begin, |
| /* */ fid_begin_const = fid_begin, |
| /* 37 */ fid_end, |
| /* */ fid_end_const = fid_end, |
| /* 38 */ fid_rbegin, |
| /* */ fid_rbegin_const = fid_rbegin, |
| /* 39 */ fid_rend, |
| /* */ fid_rend_const = fid_rend, |
| /* 40 */ fid_c_str, |
| /* 41 */ fid_data, |
| /* 42 */ fid_get_allocator, |
| /* 43 */ fid_extractor, |
| /* 44 */ fid_inserter, |
| /* 45 */ fid_getline, |
| /* -- */ fid_bits = 6, |
| /* -- */ fid_mask = 63 |
| }; |
| |
| // identifies the type of a function argument, including |
| // the implicit this |
| enum ArgId { |
| // 4 bits, 16 types max |
| /* 0 */ arg_void, // void |
| /* 1 */ arg_size, // size_type |
| /* 2 */ arg_val, // value_type |
| /* 3 */ arg_ptr, // pointer |
| /* 4 */ arg_cptr, // const_pointer |
| /* 5 */ arg_ref, // reference |
| /* 6 */ arg_cref, // const_reference |
| /* 7 */ arg_iter, // iterator |
| /* 8 */ arg_citer, // const_iterator |
| /* 9 */ arg_range, // Iterator, Iterator |
| /* 10 */ arg_str, // string& (or this for member functions) |
| /* 11 */ arg_cstr, // const string& (or const this for members) |
| /* 12 */ arg_alloc, // const allocator& |
| /* 13 */ arg_istream, // istream& |
| /* 14 */ arg_ostream, // ostream& |
| /* -- */ arg_bits = 4, |
| /* -- */ arg_mask = 15 |
| }; |
| |
| enum { |
| // bit designating a member function |
| bit_member = 1 << (fid_bits + 6 * arg_bits) |
| }; |
| |
| // define the helper macros |
| #include <rw_sigdefs.h> |
| |
| // 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) |
| MEMBER_1 (append, str, cptr), |
| // append (const basic_string&) |
| MEMBER_1 (append, str, cstr), |
| // append (const_pointer, size_type) |
| MEMBER_2 (append, str, cptr, size), |
| // append (const basic_string&, size_type, size_type) |
| MEMBER_3 (append, str, cstr, size, size), |
| // append (size_type, value_type) |
| MEMBER_2 (append, str, size, val), |
| // append (InputIterator, InputIterator) |
| MEMBER_1 (append, str, range), |
| |
| ////////////////////////////////////////////////////////////// |
| // assign (const_pointer) |
| MEMBER_1 (assign, str, cptr), |
| // assign (const basic_string&) |
| MEMBER_1 (assign, str, cstr), |
| // assign (const_pointer, size_type) |
| MEMBER_2 (assign, str, cptr, size), |
| // assign (const basic_string&, size_type, size_type) |
| MEMBER_3 (assign, str, cstr, size, size), |
| // assign (size_type, value_type) |
| MEMBER_2 (assign, str, size, val), |
| // assign (InputIterator, InputIterator) |
| MEMBER_1 (assign, str, range), |
| |
| ////////////////////////////////////////////////////////////// |
| // erase () |
| MEMBER_0 (erase, str), |
| // erase (size_type) |
| MEMBER_1 (erase, str, size), |
| // erase (size_type, size_type) |
| MEMBER_2 (erase, str, size, size), |
| // erase (iterator) |
| MEMBER_1 (erase, str, iter), |
| // erase (iterator, iterator) |
| MEMBER_2 (erase, str, iter, iter), |
| |
| ////////////////////////////////////////////////////////////// |
| // insert (size_type, const_pointer) |
| MEMBER_2 (insert, str, size, cptr), |
| // insert (size_type, const basic_string&) |
| MEMBER_2 (insert, str, size, cstr), |
| // insert (size_type, const_pointer, size_type) |
| MEMBER_3 (insert, str, size, cptr, size), |
| // insert (size_type, const basic_string&, size_type, size_type) |
| MEMBER_4 (insert, str, size, cstr, size, size), |
| // insert (size_type, size_type, value_type) |
| MEMBER_3 (insert, str, size, size, val), |
| // insert (iterator, value_type) |
| MEMBER_2 (insert, str, iter, val), |
| // insert (iterator, size_type, value_type) |
| MEMBER_3 (insert, str, iter, size, val), |
| // insert (iterator, InputIterator, InputIterator) |
| MEMBER_2 (insert, str, iter, range), |
| |
| ////////////////////////////////////////////////////////////// |
| // (size_type, size_type, const_pointer) |
| MEMBER_3 (replace, str, size, size, cptr), |
| // (size_type, size_type, const basic_string&) |
| MEMBER_3 (replace, str, size, size, cstr), |
| // (size_type, size_type, const_pointer, size_type) |
| MEMBER_4 (replace, str, size, size, cptr, size), |
| // (size_type, size_type, const basic_string&, size_type, size_type) |
| MEMBER_5 (replace, str, size, size, cstr, size, size), |
| // (size_type, size_type, size_type, value_type) |
| MEMBER_4 (replace, str, size, size, size, val), |
| // (iterator, iterator, const_pointer) |
| MEMBER_3 (replace, str, iter, iter, cptr), |
| // (iterator, iterator, const basic_string&) |
| MEMBER_3 (replace, str, iter, iter, cstr), |
| // (iterator, iterator, const_pointer, size_type) |
| MEMBER_4 (replace, str, iter, iter, cptr, size), |
| // (iterator, iterator, size_type, value_type) |
| MEMBER_4 (replace, str, iter, iter, size, val), |
| // (iterator, iterator, InputIterator, InputIterator) |
| MEMBER_3 (replace, str, iter, iter, range), |
| |
| ////////////////////////////////////////////////////////////// |
| // operator+= (const_pointer) |
| MEMBER_1 (op_plus_eq, str, cptr), |
| // operator+= (const basic_string&) |
| MEMBER_1 (op_plus_eq, str, cstr), |
| // operator+= (value_type) |
| MEMBER_1 (op_plus_eq, str, val), |
| |
| ////////////////////////////////////////////////////////////// |
| // overloads of find, rfind, find_first_of, find_last_of, |
| // find_first_not_of, find_last_not_of |
| |
| // find (const_pointer) const |
| MEMBER_1 (find, cstr, cptr), |
| // find (const basic_string&) const |
| MEMBER_1 (find, cstr, cstr), |
| // find (const_pointer, size_type) const |
| MEMBER_2 (find, cstr, cptr, size), |
| // find (const_pointer, size_type, size_type) const |
| MEMBER_3 (find, cstr, cptr, size, size), |
| // find (const basic_string&, size_type) const |
| MEMBER_2 (find, cstr, cstr, size), |
| // find (value_type) const |
| MEMBER_1 (find, cstr, val), |
| // find (value_type, size_type) const |
| MEMBER_2 (find, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // rfind (const_pointer) const |
| MEMBER_1 (rfind, cstr, cptr), |
| // rfind (const basic_string&) const |
| MEMBER_1 (rfind, cstr, cstr), |
| // rfind (const_pointer, size_type) const |
| MEMBER_2 (rfind, cstr, cptr, size), |
| // rfind (const_pointer, size_type, size_type) const |
| MEMBER_3 (rfind, cstr, cptr, size, size), |
| // rfind (const basic_string&, size_type) const |
| MEMBER_2 (rfind, cstr, cstr, size), |
| // rfind (value_type) const |
| MEMBER_1 (rfind, cstr, val), |
| // rfind (value_type, size_type) const |
| MEMBER_2 (rfind, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // find_first_of (const_pointer) const |
| MEMBER_1 (find_first_of, cstr, cptr), |
| // find_first_of (const basic_string&) const |
| MEMBER_1 (find_first_of, cstr, cstr), |
| // find_first_of (const_pointer, size_type) const |
| MEMBER_2 (find_first_of, cstr, cptr, size), |
| // find_first_of (const_pointer, size_type, size_type) const |
| MEMBER_3 (find_first_of, cstr, cptr, size, size), |
| // find_first_of (const basic_string&, size_type) const |
| MEMBER_2 (find_first_of, cstr, cstr, size), |
| // find_first_of (value_type) const |
| MEMBER_1 (find_first_of, cstr, val), |
| // find_first_of (value_type, size_type) const |
| MEMBER_2 (find_first_of, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // find_last_of (const_pointer) const |
| MEMBER_1 (find_last_of, cstr, cptr), |
| // find_last_of (const basic_string&) const |
| MEMBER_1 (find_last_of, cstr, cstr), |
| // find_last_of (const_pointer, size_type) const |
| MEMBER_2 (find_last_of, cstr, cptr, size), |
| // find_last_of (const_pointer, size_type, size_type) const |
| MEMBER_3 (find_last_of, cstr, cptr, size, size), |
| // find_last_of (const basic_string&, size_type) const |
| MEMBER_2 (find_last_of, cstr, cstr, size), |
| // find_last_of (value_type) const |
| MEMBER_1 (find_last_of, cstr, val), |
| // find_last_of (value_type, size_type) const |
| MEMBER_2 (find_last_of, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // find_first_not_of (const_pointer) const |
| MEMBER_1 (find_first_not_of, cstr, cptr), |
| // find_first_not_of (const basic_string&) const |
| MEMBER_1 (find_first_not_of, cstr, cstr), |
| // find_first_not_of (const_pointer, size_type) const |
| MEMBER_2 (find_first_not_of, cstr, cptr, size), |
| // find_first_not_of (const_pointer, size_type, size_type) const |
| MEMBER_3 (find_first_not_of, cstr, cptr, size, size), |
| // find_first_not_of (const basic_string&, size_type) const |
| MEMBER_2 (find_first_not_of, cstr, cstr, size), |
| // find_first_not_of (value_type) const |
| MEMBER_1 (find_first_not_of, cstr, val), |
| // find_first_not_of (value_type, size_type) const |
| MEMBER_2 (find_first_not_of, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // find_last_not_of (const_pointer) const |
| MEMBER_1 (find_last_not_of, cstr, cptr), |
| // find_last_not_of (const basic_string&) const |
| MEMBER_1 (find_last_not_of, cstr, cstr), |
| // find_last_not_of (const_pointer, size_type) const |
| MEMBER_2 (find_last_not_of, cstr, cptr, size), |
| // find_last_not_of (const_pointer, size_type, size_type) const |
| MEMBER_3 (find_last_not_of, cstr, cptr, size, size), |
| // find_last_not_of (const basic_string&, size_type) const |
| MEMBER_2 (find_last_not_of, cstr, cstr, size), |
| // find_last_not_of (value_type) const |
| MEMBER_1 (find_last_not_of, cstr, val), |
| // find_last_not_of (value_type, size_type) const |
| MEMBER_2 (find_last_not_of, cstr, val, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // compare (const_pointer) const |
| MEMBER_1 (compare, cstr, cptr), |
| // compare (const basic_string&) const |
| MEMBER_1 (compare, cstr, cstr), |
| // compare (size_type, size_type, const_pointer) const |
| MEMBER_3 (compare, cstr, size, size, cptr), |
| // compare (size_type, size_type, const basic_string&) const |
| MEMBER_3 (compare, cstr, size, size, cstr), |
| // compare (size_type, size_type, const_pointer, size_type) const |
| MEMBER_4 (compare, cstr, size, size, cptr, size), |
| // compare (size_type, size_type, const basic_string&, |
| // size_type, size_type) const |
| MEMBER_5 (compare, cstr, size, size, cstr, size, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // substr (void) const |
| MEMBER_0 (substr, cstr), |
| // substr (size_type) const |
| MEMBER_1 (substr, cstr, size), |
| // substr (size_type, size_type) const |
| MEMBER_2 (substr, cstr, size, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // operator[] (size_type) |
| MEMBER_1 (op_index, str, size), |
| // operator[] (size_type) const |
| MEMBER_1 (op_index_const, cstr, size), |
| // at (size_type) |
| MEMBER_1 (at, str, size), |
| // at (size_type) const |
| MEMBER_1 (at_const, cstr, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // copy (pointer, size_type) const |
| MEMBER_2 (copy, cstr, ptr, size), |
| // copy (pointer, size_type, size_type) const |
| MEMBER_3 (copy, cstr, ptr, size, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // basic_string (void) |
| MEMBER_0 (ctor, str), |
| // basic_string (const allocator_type&) |
| MEMBER_1 (ctor, str, alloc), |
| // basic_string (const_pointer) |
| MEMBER_1 (ctor, str, cptr), |
| // basic_string (const_pointer, const allocator_type&) |
| MEMBER_2 (ctor, str, cptr, alloc), |
| // basic_string (const basic_string&) |
| MEMBER_1 (ctor, str, cstr), |
| // basic_string (const basic_string&, const allocator_type&) |
| MEMBER_2 (ctor, str, cstr, alloc), |
| // basic_string (const_pointer, size_type) |
| MEMBER_2 (ctor, str, cptr, size), |
| // basic_string (const_pointer, size_type, const allocator_type&) |
| MEMBER_3 (ctor, str, cptr, size, alloc), |
| // basic_string (const basic_string&, size_type) |
| MEMBER_2 (ctor, str, cstr, size), |
| // basic_string (const basic_string&, size_type, const allocator&) |
| MEMBER_3 (ctor, str, cstr, size, alloc), |
| // basic_string (const basic_string&, size_type, size_type) |
| MEMBER_3 (ctor, str, cstr, size, size), |
| // basic_string (const basic_string&, size_type, size_type, allocator&) |
| MEMBER_4 (ctor, str, cstr, size, size, alloc), |
| // basic_string (size_type, value_type) |
| MEMBER_2 (ctor, str, size, val), |
| // basic_string (size_type, value_type, const allocator_type&) |
| MEMBER_3 (ctor, str, size, val, alloc), |
| // basic_string (InputIterator, InputIterator) |
| MEMBER_1 (ctor, str, range), |
| // basic_string (InputIterator, InputIterator, const allocator&) |
| MEMBER_2 (ctor, str, range, alloc), |
| |
| ////////////////////////////////////////////////////////////// |
| // operator= (const_pointer) |
| MEMBER_1 (op_set, str, cptr), |
| // operator= (const basic_string&) |
| MEMBER_1 (op_set, str, cstr), |
| // operator= (value_type) |
| MEMBER_1 (op_set, str, val), |
| |
| ////////////////////////////////////////////////////////////// |
| // swap (basic_string&) |
| MEMBER_1 (swap, str, str), |
| |
| ////////////////////////////////////////////////////////////// |
| // push_back (value_type) |
| 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), |
| |
| ////////////////////////////////////////////////////////////// |
| // size () const |
| MEMBER_0 (size, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // length () const |
| MEMBER_0 (length, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // max_size () const |
| MEMBER_0 (max_size, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // resize (size_type, value_type) |
| MEMBER_2 (resize, str, size, val), |
| // resize (size_type) |
| MEMBER_1 (resize, str, size), |
| |
| ////////////////////////////////////////////////////////////// |
| // capacity () const |
| MEMBER_0 (capacity, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // reserve (size_type) |
| MEMBER_1 (reserve, str, size), |
| // reserve () |
| MEMBER_0 (reserve, str), |
| |
| ////////////////////////////////////////////////////////////// |
| // clear () |
| MEMBER_0 (clear, str), |
| |
| ////////////////////////////////////////////////////////////// |
| // empty () const |
| MEMBER_0 (empty, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // begin () |
| MEMBER_0 (begin, str), |
| // begin () const |
| MEMBER_0 (begin_const, cstr), |
| // end () |
| MEMBER_0 (end, str), |
| // end () const |
| MEMBER_0 (end_const, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // rbegin () |
| MEMBER_0 (rbegin, str), |
| // rbegin () const |
| MEMBER_0 (rbegin_const, cstr), |
| // rend () |
| MEMBER_0 (rend, str), |
| // rend () const |
| MEMBER_0 (rend_const, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // c_str () const |
| MEMBER_0 (c_str, cstr), |
| // data () const |
| MEMBER_0 (data, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // get_allocator () const |
| MEMBER_0 (get_allocator, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // operator>> (istream&, basic_string&) |
| NON_MEMBER_2 (extractor, istream, str), |
| // operator<< (ostream&, const basic_string&) |
| NON_MEMBER_2 (inserter, ostream, cstr), |
| |
| ////////////////////////////////////////////////////////////// |
| // getline (istream&, basic_string&) |
| NON_MEMBER_2 (getline, istream, str), |
| // getline (istream&, basic_string&, value_type) |
| NON_MEMBER_3 (getline, istream, str, val) |
| }; |
| |
| // clean up helper macros used above |
| #include <rw_sigdefs.h> |
| |
| static ArgId arg_type (OverloadId id, int argno) { |
| return ArgId (((int (id) >> fid_bits) >> argno * arg_bits) & arg_mask); |
| } |
| }; |
| |
| /**************************************************************************/ |
| |
| static const _RWSTD_SIZE_T |
| NPOS = _RWSTD_SIZE_MAX; |
| |
| /**************************************************************************/ |
| |
| struct StringFunc |
| { |
| StringIds::CharId char_id_; |
| StringIds::TraitsId traits_id_; |
| StringIds::AllocId alloc_id_; |
| StringIds::IteratorId iter_id_; |
| StringIds::OverloadId which_; |
| }; |
| |
| |
| // describes a single test case for any overload of any string |
| // function (the same test case can be used to exercise more |
| // than one overload of the same function) |
| struct StringTestCase |
| { |
| int line; // test case line number |
| |
| int off; // offset (position argument) |
| int size; // size (count argument) |
| |
| int off2; // offset 2 (position argument) |
| int size2; // size 2 (count argument) |
| |
| int val; // value (single character to append) |
| |
| const char* str; // controlled sequence |
| _RWSTD_SIZE_T str_len; // length of sequence |
| |
| const char* arg; // sequence to insert |
| _RWSTD_SIZE_T arg_len; // length of sequence |
| |
| const char* res; // resulting sequence |
| _RWSTD_SIZE_T nres; // length of sequence or expected result |
| // value for find, rfind, compare, etc |
| |
| int bthrow; // exception expected |
| }; |
| |
| |
| // describes a set of test cases for a single overload of a function |
| struct StringTest |
| { |
| // string function overload to exercise |
| StringIds::OverloadId which; |
| |
| // test cases to exercise overload withh |
| const StringTestCase *cases; |
| |
| // number of test cases |
| _RWSTD_SIZE_T case_count; |
| }; |
| |
| |
| // sets the {CLASS}, {FUNC}, {FUNCSIG}, and optionally {FUNCALL} |
| // environment variables as follows: |
| // CLASS: the name of basic_string specialization |
| // FUNC: the name of the basic_string function |
| // FUNCSIG: the name and signature of a specific overload |
| // of the basic_string function |
| // FUNCALL: a string describing the call to the basic_string function |
| // with function with function arguments expanded (as specified |
| // by the TestCase argument) |
| _TEST_EXPORT void |
| rw_setvars (const StringFunc&, const StringTestCase* = 0); |
| |
| typedef void StringTestFunc (const StringFunc&, const StringTestCase&); |
| |
| _TEST_EXPORT int |
| rw_run_string_test (int, char**, const char*, const char*, |
| StringTestFunc*, const StringTest*, _RWSTD_SIZE_T); |
| |
| typedef void VoidFunc (); |
| |
| _TEST_EXPORT int |
| rw_run_string_test (int, char**, const char*, const char*, |
| VoidFunc* const*, const StringTest*, _RWSTD_SIZE_T); |
| |
| /**************************************************************************/ |
| |
| template <class charT> |
| class StringTestCaseData |
| { |
| private: |
| |
| enum { BUFSIZE = 256 }; |
| |
| // small buffers to avoid expensive dynamic memory allocation |
| // in most test cases (will dynamically allocate sufficient |
| // storage if necessary) |
| charT str_buf_ [BUFSIZE]; |
| charT arg_buf_ [BUFSIZE]; |
| charT res_buf_ [BUFSIZE]; |
| |
| // not defined, not copiable, not assignable |
| StringTestCaseData (const StringTestCaseData&); |
| void operator= (const StringTestCaseData&); |
| |
| // for convenience |
| typedef _RWSTD_SIZE_T SizeType; |
| |
| public: |
| |
| SizeType strlen_; // the length of the expanded string |
| SizeType arglen_; // the length of the expanded argument |
| SizeType reslen_; // the length of the expanded result |
| |
| // the offset and extent (the number of elements) of |
| // the first range into the string object being modified |
| SizeType off1_; |
| SizeType ext1_; |
| |
| // the offset and extent (the number of elements) of |
| // the argument of the function call |
| SizeType off2_; |
| SizeType ext2_; |
| |
| const charT* const str_; // pointer to the expanded string |
| const charT* const arg_; // pointer to the expanded argument |
| const charT* const res_; // pointer to the expanded result |
| |
| const StringFunc &func_; |
| const StringTestCase &tcase_; |
| |
| // converts the narrow (and possibly) condensed strings to fully |
| // expanded wide character arrays that can be used to construct |
| // basic_string objects |
| StringTestCaseData (const StringFunc &func, const StringTestCase &tcase) |
| : strlen_ (BUFSIZE), arglen_ (BUFSIZE), reslen_ (BUFSIZE), |
| str_ (rw_expand (str_buf_, tcase.str, tcase.str_len, &strlen_)), |
| arg_ (rw_expand (arg_buf_, tcase.arg, tcase.arg_len, &arglen_)), |
| res_ (rw_expand (res_buf_, tcase.res, tcase.nres, &reslen_)), |
| func_ (func), tcase_ (tcase) { |
| // compute the offset and extent of the string object |
| // representing the controlled sequence and the offset |
| // and extent of the argument of the function call |
| const SizeType argl = tcase_.arg ? arglen_ : strlen_; |
| |
| off1_ = SizeType (tcase_.off) < strlen_ ? |
| SizeType (tcase_.off) : strlen_; |
| |
| ext1_ = off1_ + tcase_.size < strlen_ ? |
| SizeType (tcase_.size) : strlen_ - off1_; |
| |
| off2_ = SizeType (tcase_.off2) < argl ? |
| SizeType (tcase_.off2) : argl; |
| |
| ext2_ = off2_ + tcase_.size2 < argl ? |
| SizeType (tcase_.size2) : argl - off2_; |
| } |
| |
| ~StringTestCaseData () { |
| // clean up dynamically allocated memory (if any) |
| if (str_ != str_buf_) |
| delete[] _RWSTD_CONST_CAST (charT*, str_); |
| if (arg_ != arg_buf_) |
| delete[] _RWSTD_CONST_CAST (charT*, arg_); |
| if (res_ != res_buf_) |
| delete[] _RWSTD_CONST_CAST (charT*, res_); |
| } |
| }; |
| |
| /**************************************************************************/ |
| |
| // encapsulates the state of a string object without regard to type |
| // used in exception safety tests to determine changes to the state |
| // after a modifying operation throws an exception |
| struct _TEST_EXPORT StringState |
| { |
| const void* data_; |
| _RWSTD_SIZE_T size_; |
| _RWSTD_SIZE_T capacity_; |
| |
| // invokes rw_assert() to verify that two states are the same |
| // returns 1 when the two states compare equal, and 0 otherwise |
| int assert_equal (const StringState&, int, int, const char*) const; |
| }; |
| |
| |
| // creates a StringState object from a basic_string |
| template <class String> |
| inline StringState |
| rw_get_string_state (const String &str) |
| { |
| const StringState state = { |
| str.data (), str.size (), str.capacity () |
| }; |
| |
| return state; |
| } |
| |
| |
| /**************************************************************************/ |
| |
| // base class-functor for the range template overloads testing |
| template <class String> |
| struct RangeBase { |
| |
| typedef typename String::value_type StringChar; |
| typedef typename String::pointer StringPtr; |
| typedef typename String::const_pointer StringConstPtr; |
| typedef typename String::iterator StringIter; |
| typedef typename String::const_iterator StringConstIter; |
| typedef typename String::reverse_iterator StringRevIter; |
| typedef typename String::const_reverse_iterator StringConstRevIter; |
| |
| RangeBase () { } |
| |
| virtual ~RangeBase () { /* silence warnings */ } |
| |
| static StringPtr |
| begin (String &str, StringPtr*) { |
| return _RWSTD_CONST_CAST (StringPtr, str.data ()); |
| } |
| |
| static StringConstPtr |
| begin (const String &str, StringConstPtr*) { |
| return str.data (); |
| } |
| |
| #ifndef _RWSTD_NO_DEBUG_ITER |
| |
| // when debugging iterators are enabled string::iterator and |
| // string::pointer are distinct types; otherwise they are the |
| // same type |
| |
| static StringIter |
| begin (String &str, StringIter*) { |
| return str.begin (); |
| } |
| |
| static StringConstIter |
| begin (const String &str, StringConstIter*) { |
| return str.begin (); |
| } |
| |
| #endif // _RWSTD_NO_DEBUG_ITER |
| |
| static StringRevIter |
| begin (String &str, StringRevIter*) { |
| return str.rbegin (); |
| } |
| |
| static StringConstRevIter |
| begin (const String &str, StringConstRevIter*) { |
| return str.rbegin (); |
| } |
| |
| virtual String& |
| operator() (String &str, const StringTestCaseData<StringChar>&) const { |
| RW_ASSERT (!"logic error: should be never called"); |
| return str; |
| } |
| }; |
| |
| /**************************************************************************/ |
| |
| #define Disabled(which) \ |
| StringIds::opt_memfun_disabled [which & ~StringIds::fid_mask] |
| |
| |
| #ifndef _RWSTD_NO_WCHAR_T |
| # define TEST_DISPATCH(Alloc, fname, func, tcase) \ |
| if (StringIds::DefaultTraits == func.traits_id_) { \ |
| if (StringIds::Char == func.char_id_) \ |
| fname (char (), (std::char_traits<char>*)0, \ |
| (Alloc<char>*)0, func, tcase); \ |
| else if (StringIds::WChar == func.char_id_) \ |
| fname (wchar_t (), (std::char_traits<wchar_t>*)0, \ |
| (Alloc<wchar_t>*)0, func, tcase); \ |
| else \ |
| rw_note (0, 0, 0, \ |
| "%{$CLASS} tests not implemented"); \ |
| } \ |
| else { \ |
| if (StringIds::Char == func.char_id_) \ |
| fname (char (), (UserTraits<char>*)0, \ |
| (Alloc<char>*)0, func, tcase); \ |
| else if (StringIds::WChar == func.char_id_) \ |
| fname (wchar_t (), (UserTraits<wchar_t>*)0, \ |
| (Alloc<wchar_t>*)0, func, tcase); \ |
| else \ |
| fname (UserChar (), (UserTraits<UserChar>*)0, \ |
| (Alloc<UserChar>*)0, func, tcase); \ |
| } \ |
| (void)0 |
| |
| #else // if defined (_RWSTD_NO_WCHAR_T) |
| # define TEST_DISPATCH(Alloc, fname, func, tcase) \ |
| if (StringIds::DefaultTraits == func.traits_id_) { \ |
| if (StringIds::Char == func.char_id_) \ |
| fname (char (), (std::char_traits<char>*)0, \ |
| (Alloc<char>*)0, func, tcase); \ |
| else if (StringIds::WChar == func.char_id_) \ |
| RW_ASSERT (!"logic error: wchar_t disabled"); \ |
| else \ |
| rw_note (0, 0, 0, \ |
| "%{$CLASS} tests not implemented"); \ |
| } \ |
| } \ |
| else { \ |
| if (StringIds::Char == func.char_id_) \ |
| fname (char (), (UserTraits<char>*)0, \ |
| (Alloc<char>*)0, func, tcase); \ |
| else if (StringIds::WChar == func.char_id_) \ |
| RW_ASSERT (!"logic error: wchar_t disabled"); \ |
| else if (StringIds::UChar == func.char_id_) \ |
| fname (UserChar (), (UserTraits<UserChar>*)0, \ |
| (Alloc<UserChar>*)0, func, tcase); \ |
| } \ |
| (void)0 |
| |
| #endif // _RWSTD_NO_WCHAR_T |
| |
| |
| #define DEFINE_STRING_TEST_DISPATCH(fname) \ |
| static void \ |
| fname (const StringFunc &func, \ |
| const StringTestCase &tcase) { \ |
| if (StringIds::DefaultAlloc == func.alloc_id_) { \ |
| TEST_DISPATCH (std::allocator, fname, func, tcase); \ |
| } \ |
| else if (StringIds::UserAlloc == func.alloc_id_) { \ |
| TEST_DISPATCH (UserAlloc, fname, func, tcase); \ |
| } \ |
| else \ |
| RW_ASSERT (!"logic error: bad allocator"); \ |
| } typedef void rw_unused_typedef |
| |
| |
| #define TFUNC(charT, Traits, Allocator) \ |
| void (*)(charT*, Traits<charT>*, Allocator<charT>*, \ |
| const StringTestCaseData<charT>&) |
| |
| #define TFUNC_ADDR(fname, charT, Traits, Allocator) \ |
| (VoidFunc*)(TFUNC (charT, Traits, Allocator)) \ |
| &fname<charT, Traits<charT>, Allocator<charT> > |
| |
| #ifndef _RWSTD_NO_WCHAR_T |
| # define DEFINE_STRING_TEST_FUNCTIONS(fname) \ |
| static VoidFunc* const fname ## _func_array [] = { \ |
| TFUNC_ADDR (fname, char, std::char_traits, std::allocator), \ |
| TFUNC_ADDR (fname, char, std::char_traits, UserAlloc), \ |
| TFUNC_ADDR (fname, char, UserTraits, std::allocator), \ |
| TFUNC_ADDR (fname, char, UserTraits, UserAlloc), \ |
| \ |
| TFUNC_ADDR (fname, wchar_t, std::char_traits, std::allocator), \ |
| TFUNC_ADDR (fname, wchar_t, std::char_traits, UserAlloc), \ |
| TFUNC_ADDR (fname, wchar_t, UserTraits, std::allocator), \ |
| TFUNC_ADDR (fname, wchar_t, UserTraits, UserAlloc), \ |
| \ |
| (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \ |
| (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \ |
| TFUNC_ADDR (fname, UserChar, UserTraits, std::allocator), \ |
| TFUNC_ADDR (fname, UserChar, UserTraits, UserAlloc) \ |
| } |
| |
| #else // if defined (_RWSTD_NO_WCHAR_T) |
| # define DEFINE_STRING_TEST_FUNCTIONS(fname) \ |
| static VoidFunc* const fname ## _func_array [] = { \ |
| TFUNC_ADDR (fname, char, std::char_traits, std::allocator), \ |
| TFUNC_ADDR (fname, char, std::char_traits, UserAlloc), \ |
| TFUNC_ADDR (fname, char, UserTraits, std::allocator), \ |
| TFUNC_ADDR (fname, char, UserTraits, UserAlloc), \ |
| \ |
| (VoidFunc*)0, /* wchar_t disabled */ \ |
| (VoidFunc*)0, /* wchar_t disabled */ \ |
| (VoidFunc*)0, /* wchar_t disabled */ \ |
| (VoidFunc*)0, /* wchar_t disabled */ \ |
| \ |
| (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \ |
| (VoidFunc*)0, /* std::char_traits<UserChar> not allowed */ \ |
| TFUNC_ADDR (fname, UserChar, UserTraits, std::allocator), \ |
| TFUNC_ADDR (fname, UserChar, UserTraits, UserAlloc) \ |
| } |
| |
| #endif // _RWSTD_NO_WCHAR_T |
| |
| |
| #endif // RW_21_STRINGS_H_INCLUDED |