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)
@@ -3090,6 +3093,63 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30903093 return " " ;
30913094}
30923095
3096+ struct FileID {
3097+ #ifdef _WIN32
3098+ struct {
3099+ std::uint64_t VolumeSerialNumber;
3100+ struct {
3101+ std::uint64_t IdentifierHi;
3102+ std::uint64_t IdentifierLo;
3103+ } FileId;
3104+ } fileIdInfo;
3105+
3106+ bool operator ==(const FileID &that) const noexcept {
3107+ return fileIdInfo.VolumeSerialNumber == that.fileIdInfo .VolumeSerialNumber &&
3108+ fileIdInfo.FileId .IdentifierHi == that.fileIdInfo .FileId .IdentifierHi &&
3109+ fileIdInfo.FileId .IdentifierLo == that.fileIdInfo .FileId .IdentifierLo ;
3110+ }
3111+ #else
3112+ dev_t dev;
3113+ ino_t ino;
3114+
3115+ bool operator ==(const FileID& that) const noexcept {
3116+ return dev == that.dev && ino == that.ino ;
3117+ }
3118+ #endif
3119+ struct Hasher {
3120+ std::size_t operator ()(const FileID &id) const {
3121+ #ifdef _WIN32
3122+ return static_cast <std::size_t >(id.fileIdInfo .FileId .IdentifierHi ^ id.fileIdInfo .FileId .IdentifierLo ^
3123+ id.fileIdInfo .VolumeSerialNumber );
3124+ #else
3125+ return static_cast <std::size_t >(id.dev ) ^ static_cast <std::size_t >(id.ino );
3126+ #endif
3127+ }
3128+ };
3129+ };
3130+
3131+ struct simplecpp ::FileDataCache::Impl
3132+ {
3133+ void clear ()
3134+ {
3135+ mIdMap .clear ();
3136+ }
3137+
3138+ using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3139+
3140+ id_map_type mIdMap ;
3141+ };
3142+
3143+ simplecpp::FileDataCache::FileDataCache ()
3144+ : mImpl(new Impl)
3145+ {}
3146+
3147+ simplecpp::FileDataCache::~FileDataCache () = default ;
3148+ simplecpp::FileDataCache::FileDataCache (FileDataCache &&) noexcept = default;
3149+ simplecpp::FileDataCache &simplecpp::FileDataCache::operator =(simplecpp::FileDataCache &&) noexcept = default ;
3150+
3151+ static bool getFileId (const std::string &path, FileID &id);
3152+
30933153std::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)
30943154{
30953155 const std::string &path = name_it->first ;
@@ -3098,8 +3158,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30983158 if (!getFileId (path, fileId))
30993159 return {nullptr , false };
31003160
3101- const auto id_it = mIdMap .find (fileId);
3102- if (id_it != mIdMap .end ()) {
3161+ const auto id_it = mImpl -> mIdMap .find (fileId);
3162+ if (id_it != mImpl -> mIdMap .end ()) {
31033163 name_it->second = id_it->second ;
31043164 return {id_it->second , false };
31053165 }
@@ -3110,7 +3170,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
31103170 data->tokens .removeComments ();
31113171
31123172 name_it->second = data;
3113- mIdMap .emplace (fileId, data);
3173+ mImpl -> mIdMap .emplace (fileId, data);
31143174 mData .emplace_back (data);
31153175
31163176 return {data, true };
@@ -3162,7 +3222,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31623222 return {nullptr , false };
31633223}
31643224
3165- bool simplecpp::FileDataCache::getFileId (const std::string &path, FileID &id)
3225+ void simplecpp::FileDataCache::clear ()
3226+ {
3227+ mImpl ->clear ();
3228+ mNameMap .clear ();
3229+ mData .clear ();
3230+ }
3231+
3232+ static bool getFileId (const std::string &path, FileID &id)
31663233{
31673234#ifdef _WIN32
31683235 HANDLE hFile = CreateFileA (path.c_str (), 0 , FILE_SHARE_READ | FILE_SHARE_WRITE , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr );
0 commit comments