I am trying to use std::regex in a C++11 piece of code, but it appears that the support is a bit buggy. An example:
#include
#include
This is a snippet to detect if the libstdc++
implementation is implemented with C preprocessor defines:
#include
#if __cplusplus >= 201103L && \
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
(defined(_GLIBCXX_RELEASE) && \
_GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
is defined in bits/regex.tcc
in 4.9.x
_GLIBCXX_REGEX_STATE_LIMIT
is defined in bits/regex_automatron.h
in 5+
_GLIBCXX_RELEASE
was added to 7+
as a result of this answer and is the GCC major versionYou can test it with GCC like this:
cat << EOF | g++ --std=c++11 -x c++ - && ./a.out
#include
#if __cplusplus >= 201103L && \
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
(defined(_GLIBCXX_RELEASE) && \
_GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif
#include
int main() {
const std::regex regex(".*");
const std::string string = "This should match!";
const auto result = std::regex_search(string, regex);
#if HAVE_WORKING_REGEX
std::cerr << " works, look: " << std::boolalpha << result << std::endl;
#else
std::cerr << " doesn't work, look: " << std::boolalpha << result << std::endl;
#endif
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF
Here are some results for various compilers:
$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
doesn't work, look: false
$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
works, look: true
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
works, look: true
$ gcc --version
gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
works, look: true
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
works, look: true
$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ ./a.out # compiled with 'clang -lstdc++'
works, look: true
This is totally unsupported and relies on the detection of private macros that the GCC developers have put into the bits/regex*
headers. They could change and go away at anytime. Hopefully, they won't be removed in the current 4.9.x, 5.x, 6.x releases but they could go away in the 7.x releases.
If the GCC developers added a #define _GLIBCXX_HAVE_WORKING_REGEX 1
(or something, hint hint nudge nudge) in the 7.x release that persisted, this snippet could be updated to include that and later GCC releases would work with the snippet above.
As far as I know, all other compilers have a working
when __cplusplus >= 201103L
but YMMV.
Obviously this would completely break if someone defined the _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
or _GLIBCXX_REGEX_STATE_LIMIT
macros outside of the stdc++-v3
headers.