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// template <class charT> struct regex_traits;
12
13// template <class ForwardIterator>
14// char_class_type
15// lookup_classname(ForwardIterator first, ForwardIterator last,
16// bool icase = false) const;
17
18#include <regex>
19#include <cassert>
20#include "test_macros.h"
21#include "test_iterators.h"
22
23template <class char_type>
24void
25test(const char_type* A,
26 typename std::regex_traits<char_type>::char_class_type expected,
27 bool icase = false)
28{
29 typedef typename std::regex_traits<char_type>::char_class_type char_class_type;
30 std::regex_traits<char_type> t;
31 typedef forward_iterator<const char_type*> F;
32 char_class_type result = t.lookup_classname(F(A), F(A + t.length(A)), icase);
33 assert(result == expected);
34}
35
36template <class char_type>
37void
38test_w(const char_type* A,
39 typename std::regex_traits<char_type>::char_class_type expected,
40 bool icase = false)
41{
42 typedef typename std::regex_traits<char_type>::char_class_type char_class_type;
43 std::regex_traits<char_type> t;
44 typedef forward_iterator<const char_type*> F;
45 char_class_type result = t.lookup_classname(F(A), F(A + t.length(A)), icase);
46 assert((result & expected) == expected);
47 LIBCPP_ASSERT((expected | std::regex_traits<char_type>::__regex_word) == result);
48
49 const bool matches_underscore = t.isctype('_', result);
50 if (result != expected)
51 assert(matches_underscore && "expected to match underscore");
52 else
53 assert(!matches_underscore && "should not match underscore");
54}
55
56int main(int, char**)
57{
58// if __regex_word is not distinct from all the classes, bad things happen
59// See https://llvm.org/PR26476 for an example.
60 LIBCPP_ASSERT((std::ctype_base::space & std::regex_traits<char>::__regex_word) == 0);
61 LIBCPP_ASSERT((std::ctype_base::print & std::regex_traits<char>::__regex_word) == 0);
62 LIBCPP_ASSERT((std::ctype_base::cntrl & std::regex_traits<char>::__regex_word) == 0);
63 LIBCPP_ASSERT((std::ctype_base::upper & std::regex_traits<char>::__regex_word) == 0);
64 LIBCPP_ASSERT((std::ctype_base::lower & std::regex_traits<char>::__regex_word) == 0);
65 LIBCPP_ASSERT((std::ctype_base::alpha & std::regex_traits<char>::__regex_word) == 0);
66 LIBCPP_ASSERT((std::ctype_base::digit & std::regex_traits<char>::__regex_word) == 0);
67 LIBCPP_ASSERT((std::ctype_base::punct & std::regex_traits<char>::__regex_word) == 0);
68 LIBCPP_ASSERT((std::ctype_base::xdigit & std::regex_traits<char>::__regex_word) == 0);
69 LIBCPP_ASSERT((std::ctype_base::blank & std::regex_traits<char>::__regex_word) == 0);
70
71 test(A: "d", expected: std::ctype_base::digit);
72 test(A: "D", expected: std::ctype_base::digit);
73 test(A: "d", expected: std::ctype_base::digit, icase: true);
74 test(A: "D", expected: std::ctype_base::digit, icase: true);
75
76 test_w(A: "w", expected: std::ctype_base::alnum
77 | std::ctype_base::upper | std::ctype_base::lower);
78 test_w(A: "W", expected: std::ctype_base::alnum
79 | std::ctype_base::upper | std::ctype_base::lower);
80 test_w(A: "w", expected: std::ctype_base::alnum
81 | std::ctype_base::upper | std::ctype_base::lower, icase: true);
82 test_w(A: "W", expected: std::ctype_base::alnum
83 | std::ctype_base::upper | std::ctype_base::lower, icase: true);
84
85 test(A: "s", expected: std::ctype_base::space);
86 test(A: "S", expected: std::ctype_base::space);
87 test(A: "s", expected: std::ctype_base::space, icase: true);
88 test(A: "S", expected: std::ctype_base::space, icase: true);
89
90 test(A: "alnum", expected: std::ctype_base::alnum);
91 test(A: "AlNum", expected: std::ctype_base::alnum);
92 test(A: "alnum", expected: std::ctype_base::alnum, icase: true);
93 test(A: "AlNum", expected: std::ctype_base::alnum, icase: true);
94
95 test(A: "alpha", expected: std::ctype_base::alpha);
96 test(A: "Alpha", expected: std::ctype_base::alpha);
97 test(A: "alpha", expected: std::ctype_base::alpha, icase: true);
98 test(A: "Alpha", expected: std::ctype_base::alpha, icase: true);
99
100 test(A: "blank", expected: std::ctype_base::blank);
101 test(A: "Blank", expected: std::ctype_base::blank);
102 test(A: "blank", expected: std::ctype_base::blank, icase: true);
103 test(A: "Blank", expected: std::ctype_base::blank, icase: true);
104
105 test(A: "cntrl", expected: std::ctype_base::cntrl);
106 test(A: "Cntrl", expected: std::ctype_base::cntrl);
107 test(A: "cntrl", expected: std::ctype_base::cntrl, icase: true);
108 test(A: "Cntrl", expected: std::ctype_base::cntrl, icase: true);
109
110 test(A: "digit", expected: std::ctype_base::digit);
111 test(A: "Digit", expected: std::ctype_base::digit);
112 test(A: "digit", expected: std::ctype_base::digit, icase: true);
113 test(A: "Digit", expected: std::ctype_base::digit, icase: true);
114
115 test(A: "digit", expected: std::ctype_base::digit);
116 test(A: "DIGIT", expected: std::ctype_base::digit);
117 test(A: "digit", expected: std::ctype_base::digit, icase: true);
118 test(A: "Digit", expected: std::ctype_base::digit, icase: true);
119
120 test(A: "graph", expected: std::ctype_base::graph);
121 test(A: "GRAPH", expected: std::ctype_base::graph);
122 test(A: "graph", expected: std::ctype_base::graph, icase: true);
123 test(A: "Graph", expected: std::ctype_base::graph, icase: true);
124
125 test(A: "lower", expected: std::ctype_base::lower);
126 test(A: "LOWER", expected: std::ctype_base::lower);
127 test(A: "lower", expected: std::ctype_base::lower | std::ctype_base::alpha, icase: true);
128 test(A: "Lower", expected: std::ctype_base::lower | std::ctype_base::alpha, icase: true);
129
130 test(A: "print", expected: std::ctype_base::print);
131 test(A: "PRINT", expected: std::ctype_base::print);
132 test(A: "print", expected: std::ctype_base::print, icase: true);
133 test(A: "Print", expected: std::ctype_base::print, icase: true);
134
135 test(A: "punct", expected: std::ctype_base::punct);
136 test(A: "PUNCT", expected: std::ctype_base::punct);
137 test(A: "punct", expected: std::ctype_base::punct, icase: true);
138 test(A: "Punct", expected: std::ctype_base::punct, icase: true);
139
140 test(A: "space", expected: std::ctype_base::space);
141 test(A: "SPACE", expected: std::ctype_base::space);
142 test(A: "space", expected: std::ctype_base::space, icase: true);
143 test(A: "Space", expected: std::ctype_base::space, icase: true);
144
145 test(A: "upper", expected: std::ctype_base::upper);
146 test(A: "UPPER", expected: std::ctype_base::upper);
147 test(A: "upper", expected: std::ctype_base::upper | std::ctype_base::alpha, icase: true);
148 test(A: "Upper", expected: std::ctype_base::upper | std::ctype_base::alpha, icase: true);
149
150 test(A: "xdigit", expected: std::ctype_base::xdigit);
151 test(A: "XDIGIT", expected: std::ctype_base::xdigit);
152 test(A: "xdigit", expected: std::ctype_base::xdigit, icase: true);
153 test(A: "Xdigit", expected: std::ctype_base::xdigit, icase: true);
154
155 test(A: "dig", expected: std::ctype_base::mask());
156 test(A: "", expected: std::ctype_base::mask());
157 test(A: "digits", expected: std::ctype_base::mask());
158
159#ifndef TEST_HAS_NO_WIDE_CHARACTERS
160 test(A: L"d", expected: std::ctype_base::digit);
161 test(A: L"D", expected: std::ctype_base::digit);
162 test(A: L"d", expected: std::ctype_base::digit, icase: true);
163 test(A: L"D", expected: std::ctype_base::digit, icase: true);
164
165 test_w(A: L"w", expected: std::ctype_base::alnum
166 | std::ctype_base::upper | std::ctype_base::lower);
167 test_w(A: L"W", expected: std::ctype_base::alnum
168 | std::ctype_base::upper | std::ctype_base::lower);
169 test_w(A: L"w", expected: std::ctype_base::alnum
170 | std::ctype_base::upper | std::ctype_base::lower, icase: true);
171 test_w(A: L"W", expected: std::ctype_base::alnum
172 | std::ctype_base::upper | std::ctype_base::lower, icase: true);
173
174 test(A: L"s", expected: std::ctype_base::space);
175 test(A: L"S", expected: std::ctype_base::space);
176 test(A: L"s", expected: std::ctype_base::space, icase: true);
177 test(A: L"S", expected: std::ctype_base::space, icase: true);
178
179 test(A: L"alnum", expected: std::ctype_base::alnum);
180 test(A: L"AlNum", expected: std::ctype_base::alnum);
181 test(A: L"alnum", expected: std::ctype_base::alnum, icase: true);
182 test(A: L"AlNum", expected: std::ctype_base::alnum, icase: true);
183
184 test(A: L"alpha", expected: std::ctype_base::alpha);
185 test(A: L"Alpha", expected: std::ctype_base::alpha);
186 test(A: L"alpha", expected: std::ctype_base::alpha, icase: true);
187 test(A: L"Alpha", expected: std::ctype_base::alpha, icase: true);
188
189 test(A: L"blank", expected: std::ctype_base::blank);
190 test(A: L"Blank", expected: std::ctype_base::blank);
191 test(A: L"blank", expected: std::ctype_base::blank, icase: true);
192 test(A: L"Blank", expected: std::ctype_base::blank, icase: true);
193
194 test(A: L"cntrl", expected: std::ctype_base::cntrl);
195 test(A: L"Cntrl", expected: std::ctype_base::cntrl);
196 test(A: L"cntrl", expected: std::ctype_base::cntrl, icase: true);
197 test(A: L"Cntrl", expected: std::ctype_base::cntrl, icase: true);
198
199 test(A: L"digit", expected: std::ctype_base::digit);
200 test(A: L"Digit", expected: std::ctype_base::digit);
201 test(A: L"digit", expected: std::ctype_base::digit, icase: true);
202 test(A: L"Digit", expected: std::ctype_base::digit, icase: true);
203
204 test(A: L"digit", expected: std::ctype_base::digit);
205 test(A: L"DIGIT", expected: std::ctype_base::digit);
206 test(A: L"digit", expected: std::ctype_base::digit, icase: true);
207 test(A: L"Digit", expected: std::ctype_base::digit, icase: true);
208
209 test(A: L"graph", expected: std::ctype_base::graph);
210 test(A: L"GRAPH", expected: std::ctype_base::graph);
211 test(A: L"graph", expected: std::ctype_base::graph, icase: true);
212 test(A: L"Graph", expected: std::ctype_base::graph, icase: true);
213
214 test(A: L"lower", expected: std::ctype_base::lower);
215 test(A: L"LOWER", expected: std::ctype_base::lower);
216 test(A: L"lower", expected: std::ctype_base::lower | std::ctype_base::alpha, icase: true);
217 test(A: L"Lower", expected: std::ctype_base::lower | std::ctype_base::alpha, icase: true);
218
219 test(A: L"print", expected: std::ctype_base::print);
220 test(A: L"PRINT", expected: std::ctype_base::print);
221 test(A: L"print", expected: std::ctype_base::print, icase: true);
222 test(A: L"Print", expected: std::ctype_base::print, icase: true);
223
224 test(A: L"punct", expected: std::ctype_base::punct);
225 test(A: L"PUNCT", expected: std::ctype_base::punct);
226 test(A: L"punct", expected: std::ctype_base::punct, icase: true);
227 test(A: L"Punct", expected: std::ctype_base::punct, icase: true);
228
229 test(A: L"space", expected: std::ctype_base::space);
230 test(A: L"SPACE", expected: std::ctype_base::space);
231 test(A: L"space", expected: std::ctype_base::space, icase: true);
232 test(A: L"Space", expected: std::ctype_base::space, icase: true);
233
234 test(A: L"upper", expected: std::ctype_base::upper);
235 test(A: L"UPPER", expected: std::ctype_base::upper);
236 test(A: L"upper", expected: std::ctype_base::upper | std::ctype_base::alpha, icase: true);
237 test(A: L"Upper", expected: std::ctype_base::upper | std::ctype_base::alpha, icase: true);
238
239 test(A: L"xdigit", expected: std::ctype_base::xdigit);
240 test(A: L"XDIGIT", expected: std::ctype_base::xdigit);
241 test(A: L"xdigit", expected: std::ctype_base::xdigit, icase: true);
242 test(A: L"Xdigit", expected: std::ctype_base::xdigit, icase: true);
243
244 test(A: L"dig", expected: std::ctype_base::mask());
245 test(A: L"", expected: std::ctype_base::mask());
246 test(A: L"digits", expected: std::ctype_base::mask());
247#endif
248
249 return 0;
250}
251

source code of libcxx/test/std/re/re.traits/lookup_classname.pass.cpp