Loading...
Searching...
No Matches
string_matcher.hpp
Go to the documentation of this file.
#ifndef OSMIUM_UTIL_STRING_MATCHER_HPP
#define OSMIUM_UTIL_STRING_MATCHER_HPP
/*
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2023 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <cstring>
#include <iosfwd>
#include <regex>
#include <string>
#include <utility>
#include <vector>
#ifdef __has_include
# if __has_include(<variant>)
# include <variant>
# ifdef __cpp_lib_variant
# define OSMIUM_USE_STD_VARIANT
# endif
# endif
#endif
#ifndef OSMIUM_USE_STD_VARIANT
# include <boost/variant.hpp>
#endif
// std::regex isn't implemented properly in glibc++ (before the version
// delivered with GCC 4.9) and libc++ before the version 3.6, so the use is
// disabled by these checks. Checks for GLIBC were based on
// https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
// Checks for libc++ are simply based on compiler defines. This is probably
// not optimal but seems to work for now.
#if defined(__GLIBCXX__)
# if ((__cplusplus >= 201402L) || \
defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT))
# define OSMIUM_WITH_REGEX
# else
# pragma message("Disabling regex functionality. See source code for info.")
# endif
#elif defined(__clang__)
# if ((__clang_major__ > 3) || \
(__clang_minor__ == 3 && __clang_minor__ > 5))
# define OSMIUM_WITH_REGEX
# else
# pragma message("Disabling regex functionality")
# endif
#endif
namespace osmium {
class StringMatcher {
public:
// Parent class for all matcher classes. Used for enable_if check.
class matcher {
};
class always_false : public matcher {
public:
static bool match(const char* /*test_string*/) noexcept {
return false;
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "always_false";
}
}; // class always_false
class always_true : public matcher {
public:
static bool match(const char* /*test_string*/) noexcept {
return true;
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "always_true";
}
}; // class always_true
class equal : public matcher {
std::string m_str;
public:
explicit equal(std::string str) :
m_str(std::move(str)) {
}
explicit equal(const char* str) :
m_str(str) {
}
bool match(const char* test_string) const noexcept {
return !std::strcmp(m_str.c_str(), test_string);
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "equal[" << m_str << ']';
}
}; // class equal
class prefix : public matcher {
std::string m_str;
public:
explicit prefix(std::string str) :
m_str(std::move(str)) {
}
explicit prefix(const char* str) :
m_str(str) {
}
bool match(const char* test_string) const noexcept {
return m_str.compare(0, std::string::npos, test_string, 0, m_str.size()) == 0;
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "prefix[" << m_str << ']';
}
}; // class prefix
class substring : public matcher {
std::string m_str;
public:
explicit substring(std::string str) :
m_str(std::move(str)) {
}
explicit substring(const char* str) :
m_str(str) {
}
bool match(const char* test_string) const noexcept {
return std::strstr(test_string, m_str.c_str()) != nullptr;
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "substring[" << m_str << ']';
}
}; // class substring
#ifdef OSMIUM_WITH_REGEX
class regex : public matcher {
std::regex m_regex;
public:
explicit regex(std::regex regex) :
m_regex(std::move(regex)) {
}
bool match(const char* test_string) const noexcept {
return std::regex_search(test_string, m_regex);
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "regex";
}
}; // class regex
#endif
class list : public matcher {
std::vector<std::string> m_strings;
public:
explicit list() = default;
explicit list(std::vector<std::string> strings) :
m_strings(std::move(strings)) {
}
list& add_string(const char* str) {
m_strings.emplace_back(str);
return *this;
}
list& add_string(const std::string& str) {
m_strings.push_back(str);
return *this;
}
bool match(const char* test_string) const noexcept {
return std::any_of(m_strings.cbegin(), m_strings.cend(),
[&test_string](const std::string& s){
return s == test_string;
});
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
out << "list[";
for (const auto& s : m_strings) {
out << '[' << s << ']';
}
out << ']';
}
}; // class list
private:
using matcher_type =
#ifdef OSMIUM_USE_STD_VARIANT
std::variant
#else
boost::variant
#endif
<always_false,
always_true,
equal,
prefix,
substring,
#ifdef OSMIUM_WITH_REGEX
regex,
#endif
list>;
matcher_type m_matcher;
class match_visitor
#ifndef OSMIUM_USE_STD_VARIANT
: public boost::static_visitor<bool>
#endif
{
const char* m_str;
public:
explicit match_visitor(const char* str) noexcept :
m_str(str) {
}
template <typename TMatcher>
bool operator()(const TMatcher& t) const noexcept {
return t.match(m_str);
}
}; // class match_visitor
template <typename TChar, typename TTraits>
class print_visitor
#ifndef OSMIUM_USE_STD_VARIANT
: public boost::static_visitor<void>
#endif
{
std::basic_ostream<TChar, TTraits>* m_out;
public:
explicit print_visitor(std::basic_ostream<TChar, TTraits>& out) :
m_out(&out) {
}
template <typename TMatcher>
void operator()(const TMatcher& t) const noexcept {
t.print(*m_out);
}
}; // class print_visitor
public:
StringMatcher() :
m_matcher(always_false{}) {
}
// cppcheck-suppress noExplicitConstructor
StringMatcher(bool result) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(always_false{}) {
if (result) {
m_matcher = always_true{};
}
}
// cppcheck-suppress noExplicitConstructor
StringMatcher(const char* str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(equal{str}) {
}
// cppcheck-suppress noExplicitConstructor
StringMatcher(const std::string& str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(equal{str}) {
}
#ifdef OSMIUM_WITH_REGEX
// cppcheck-suppress noExplicitConstructor
StringMatcher(const std::regex& aregex) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(regex{aregex}) {
}
#endif
// cppcheck-suppress noExplicitConstructor
StringMatcher(const std::vector<std::string>& strings) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(list{strings}) {
}
// cppcheck-suppress noExplicitConstructor
template <typename TMatcher, typename X = typename std::enable_if<
std::is_base_of<matcher, TMatcher>::value, void>::type>
StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
m_matcher(std::forward<TMatcher>(matcher)) {
}
bool operator()(const char* str) const noexcept {
#ifdef OSMIUM_USE_STD_VARIANT
return std::visit(match_visitor{str}, m_matcher);
#else
return boost::apply_visitor(match_visitor{str}, m_matcher);
#endif
}
bool operator()(const std::string& str) const noexcept {
return operator()(str.c_str());
}
template <typename TChar, typename TTraits>
void print(std::basic_ostream<TChar, TTraits>& out) const {
#ifdef OSMIUM_USE_STD_VARIANT
std::visit(print_visitor<TChar, TTraits>{out}, m_matcher);
#else
boost::apply_visitor(print_visitor<TChar, TTraits>{out}, m_matcher);
#endif
}
}; // class StringMatcher
template <typename TChar, typename TTraits>
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const StringMatcher& matcher) {
matcher.print(out);
return out;
}
} // namespace osmium
#undef OSMIUM_USE_STD_VARIANT
#endif // OSMIUM_UTIL_STRING_MATCHER_HPP
osmium::StringMatcher::always_false
Definition string_matcher.hpp:97
osmium::StringMatcher::always_false::match
static bool match(const char *) noexcept
Definition string_matcher.hpp:101
osmium::StringMatcher::always_false::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:106
osmium::StringMatcher::always_true
Definition string_matcher.hpp:115
osmium::StringMatcher::always_true::match
static bool match(const char *) noexcept
Definition string_matcher.hpp:119
osmium::StringMatcher::always_true::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:124
osmium::StringMatcher::equal
Definition string_matcher.hpp:133
osmium::StringMatcher::equal::equal
equal(const char *str)
Definition string_matcher.hpp:143
osmium::StringMatcher::equal::m_str
std::string m_str
Definition string_matcher.hpp:135
osmium::StringMatcher::equal::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:147
osmium::StringMatcher::equal::equal
equal(std::string str)
Definition string_matcher.hpp:139
osmium::StringMatcher::equal::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:152
osmium::StringMatcher::list
Definition string_matcher.hpp:243
osmium::StringMatcher::list::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:265
osmium::StringMatcher::list::add_string
list & add_string(const std::string &str)
Definition string_matcher.hpp:260
osmium::StringMatcher::list::add_string
list & add_string(const char *str)
Definition string_matcher.hpp:255
osmium::StringMatcher::list::list
list()=default
osmium::StringMatcher::list::m_strings
std::vector< std::string > m_strings
Definition string_matcher.hpp:245
osmium::StringMatcher::list::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:273
osmium::StringMatcher::list::list
list(std::vector< std::string > strings)
Definition string_matcher.hpp:251
osmium::StringMatcher::match_visitor
Definition string_matcher.hpp:307
osmium::StringMatcher::match_visitor::match_visitor
match_visitor(const char *str) noexcept
Definition string_matcher.hpp:313
osmium::StringMatcher::match_visitor::m_str
const char * m_str
Definition string_matcher.hpp:309
osmium::StringMatcher::match_visitor::operator()
bool operator()(const TMatcher &t) const noexcept
Definition string_matcher.hpp:318
osmium::StringMatcher::matcher
Definition string_matcher.hpp:91
osmium::StringMatcher::prefix
Definition string_matcher.hpp:161
osmium::StringMatcher::prefix::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:180
osmium::StringMatcher::prefix::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:175
osmium::StringMatcher::prefix::prefix
prefix(std::string str)
Definition string_matcher.hpp:167
osmium::StringMatcher::prefix::m_str
std::string m_str
Definition string_matcher.hpp:163
osmium::StringMatcher::prefix::prefix
prefix(const char *str)
Definition string_matcher.hpp:171
osmium::StringMatcher::print_visitor
Definition string_matcher.hpp:329
osmium::StringMatcher::print_visitor::print_visitor
print_visitor(std::basic_ostream< TChar, TTraits > &out)
Definition string_matcher.hpp:335
osmium::StringMatcher::print_visitor::m_out
std::basic_ostream< TChar, TTraits > * m_out
Definition string_matcher.hpp:331
osmium::StringMatcher::print_visitor::operator()
void operator()(const TMatcher &t) const noexcept
Definition string_matcher.hpp:340
osmium::StringMatcher::substring
Definition string_matcher.hpp:189
osmium::StringMatcher::substring::m_str
std::string m_str
Definition string_matcher.hpp:191
osmium::StringMatcher::substring::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:208
osmium::StringMatcher::substring::match
bool match(const char *test_string) const noexcept
Definition string_matcher.hpp:203
osmium::StringMatcher::substring::substring
substring(std::string str)
Definition string_matcher.hpp:195
osmium::StringMatcher::substring::substring
substring(const char *str)
Definition string_matcher.hpp:199
osmium::StringMatcher
Definition string_matcher.hpp:86
osmium::StringMatcher::StringMatcher
StringMatcher()
Definition string_matcher.hpp:351
osmium::StringMatcher::StringMatcher
StringMatcher(const std::vector< std::string > &strings)
Definition string_matcher.hpp:410
osmium::StringMatcher::StringMatcher
StringMatcher(const char *str)
Definition string_matcher.hpp:377
osmium::StringMatcher::operator()
bool operator()(const char *str) const noexcept
Definition string_matcher.hpp:431
osmium::StringMatcher::print
void print(std::basic_ostream< TChar, TTraits > &out) const
Definition string_matcher.hpp:447
osmium::StringMatcher::operator()
bool operator()(const std::string &str) const noexcept
Definition string_matcher.hpp:442
osmium::StringMatcher::m_matcher
matcher_type m_matcher
Definition string_matcher.hpp:301
osmium::StringMatcher::StringMatcher
StringMatcher(TMatcher &&matcher)
Definition string_matcher.hpp:424
osmium::StringMatcher::StringMatcher
StringMatcher(bool result)
Definition string_matcher.hpp:364
osmium::StringMatcher::StringMatcher
StringMatcher(const std::string &str)
Definition string_matcher.hpp:387
osmium::StringMatcher::matcher_type
boost::variant< always_false, always_true, equal, prefix, substring, list > matcher_type
Definition string_matcher.hpp:285
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:555