Libosmium: include/osmium/util/string_matcher.hpp Source File

Libosmium Fast and flexible C++ library for working with OpenStreetMap data

Loading...
Searching...
No Matches
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-2026 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
62 class StringMatcher {
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
259 using matcher_type =
260#ifdef OSMIUM_USE_STD_VARIANT
261 std::variant
262#else
263 boost::variant
264#endif
265 <always_false,
266 always_true,
267 equal,
268 prefix,
269 substring,
270 regex,
271 list>;
272
273 matcher_type m_matcher;
274
275 class match_visitor
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>
297 class print_visitor
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
323 StringMatcher() :
324 m_matcher(always_false{}) {
325 }
326
335 // cppcheck-suppress noExplicitConstructor
336 StringMatcher(bool result) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
337 m_matcher(always_false{}) {
338 if (result) {
339 m_matcher = always_true{};
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
419 std::visit(print_visitor<TChar, TTraits>{out}, m_matcher);
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
osmium::StringMatcher::always_false
Definition string_matcher.hpp:73
osmium::StringMatcher::always_false::match
static bool match(const char *) noexcept
Definition string_matcher.hpp:77
osmium::StringMatcher::always_false::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:82
osmium::StringMatcher::always_true
Definition string_matcher.hpp:91
osmium::StringMatcher::always_true::match
static bool match(const char *) noexcept
Definition string_matcher.hpp:95
osmium::StringMatcher::always_true::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:100
osmium::StringMatcher::equal
Definition string_matcher.hpp:109
osmium::StringMatcher::equal::equal
equal(const char *str)
Definition string_matcher.hpp:119
osmium::StringMatcher::equal::m_str
std::string m_str
Definition string_matcher.hpp:111
osmium::StringMatcher::equal::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:123
osmium::StringMatcher::equal::equal
equal(std::string str)
Definition string_matcher.hpp:115
osmium::StringMatcher::equal::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:128
osmium::StringMatcher::list
Definition string_matcher.hpp:217
osmium::StringMatcher::list::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:239
osmium::StringMatcher::list::add_string
list & add_string(const std::string &str)
Definition string_matcher.hpp:234
osmium::StringMatcher::list::add_string
list & add_string(const char *str)
Definition string_matcher.hpp:229
osmium::StringMatcher::list::list
list()=default
osmium::StringMatcher::list::m_strings
std::vector< std::string > m_strings
Definition string_matcher.hpp:219
osmium::StringMatcher::list::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:247
osmium::StringMatcher::list::list
list(std::vector< std::string > strings)
Definition string_matcher.hpp:225
osmium::StringMatcher::match_visitor
Definition string_matcher.hpp:279
osmium::StringMatcher::match_visitor::match_visitor
match_visitor(const char *str) noexcept
Definition string_matcher.hpp:285
osmium::StringMatcher::match_visitor::m_str
const char * m_str
Definition string_matcher.hpp:281
osmium::StringMatcher::match_visitor::operator()
bool operator()(const TMatcher &t) const noexcept
Definition string_matcher.hpp:290
osmium::StringMatcher::matcher
Definition string_matcher.hpp:67
osmium::StringMatcher::prefix
Definition string_matcher.hpp:137
osmium::StringMatcher::prefix::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:156
osmium::StringMatcher::prefix::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:151
osmium::StringMatcher::prefix::prefix
prefix(std::string str)
Definition string_matcher.hpp:143
osmium::StringMatcher::prefix::m_str
std::string m_str
Definition string_matcher.hpp:139
osmium::StringMatcher::prefix::prefix
prefix(const char *str)
Definition string_matcher.hpp:147
osmium::StringMatcher::print_visitor
Definition string_matcher.hpp:301
osmium::StringMatcher::print_visitor::print_visitor
print_visitor(std::basic_ostream< TChar, TTraits > &out)
Definition string_matcher.hpp:307
osmium::StringMatcher::print_visitor::m_out
std::basic_ostream< TChar, TTraits > * m_out
Definition string_matcher.hpp:303
osmium::StringMatcher::print_visitor::operator()
void operator()(const TMatcher &t) const noexcept
Definition string_matcher.hpp:312
osmium::StringMatcher::regex
Definition string_matcher.hpp:193
osmium::StringMatcher::regex::regex
regex(std::regex regex)
Definition string_matcher.hpp:199
osmium::StringMatcher::regex::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:203
osmium::StringMatcher::regex::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:208
osmium::StringMatcher::regex::m_regex
std::regex m_regex
Definition string_matcher.hpp:195
osmium::StringMatcher::substring
Definition string_matcher.hpp:165
osmium::StringMatcher::substring::m_str
std::string m_str
Definition string_matcher.hpp:167
osmium::StringMatcher::substring::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:184
osmium::StringMatcher::substring::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:179
osmium::StringMatcher::substring::substring
substring(std::string str)
Definition string_matcher.hpp:171
osmium::StringMatcher::substring::substring
substring(const char *str)
Definition string_matcher.hpp:175
osmium::StringMatcher::matcher_type
boost::variant< always_false, always_true, equal, prefix, substring, regex, list > matcher_type
Definition string_matcher.hpp:259
osmium::StringMatcher::StringMatcher
StringMatcher()
Definition string_matcher.hpp:323
osmium::StringMatcher::StringMatcher
StringMatcher(const std::vector< std::string > &strings)
Definition string_matcher.hpp:380
osmium::StringMatcher::StringMatcher
StringMatcher(const std::regex &aregex)
Definition string_matcher.hpp:369
osmium::StringMatcher::StringMatcher
StringMatcher(const char *str)
Definition string_matcher.hpp:349
osmium::StringMatcher::operator()
bool operator()(const char *str) const noexcept
Definition string_matcher.hpp:401
osmium::StringMatcher::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:417
osmium::StringMatcher::operator()
bool operator()(const std::string &str) const noexcept
Definition string_matcher.hpp:412
osmium::StringMatcher::m_matcher
matcher_type m_matcher
Definition string_matcher.hpp:273
osmium::StringMatcher::StringMatcher
StringMatcher(TMatcher &&matcher)
Definition string_matcher.hpp:394
osmium::StringMatcher::StringMatcher
StringMatcher(bool result)
Definition string_matcher.hpp:336
osmium::StringMatcher::StringMatcher
StringMatcher(const std::string &str)
Definition string_matcher.hpp:359
osmium
Namespace for everything in the Osmium library.
Definition assembler.hpp:53
osmium::operator<<
std::basic_ostream< TChar, TTraits > & operator<<(std::basic_ostream< TChar, TTraits > &out, const item_type item_type)
Definition item_type.hpp:187
std
Definition location.hpp:654