Awesome
Wildcards
Wildcards is a simple C++ header-only template library which implements a general purpose algorithm for matching using wildcards. It supports both runtime and compile time execution.
Basic usage
The following examples of the basic usage are functionaly equivalent.
#include <wildcards.hpp>
int main()
{
{
using wildcards::match;
static_assert(match("Hello, World!", "H*World?"), "");
}
{
using wildcards::make_matcher;
static_assert(make_matcher("H*World?").matches("Hello, World!"), "");
}
{
using namespace wildcards::literals;
static_assert("H*World?"_wc.matches("Hello, World!"), "");
}
return 0;
}
Advanced usage
The following examples of the advanced usage are functionaly equivalent.
#include <wildcards.hpp>
int main()
{
{
using wildcards::match;
static_assert(match("Hello, World!", "H%World_", {'%', '_', '\\'}), "");
}
{
using wildcards::make_matcher;
static_assert(make_matcher("H%World_", {'%', '_', '\\'}).matches("Hello, World!"), "");
}
return 0;
}
See more useful and complex examples and try them online! See also the tests to learn more.
Demonstration on Compiler Explorer
Check compilers output of the following example on Compiler Explorer.
#include <wildcards.hpp>
using namespace wildcards::literals;
constexpr auto pattern = "*.[hc](pp|)"_wc;
// returns true
bool test1()
{
constexpr auto res = pattern.matches("source.c");
static_assert(res, "must be true");
return res;
}
// returns false
bool test2()
{
constexpr auto res = pattern.matches("source.cc");
static_assert(!res, "must be false");
return res;
}
Integration
-
Single-header approach
- Copy
wildcards.hpp
fromsingle_include
directory to your project's header search path. - Add
#include <wildcards.hpp>
to your source file. - Use
wildcards::match()
orwildcards::make_matcher()
. You can also use operator""_wc
fromwildcards::literals
namespace.
- Copy
-
Multi-header approach
- Add
include
directory to your project's header search path. - Add
#include <wildcards.hpp>
to your source file. - Use
wildcards::match()
orwildcards::make_matcher()
. You can also use operator""_wc
fromwildcards::literals
namespace.
- Add
Portability
The library requires at least a C++11 compiler to build. It has no external dependencies.
The following compilers are continuously tested at Travis CI and Appveyor CI.
Compiler | Version | Operating System | Notes |
---|---|---|---|
Xcode | 9.0 | OS X 10.12 | C++11/14/17 |
Clang (with libcxx) | 3.9 | Ubuntu 14.04 LTS | C++14/17 |
Clang (with libcxx) | 4.0 | Ubuntu 14.04 LTS | C++11/14/17 |
Clang (with libcxx) | 5.0 | Ubuntu 14.04 LTS | C++11/14/17 |
Clang (with libcxx) | 6.0 | Ubuntu 14.04 LTS | C++11/14/17 |
GCC | 5.5 | Ubuntu 14.04 LTS | C++11/14/17 |
GCC | 6.4 | Ubuntu 14.04 LTS | C++11/14/17 |
GCC | 7.3 | Ubuntu 14.04 LTS | C++11/14/17 |
GCC | 8.1 | Ubuntu 14.04 LTS | C++11/14/17 |
DJGPP | 7.2 | Ubuntu 14.04 LTS | C++11/14/17, build only |
Visual Studio | 14 2015 | Windows Server 2016 | C++11/14/17, limited |
Visual Studio | 15 2017 | Windows Server 2016 | C++11/14/17 |
MinGW | 6.3 | Windows Server 2016 | C++11/14/17 |
MinGW | 7.2 | Windows Server 2016 | C++11/14/17 |
MinGW | 7.3 | Windows Server 2016 | C++11/14/17 |
License
This project is licensed under the Boost 1.0.
Details
Syntax
Pattern | Meaning |
---|---|
* | Matches everything. |
? | Matches any single character. |
\ | Escape character. |
[abc] | Matches any character in Set. |
[!abc] | Matches any character not in Set. |
(ab|c) | Matches one of the sequences in Alternative. |
- Set cannot be empty. Any special character loses its special meaning in it.
- Alternative can contain more than two or just one sequence.
- The use of Sets and Alternatives can be switched off.
- Special characters are predefined for
char
,char16_t
,char32_t
andwchar_t
, but can be redefined.
Technical Notes
-
Wildcards depends on two components which originate from external sources and were made part of the repository:
cpp_feature.hpp
taken from here,catch.hpp
taken from here.
-
Wildcards uses a recursive approach. Hence you can simply run out of stack (during runtime execution) or you can exceed the maximum depth of constexpr evaluation (during compile time execution). If so, try making the input sequence shorter or the pattern less complex. You can also try to build using the C++14 standard since the C++14 implementation of the library is more effective and consumes less resources.
-
Place more specific sequences in Alternatives first. This becomes important when Alternatives are nested. E.g.
match("source.cpp", "(*.[hc](pp|))")
will work as expected butmatch("source.cpp", "(*.[hc](|pp))")
will not. Fixing that would make Wildcards unreasonably complex. -
The
cx
library is a byproduct created during the development of Wildcards which uses some pieces from its functionality internally. More of thecx
is used in tests and examples. You can use this library in exactly the same way as you use Wildcards (single-header / multi-header approach) but if you are interested only in Wildcards, you don't need to care about thecx
at all. This library might become a separate project in the future.