15 #include "absl/strings/str_split.h"
18 #include <initializer_list>
23 #include <type_traits>
24 #include <unordered_map>
25 #include <unordered_set>
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include "absl/base/dynamic_annotations.h"
31 #include "absl/base/macros.h"
32 #include "absl/container/btree_map.h"
33 #include "absl/container/btree_set.h"
34 #include "absl/container/flat_hash_map.h"
35 #include "absl/container/node_hash_map.h"
36 #include "absl/strings/numbers.h"
50 std::vector<std::string>>::
value,
56 std::vector<absl::string_view>>::
value,
59 std::map<std::string, std::string>>::
value,
62 std::map<absl::string_view, absl::string_view>>::
value,
65 std::map<int, std::string>>::
value,
68 std::map<std::string, int>>::
value,
142 std::vector<std::string>
v =
absl::StrSplit(embedded_nulls, null_delim);
156 std::set<std::string>
v =
absl::StrSplit(
"a,b,c,a,b,c,a,b,c",
',');
178 std::vector<std::string>
v =
204 std::map<std::string, std::string>
m =
absl::StrSplit(
"a,1,b,2,a,3",
',');
212 std::multimap<std::string, std::string>
m =
215 auto it =
m.find(
"a");
245 std::map<std::string, std::string>
m;
260 TEST(SplitIterator, Basics) {
262 auto it = splitter.begin();
263 auto end = splitter.end();
285 TEST(SplitIterator, Predicate) {
287 auto it = splitter.begin();
288 auto end = splitter.end();
300 TEST(SplitIterator, EdgeCases) {
304 std::vector<std::string> expect;
309 {
",foo", {
"",
"foo"}},
310 {
"foo,", {
"foo",
""}},
311 {
",foo,", {
"",
"foo",
""}},
312 {
"foo,bar", {
"foo",
"bar"}},
315 for (
const auto&
spec : specs) {
318 auto it = splitter.begin();
319 auto end = splitter.end();
320 for (
const auto& expected :
spec.expect) {
344 TEST(SplitIterator, EqualityAsEndCondition) {
346 auto it = splitter.begin();
358 std::vector<absl::string_view>
v;
359 for (;
it != it2; ++
it) {
369 TEST(Splitter, RangeIterators) {
371 std::vector<absl::string_view>
output;
379 template <
typename ContainerType,
typename Splitter>
380 void TestConversionOperator(
const Splitter& splitter) {
381 ContainerType
output = splitter;
385 template <
typename MapType,
typename Splitter>
386 void TestMapConversionOperator(
const Splitter& splitter) {
387 MapType
m = splitter;
391 template <
typename FirstType,
typename SecondType,
typename Splitter>
392 void TestPairConversionOperator(
const Splitter& splitter) {
393 std::pair<FirstType, SecondType>
p = splitter;
394 EXPECT_EQ(
p, (std::pair<FirstType, SecondType>(
"a",
"b")));
397 TEST(Splitter, ConversionOperator) {
400 TestConversionOperator<std::vector<absl::string_view>>(splitter);
401 TestConversionOperator<std::vector<std::string>>(splitter);
402 TestConversionOperator<std::list<absl::string_view>>(splitter);
403 TestConversionOperator<std::list<std::string>>(splitter);
404 TestConversionOperator<std::deque<absl::string_view>>(splitter);
405 TestConversionOperator<std::deque<std::string>>(splitter);
406 TestConversionOperator<std::set<absl::string_view>>(splitter);
407 TestConversionOperator<std::set<std::string>>(splitter);
408 TestConversionOperator<std::multiset<absl::string_view>>(splitter);
409 TestConversionOperator<std::multiset<std::string>>(splitter);
410 TestConversionOperator<absl::btree_set<absl::string_view>>(splitter);
411 TestConversionOperator<absl::btree_set<std::string>>(splitter);
412 TestConversionOperator<absl::btree_multiset<absl::string_view>>(splitter);
413 TestConversionOperator<absl::btree_multiset<std::string>>(splitter);
414 TestConversionOperator<std::unordered_set<std::string>>(splitter);
418 TestMapConversionOperator<std::map<absl::string_view, absl::string_view>>(
420 TestMapConversionOperator<std::map<absl::string_view, std::string>>(splitter);
421 TestMapConversionOperator<std::map<std::string, absl::string_view>>(splitter);
422 TestMapConversionOperator<std::map<std::string, std::string>>(splitter);
423 TestMapConversionOperator<
424 std::multimap<absl::string_view, absl::string_view>>(splitter);
425 TestMapConversionOperator<std::multimap<absl::string_view, std::string>>(
427 TestMapConversionOperator<std::multimap<std::string, absl::string_view>>(
429 TestMapConversionOperator<std::multimap<std::string, std::string>>(splitter);
430 TestMapConversionOperator<
432 TestMapConversionOperator<absl::btree_map<absl::string_view, std::string>>(
434 TestMapConversionOperator<absl::btree_map<std::string, absl::string_view>>(
436 TestMapConversionOperator<absl::btree_map<std::string, std::string>>(
438 TestMapConversionOperator<
440 TestMapConversionOperator<
442 TestMapConversionOperator<
444 TestMapConversionOperator<absl::btree_multimap<std::string, std::string>>(
446 TestMapConversionOperator<std::unordered_map<std::string, std::string>>(
448 TestMapConversionOperator<
450 TestMapConversionOperator<
452 TestMapConversionOperator<
454 TestMapConversionOperator<
456 TestMapConversionOperator<
458 TestMapConversionOperator<
463 TestPairConversionOperator<absl::string_view, absl::string_view>(splitter);
464 TestPairConversionOperator<absl::string_view, std::string>(splitter);
465 TestPairConversionOperator<std::string, absl::string_view>(splitter);
466 TestPairConversionOperator<std::string, std::string>(splitter);
473 TEST(Splitter, ToPair) {
511 TEST(Splitter, Predicates) {
512 static const char kTestChars[] =
",a, ,b,";
520 std::vector<std::string>
v = splitter;
527 std::vector<std::string> v_allowempty = splitter;
532 std::vector<std::string> v_nopredicate = splitter_nopredicate;
539 std::vector<std::string>
v = splitter;
545 auto splitter =
absl::StrSplit(kTestChars,
',', SkipWhitespace());
546 std::vector<std::string>
v = splitter;
575 std::vector<std::string>
v;
579 std::map<std::string, std::string>
m;
582 std::unordered_map<std::string, std::string> hm;
589 const char* ReturnConstCharP() {
return "Hello World"; }
590 char* ReturnCharP() {
return const_cast<char*
>(
"Hello World"); }
593 std::vector<std::string>
v;
606 const char input[] =
"a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u";
608 <<
"Input should be larger than fits on the stack.";
629 template <
typename T>
630 static std::unique_ptr<T> CopyToHeap(
const T&
value) {
631 return std::unique_ptr<T>(
new T(
value));
637 auto stack_splitter = *heap_splitter;
638 heap_splitter.reset();
639 std::vector<std::string>
result = stack_splitter;
643 TEST(
Split, TemporaryCaptureIsCopyable) {
645 auto stack_splitter = *heap_splitter;
646 heap_splitter.reset();
647 std::vector<std::string>
result = stack_splitter;
651 TEST(
Split, SplitterIsCopyableAndMoveable) {
675 std::vector<absl::string_view>
v =
681 #if !defined(__cpp_char8_t)
682 #if defined(__clang__)
683 #pragma clang diagnostic push
684 #pragma clang diagnostic ignored "-Wc++2a-compat"
688 std::string utf8_string = u8
"\u03BA\u1F79\u03C3\u03BC\u03B5";
699 std::string unicode_delimiter =
"," + utf8_string +
",";
700 std::vector<absl::string_view>
v =
707 std::vector<absl::string_view>
v =
712 #if defined(__clang__)
713 #pragma clang diagnostic pop
715 #endif // !defined(__cpp_char8_t)
740 std::vector<absl::string_view>
results;
772 std::vector<absl::string_view>
results;
802 template <
typename Delimiter>
804 size_t starting_pos,
int expected_pos) {
807 expected_pos ==
found.data() -
text.data();
815 template <
typename Delimiter>
818 return IsFoundAtStartingPos(
text,
d, 0, expected_pos) &&
820 leading_text.length(),
821 expected_pos + leading_text.length());
829 template <
typename Delimiter>
830 void TestComma(Delimiter
d) {
845 TEST(Delimiter, ByString) {
847 TestComma(ByString(
","));
850 ByString comma_string(
",");
851 TestComma(comma_string);
869 TestComma(ByChar(
','));
872 ByChar comma_char(
',');
873 TestComma(comma_char);
880 TEST(Delimiter, ByAnyChar) {
882 ByAnyChar one_delim(
",");
895 ByAnyChar two_delims(
",;");
928 TEST(Delimiter, ByLength) {
931 ByLength four_char_delim(4);
934 EXPECT_TRUE(IsFoundAt(
"abcde", four_char_delim, 4));
935 EXPECT_TRUE(IsFoundAt(
"abcdefghijklmnopqrstuvwxyz", four_char_delim, 4));
936 EXPECT_TRUE(IsFoundAt(
"a b,c\nd", four_char_delim, 4));
946 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
947 defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
952 if (
sizeof(
size_t) > 4) {
966 TEST(SplitInternalTest, TypeTraits) {
978 std::initializer_list<int>>::
value));