Libosmium  2.22.0
Fast and flexible C++ library for working with OpenStreetMap data
string_matcher.hpp
Go to the documentation of this file.
1#ifndef OSMIUM_UTIL_STRING_MATCHER_HPP
2#define OSMIUM_UTIL_STRING_MATCHER_HPP
3
4/*
5
6This file is part of Osmium (https://osmcode.org/libosmium).
7
8Copyright 2013-2025 Jochen Topf <jochen@topf.org> and others (see README).
9
10Boost Software License - Version 1.0 - August 17th, 2003
11
12Permission is hereby granted, free of charge, to any person or organization
13obtaining a copy of the software and accompanying documentation covered by
14this license (the "Software") to use, reproduce, display, distribute,
15execute, and transmit the Software, and to prepare derivative works of the
16Software, and to permit third-parties to whom the Software is furnished to
17do so, all subject to the following:
18
19The copyright notices in the Software and this entire statement, including
20the above license grant, this restriction and the following disclaimer,
21must be included in all copies of the Software, in whole or in part, and
22all derivative works of the Software, unless such copies or derivative
23works are solely in the form of machine-executable object code generated by
24a source language processor.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32DEALINGS IN THE SOFTWARE.
33
34*/
35
36#include <algorithm>
37#include <cstring>
38#include <iosfwd>
39#include <regex>
40#include <string>
41#include <utility>
42#include <vector>
43
44#ifdef __has_include
45# if __has_include(<variant>)
46# include <variant>
47# ifdef __cpp_lib_variant
48# define OSMIUM_USE_STD_VARIANT
49# endif
50# endif
51#endif
52
53#ifndef OSMIUM_USE_STD_VARIANT
54# include <boost/variant.hpp>
55#endif
56
57namespace osmium {
58
63
64 public:
65
66 // Parent class for all matcher classes. Used for enable_if check.
67 class matcher {
68 };
69
73 class always_false : public matcher {
74
75 public:
76
77 static bool match(const char* /*test_string*/) noexcept {
78 return false;
79 }
80
81 template <typename TChar, typename TTraits>
82 void print(std::basic_ostream<TChar, TTraits>& out) const {
83 out << "always_false";
84 }
85
86 }; // class always_false
87
91 class always_true : public matcher {
92
93 public:
94
95 static bool match(const char* /*test_string*/) noexcept {
96 return true;
97 }
98
99 template <typename TChar, typename TTraits>
100 void print(std::basic_ostream<TChar, TTraits>& out) const {
101 out << "always_true";
102 }
103
104 }; // class always_true
105
109 class equal : public matcher {
110
111 std::string m_str;
112
113 public:
114
115 explicit equal(std::string str) :
116 m_str(std::move(str)) {
117 }
118
119 explicit equal(const char* str) :
120 m_str(str) {
121 }
122
123 bool match(const char* test_string) const noexcept {
124 return !std::strcmp(m_str.c_str(), test_string);
125 }
126
127 template <typename TChar, typename TTraits>
128 void print(std::basic_ostream<TChar, TTraits>& out) const {
129 out << "equal[" << m_str << ']';
130 }
131
132 }; // class equal
133
137 class prefix : public matcher {
138
139 std::string m_str;
140
141 public:
142
143 explicit prefix(std::string str) :
144 m_str(std::move(str)) {
145 }
146
147 explicit prefix(const char* str) :
148 m_str(str) {
149 }
150
151 bool match(const char* test_string) const noexcept {
152 return m_str.compare(0, std::string::npos, test_string, 0, m_str.size()) == 0;
153 }
154
155 template <typename TChar, typename TTraits>
156 void print(std::basic_ostream<TChar, TTraits>& out) const {
157 out << "prefix[" << m_str << ']';
158 }
159
160 }; // class prefix
161
165 class substring : public matcher {
166
167 std::string m_str;
168
169 public:
170
171 explicit substring(std::string str) :
172 m_str(std::move(str)) {
173 }
174
175 explicit substring(const char* str) :
176 m_str(str) {
177 }
178
179 bool match(const char* test_string) const noexcept {
180 return std::strstr(test_string, m_str.c_str()) != nullptr;
181 }
182
183 template <typename TChar, typename TTraits>
184 void print(std::basic_ostream<TChar, TTraits>& out) const {
185 out << "substring[" << m_str << ']';
186 }
187
188 }; // class substring
189
193 class regex : public matcher {
194
195 std::regex m_regex;
196
197 public:
198
199 explicit regex(std::regex regex) :
200 m_regex(std::move(regex)) {
201 }
202
203 bool match(const char* test_string) const noexcept {
204 return std::regex_search(test_string, m_regex);
205 }
206
207 template <typename TChar, typename TTraits>
208 void print(std::basic_ostream<TChar, TTraits>& out) const {
209 out << "regex";
210 }
211
212 }; // class regex
213
217 class list : public matcher {
218
219 std::vector<std::string> m_strings;
220
221 public:
222
223 explicit list() = default;
224
225 explicit list(std::vector<std::string> strings) :
226 m_strings(std::move(strings)) {
227 }
228
229 list& add_string(const char* str) {
230 m_strings.emplace_back(str);
231 return *this;
232 }
233
234 list& add_string(const std::string& str) {
235 m_strings.push_back(str);
236 return *this;
237 }
238
239 bool match(const char* test_string) const noexcept {
240 return std::any_of(m_strings.cbegin(), m_strings.cend(),
241 [&test_string](const std::string& s){
242 return s == test_string;
243 });
244 }
245
246 template <typename TChar, typename TTraits>
247 void print(std::basic_ostream<TChar, TTraits>& out) const {
248 out << "list[";
249 for (const auto& s : m_strings) {
250 out << '[' << s << ']';
251 }
252 out << ']';
253 }
254
255 }; // class list
256
257 private:
258
260#ifdef OSMIUM_USE_STD_VARIANT
261 std::variant
262#else
263 boost::variant
264#endif
267 equal,
268 prefix,
269 substring,
270 regex,
271 list>;
272
274
276#ifndef OSMIUM_USE_STD_VARIANT
277 : public boost::static_visitor<bool>
278#endif
279 {
280
281 const char* m_str;
282
283 public:
284
285 explicit match_visitor(const char* str) noexcept :
286 m_str(str) {
287 }
288
289 template <typename TMatcher>
290 bool operator()(const TMatcher& t) const noexcept {
291 return t.match(m_str);
292 }
293
294 }; // class match_visitor
295
296 template <typename TChar, typename TTraits>
298#ifndef OSMIUM_USE_STD_VARIANT
299 : public boost::static_visitor<void>
300#endif
301 {
302
303 std::basic_ostream<TChar, TTraits>* m_out;
304
305 public:
306
307 explicit print_visitor(std::basic_ostream<TChar, TTraits>& out) :
308 m_out(&out) {
309 }
310
311 template <typename TMatcher>
312 void operator()(const TMatcher& t) const noexcept {
313 t.print(*m_out);
314 }
315
316 }; // class print_visitor
317
318 public:
319
325 }
326
335 // cppcheck-suppress noExplicitConstructor
336 StringMatcher(bool result) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
338 if (result) {
340 }
341 }
342
348 // cppcheck-suppress noExplicitConstructor
349 StringMatcher(const char* str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
350 m_matcher(equal{str}) {
351 }
352
358 // cppcheck-suppress noExplicitConstructor
359 StringMatcher(const std::string& str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
360 m_matcher(equal{str}) {
361 }
362
368 // cppcheck-suppress noExplicitConstructor
369 StringMatcher(const std::regex& aregex) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
370 m_matcher(regex{aregex}) {
371 }
372
379 // cppcheck-suppress noExplicitConstructor
380 StringMatcher(const std::vector<std::string>& strings) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
381 m_matcher(list{strings}) {
382 }
383
391 // cppcheck-suppress noExplicitConstructor
392 template <typename TMatcher, typename X = std::enable_if_t<
393 std::is_base_of<matcher, TMatcher>::value, void>>
394 StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
395 m_matcher(std::forward<TMatcher>(matcher)) {
396 }
397
401 bool operator()(const char* str) const noexcept {
402#ifdef OSMIUM_USE_STD_VARIANT
403 return std::visit(match_visitor{str}, m_matcher);
404#else
405 return boost::apply_visitor(match_visitor{str}, m_matcher);
406#endif
407 }
408
412 bool operator()(const std::string& str) const noexcept {
413 return operator()(str.c_str());
414 }
415
416 template <typename TChar, typename TTraits>
417 void print(std::basic_ostream<TChar, TTraits>& out) const {
418#ifdef OSMIUM_USE_STD_VARIANT
420#else
421 boost::apply_visitor(print_visitor<TChar, TTraits>{out}, m_matcher);
422#endif
423 }
424
425 }; // class StringMatcher
426
427 template <typename TChar, typename TTraits>
428 inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const StringMatcher& matcher) {
429 matcher.print(out);
430 return out;
431 }
432
433} // namespace osmium
434
435#undef OSMIUM_USE_STD_VARIANT
436
437#endif // OSMIUM_UTIL_STRING_MATCHER_HPP
Definition: string_matcher.hpp:73
static bool match(const char *) noexcept
Definition: string_matcher.hpp:77
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:82
Definition: string_matcher.hpp:91
static bool match(const char *) noexcept
Definition: string_matcher.hpp:95
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:100
Definition: string_matcher.hpp:109
equal(const char *str)
Definition: string_matcher.hpp:119
std::string m_str
Definition: string_matcher.hpp:111
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:123
equal(std::string str)
Definition: string_matcher.hpp:115
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:128
Definition: string_matcher.hpp:217
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:239
list & add_string(const std::string &str)
Definition: string_matcher.hpp:234
list & add_string(const char *str)
Definition: string_matcher.hpp:229
std::vector< std::string > m_strings
Definition: string_matcher.hpp:219
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:247
list(std::vector< std::string > strings)
Definition: string_matcher.hpp:225
Definition: string_matcher.hpp:279
match_visitor(const char *str) noexcept
Definition: string_matcher.hpp:285
const char * m_str
Definition: string_matcher.hpp:281
bool operator()(const TMatcher &t) const noexcept
Definition: string_matcher.hpp:290
Definition: string_matcher.hpp:67
Definition: string_matcher.hpp:137
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:156
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:151
prefix(std::string str)
Definition: string_matcher.hpp:143
std::string m_str
Definition: string_matcher.hpp:139
prefix(const char *str)
Definition: string_matcher.hpp:147
Definition: string_matcher.hpp:301
print_visitor(std::basic_ostream< TChar, TTraits > &out)
Definition: string_matcher.hpp:307
std::basic_ostream< TChar, TTraits > * m_out
Definition: string_matcher.hpp:303
void operator()(const TMatcher &t) const noexcept
Definition: string_matcher.hpp:312
Definition: string_matcher.hpp:193
regex(std::regex regex)
Definition: string_matcher.hpp:199
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:203
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:208
std::regex m_regex
Definition: string_matcher.hpp:195
Definition: string_matcher.hpp:165
std::string m_str
Definition: string_matcher.hpp:167
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:184
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:179
substring(std::string str)
Definition: string_matcher.hpp:171
substring(const char *str)
Definition: string_matcher.hpp:175
Definition: string_matcher.hpp:62
StringMatcher()
Definition: string_matcher.hpp:323
StringMatcher(const std::vector< std::string > &strings)
Definition: string_matcher.hpp:380
StringMatcher(const std::regex &aregex)
Definition: string_matcher.hpp:369
StringMatcher(const char *str)
Definition: string_matcher.hpp:349
bool operator()(const char *str) const noexcept
Definition: string_matcher.hpp:401
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:417
bool operator()(const std::string &str) const noexcept
Definition: string_matcher.hpp:412
matcher_type m_matcher
Definition: string_matcher.hpp:273
StringMatcher(TMatcher &&matcher)
Definition: string_matcher.hpp:394
StringMatcher(bool result)
Definition: string_matcher.hpp:336
StringMatcher(const std::string &str)
Definition: string_matcher.hpp:359
boost::variant< always_false, always_true, equal, prefix, substring, regex, list > matcher_type
Definition: string_matcher.hpp:271
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
std::basic_ostream< TChar, TTraits > & operator<<(std::basic_ostream< TChar, TTraits > &out, const item_type item_type)
Definition: item_type.hpp:187
Definition: location.hpp:555