Détection des caractéristiques
Il s'agit d'un extrait permettant de détecter si l'option libstdc++
est implémentée avec les définitions du préprocesseur C :
#include <regex>
#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
Macros
-
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
es défini en bits/regex.tcc
en 4.9.x
-
_GLIBCXX_REGEX_STATE_LIMIT
es défini en bits/regex_automatron.h
en 5+
-
_GLIBCXX_RELEASE
a été ajouté à 7+
à la suite de cette réponse et est la version majeure de GCC
Essais
Vous pouvez le tester avec GCC comme ceci :
cat << EOF | g++ --std=c++11 -x c++ - && ./a.out
#include <regex>
#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 <iostream>
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 << "<regex> works, look: " << std::boolalpha << result << std::endl;
#else
std::cerr << "<regex> doesn't work, look: " << std::boolalpha << result << std::endl;
#endif
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF
Résultats
Voici quelques résultats pour différents compilateurs :
$ 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
<regex> 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
<regex> 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
<regex> 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
<regex> 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
<regex> 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++'
<regex> works, look: true
Ici les Dragons
Cette méthode n'est absolument pas supportée et repose sur la détection de macros privées que les développeurs de GCC ont placées dans le fichier bits/regex*
Les en-têtes. Ils peuvent changer et disparaître à à tout moment . Avec un peu de chance, ils ne seront pas supprimés dans les versions actuelles 4.9.x, 5.x, 6.x mais ils pourraient disparaître dans les versions 7.x.
Si les développeurs de GCC ont ajouté un #define _GLIBCXX_HAVE_WORKING_REGEX 1
(ou quelque chose, hint hint nudge nudge) dans la version 7.x qui a persisté, ce snippet pourrait être mis à jour pour l'inclure et les versions ultérieures de GCC fonctionneraient avec le snippet ci-dessus.
Pour autant que je sache, tous les autres compilateurs disposent d'une fonctionnalité <regex>
quand __cplusplus >= 201103L
mais YMMV.
Évidemment, cela serait complètement cassé si quelqu'un définissait le _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
o _GLIBCXX_REGEX_STATE_LIMIT
en dehors de l'élément stdc++-v3
les en-têtes.