168 lines · cpp
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-exception6//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 20void 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 54void test_prefix_adjustment() {55 // Check that we correctly adjust the match prefix when dealing with zero-length matches -- this is explicitly56 // 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 matches58 // empty sequences, there is an implicit zero-length match between every character in a string -- make sure the59 // 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 68int 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/PR33681146 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