xref: /llvm-project/libcxx/test/std/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp (revision e9adcc488f96a9f2b8c4344f5e3c7ca6639b9562)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <regex>
10 
11 // class regex_iterator<BidirectionalIterator, charT, traits>
12 
13 // regex_iterator operator++(int);
14 
15 #include <regex>
16 #include <cassert>
17 #include <iterator>
18 #include "test_macros.h"
19 
validate_prefixes(const std::regex & empty_matching_pattern)20 void validate_prefixes(const std::regex& empty_matching_pattern) {
21   const char source[] = "abc";
22 
23   std::cregex_iterator i(source, source + 3, empty_matching_pattern);
24   assert(!i->prefix().matched);
25   assert(i->prefix().length() == 0);
26   assert(i->prefix().first == source);
27   assert(i->prefix().second == source);
28 
29   ++i;
30   assert(i->prefix().matched);
31   assert(i->prefix().length() == 1);
32   assert(i->prefix().first == source);
33   assert(i->prefix().second == source + 1);
34   assert(i->prefix().str() == "a");
35 
36   ++i;
37   assert(i->prefix().matched);
38   assert(i->prefix().length() == 1);
39   assert(i->prefix().first == source + 1);
40   assert(i->prefix().second == source + 2);
41   assert(i->prefix().str() == "b");
42 
43   ++i;
44   assert(i->prefix().matched);
45   assert(i->prefix().length() == 1);
46   assert(i->prefix().first == source + 2);
47   assert(i->prefix().second == source + 3);
48   assert(i->prefix().str() == "c");
49 
50   ++i;
51   assert(i == std::cregex_iterator());
52 }
53 
test_prefix_adjustment()54 void test_prefix_adjustment() {
55   // Check that we correctly adjust the match prefix when dealing with zero-length matches -- this is explicitly
56   // required by the Standard ([re.regiter.incr]: "In all cases in which the call to `regex_search` returns true,
57   // `match.prefix().first` shall be equal to the previous value of `match[0].second`"). For a pattern that matches
58   // empty sequences, there is an implicit zero-length match between every character in a string -- make sure the
59   // prefix of each of these matches (except the first one) is the preceding character.
60 
61   // An empty pattern produces zero-length matches.
62   validate_prefixes(std::regex(""));
63   // Any character repeated zero or more times can produce zero-length matches.
64   validate_prefixes(std::regex("X*"));
65   validate_prefixes(std::regex("X{0,3}"));
66 }
67 
main(int,char **)68 int main(int, char**) {
69   {
70     std::regex phone_numbers("\\d{3}-\\d{4}");
71     const char phone_book[] = "555-1234, 555-2345, 555-3456";
72     std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers);
73     std::cregex_iterator i2 = i;
74     assert(i != std::cregex_iterator());
75     assert(i2 != std::cregex_iterator());
76     assert((*i).size() == 1);
77     assert((*i).position() == 0);
78     assert((*i).str() == "555-1234");
79     assert((*i2).size() == 1);
80     assert((*i2).position() == 0);
81     assert((*i2).str() == "555-1234");
82     i++;
83     assert(i != std::cregex_iterator());
84     assert(i2 != std::cregex_iterator());
85     assert((*i).size() == 1);
86     assert((*i).position() == 10);
87     assert((*i).str() == "555-2345");
88     assert((*i2).size() == 1);
89     assert((*i2).position() == 0);
90     assert((*i2).str() == "555-1234");
91     i++;
92     assert(i != std::cregex_iterator());
93     assert(i2 != std::cregex_iterator());
94     assert((*i).size() == 1);
95     assert((*i).position() == 20);
96     assert((*i).str() == "555-3456");
97     assert((*i2).size() == 1);
98     assert((*i2).position() == 0);
99     assert((*i2).str() == "555-1234");
100     i++;
101     assert(i == std::cregex_iterator());
102     assert(i2 != std::cregex_iterator());
103     assert((*i2).size() == 1);
104     assert((*i2).position() == 0);
105     assert((*i2).str() == "555-1234");
106   }
107   {
108     std::regex phone_numbers("\\d{3}-\\d{4}");
109     const char phone_book[] = "555-1234, 555-2345, 555-3456";
110     std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers);
111     std::cregex_iterator i2 = i;
112     assert(i != std::cregex_iterator());
113     assert(i2 != std::cregex_iterator());
114     assert((*i).size() == 1);
115     assert((*i).position() == 0);
116     assert((*i).str() == "555-1234");
117     assert((*i2).size() == 1);
118     assert((*i2).position() == 0);
119     assert((*i2).str() == "555-1234");
120     ++i;
121     assert(i != std::cregex_iterator());
122     assert(i2 != std::cregex_iterator());
123     assert((*i).size() == 1);
124     assert((*i).position() == 10);
125     assert((*i).str() == "555-2345");
126     assert((*i2).size() == 1);
127     assert((*i2).position() == 0);
128     assert((*i2).str() == "555-1234");
129     ++i;
130     assert(i != std::cregex_iterator());
131     assert(i2 != std::cregex_iterator());
132     assert((*i).size() == 1);
133     assert((*i).position() == 20);
134     assert((*i).str() == "555-3456");
135     assert((*i2).size() == 1);
136     assert((*i2).position() == 0);
137     assert((*i2).str() == "555-1234");
138     ++i;
139     assert(i == std::cregex_iterator());
140     assert(i2 != std::cregex_iterator());
141     assert((*i2).size() == 1);
142     assert((*i2).position() == 0);
143     assert((*i2).str() == "555-1234");
144   }
145   { // https://llvm.org/PR33681
146     std::regex rex(".*");
147     const char foo[] = "foo";
148     //  The -1 is because we don't want the implicit null from the array.
149     std::cregex_iterator i(std::begin(foo), std::end(foo) - 1, rex);
150     std::cregex_iterator e;
151     assert(i != e);
152     assert((*i).size() == 1);
153     assert((*i).str() == "foo");
154 
155     ++i;
156     assert(i != e);
157     assert((*i).size() == 1);
158     assert((*i).str() == "");
159 
160     ++i;
161     assert(i == e);
162   }
163 
164   test_prefix_adjustment();
165 
166   return 0;
167 }
168