33 * Copyright (C) 2016-2023 simplecpp team
44 */
55
6+ // needs to be specified here otherwise _mingw.h will define it as 0x0601
7+ // causing FileIdInfo not to be available
68#if defined(_WIN32)
79# ifndef _WIN32_WINNT
810# define _WIN32_WINNT 0x0602
911# endif
10- # ifndef NOMINMAX
11- # define NOMINMAX
12- # endif
13- # ifndef WIN32_LEAN_AND_MEAN
14- # define WIN32_LEAN_AND_MEAN
15- # endif
16- # include < windows.h>
17- # undef ERROR
1812#endif
1913
2014#include " simplecpp.h"
5145#include < utility>
5246#include < vector>
5347
54- #ifdef _WIN32
48+ #if defined(_WIN32)
49+ # ifndef NOMINMAX
50+ # define NOMINMAX
51+ # endif
52+ # ifndef WIN32_LEAN_AND_MEAN
53+ # define WIN32_LEAN_AND_MEAN
54+ # endif
55+ # include < windows.h>
56+ # undef ERROR
5557# include < direct.h>
5658#else
5759# include < sys/stat.h>
60+ # include < sys/types.h>
5861#endif
5962
6063static bool isHex (const std::string &s)
@@ -3071,6 +3074,65 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30713074 return " " ;
30723075}
30733076
3077+ namespace {
3078+ struct FileID {
3079+ #ifdef _WIN32
3080+ struct {
3081+ std::uint64_t VolumeSerialNumber;
3082+ struct {
3083+ std::uint64_t IdentifierHi;
3084+ std::uint64_t IdentifierLo;
3085+ } FileId;
3086+ } fileIdInfo;
3087+
3088+ bool operator ==(const FileID &that) const noexcept {
3089+ return fileIdInfo.VolumeSerialNumber == that.fileIdInfo .VolumeSerialNumber &&
3090+ fileIdInfo.FileId .IdentifierHi == that.fileIdInfo .FileId .IdentifierHi &&
3091+ fileIdInfo.FileId .IdentifierLo == that.fileIdInfo .FileId .IdentifierLo ;
3092+ }
3093+ #else
3094+ dev_t dev;
3095+ ino_t ino;
3096+
3097+ bool operator ==(const FileID& that) const noexcept {
3098+ return dev == that.dev && ino == that.ino ;
3099+ }
3100+ #endif
3101+ struct Hasher {
3102+ std::size_t operator ()(const FileID &id) const {
3103+ #ifdef _WIN32
3104+ return static_cast <std::size_t >(id.fileIdInfo .FileId .IdentifierHi ^ id.fileIdInfo .FileId .IdentifierLo ^
3105+ id.fileIdInfo .VolumeSerialNumber );
3106+ #else
3107+ return static_cast <std::size_t >(id.dev ) ^ static_cast <std::size_t >(id.ino );
3108+ #endif
3109+ }
3110+ };
3111+ };
3112+ }
3113+
3114+ struct simplecpp ::FileDataCache::Impl
3115+ {
3116+ void clear ()
3117+ {
3118+ mIdMap .clear ();
3119+ }
3120+
3121+ using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3122+
3123+ id_map_type mIdMap ;
3124+ };
3125+
3126+ simplecpp::FileDataCache::FileDataCache ()
3127+ : mImpl(new Impl)
3128+ {}
3129+
3130+ simplecpp::FileDataCache::~FileDataCache () = default ;
3131+ simplecpp::FileDataCache::FileDataCache (FileDataCache &&) noexcept = default;
3132+ simplecpp::FileDataCache &simplecpp::FileDataCache::operator =(simplecpp::FileDataCache &&) noexcept = default ;
3133+
3134+ static bool getFileId (const std::string &path, FileID &id);
3135+
30743136std::pair<simplecpp::FileData *, bool > simplecpp::FileDataCache::tryload (FileDataCache::name_map_type::iterator &name_it, const simplecpp::DUI &dui, std::vector<std::string> &filenames, simplecpp::OutputList *outputList)
30753137{
30763138 const std::string &path = name_it->first ;
@@ -3079,8 +3141,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30793141 if (!getFileId (path, fileId))
30803142 return {nullptr , false };
30813143
3082- const auto id_it = mIdMap .find (fileId);
3083- if (id_it != mIdMap .end ()) {
3144+ const auto id_it = mImpl -> mIdMap .find (fileId);
3145+ if (id_it != mImpl -> mIdMap .end ()) {
30843146 name_it->second = id_it->second ;
30853147 return {id_it->second , false };
30863148 }
@@ -3091,7 +3153,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30913153 data->tokens .removeComments ();
30923154
30933155 name_it->second = data;
3094- mIdMap .emplace (fileId, data);
3156+ mImpl -> mIdMap .emplace (fileId, data);
30953157 mData .emplace_back (data);
30963158
30973159 return {data, true };
@@ -3143,7 +3205,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31433205 return {nullptr , false };
31443206}
31453207
3146- bool simplecpp::FileDataCache::getFileId (const std::string &path, FileID &id)
3208+ void simplecpp::FileDataCache::clear ()
3209+ {
3210+ mImpl ->clear ();
3211+ mNameMap .clear ();
3212+ mData .clear ();
3213+ }
3214+
3215+ static bool getFileId (const std::string &path, FileID &id)
31473216{
31483217#ifdef _WIN32
31493218 HANDLE hFile = CreateFileA (path.c_str (), 0 , FILE_SHARE_READ | FILE_SHARE_WRITE , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr );
0 commit comments