28#define _RWSTD_TEST_SRC
49_rw_this_file[] = __FILE__;
52static const char*
const
54 "char",
"wchar_t",
"UserChar"
58static const char*
const
60 "char_traits",
"UserTraits"
64static const char*
const
66 "allocator",
"UserAlloc"
70static const char*
const
73 "InputIterator",
"ForwardIterator",
"BidirectionalIterator",
74 "RandomAccessIterator",
75 "pointer",
"const_pointer",
76 "iterator",
"const_iterator",
77 "reverse_iterator",
"const_reverse_iterator"
82static const char*
const
84 "append",
"assign",
"erase",
"insert",
"replace",
"operator+=",
"find",
85 "rfind",
"find_first_of",
"find_last_of",
"find_first_not_of",
86 "find_last_not_of",
"compare",
"substr",
"operator[]",
"at",
"copy",
87 0 ,
"operator=",
"swap",
"push_back",
88 "operator+",
"operator==",
"operator!=",
"operator<",
"operator<=",
89 "operator>",
"operator>=",
"size",
"length",
"max_size",
"resize",
90 "capacity",
"reserve",
"clear",
"empty",
"begin",
"end",
"rbegin",
91 "rend",
"c_str",
"data",
"get_allocator",
"operator>>",
"operator<<",
110_rw_string_test_count;
113_rw_opt_char_types [
sizeof _rw_char_names /
sizeof *_rw_char_names];
116_rw_opt_traits_types [
sizeof _rw_traits_names /
sizeof *_rw_traits_names];
119_rw_opt_alloc_types [
sizeof _rw_alloc_names /
sizeof *_rw_alloc_names];
122_rw_opt_iter_types [
sizeof _rw_iter_names /
sizeof *_rw_iter_names];
125_rw_opt_no_exceptions;
128_rw_opt_no_exception_safety;
138 size_t inx = _RWSTD_SIZE_MAX;
140 for (
size_t i = 0; _rw_string_test_count; ++
i) {
141 if (fid == _rw_string_tests [
i].
which) {
156 const char *when)
const
164 "line %d: %{$FUNCALL}: object state unexpectedly changed "
165 "from { %#p, %zu, %zu } to { %#p, %zu, %zu } (data, size, "
166 "capacity) after %s",
189 return "basic_string";
199_rw_sigcat (
char **pbuf,
size_t *pbufsize,
210 const bool is_member = 0 != (Ids::bit_member & int (
which));
213 int argmap = (~Ids::bit_member & int (
which)) >> Ids::fid_bits;
216 bool is_const_member =
217 is_member && Ids::arg_cstr == (argmap & Ids::arg_mask);
221 argmap >>= Ids::arg_bits;
223 const char* funcname = 0;
230 case Ids::fid_ctor: funcname =
"ctor";
break;
231 case Ids::fid_op_plus_eq: funcname =
"op_plus_eq";
break;
232 case Ids::fid_op_index: funcname =
"op_index";
break;
233 case Ids::fid_op_set: funcname =
"op_assign";
break;
234 case Ids::fid_op_plus: funcname =
"op_plus";
break;
235 case Ids::fid_op_equal: funcname =
"op_equal";
break;
236 case Ids::fid_op_not_equal: funcname =
"op_not_equal";
break;
237 case Ids::fid_op_less: funcname =
"op_less";
break;
238 case Ids::fid_op_less_equal: funcname =
"op_less_equal";
break;
239 case Ids::fid_op_greater: funcname =
"op_greater";
break;
240 case Ids::fid_op_greater_equal: funcname =
"op_greater_equal";
break;
241 case Ids::fid_extractor: funcname =
"extractor";
break;
242 case Ids::fid_inserter: funcname =
"inserter";
break;
244 case Ids::fid_compare:
247 case Ids::fid_find_first_not_of:
248 case Ids::fid_find_first_of:
249 case Ids::fid_find_last_not_of:
250 case Ids::fid_find_last_of:
252 case Ids::fid_substr:
255 case Ids::fid_get_allocator:
258 is_const_member =
false;
264 const size_t nfuncs =
265 sizeof _rw_func_names /
sizeof *_rw_func_names;
269 funcname = _rw_func_names [fid];
277 const char*
const iname =
func ? _rw_iter_names [
func->iter_id_] :
"";
280 "%{+}%{?}%s%{?}_const%{;}%{:}%{?}<%s>%{;}(%{;}",
281 0 ==
func, funcname, is_const_member, 0 != *iname, iname);
289 for (
size_t argno = 0; argmap; ++argno, argmap >>= Ids::arg_bits) {
291 const char* pfx =
"";
292 const char* sfx =
"";
294 const int argtype = argmap & Ids::arg_mask;
296 const char* tname = 0;
300 case Ids::arg_size: tname =
"size_type";
break;
301 case Ids::arg_val: tname =
"value_type";
break;
302 case Ids::arg_ptr: tname =
"pointer";
break;
303 case Ids::arg_cptr: tname =
"const_pointer";
break;
304 case Ids::arg_ref: tname =
"reference";
break;
305 case Ids::arg_cref: tname =
"const_reference";
break;
306 case Ids::arg_iter: tname =
"iterator";
break;
307 case Ids::arg_citer: tname =
"const_iterator";
break;
309 if (
'\0' == *iname_buf) {
310 strcpy (iname_buf, iname);
311 strcat (iname_buf,
", ");
312 strcat (iname_buf, iname);
317 case Ids::arg_alloc: tname =
"const allocator_type&";
break;
322 tname = _rw_class_name (*
func);
326 case Ids::arg_istream: tname =
"istream&";
break;
327 case Ids::arg_ostream: tname =
"ostream&";
break;
332 case Ids::arg_size: tname =
"size";
break;
333 case Ids::arg_val: tname =
"val";
break;
334 case Ids::arg_ptr: tname =
"ptr";
break;
335 case Ids::arg_cptr: tname =
"cptr";
break;
336 case Ids::arg_ref: tname =
"ref";
break;
337 case Ids::arg_cref: tname =
"cref";
break;
338 case Ids::arg_iter: tname =
"iter";
break;
339 case Ids::arg_citer: tname =
"citer";
break;
340 case Ids::arg_range: tname =
"range";
break;
341 case Ids::arg_alloc: tname =
"alloc";
break;
342 case Ids::arg_str: tname =
"str";
break;
343 case Ids::arg_cstr: tname =
"cstr";
break;
344 case Ids::arg_istream: tname =
"istream";
break;
345 case Ids::arg_ostream: tname =
"ostream";
break;
351 if ( 0 ==
func || is_member
352 || Ids::arg_str != argtype && Ids::arg_cstr != argtype
353 && Ids::arg_istream != argtype && Ids::arg_ostream != argtype) {
355 rw_asnprintf (pbuf, pbufsize,
"%{+}%{?}_%{:}%{?}, %{;}%{;}%s%s%s",
356 0 ==
func, 0 < argno, pfx, tname, sfx);
358 else if (Ids::arg_istream == argtype || Ids::arg_ostream == argtype) {
363 "%{+}%{?}, %{;}%{?}%{$ISTREAM}%{:}%{$OSTREAM}%{;}&",
364 0 < argno, Ids::arg_istream == argtype);
371 "%{+}%{?}, %{;}%{?}const %{;}%{$CLASS}&",
372 0 < argno, Ids::arg_cstr == argtype);
378 rw_asnprintf (pbuf, pbufsize,
"%{+})%{?} const%{;}", is_const_member);
415 const char*
const class_name = _rw_class_name (
func);
423 rw_fprintf (0,
"%{$Traits!:*}", _rw_traits_names [
func.traits_id_]);
425 rw_fprintf (0,
"%{$Allocator!:*}", _rw_alloc_names [
func.alloc_id_]);
427 rw_fprintf (0,
"%{$Iterator!:*}", _rw_iter_names [
func.iter_id_]);
447 "std::basic_string<%s, %s<%1$s>%{?}, %s<%1$s>%{;}>",
448 _rw_char_names [
func.char_id_],
449 _rw_traits_names [
func.traits_id_],
451 _rw_alloc_names [
func.alloc_id_]);
475 "std::basic_istream<%s, %s<%1$s>>",
476 _rw_char_names [
func.char_id_],
477 _rw_traits_names [
func.traits_id_]);
499 "std::basic_ostream<%s, %s<%1$s>>",
500 _rw_char_names [
func.char_id_],
501 _rw_traits_names [
func.traits_id_]);
511 const size_t nfuncs =
sizeof _rw_func_names /
sizeof *_rw_func_names;
518 const char*
const funcname = _rw_func_names [funcinx] ?
519 _rw_func_names [funcinx] : class_name;
522 const bool is_member =
528 !is_member, funcname);
533 _rw_sigcat (&
buf, &bufsize, &
func);
542 const bool self = 0 == pcase->
arg;
550 size_t str_len =
sizeof str_buf;
551 size_t arg_len =
sizeof arg_buf;
564 const bool is_member =
577 else if (is_member) {
581 "%{$CLASS} (%{?}%{#*s}%{;}).%{$FUNC}",
582 str != 0,
int (str_len),
str);
592 const size_t range1_end = pcase->
off + pcase->
size;
593 const size_t range2_end = pcase->
off2 + pcase->
size2;
600 switch (
func.which_) {
601 case StringIds::append_cptr:
602 case StringIds::assign_cptr:
603 case StringIds::op_plus_eq_cptr:
604 case StringIds::find_cptr:
605 case StringIds::rfind_cptr:
606 case StringIds::find_first_of_cptr:
607 case StringIds::find_last_of_cptr:
608 case StringIds::find_first_not_of_cptr:
609 case StringIds::find_last_not_of_cptr:
610 case StringIds::compare_cptr:
611 case StringIds::op_set_cptr:
612 case StringIds::ctor_cptr:
613 case StringIds::ctor_cptr_alloc:
616 "%{+} (%{?}c_str()%{:}%{#*s}%{;}"
617 "%{?}, const allocator_type&%{;})",
618 self,
int (arg_len),
arg, use_alloc);
621 case StringIds::append_cstr:
622 case StringIds::assign_cstr:
623 case StringIds::op_plus_eq_cstr:
624 case StringIds::find_cstr:
625 case StringIds::rfind_cstr:
626 case StringIds::find_first_of_cstr:
627 case StringIds::find_last_of_cstr:
628 case StringIds::find_first_not_of_cstr:
629 case StringIds::find_last_not_of_cstr:
630 case StringIds::compare_cstr:
631 case StringIds::ctor_cstr:
632 case StringIds::op_set_cstr:
633 case StringIds::swap_str:
636 "%{+} (%{?}*this%{:}%s(%{#*s})%{;}"
637 "%{?}, const allocator_type&%{;})",
638 self, class_name,
int (arg_len),
arg, use_alloc);
641 case StringIds::append_cptr_size:
642 case StringIds::assign_cptr_size:
643 case StringIds::copy_ptr_size:
644 case StringIds::ctor_cptr_size:
645 case StringIds::ctor_cptr_size_alloc:
648 "%{?}data()%{:}%{#*s}%{;}, %zu"
649 "%{?}, const allocator_type&%{;})",
650 self,
int (arg_len),
arg, pcase->
size, use_alloc);
653 case StringIds::find_cptr_size:
654 case StringIds::rfind_cptr_size:
655 case StringIds::find_first_of_cptr_size:
656 case StringIds::find_last_of_cptr_size:
657 case StringIds::find_first_not_of_cptr_size:
658 case StringIds::find_last_not_of_cptr_size:
661 "%{?}data()%{:}%{#*s}%{;}, %zu)",
662 self,
int (arg_len),
arg, pcase->
off);
665 case StringIds::find_cstr_size:
666 case StringIds::rfind_cstr_size:
667 case StringIds::find_first_of_cstr_size:
668 case StringIds::find_last_of_cstr_size:
669 case StringIds::find_first_not_of_cstr_size:
670 case StringIds::find_last_not_of_cstr_size:
671 case StringIds::ctor_cstr_size:
672 case StringIds::ctor_cstr_size_alloc:
675 "%{?}*this%{:}%s(%{#*s})%{;}, %zu"
676 "%{?}, const allocator_type%{;})",
677 self, class_name,
int (arg_len),
arg, pcase->
off,
681 case StringIds::find_cptr_size_size:
682 case StringIds::rfind_cptr_size_size:
683 case StringIds::find_first_of_cptr_size_size:
684 case StringIds::find_last_of_cptr_size_size:
685 case StringIds::find_first_not_of_cptr_size_size:
686 case StringIds::find_last_not_of_cptr_size_size:
689 "%{?}data()%{:}%{#*s}%{;}, %zu, %zu)",
690 self,
int (arg_len),
arg,
694 case StringIds::copy_ptr_size_size:
697 "%{?}data()%{:}%{#*s}%{;}, %zu, %zu)",
698 self,
int (arg_len),
arg,
702 case StringIds::append_cstr_size_size:
703 case StringIds::assign_cstr_size_size:
704 case StringIds::ctor_cstr_size_size:
705 case StringIds::ctor_cstr_size_size_alloc:
708 "%{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu"
709 "%{?}, const allocator_type%{;})",
710 self, class_name,
int (arg_len),
arg,
711 pcase->
off, pcase->
size, use_alloc);
714 case StringIds::append_size_val:
715 case StringIds::assign_size_val:
716 case StringIds::ctor_size_val:
717 case StringIds::ctor_size_val_alloc:
719 "%{+} (%zu, %{#c}%{?}, const allocator_type&%{;})",
720 pcase->
size, pcase->
val, use_alloc);
723 case StringIds::append_range:
724 case StringIds::assign_range:
725 case StringIds::ctor_range:
726 case StringIds::ctor_range_alloc:
728 "%{?}begin()%{:}%{$Iterator:-Iterator}(%{#*s})%{;}"
730 "%{?}begin()%{:}%{$Iterator:-Iterator}(...)%{;}"
732 "%{?}, const allocator_type&%{;})",
733 self,
int (arg_len),
arg,
735 self, 0 != range2_end, range2_end, use_alloc);
738 case StringIds::insert_size_cptr:
741 "%{+} (%zu, %{?}c_str()%{:}%{#*s}%{;})",
742 pcase->
off, self, int (arg_len),
arg);
745 case StringIds::insert_size_cstr:
748 "%{+} (%zu, %{?}*this%{:}%s(%{#*s})%{;})",
749 pcase->
off, self, class_name, int (arg_len),
arg);
752 case StringIds::insert_size_cptr_size:
755 "%zu, %{?}data()%{:}%{#*s}%{;}, %zu)",
756 pcase->
off, self, int (arg_len),
arg,
760 case StringIds::insert_size_cstr_size_size:
763 "%zu, %{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu)",
764 pcase->
off, self, class_name, int (arg_len),
arg,
768 case StringIds::insert_size_size_val:
770 "%{+} (%zu, %zu, %{#c})",
774 case StringIds::insert_iter_val:
776 "%{+} (begin()%{?} + %zu%{;}, %{#c})",
777 0 != pcase->
off, pcase->
off, pcase->
val);
780 case StringIds::insert_iter_size_val:
782 "%{+} (begin()%{?} + %zu%{;}, %zu, %{#c})",
786 case StringIds::insert_iter_range:
788 "(begin()%{?} + %zu%{;}, "
789 "%{?}begin()%{:}%{$Iterator:-Iterator}(%{#*s})%{;}"
791 "%{?}begin()%{:}%{$Iterator:-Iterator}(...)"
793 0 != pcase->
off, pcase->
off,
794 self, int (arg_len),
arg,
796 self, 0 != range2_end, range2_end);
799 case StringIds::replace_size_size_cptr:
800 case StringIds::compare_size_size_cptr:
803 "%zu, %zu, %{?}c_str()%{:}%{#*s}%{;})",
808 case StringIds::replace_size_size_cstr:
809 case StringIds::compare_size_size_cstr:
812 "%zu, %zu, %{?}*this%{:}%s(%{#*s})%{;})",
813 pcase->
off, pcase->
size, self, class_name,
817 case StringIds::replace_size_size_cptr_size:
818 case StringIds::compare_size_size_cptr_size:
821 "%zu, %zu, %{?}data()%{:}%{#*s}%{;}, %zu)",
826 case StringIds::replace_size_size_cstr_size_size:
827 case StringIds::compare_size_size_cstr_size_size:
830 "%{?}*this%{:}%s(%{#*s})%{;}, %zu, %zu)",
832 self, class_name, int (arg_len),
arg,
836 case StringIds::replace_size_size_size_val:
838 "%{+} (%zu, %zu, %zu, %{#c})",
842 case StringIds::replace_iter_iter_cptr:
845 "begin()%{?} + %zu%{;}, "
846 "%{?}c_str()%{:}%{#*s}%{;})",
847 0 != pcase->
off, pcase->
off,
848 0 != range1_end, range1_end,
849 self, int (arg_len),
arg);
852 case StringIds::replace_iter_iter_cstr:
855 "begin()%{?} + %zu%{;}, "
856 "%{?}*this%{:}%s(%{#*s})%{;})",
857 0 != pcase->
off, pcase->
off,
858 0 != range1_end, range1_end,
859 self, class_name, int (arg_len),
arg);
862 case StringIds::replace_iter_iter_cptr_size:
865 "begin()%{?} + %zu%{;}, "
866 "%{?}data()%{:}%{#*s}%{;}, %zu)",
867 0 != pcase->
off, pcase->
off,
868 0 != range1_end, range1_end,
869 self, int (arg_len),
arg, pcase->
size2);
872 case StringIds::replace_iter_iter_size_val:
874 "%{+} (begin()%{?} + %zu%{;}, begin()%{? + %zu%{;}, "
876 0 != pcase->
off, pcase->
off, 0 != range1_end, range1_end,
880 case StringIds::replace_iter_iter_range:
882 "begin()%{?} + %zu%{;}, "
883 "begin()%{?} + %zu%{;}, "
884 "%{?}begin()%{:}%{$Iterator:-Iterator}(%{#*s})%{;}"
886 "%{?}begin()%{:}%{$Iterator:-Iterator}(...)%{;}"
888 0 != pcase->
off, pcase->
off,
889 0 != range1_end, range1_end,
890 self, int (arg_len),
arg,
892 self, 0 != range2_end, range2_end);
895 case StringIds::op_plus_eq_val:
896 case StringIds::find_val:
897 case StringIds::rfind_val:
898 case StringIds::find_first_of_val:
899 case StringIds::find_last_of_val:
900 case StringIds::find_first_not_of_val:
901 case StringIds::find_last_not_of_val:
902 case StringIds::op_set_val:
903 case StringIds::push_back_val:
905 "%{+} (%{#c})", pcase->
val);
908 case StringIds::find_val_size:
909 case StringIds::rfind_val_size:
910 case StringIds::find_first_of_val_size:
911 case StringIds::find_last_of_val_size:
912 case StringIds::find_first_not_of_val_size:
913 case StringIds::find_last_not_of_val_size:
915 "%{+} (%{#c}, %zu)", pcase->
val, pcase->
off);
918 case StringIds::erase_void:
919 case StringIds::substr_void:
920 case StringIds::ctor_void:
921 case StringIds::size_void:
922 case StringIds::length_void:
923 case StringIds::max_size_void:
924 case StringIds::capacity_void:
925 case StringIds::reserve_void:
926 case StringIds::clear_void:
927 case StringIds::empty_void:
928 case StringIds::begin_void:
929 case StringIds::end_void:
930 case StringIds::rbegin_void:
931 case StringIds::rend_void:
932 case StringIds::c_str_void:
933 case StringIds::data_void:
934 case StringIds::get_allocator_void:
939 case StringIds::begin_const_void:
940 case StringIds::end_const_void:
941 case StringIds::rbegin_const_void:
942 case StringIds::rend_const_void:
947 case StringIds::ctor_alloc:
949 "%{+} (const allocator_type&)");
952 case StringIds::erase_size:
953 case StringIds::substr_size:
954 case StringIds::op_index_size:
955 case StringIds::at_size:
957 "%{+} (%zu)", pcase->
off);
960 case StringIds::op_index_const_size:
961 case StringIds::at_const_size:
963 "%{+} (%zu) const", pcase->
off);
966 case StringIds::erase_size_size:
967 case StringIds::substr_size_size:
969 "%{+} (%zu, %zu)", pcase->
off, pcase->
size);
972 case StringIds::erase_iter:
974 "%{+} (begin()%{?} + %zu%{;})",
975 0 != pcase->
off, pcase->
off);
978 case StringIds::erase_iter_iter:
980 "%{+} (begin()%{?} + %zu%{;}, begin()%{?} + %zu%{;})",
981 0 != pcase->
off, pcase->
off,
982 0 != range1_end, range1_end);
985 case StringIds::op_plus_cptr_cstr:
986 case StringIds::op_equal_cptr_cstr:
987 case StringIds::op_not_equal_cptr_cstr:
988 case StringIds::op_less_cptr_cstr:
989 case StringIds::op_less_equal_cptr_cstr:
990 case StringIds::op_greater_cptr_cstr:
991 case StringIds::op_greater_equal_cptr_cstr:
994 "%{+} (%{?}arg2.c_str()%{:}%{#*s}%{;}, "
995 "%{$CLASS}(%{#*s}))",
996 0 ==
str,
int (str_len),
str,
int (arg_len),
arg);
999 case StringIds::op_plus_cstr_cptr:
1000 case StringIds::op_equal_cstr_cptr:
1001 case StringIds::op_not_equal_cstr_cptr:
1002 case StringIds::op_less_cstr_cptr:
1003 case StringIds::op_less_equal_cstr_cptr:
1004 case StringIds::op_greater_cstr_cptr:
1005 case StringIds::op_greater_equal_cstr_cptr:
1008 "%{+} (%{$CLASS}(%{#*s}), "
1009 "%{?}arg1.c_str()%{:}%{#*s}%{;})",
1010 int (str_len),
str, self,
int (arg_len),
arg);
1013 case StringIds::op_plus_cstr_cstr:
1014 case StringIds::op_equal_cstr_cstr:
1015 case StringIds::op_not_equal_cstr_cstr:
1016 case StringIds::op_less_cstr_cstr:
1017 case StringIds::op_less_equal_cstr_cstr:
1018 case StringIds::op_greater_cstr_cstr:
1019 case StringIds::op_greater_equal_cstr_cstr:
1022 "%{+} (%{?}arg2%{:}%{$CLASS}(%{#*s})%{;}, "
1023 "%{?}arg1%{:}%{$CLASS}(%{#*s})%{;})",
1024 0 ==
str,
int (str_len),
str, self,
int (arg_len),
arg);
1027 case StringIds::op_plus_cstr_val:
1029 "%{+} (%{$CLASS}(%{#*s}), %{#c})",
1030 int (arg_len),
arg, pcase->
val);
1033 case StringIds::op_plus_val_cstr:
1035 "%{+} (%{#c}, %{$CLASS}(%{#*s}))",
1036 pcase->
val, int (arg_len),
arg);
1039 case StringIds::extractor_istream_str:
1040 case StringIds::getline_istream_str:
1042 "%{+} (%{$ISTREAM}&, %{$CLASS}(%{?}%{#*s}%{;}))",
1043 0 < str_len,
int (str_len),
str);
1046 case StringIds::getline_istream_str_val:
1048 "%{+} (%{$ISTREAM}&, %{$CLASS}(%{?}%{#*s}%{;}), %{#c})",
1049 0 < str_len,
int (str_len),
str, pcase->
val);
1052 case StringIds::inserter_ostream_cstr:
1054 "%{+} (%{$OSTREAM}&, %{$CLASS}(%{?}%{#*s}%{;}))",
1055 0 < str_len,
int (str_len),
str);
1058 case StringIds::resize_size_val:
1060 "%{+} (%zu, %{#c})", pcase->
size, pcase->
val);
1063 case StringIds::resize_size:
1064 case StringIds::reserve_size:
1066 "%{+} (%zu)", pcase->
size);
1070 RW_ASSERT (!
"test logic error: unknown overload");
1088 size_t off,
size_t ext)
1095 const size_t res_off =
off;
1096 const size_t res_ext = (ext < res_len ? ext : res_len) - 1;
1098 char* beg = new_res + res_off;
1099 char*
end = beg + res_ext;
1101 for (; beg <
end; ++beg, --
end) {
1102 const char tmp = *beg;
1118template <
class charT,
class Traits,
class Allocator>
1128 const size_t inx =
func.char_id_ * 4 +
func.traits_id_ * 2 +
func.alloc_id_;
1134 "logic error: null test function for %{$FUNCSIG}");
1138 const bool reverse_iter =
1142 const Data tdata (
func, tcase);
1153 const size_t off = like_ctor ? 0 : tdata.off1_;
1154 const size_t ext = like_ctor ? tdata.reslen_ : tdata.ext2_;
1159 const Data rev_tdata (
func, rev_tcase);
1164 delete[] rev_tcase.
res;
1171template <
class charT,
class Traits>
1179 typedef std::allocator<charT>
Alloc;
1187 RW_ASSERT (!
"logic error: unknown Allocator argument");
1192template <
class charT>
1200 typedef std::char_traits<charT>
Traits;
1208 RW_ASSERT (!
"logic error: unknown Traits argument");
1227 RW_ASSERT (!
"logic error: std::char_traits<UserChar> not allowed");
1235 RW_ASSERT (!
"logic error: unknown charT argument");
1251 if (-1 == tcase.
bthrow && _rw_opt_no_exception_safety) {
1254 rw_note (1 < _rw_opt_no_exception_safety++, _rw_this_file, __LINE__,
1255 "exception safety tests disabled");
1262 if (tcase.
bthrow && _rw_opt_no_exceptions) {
1265 rw_note (1 < _rw_opt_no_exceptions++, _rw_this_file, __LINE__,
1266 "exception tests disabled");
1270 const bool self_ref = 0 == tcase.
arg;
1274 if (_rw_opt_self_ref < 0 && self_ref) {
1277 "self-referential test disabled");
1280 else if (0 < _rw_opt_self_ref && !self_ref) {
1283 "non-self-referential test disabled");
1294 if (test_callback) {
1296 test_callback (
func, tcase);
1304 "test on line %d disabled", tcase.
line);
1331 const size_t siginx = _rw_get_func_inx (
test.which);
1335 if (0 ==
rw_note (0 <= _rw_opt_func [siginx], _rw_this_file, __LINE__,
1336 "%{?}%{$CLASS}::%{;}%{$FUNCSIG} tests disabled",
1340 rw_info (0, 0, 0,
"%{?}%{$CLASS}::%{;}%{$FUNCSIG}", is_member);
1342 const size_t case_count =
test.case_count;
1347 for (
size_t n = 0;
n != case_count; ++
n) {
1351 _rw_test_case (
func, tcase, _rw_test_callback, _rw_func_array);
1358_rw_toggle_options (
int *opts,
size_t count)
1360 for (
size_t i = 0;
i !=
count; ++
i) {
1376_rw_run_test (
int,
char*[])
1378#ifdef _RWSTD_NO_EXCEPTIONS
1380 rw_note (0, 0, 0,
"exception tests disabled (macro "
1381 "_RWSTD_NO_EXCEPTIONS #defined)");
1384 _rw_no_exceptions = 2;
1385 _rw_no_exception_safety = 2;
1389#ifdef _RWSTD_NO_WCHAR_T
1391 rw_note (0, 0, 0,
"wchar_t tests disabled (macro "
1392 "_RWSTD_NO_WCHAR_T #defined)");
1404 const size_t nopts =
sizeof _rw_opt_func /
sizeof *_rw_opt_func;
1405 _rw_toggle_options (_rw_opt_func, nopts);
1427 const size_t n_char_types =
sizeof char_types /
sizeof *char_types;
1428 const size_t n_traits_types =
sizeof traits_types /
sizeof *traits_types;
1429 const size_t n_alloc_types =
sizeof alloc_types /
sizeof *alloc_types;
1430 const size_t n_iter_types =
sizeof iter_types /
sizeof *iter_types;
1434 _rw_toggle_options (_rw_opt_char_types, n_char_types);
1435 _rw_toggle_options (_rw_opt_traits_types, n_traits_types);
1436 _rw_toggle_options (_rw_opt_alloc_types, n_alloc_types);
1437 _rw_toggle_options (_rw_opt_iter_types, n_iter_types);
1440 for (
size_t i = 0;
i != n_char_types; ++
i) {
1442 if (_rw_opt_char_types [
i] < 0) {
1444 rw_note (-1 > _rw_opt_char_types [
i]--,
1445 _rw_this_file, __LINE__,
1446 "%s tests disabled", _rw_char_names [
i]);
1451 for (
size_t j = 0;
j != n_traits_types; ++
j) {
1460 if (_rw_opt_traits_types [
j] < 0) {
1462 rw_note (-1 > _rw_opt_traits_types [
j]--,
1463 _rw_this_file, __LINE__,
1464 "%s tests disabled", _rw_traits_names [
j]);
1468 for (
size_t k = 0;
k != n_alloc_types; ++
k) {
1470 if (_rw_opt_alloc_types [
k] < 0) {
1472 rw_note (-1 > _rw_opt_alloc_types [
k]--,
1473 _rw_this_file, __LINE__,
1474 "%s tests disabled", _rw_alloc_names [
k]);
1478 for (
size_t m = 0;
m != _rw_string_test_count; ++
m) {
1499 for (
size_t l = 0; l != n_iter_types; ++l) {
1501 if (_rw_opt_iter_types [l] < 0) {
1503 rw_note (-1 > _rw_opt_iter_types [l]--,
1504 _rw_this_file, __LINE__,
1505 "%s tests disabled",
1506 _rw_iter_names [l]);
1510 func.iter_id_ = iter_types [l];
1534_rw_add_toggles (
char **pbuf,
size_t *pbufsize,
1535 const char*
const names[],
size_t count)
1537 for (
size_t i = 0;
i !=
count; ++
i) {
1544_rw_run_test (
int argc,
1554 _rw_test_callback = test_callback;
1555 _rw_func_array = func_array,
1556 _rw_string_tests = tests;
1557 _rw_string_test_count = test_count;
1563 size_t optbufsize = 0;
1567 "|-no-exception-safety# "
1570 const size_t n_chars =
sizeof _rw_char_names /
sizeof *_rw_char_names;
1571 const size_t n_traits =
sizeof _rw_traits_names /
sizeof *_rw_traits_names;
1572 const size_t n_allocs =
sizeof _rw_alloc_names /
sizeof *_rw_alloc_names;
1573 const size_t n_iters =
sizeof _rw_iter_names /
sizeof *_rw_iter_names;
1577 _rw_add_toggles (&optbuf, &optbufsize, _rw_char_names, n_chars);
1578 _rw_add_toggles (&optbuf, &optbufsize, _rw_traits_names, n_traits);
1579 _rw_add_toggles (&optbuf, &optbufsize, _rw_alloc_names, n_allocs);
1580 _rw_add_toggles (&optbuf, &optbufsize, _rw_iter_names + 1, n_iters - 1);
1582 for (
size_t i = 0;
i != test_count; ++
i) {
1587 _rw_sigcat (&optbuf, &optbufsize, 0, tests [
i].
which);
1596 rw_test (argc, argv, file, clause,
1602 &_rw_opt_no_exceptions,
1603 &_rw_opt_no_exception_safety,
1610 _rw_opt_char_types + 0,
1611 _rw_opt_char_types + 1,
1612 _rw_opt_char_types + 2,
1615 _rw_opt_traits_types + 0,
1616 _rw_opt_traits_types + 1,
1619 _rw_opt_alloc_types + 0,
1620 _rw_opt_alloc_types + 1,
1628 _rw_opt_iter_types + 0,
1629 _rw_opt_iter_types + 1,
1630 _rw_opt_iter_types + 2,
1631 _rw_opt_iter_types + 3,
1632 _rw_opt_iter_types + 4,
1633 _rw_opt_iter_types + 5,
1634 _rw_opt_iter_types + 6,
1635 _rw_opt_iter_types + 7,
1636 _rw_opt_iter_types + 8,
1637 _rw_opt_iter_types + 9,
1696 return _rw_run_test (argc, argv, file, clause, callback, 0, tests,
count);
1709 return _rw_run_test (argc, argv, file, clause, 0, farray, tests,
count);
void count(T, T, const U &,...)
bool equal(const T &x, const U &y)
const size_t MAX_OVERLOADS
_TEST_EXPORT int rw_run_string_test(int argc, char *argv[], const char *file, const char *clause, StringTestFunc *callback, const StringTest *tests, size_t count)
_TEST_EXPORT void rw_setvars(const StringFunc &func, const StringTestCase *pcase)
_RWSTD_INTERNAL StringTestCase _rw_reverse_results(const StringTestCase &tsrc, size_t off, size_t ext)
void _rw_dispatch(charT *, Traits *, Allocator *, VoidFunc *const *farray, const StringFunc &func, const StringTestCase &tcase)
std::char_traits< S > Traits
#define _RWSTD_REINTERPRET_CAST(T, x)
_TEST_EXPORT char * rw_expand(char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX, _RWSTD_SIZE_T *=0)
_TEST_EXPORT int rw_enabled(const char *name)
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_fprintf(rw_file *, const char *,...)
_TEST_EXPORT int rw_asnprintf(char **pbuf, _RWSTD_SIZE_T *pbufsize, const char *fmt,...)
void StringTestFunc(const StringFunc &, const StringTestCase &)
int assert_equal(const StringState &, int, int, const char *) const