
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstreamghc::filesystem::u8arguments Il s'agit d'une bibliothèque d'assistance compatible std::filesystem uniquement uniquement en tête, basée sur les spécifications C ++ 17 et C ++ 20, mais implémentée pour C ++ 11, C ++ 14, C ++ 17 ou C ++ 20 (suivant étroitement la norme C ++ 17 avec très peu d'exceptions documentées). Il est actuellement testé sur MacOS 10.12 / 10.14 / 10.15/11.6, Windows 10, Ubuntu 18.04, Ubuntu 20.04, Centos 7, Centos 8, FreeBSD 12, Alpine ARM / ARM64 Linux et Solaris 10, mais devrait également fonctionner sur d'autres systèmes, tant que vous avez au moins un compatileur compatible C ++ 11. Cela devrait fonctionner avec Android NDK, Emscripten et moi avions même des rapports de son utilisation sur iOS (dans les contraintes de sable) et avec V1.5.6, il y a un support expérimental pour QNX. Le support d'Android NDK, Emscripten, QNX et depuis le 1.5.14 GNU / HURD et Haiku ne sont pas sauvegardés par des tests automatisés, mais les rapports PRS et Bug sont les bienvenus pour ceux-ci et ils seraient également rapportés. Il est bien sûr dans son propre espace de noms ghc::filesystem pour ne pas interférer avec un std::filesystem si vous l'utilisez dans un environnement mixte C ++ 17 (ce qui est possible).
La couverture des tests est bien supérieure à 90%, et à commencer par la V1.3.6 et en V1.5.0, plus de temps a été investi dans l'analyse comparative et l'optimisation des parties de la bibliothèque. Je vais essayer de continuer à optimiser certaines parties et à refacter d'autres, s'efforçant de l'améliorer tant qu'il n'introdonne pas des problèmes de compatibilité C ++ 17 / C ++ 20 supplémentaires. Les commentaires sont toujours les bienvenus. Ouvrez simplement un problème si vous voyez quelque chose de manque ou de mal ou de ne pas vous comporter comme prévu et que je vais commenter.
J'ai souvent besoin de fonctionnalités de système de fichiers, principalement fs::path , mais aussi un accès répertoire, et lorsque je commence à utiliser C ++ 11, j'ai utilisé cette mise à jour de la langue pour essayer de réduire mes dépendances tierces. Je pouvais laisser tomber la plupart de ce que j'ai utilisé, mais j'ai toujours manqué des choses que j'ai commencé à mettre en œuvre pour le plaisir. À l'origine, j'ai basé ces aides sur mes propres conventions de codage et de dénomination. Lorsque C ++ 17 a été finalisé, je voulais utiliser cette interface, mais il a fallu un certain temps, pour me pousser pour convertir mes cours.
La mise en œuvre est étroitement basée sur le chapitre 30.10 de la norme C ++ 17 et un projet proche de cette version fonctionne N4687. Il s'agit d'après la normalisation de C ++ 17, mais il contient les dernières modifications d'interface du système de fichiers par rapport au projet de travail N4659. En regardant avec v1.4.0, lorsqu'il est compilé à l'aide de C ++ 20, il s'adapte aux modifications en fonction de l'ordre de tri de chemin et de la gestion std::u8string à partir du projet de travail N4860.
Je tiens à remercier les personnes travaillant sur l'amélioration du C ++, j'ai vraiment aimé la façon dont la langue a évolué avec C ++ 11 et les normes suivantes. Continuez le bon travail!
Si vous vous demandez, ce que ghc représente, ce sont simplement gulraks helper classes , oui, je sais, pas très imaginatif, mais je voulais un court espace de noms et je l'utilise dans certaines de mes cours privés (donc cela n'a rien à voir avec Haskell , désolé pour le nom de nom).
ghc::filesystem est développé sur macOS, mais CI a été testé sur macOS, Windows, diverses distributions Linux, FreeBSD et commençant par V1.5.12 sur Solaris. Il devrait fonctionner sur l'un de ces éléments avec un compilateur C ++ 11 capable. Il y a également des vérifications pour mieux travailler sur Android, mais comme je ne teste actuellement pas avec l'Android NDK, je ne l'appellerais pas encore une plate-forme prise en charge, il en va de même pour l'utiliser avec Emscripten. Il fait désormais partie des plates-formes détectées, j'ai résolu les problèmes évidents et effectué des tests avec lui, donc ça devrait être bien. Dans l'ensemble, je ne le vois pas remplacer std::filesystem où C ++ 17 ou C ++ 20 est disponible, il n'essaye pas d'être un "meilleur" std::filesystem , juste un peu de dépassement si vous ne pouvez pas l'utiliser (à l'exception de la préférence UTF-8).
IMPORTANT: Cette implémentation suit la philosophie "UTF-8 Partout" en ce que toutes les instances std::string seront interprétées de la même manière que std::u8string Encoding Wise et comme étant dans UTF-8. Le std::u16string sera considéré comme UTF-16. Voir les différences dans l'API pour plus d'informations.
Les tests unitaires sont actuellement exécutés avec:
L'en-tête est livré avec un ensemble de tests unitaires et utilise CMake comme outil de construction et Catch2 comme Framework de test. Tous les tests sont enregistrés avec CMake, de sorte que le commando CTEST peut être utilisé pour exécuter les tests.
Tous les tests contre cette implémentation devraient réussir, selon votre environnement, il se peut qu'il y ait des avertissements, par exemple si vous n'avez aucun droit de créer des liens symboliques sur Windows ou du moins le test le pense, mais ceux-ci sont tout simplement informatifs.
Pour construire les tests à l'intérieur du répertoire du projet sous macOS ou Linux Just:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
ctestCela génère les binaires de test qui exécutent les tests et la dernière commande les exécute.
Si le compilateur par défaut est un GCC 8 ou plus récent, ou Clang 7 ou plus récent, il essaie en outre de créer une version du test binaire compilé avec GCCS / Clangs std::filesystem , nommé std_filesystem_test en tant que test supplémentaire de conformité. Idéalement, tous les tests devraient compiler et réussir avec toutes les implémentations du système de fichiers, mais en réalité, il y a quelques différences de comportement, parfois en raison de la place d'interprétation dans la norme, et il pourrait également y avoir des problèmes dans ces implémentations.
La dernière version de version est V1.5.14 et les archives source peuvent être trouvées ici.
La dernière version pré-native-dost est la V1.4.0 et les archives source peuvent être trouvées ici.
La dernière version de version pré-C ++ 20 support est la V1.3.10 et les archives source peuvent être trouvées ici.
Actuellement, seule la dernière version de version mineure reçoit BugFixes, donc si possible, vous devez utiliser la dernière version.
Comme ghc::filesystem est d'abord une bibliothèque d'en-tête uniquement, il devrait être suffisant pour copier l'en-tête ou le répertoire include/ghc dans votre dossier de projet ou indiquez votre chemin d'inclusion vers cet endroit et incluez simplement l'en-tête filesystem.hpp (ou ghc/filesystem.hpp si vous utilisez le sous-répertoire).
Tout se trouve dans l'espace de noms ghc::filesystem , donc une façon de l'utiliser uniquement comme une secours pourrait être:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs = std::filesystem;
# else
# include " filesystem.hpp "
namespace fs = ghc::filesystem;
# endif Si vous souhaitez également utiliser l'emballage fstream avec le support path comme Fallback, vous pouvez utiliser:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs {
using namespace std ::filesystem ;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
# else
# include " filesystem.hpp "
namespace fs {
using namespace ghc ::filesystem ;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
# endif Maintenant, vous avez par exemple fs::ofstream out(somePath); Et c'est l'emballage ou le C ++ 17 std::ofstream .
Sachez que, en tant que bibliothèque d'en-tête uniquement, il ne cache pas le fait qu'il utilise le système comprend, afin qu'ils «polluent» votre espace de noms global. Utilisez l'approche basée sur le transfert / implémentation basée sur les tumas (voir ci-dessous) pour éviter cela. Pour Windows, il a besoin Windows.h et il pourrait être une bonne idée de définir WIN32_LEAN_AND_MEAN ou NOMINMAX avant d'inclure des en-têtes filesystem.hpp ou fs_std.hpp pour réduire la pollution de votre espace de noms global et de compilation. Ils ne sont pas définis par ghc::filesystem pour permettre une combinaison avec des contextes où les Windows.h complètes sont nécessaires, par exemple pour les éléments d'interface utilisateur.
Astuce: il existe un en-tête supplémentaire nommé ghc/fs_std.hpp qui met en œuvre cette sélection dynamique d'une implémentation de système de fichiers, que vous pouvez inclure à la place de ghc/filesystem.hpp lorsque vous voulez std::filesystem où disponible et ghc::filesystem où non.
Alternativement, à partir de V1.1.0 ghc::filesystem peut également être utilisé en incluant l'un des deux en-têtes de wrapper supplémentaires. Ceux-ci permettent d'inclure une version transmise dans la plupart des endroits ( ghc/fs_fwd.hpp ) tout en cachant les détails d'implémentation dans un seul fichier CPP qui inclut ghc/fs_impl.hpp pour implémenter le code nécessaire. En utilisant ghc::filesystem de cette façon, assurez-vous que les incluses du système ne sont visibles que de l'intérieur du fichier CPP, tous les autres endroits sont propres.
Sachez qu'il n'est actuellement pas pris en charge pour masquer l'implémentation dans une Windows-DLL, car une interface DLL avec les modèles standard C ++ dans les interfaces est une bête différente. Si quelqu'un est prêt à essayer, je pourrais intégrer un RP, mais y travailler actuellement, moi-même, ce n'est pas une priorité.
Si vous utilisez l'approche de transfert / implémentation, vous pouvez toujours utiliser la commutation dynamique comme ceci:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifdef GHC_USE_STD_FS
# include < filesystem >
namespace fs {
using namespace std ::filesystem ;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
# else
# include " fs_fwd.hpp "
namespace fs {
using namespace ghc ::filesystem ;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
# endif Et dans la mise en œuvre de la mise en œuvre du CPP, vous pouvez utiliser (avant tout inclure qui inclut ghc/fs_fwd.hpp pour prendre la priorité:
# if _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
# if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html
# define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
# ifdef __APPLE__
# include < Availability.h >
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
# if __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|| __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
|| __TV_OS_VERSION_MIN_REQUIRED && __TV_OS_VERSION_MIN_REQUIRED < 130000
|| __WATCH_OS_VERSION_MAX_ALLOWED && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
# undef GHC_USE_STD_FS
# endif
# endif
# endif
# endif
# ifndef GHC_USE_STD_FS
# include " fs_impl.hpp "
# endif Astuce: il existe des en-têtes d'assistance supplémentaires, nommés ghc/fs_std_fwd.hpp et ghc/fs_std_impl.hpp qui utilisent cette technique, afin que vous puissiez simplement les inclure si vous souhaitez sélectionner dynamiquement l'implémentation du système de fichiers.
À partir de v1.1.0, il est possible d'ajouter ghc::filesystem en tant que sous-module GIT, d'ajouter le répertoire à votre CMakeLists.txt avec add_subdirectory() , puis d'utiliser simplement target_link_libraries(your-target ghc_filesystem) pour #include <ghc/filesystem.hpp> assurer de fonctionner.
Le CMakeLists.txt offre quelques options pour personnaliser son comportement:
GHC_FILESYSTEM_BUILD_TESTING - Tests de compilation, la valeur par défaut est OFF lorsqu'elle est utilisée comme sous-module, ON .GHC_FILESYSTEM_BUILD_EXAMPLES - compiler les exemples, la valeur par défaut est OFF lorsqu'elle est utilisée comme sous-module, ON .GHC_FILESYSTEM_WITH_INSTALL - Ajouter une cible d'installation à la construction, la valeur par défaut est OFF lorsqu'elle est utilisée comme sous-module, ON .GHC_FILESYSTEM_BUILD_STD_TESTING - compiler std_filesystem_test , la variante de la suite de test exécutée contre std::filesystem , défaut à GHC_FILESYSTEM_BUILD_TESTING . Cela n'est fait que si le compilateur est détecté comme étant capable de le faire.GHC_FILESYSTEM_TEST_COMPILE_FEATURES PEUT être défini sur une liste de fonctionnalités pour remplacer CMAKE_CXX_COMPILE_FEATURES lorsque la détection de C ++ 17 ou C ++ 20 pour des tests supplémentaires ne fonctionne pas (par exemple cxx_std_20 pour appliquer la création d'un filesystem_test_cpp20 avec C ++ 20).Veuillez utiliser HeDronVision / Bazel-Cc-FileSystem-Backport, qui configurera automatiquement tout pour vous.
Il existe une version macro GHC_FILESYSTEM_VERSION définie dans le cas où les modifications futures pourraient le rendre nécessaire pour réagir sur la version, mais je n'ai pas l'intention de briser quoi que ce soit. C'est la version comme numéro décimal (major * 10000 + minor * 100 + patch) .
Remarque: seules les versions de correctifs seront utilisées pour les versions et la version de patch impair ne sera utilisée que entre les validations tout en travaillant sur la prochaine version.
Il n'y a presque pas de documentation dans cette version, car toute documentation std::filesystem fonctionnerait, outre les quelques différences expliquées dans la section suivante. Vous pouvez donc vous rendre sur https://en.cppreference.com/w/cpp/filesystem pour une description des composants de cette bibliothèque.
Lors de la compilation avec C ++ 11, C ++ 14 ou C ++ 17, l'API suit la norme C ++ 17, si possible, à l'exception que les paramètres std::string_view ne sont pris en charge que sur C ++ 17. Lors de la compilation avec C ++ 20, ghc::filesysytem par défaut à l'API C ++ 20, avec les interfaces char8_t et std::u8string et la méthode fs::u8path Factory.
Remarque: Si l'API C ++ 17 doit être appliquée même en mode C ++ 20, utilisez le ghc_filesystem_enforce define GHC_FILESYSTEM_ENFORCE_CPP17_API . Même alors, il est possible de créer fws::path à partir de std::u8string mais fs::path::u8string() et fs::path::generic_u8string() renvoie normal utf-8 codé std::string instances, donc le code écrit pour C ++ 17 pourrait toujours fonctionner avec ghc::filesystem lors de la compilation avec C ++ 20.
Les seuls ajouts à la norme sont documentés ici:
ghc::filesystem::ifstream , ghc::filesystem::ofstream , ghc::filesystem::fstream Ce sont des emballages simples autour de std::ifstream , std::ofstream et std::fstream . Ils ajoutent simplement une méthode open() et un constructeur avec un argument ghc::filesystem::path car les variantes fstream dans C ++ 17 les ont.
ghc::filesystem::u8argumentsIl s'agit d'une classe d'aide qui vérifie actuellement le codage UTF-8 sur des plates-formes non Windows, mais sur Windows, il récupère les arguments de ligne de commande comme des chaînes Unicode du système d'exploitation avec
::CommandLineToArgvW (::GetCommandLineW(), &argc) puis les convertit en UTF-8, et remplace argc et argv . Il s'agit d'une classe de garde qui reprend ses changements en sortant de la portée.
L'utilisation de base est donc:
namespace fs = ghc::filesystem;
int main ( int argc, char * argv[])
{
fs::u8arguments u8guard (argc, argv);
if (!u8guard. valid ()) {
std::cerr << " Bad encoding, needs UTF-8. " << std::endl;
exit (EXIT_FAILURE);
}
// now use argc/argv as usual, they have utf-8 encoding on windows
// ...
return 0 ;
} De cette façon, argv est encodé UTF-8 tant que la portée de main est valide.
Remarque: Sur macOS, tout en débogage sous Xcode, le code reviendra actuellement false car Xcode démarre l'application avec US-ASCII comme codage, quel que soit le codage utilisé et même la définition LC_ALL dans le schéma de produit ne change rien. J'ai encore besoin d'enquêter sur cela.
Comme cette implémentation est basée sur le code existant de mes classes d'assistance privées, elle en a dérivé certaines contraintes. À partir de V1.5.0, la plupart des différences entre ceci et l'API standard C ++ 17 / C ++ 20, là où ils sont supprimés.
Cette implémentation a un comportement commutable pour les défauts LWG # 2682, # 2935, # 2936 et # 2937. Le comportement actuellement sélectionné (à partir de la v1.4.0) suit # 2682, # 2936, # fs::is_directory mais ne suivant pas le # 2935, car je pense qu'il s'agit d'un bogue pour signaler aucune erreur sur un create_directory() nom prohibit la create_directories() d'un répertoire et forces à l'utilisateur de ces fonctions à doubler. L'approche plus intuitive de la création de répertoires du traitement d'un fichier avec ce nom comme une erreur est également préconisée par le nouveau papier WG21 P1164R0, la révision P1161R1 a été convenue lors de la réunion de Kona 2019 Voir Merge et GCC est maintenant passé à la suite de sa proposition (GCC # 86910).
// methods in ghc::filesystem::path:
path& operator +=(basic_string_view<value_type> x);
int compare (basic_string_view<value_type> s) const ; Ceux-ci ne sont pas mis en œuvre sous C ++ 11 et C ++ 14, car il n'y a pas de std::basic_string_view disponible et je voulais garder cette implémentation autonome et ne pas écrire une mise à niveau complète de C ++ 17 pour C ++ 11/14. En commençant par v1.1.0, ceux-ci sont pris en charge lors de la compilation ghc::filesystem sous C ++ 17 de C ++ 20.
En commençant par V1.5.2 ghc::filesystem essaiera de permettre l'utilisation de std::experimental::basic_string_view où il détecte la disponibilité. De plus, si vous avez une implémentation C ++ 11 compatible basic_string_view , il peut être utilisé à la place de std::basic_string_view en définissant GHC_HAS_CUSTOM_STRING_VIEW et en importation de l'implémentation dans l'espace de noms ghc::filesystem avec:
namespace ghc {
namespace filesystem {
using my::basic_string_view;
}
}Avant d'inclure l'en-tête du système de fichiers.
Pour ne pas dépendre de bibliothèques tierces externes tout en restant portables et compactes, cette implémentation suit la philosophie "UTF-8 partout" en ce que toutes les instances std::string seront interprétées de la même manière que std::u8string Encoding Wise et comme étant dans UTF-8. Le std::u16string sera considéré comme UTF-16 et std::u32string sera considéré comme un codepoints Unicode. Selon la taille des caractères std::wstring , il gérera std::wstring comme étant UTF-16 (par exemple Windows) ou char32_t Unicode CodePoints (actuellement toutes les autres plateformes).
En commençant par V1.5.0 ghc::filesystem suit la norme C ++ 17 en utilisant wchar_t et std::wstring sur Windows comme types utilisés en interne pour la représentation de chemin. Il est toujours possible d'obtenir l'ancien comportement en définissant GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE et Get filesystem::path::string_type en tant que std::string and filesystem::path::value_type en tant que wchar_t .
Si vous devez appeler une API Windows, avec v1.5.0 et supérieur, utilisez simplement le Variant W de l'appel Windows-API (par exemple GetFileAttributesW(p.c_str()) ).
Remarque: Lorsque vous utilisez l'ancien comportement en définissant GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE , utilisez le membre path::wstring() (par exemple GetFileAttributesW(p.wstring().c_str()) ). Cela vous donne la variante Unicode indépendante de la macro UNICODE et facilite le code Windows, Linux et MacOS et fonctionne avec std::filesystem et ghc::filesystem .
std::string path::u8string () const ;
std::string path::generic_u8string () const ;
vs.
std::u8string path::u8string () const ;
std::u8string path::generic_u8string () const ; Le type de retour de ces deux méthodes dépend de la norme C ++ utilisée et si GHC_FILESYSTEM_ENFORCE_CPP17_API est défini. Sur C ++ 11, C ++ 14 et C ++ 17 ou lorsque GHC_FILESYSTEM_ENFORCE_CPP17_API est défini, le type de retour est std::string , et sur C ++ 20 sans le définir, il est std::u8string .
J'ai créé une entrée wiki sur beaucoup de différences comportementales entre les différentes implémentations std::filesystem qui pourraient entraîner une mention ici, mais ce ReadMe essaie uniquement de traiter les différences de choix de conception entre ghc::filesystem et ceux-ci. J'essaie de mettre à jour la page Wiki de temps en temps.
Toutes les observations supplémentaires sont les bienvenues!
Depuis V1.5.0, la mécanique interne complète de ces implémentations fs::path a changé au format natif comme représentation interne. La création de tout objet mixte fs::path sous Windows (par exemple avec "C:foo/bar" ) mènera le chemin propre avec "C:foobar" via native() et "C:/foo/bar" via generic_string() api. Sur toutes les plates-formes, des séparateurs supplémentaires redondants sont supprimés, même si cela n'est pas appliqué par la norme et d'autres implémentations ne le font pas pour la plupart.
De plus, cette implémentation suit la suggestion des normes pour gérer les chemins POSIX du formulaire "//host/path" et le chemin USC sur Windows également comme ayant un nom racine (par exemple "//host" ). L'implémentation GCC n'a pas choisi de le faire lors des tests sur Ubuntu 18.04 et MacOS avec GCC 8.1.0 ou Clang 7.0.0. Cette différence montrera comme des avertissements sous std::filesystem . Cela conduit à un changement dans l'algorithme décrit dans la norme pour operator/=(path& p) où tout chemin p avec p.is_absolute() se dégradera en une affectation, tandis que cette implémentation a l'exception où *this == *this.root_name() et p == preferred_separator une annexe normale sera effectuée, pour permettre:
fs::path p1 = " //host/foo/bar/file.txt " ;
fs::path p2;
for ( auto p : p1) p2 /= p;
ASSERT (p1 == p2);Pour tous les chemins sans hôte, le comportement correspondra à celui décrit par la norme.
En tant que liens symboliques sur Windows, tout en étant pris en charge plus ou moins depuis Windows Vista (avec certaines contraintes de sécurité strictes) et entièrement depuis une construction antérieure de Windows 10, lorsque le "mode développeur" est activé, sont au moment de la rédaction (2018), ils sont toujours pris en charge avec cette implémentation.
La fonction d'autorisation Windows ACL se traduit mal au masque de bit d'autorisation POSIX utilisé dans l'interface du système de fichiers C ++ 17. Les autorisations renvoyées dans le file_status sont donc actuellement synthétisées pour le niveau user et copiées dans le group - et other niveau. Il y a encore un potentiel pour plus d'interaction avec le système d'autorisation Windows, mais actuellement la définition ou la lecture des autorisations avec cette implémentation ne conduira certainement pas au comportement attendu.
extension() a renvoyé le résultat non vide pour le nom du répertoire ".."ghcFilesystem::ghc_filesystem est désormais défini inconditionnellementstem() , filename() et extension() de fs::path renvoyerait un mauvais résultat si un côlon était dans le nom de fichierfs::last_write_time(path, time, ec) Setter sur iOS, TVOS et Watchosfs::directory_entry::refresh() Maintenant, cohérentement avec status() ne jettera pas les liens symboliques à des cibles inexistantes, mais rendez l'entrée avoir file_type::not_found comme typeEINTR sur l'itération du répertoire POSIX et la copie de fichiers pour éviter les erreurs sur les systèmes de fichiers réseaufs::copy_file() Copie désormais également les autorisationsfs::copy_file() ignorer l'option skip_existing .GHC_NO_DIRENT_D_TYPE sur les systèmes qui ne prennent pas en charge dirent::d_type et fixe la configuration et les tests de construction pour prendre en charge Solaris en tant que nouvelle plate-forme.PATH_MAX , une est définie.fs::remove_all supprime maintenant les liens symboliques au lieu de les suivre.fs::space où un débordement numérique pourrait se produire dans une multiplication.fs::create_directories SUR LES WINDESS ne se casse plus sur les noms de fichiers longs.ghc::filesystem Traité Folder / Volumes à tort comme des liens symboliques, menant fs::canonical à échouer sur les chemins en contenant.recursive_directory_iterator n'essaiera pas de saisir des liens symboliques morts.fs::remove a échoué lorsque le chemin a indiqué une entrée en lecture seule, voir également (Microsoft / STL # 1511) pour le problème correspondant dans std::fs sur Windows.GHC_NO_DIRENT_D_TYPE permet à la détection du système d'exploitation de prendre en charge les systèmes sans le membre dirent.d_type , la prise en charge expérimentale de la compilation QNX en tant que cas d'utilisation initiale, corrigez le problème avec les systèmes de fichiers renvoyant dt_unknown (par exemple Reiserfs).string_view ajouté lorsque Clang avec libstdc ++ est détecté.<Availability.h> a été incluse avant <ghc/fs_std.hpp> ou <ghc/fs_std_fwd.hpp> / <ghc/fs_std_impl.hpp> .std::filesystem sont prises en charge et ont été remplacées par les noms de chapitre de type balise qui restent (principalement) cohérents sur les versions.recursive_directory_iterator sur de grands arbres maintenant quelque part entre Libc ++ et libstdc ++.ghc::filesystem a désormais un support préliminaire pour Cygwin. Modifications lors de l'autorisation des tests de compilation et d'exécution avec succès (testé avec GCC 10.2.0), les commentaires et les PR supplémentaires sont les bienvenus car il ne fait actuellement pas partie de la configuration CI.GHC_FILESYSTEM_BUILD_STD_TESTING pour remplacer la génération supplémentaire des versions std::filesystem des tests de comparaison et la possibilité d'utiliser GHC_FILESYSTEM_TEST_COMPILE_FEATURES pour pré-remplir les fonctionnalités de compilation de compilation utilisées lorsqu'ils ne CMAKE_CXX_COMPILE_FEATURES pas donnés.directory_entry conduit à environ 20% -25% dans les tests avec recursive_directory_iterator sur un arbre de répertoire plus grand.wchar_t n'était pas dans la liste des types de char pris en charge sur les backends des non-fenêtres.string_view utilise <string_view> ou <experimental/string_view> lorsqu'il est disponible, et permet d'utiliser une implémentation personnalisée basic_string_view lors de la définition de GHC_HAS_CUSTOM_STRING_VIEW et de l'importation de la vue String dans l'espace de noms ghc::filesystem avant d'inclure un en-tête de fichier.std::filesystem sont désormais liés à -lrt pour éviter les problèmes.fs::hard_link_count a échoué en raison du comportement des systèmes de fichiers, le cas de test a été adapté pour en tenir compte.GHC_FS_API et GHC_FS_API_CLASS est maintenant honoré lorsque vous êtes défini depuis l'extérieur pour permettre le remplacement du comportement.make install .GHC_FILESYSTEM_BUILD_TESTING , GHC_FILESYSTEM_BUILD_EXAMPLES et GHC_FILESYSTEM_WITH_INSTALL où implémenté, interdite à les définir à nouveau d'un projet parent lors de l'utilisation via add_subdirectory , ce correctif permet de les remettre à nouveau.fs::path a été créée à l'origine à partir de l'implémentation basée sur POSIX, par adaptation des chaînes entrantes et sortantes. Cela a abouti à un cache mutable à l'intérieur fs::path sur Windows, qui n'était pas intrinsèquement pas en file d'attente, même pour les méthodes const . Pour ne pas ajouter de correctifs supplémentaires à une solution sous-optimale, cette fois, j'ai retravaillé le code path pour stocker maintenant la représentation du chemin natif . Cela a changé beaucoup de code, mais lorsqu'il est combiné avec wchar_t en tant que value_type a aidé à éviter beaucoup de conversion pour les appels à Win-API.fs::path::native() et fs::path::c_str() ne peut désormais être noexcept des mandats standardwchar_t est désormais la valeur par défaut de fs::path::value_type et std::wstring est la valeur par défaut pour fs::path::string_type .const de fs::path n'est plus un problèmeGHC_WIN_DISABLE_AUTO_PREFIXES , pour tous les autres types de préfixes ou espaces de noms, le comportement suit celui de MSVC std::filesystem::pathchar / std::string pour Windows est toujours nécessaire, elle peut être activée avec GHC_WIN_DISABLE_WSTRING_STORAGE_TYPEfs::file_status prend désormais en charge operator== introduit dans std::filesystem avec C ++ 20.fs::path::parent_path() avait un problème de performance, car il utilisait toujours une approche basée sur une boucle pour recréer le parent à partir d'éléments. Cela a créé beaucoup de temporaires et a été trop lent, en particulier sur les longs trajets.char8_t et std::u8string sont pris en charge lorsque Source est le type de paramètrefs::path::u8string() et fs::path::generic_u8string() renvoie maintenant un std::u8string<=> est maintenant pris en charge pour fs::pathGHC_FILESYSTEM_ENFORCE_CPP17_API ghc::filesystem retombera sur l'ancien fs::path::u8string() et fs::path::generic_u8string() API si préféréefs::proximate(p, ec) où l'appel interne vers fs::current_path() n'utilisait pas la variante error_code , lançant des exceptions possibles au lieu de définir ec .LWG_2936_BEHAVIOUR est maintenant allumée par défaut.Source qui sont des vues de chaîne.constexpr .__MAC_OS_X_VERSION_MIN_REQUIRED pour garantir que std::filesystem n'est sélectionné que sur la macOS si la cible de déploiement est au moins Catalina.directory_iterator et l' recursive_directory_iterator avaient un problème avec l'option skip_permission_denied , ce qui conduit à l'incapacité de sauter des dossiers protégés SIP sur macOS._MSVC_LANG est maintenant utilisée lorsqu'elle est disponible, en plus de __cplusplus , dans les en-têtes d'aide pour leur permettre de fonctionner même lorsque /Zc:__cplusplus n'est pas utilisé.false sur fs::exists ou pas les erreurs de fond sur fs::status . Les chemins de noms ne sont plus filtrés.TestAllocator dans filesystem_test.cpp a été achevé pour répondre aux exigences pour construire sur Centos 7 avec devtoolset-9 . Centos 7 et Centos 8 font désormais partie des constructions CI.LWG_2936_BEHAVIOUR qui permet d'activer le post C ++ 17 fs::path::compare le comportement, où la comparaison est comme s'il s'agissait d'une comparaison de chemin d'élément comme décrit dans LWG 2936 et C ++ 20 [fs.path.compare] . Il est par défaut dans V1.3.6 et sera par défaut à partir de la V1.4.0 car il modifie la commande.wchar_t de std::fstream de ghc::filesystem::fstream wrappers sous Windows si vous utilisez GCC avec LIBC ++.fs::directory_options::skip_permission_denied et une prise en charge initiale de la compilation avec Emscripten.ghc::filesystem prend désormais en charge l'utilisation dans des projets avec des exceptions désactivées. Les signatures API utilisant des exceptions pour la gestion des erreurs ne sont pas disponibles dans ce mode, merci pour le PR (cela résout # 60 et # 43)ERROR_FILE_TOO_LARGE non définie_file_too_large.fs::lexically_relative n'a pas ignoré la barre de fuite sur le paramètre de base, merci pour PR # 57.fs::create_directories returned true when nothing needed to be created, because the directory already existed.error_code was not reset, if cached result was returned.fs::path from a stream.timespec fields to avoid warnings.ghc::filesystem is re-licensed from BSD-3-Clause to MIT license. (see #47)fs::rename on Windows didn't replace an existing regular file as required by the standard, but gave an error. New tests and a fix as provided in the issue was implemented.fs_fwd.hpp or fs_std_fwd.hpp there was a use of DWORD in the forwarding part leading to an error if Windows.h was not included before the header. The tests were changed to give an error in that case too and the useage of DWORD was removed.GetProcAddress gave a warning with -Wcast-function-type on MSYS2 and MinGW GCC 9 builds.CMakeLists.txt will automatically exclude building examples and tests when used as submodule, the configuration options now use a prefixed name to reduce risk of conflicts.ghcFilesystemConfig.cmake in ${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem for find_package that exports a target as ghcFilesystem::ghc_filesystem .error: redundant redeclaration of 'constexpr' static data member deprecation warning in C++17 mode.fs::create_directories , thanks for the PR!GHC_FILESYSTEM_WITH_INSTALL that is defaulted to OFF if ghc::filesystem is used via add_subdirectory .fs::path::lexically_normal() that leaves a trailing separator in case of a resulting path ending with .. as last element.BUILD_TESTING and BUILD_EXAMPLES to NO , OFF or FALSE .std::string_view when available was added.std::string_view is available.fs::path::preferred_separator declaration was not compiling on pre C++17 compilers and no test accessed it, to show the problem. Fixed it to an construction C++11 compiler should accept and added a test that is successful on all combinations tested.fs::copy_options where not forwarded from fs::copy to fs::copy_file in one of the cases.strerror_r signature was expected. The complex preprocessor define mix was dropped in favor of the usual dispatch by overloading a unifying wrapper.ghc::filesystem missed a <vector> include in the windows case.wchar_t/std::wstring interface when compiling on Windows with defined GHC_WIN_WSTRING_STRING_TYPE , this is default when using the ghc/fs_std*.hpp header, to enhance compatibility.GHC_RAISE_UNICODE_ERRORS (instead of replacing invalid code points or UTF-8 encoding errors with the replacement character U+FFFD ).fs::copy_file .readdir/readdir_r code of fs::directory_iterator ; as readdir_r is now deprecated, I decided to drop it and the resulting code is much easier, shorter and due to more refactoring fasterstd::filesystemfs::path::lexically_normal() had some issues with ".." -sequences.fs::recursive_directory_iterator could run into endless loops, the methods depth() and pop() had issues and the copy behavior and input_iterator_tag conformance was broken, added testsstd::filesystem builds of tests and examples for interoperability checks.fs::weakly_canonical() tests against std::fsdu example showing the recursive_directory_iterator used to add the sizes of files in a directory tree.fs::file_time_type test helpersfs::copy() now conforms LWG #2682, disallowing the use of `copy_option::create_symlinks' to be used on directorieshpp as extension to be marked as c++ and they where moved to include/ghc/ to be able to include by <ghc/filesystem.hpp> as the former include name might have been to generic and conflict with other files.ghc::filesystem now can be used as a submodul and added with add_subdirectory and will export itself as ghc_filesystem target. To use it, only target_link_libraries(your-target ghc_filesystem) is needed and the include directories will be set so #include <ghc/filesystem.hpp> will be a valid directive. Still you can simply only add the header file to you project and include it from there.ghc::filesystem declarations ( fs_fwd.hpp ) and to wrap the implementation into a single cpp ( fs_impl.hpp )std::basic_string_view variants of the fs::path api are now supported when compiling with C++17.ghc::filesystem::path::generic_string()filesystem.h was renamed filesystem.hpp to better reflect that it is a c++ language header.ghc::filesystem::remove() and ghc::filesystem::remove_all() both are now able to remove a single file and both will not raise an error if the path doesn't exist.ghc::filesystem::remove() under Windows.ghc::filesystem::directory_iterator now releases resources when reaching end() like the POSIX one does.ghc::filesystem::copy() and ghc::filesystem::remove_all fixed.ghc::filesystem::recursive_directory_iterator::difference_type .-Wall -Wextra -Werror and fixed resulting issues.fs.op.permissions test to work with all tested std::filesystem implementations (gcc, clang, msvc++).ghc::filesystem::u8arguments as argv converter, to help follow the UTF-8 path on windows. Simply instantiate it with argc and argv and it will fetch the Unicode version of the command line and convert it to UTF-8. The destructor reverts the change.examples folder with hopefully some usefull example usage. Examples are tested (and build) with ghc::filesystem and C++17 std::filesystem when available.std::filesystem for comparison.fstream include.timespec / timeval usage.chrono conversion issues in test and example on clang 7.0.0.ghc::filesystem::canonical now sees empty path as non-existant and reports an error. Due to this ghc::filesystem::weakly_canonical now returns relative paths for non-existant argument paths. (#1)ghc::filesystem::remove_all now also counts directories removed (#2)recursive_directory_iterator tests didn't respect equality domain issues and dereferencapable constraints, leading to fails on std::filesystem tests.noexcept tagged methods and functions could indirectly throw exceptions due to UFT-8 decoding issues.std_filesystem_test is now also generated if LLVM/clang 7.0.0 is found. This was the first public release version. It implements the full range of C++17 std::filesystem , as far as possible without other C++17 dependencies.