Libosmium  2.17.0
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-2021 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 <boost/variant.hpp>
37
38#include <algorithm>
39#include <cstring>
40#include <iosfwd>
41#include <regex>
42#include <string>
43#include <utility>
44#include <vector>
45
46// std::regex isn't implemented properly in glibc++ (before the version
47// delivered with GCC 4.9) and libc++ before the version 3.6, so the use is
48// disabled by these checks. Checks for GLIBC were based on
49// https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
50// Checks for libc++ are simply based on compiler defines. This is probably
51// not optimal but seems to work for now.
52#if defined(__GLIBCXX__)
53# if ((__cplusplus >= 201402L) || \
54 defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
55 defined(_GLIBCXX_REGEX_STATE_LIMIT))
56# define OSMIUM_WITH_REGEX
57# else
58# pragma message("Disabling regex functionality. See source code for info.")
59# endif
60#elif defined(__clang__)
61# if ((__clang_major__ > 3) || \
62 (__clang_minor__ == 3 && __clang_minor__ > 5))
63# define OSMIUM_WITH_REGEX
64# else
65# pragma message("Disabling regex functionality")
66# endif
67#endif
68
69namespace osmium {
70
75
76 public:
77
78 // Parent class for all matcher classes. Used for enable_if check.
79 class matcher {
80 };
81
85 class always_false : public matcher {
86
87 public:
88
89 static bool match(const char* /*test_string*/) noexcept {
90 return false;
91 }
92
93 template <typename TChar, typename TTraits>
94 void print(std::basic_ostream<TChar, TTraits>& out) const {
95 out << "always_false";
96 }
97
98 }; // class always_false
99
103 class always_true : public matcher {
104
105 public:
106
107 static bool match(const char* /*test_string*/) noexcept {
108 return true;
109 }
110
111 template <typename TChar, typename TTraits>
112 void print(std::basic_ostream<TChar, TTraits>& out) const {
113 out << "always_true";
114 }
115
116 }; // class always_true
117
121 class equal : public matcher {
122
123 std::string m_str;
124
125 public:
126
127 explicit equal(std::string str) :
128 m_str(std::move(str)) {
129 }
130
131 explicit equal(const char* str) :
132 m_str(str) {
133 }
134
135 bool match(const char* test_string) const noexcept {
136 return !std::strcmp(m_str.c_str(), test_string);
137 }
138
139 template <typename TChar, typename TTraits>
140 void print(std::basic_ostream<TChar, TTraits>& out) const {
141 out << "equal[" << m_str << ']';
142 }
143
144 }; // class equal
145
149 class prefix : public matcher {
150
151 std::string m_str;
152
153 public:
154
155 explicit prefix(std::string str) :
156 m_str(std::move(str)) {
157 }
158
159 explicit prefix(const char* str) :
160 m_str(str) {
161 }
162
163 bool match(const char* test_string) const noexcept {
164 return m_str.compare(0, std::string::npos, test_string, 0, m_str.size()) == 0;
165 }
166
167 template <typename TChar, typename TTraits>
168 void print(std::basic_ostream<TChar, TTraits>& out) const {
169 out << "prefix[" << m_str << ']';
170 }
171
172 }; // class prefix
173
177 class substring : public matcher {
178
179 std::string m_str;
180
181 public:
182
183 explicit substring(std::string str) :
184 m_str(std::move(str)) {
185 }
186
187 explicit substring(const char* str) :
188 m_str(str) {
189 }
190
191 bool match(const char* test_string) const noexcept {
192 return std::strstr(test_string, m_str.c_str()) != nullptr;
193 }
194
195 template <typename TChar, typename TTraits>
196 void print(std::basic_ostream<TChar, TTraits>& out) const {
197 out << "substring[" << m_str << ']';
198 }
199
200 }; // class substring
201
202#ifdef OSMIUM_WITH_REGEX
206 class regex : public matcher {
207
208 std::regex m_regex;
209
210 public:
211
212 explicit regex(std::regex regex) :
213 m_regex(std::move(regex)) {
214 }
215
216 bool match(const char* test_string) const noexcept {
217 return std::regex_search(test_string, m_regex);
218 }
219
220 template <typename TChar, typename TTraits>
221 void print(std::basic_ostream<TChar, TTraits>& out) const {
222 out << "regex";
223 }
224
225 }; // class regex
226#endif
227
231 class list : public matcher {
232
233 std::vector<std::string> m_strings;
234
235 public:
236
237 explicit list() = default;
238
239 explicit list(std::vector<std::string> strings) :
240 m_strings(std::move(strings)) {
241 }
242
243 list& add_string(const char* str) {
244 m_strings.emplace_back(str);
245 return *this;
246 }
247
248 list& add_string(const std::string& str) {
249 m_strings.push_back(str);
250 return *this;
251 }
252
253 bool match(const char* test_string) const noexcept {
254 return std::any_of(m_strings.cbegin(), m_strings.cend(),
255 [&test_string](const std::string& s){
256 return s == test_string;
257 });
258 }
259
260 template <typename TChar, typename TTraits>
261 void print(std::basic_ostream<TChar, TTraits>& out) const {
262 out << "list[";
263 for (const auto& s : m_strings) {
264 out << '[' << s << ']';
265 }
266 out << ']';
267 }
268
269 }; // class list
270
271 private:
272
273 using matcher_type = boost::variant<always_false,
275 equal,
276 prefix,
277 substring,
278#ifdef OSMIUM_WITH_REGEX
279 regex,
280#endif
281 list>;
282
284
285 class match_visitor : public boost::static_visitor<bool> {
286
287 const char* m_str;
288
289 public:
290
291 explicit match_visitor(const char* str) noexcept :
292 m_str(str) {
293 }
294
295 template <typename TMatcher>
296 bool operator()(const TMatcher& t) const noexcept {
297 return t.match(m_str);
298 }
299
300 }; // class match_visitor
301
302 template <typename TChar, typename TTraits>
303 class print_visitor : public boost::static_visitor<void> {
304
305 std::basic_ostream<TChar, TTraits>* m_out;
306
307 public:
308
309 explicit print_visitor(std::basic_ostream<TChar, TTraits>& out) :
310 m_out(&out) {
311 }
312
313 template <typename TMatcher>
314 void operator()(const TMatcher& t) const noexcept {
315 t.print(*m_out);
316 }
317
318 }; // class print_visitor
319
320 public:
321
327 }
328
337 // cppcheck-suppress noExplicitConstructor
338 StringMatcher(bool result) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
340 if (result) {
342 }
343 }
344
350 // cppcheck-suppress noExplicitConstructor
351 StringMatcher(const char* str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
352 m_matcher(equal{str}) {
353 }
354
360 // cppcheck-suppress noExplicitConstructor
361 StringMatcher(const std::string& str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
362 m_matcher(equal{str}) {
363 }
364
365#ifdef OSMIUM_WITH_REGEX
371 // cppcheck-suppress noExplicitConstructor
372 StringMatcher(const std::regex& aregex) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
373 m_matcher(regex{aregex}) {
374 }
375#endif
376
383 // cppcheck-suppress noExplicitConstructor
384 StringMatcher(const std::vector<std::string>& strings) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
385 m_matcher(list{strings}) {
386 }
387
395 // cppcheck-suppress noExplicitConstructor
396 template <typename TMatcher, typename X = typename std::enable_if<
397 std::is_base_of<matcher, TMatcher>::value, void>::type>
398 StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
399 m_matcher(std::forward<TMatcher>(matcher)) {
400 }
401
405 bool operator()(const char* str) const noexcept {
406 return boost::apply_visitor(match_visitor{str}, m_matcher);
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 boost::apply_visitor(print_visitor<TChar, TTraits>{out}, m_matcher);
419 }
420
421 }; // class StringMatcher
422
423 template <typename TChar, typename TTraits>
424 inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const StringMatcher& matcher) {
425 matcher.print(out);
426 return out;
427 }
428
429} // namespace osmium
430
431#endif // OSMIUM_UTIL_STRING_MATCHER_HPP
Definition: string_matcher.hpp:85
static bool match(const char *) noexcept
Definition: string_matcher.hpp:89
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:94
Definition: string_matcher.hpp:103
static bool match(const char *) noexcept
Definition: string_matcher.hpp:107
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:112
Definition: string_matcher.hpp:121
equal(const char *str)
Definition: string_matcher.hpp:131
std::string m_str
Definition: string_matcher.hpp:123
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:135
equal(std::string str)
Definition: string_matcher.hpp:127
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:140
Definition: string_matcher.hpp:231
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:253
list & add_string(const std::string &str)
Definition: string_matcher.hpp:248
list & add_string(const char *str)
Definition: string_matcher.hpp:243
std::vector< std::string > m_strings
Definition: string_matcher.hpp:233
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:261
list(std::vector< std::string > strings)
Definition: string_matcher.hpp:239
Definition: string_matcher.hpp:285
match_visitor(const char *str) noexcept
Definition: string_matcher.hpp:291
const char * m_str
Definition: string_matcher.hpp:287
bool operator()(const TMatcher &t) const noexcept
Definition: string_matcher.hpp:296
Definition: string_matcher.hpp:79
Definition: string_matcher.hpp:149
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:168
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:163
prefix(std::string str)
Definition: string_matcher.hpp:155
std::string m_str
Definition: string_matcher.hpp:151
prefix(const char *str)
Definition: string_matcher.hpp:159
Definition: string_matcher.hpp:303
print_visitor(std::basic_ostream< TChar, TTraits > &out)
Definition: string_matcher.hpp:309
std::basic_ostream< TChar, TTraits > * m_out
Definition: string_matcher.hpp:305
void operator()(const TMatcher &t) const noexcept
Definition: string_matcher.hpp:314
Definition: string_matcher.hpp:177
std::string m_str
Definition: string_matcher.hpp:179
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition: string_matcher.hpp:196
bool match(const char *test_string) const noexcept
Definition: string_matcher.hpp:191
substring(std::string str)
Definition: string_matcher.hpp:183
substring(const char *str)
Definition: string_matcher.hpp:187
Definition: string_matcher.hpp:74
StringMatcher()
Definition: string_matcher.hpp:325
StringMatcher(const std::vector< std::string > &strings)
Definition: string_matcher.hpp:384
StringMatcher(const char *str)
Definition: string_matcher.hpp:351
bool operator()(const char *str) const noexcept
Definition: string_matcher.hpp:405
boost::variant< always_false, always_true, equal, prefix, substring, list > matcher_type
Definition: string_matcher.hpp:281
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:283
StringMatcher(TMatcher &&matcher)
Definition: string_matcher.hpp:398
StringMatcher(bool result)
Definition: string_matcher.hpp:338
StringMatcher(const std::string &str)
Definition: string_matcher.hpp:361
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:185
Definition: location.hpp:551