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)
@@ -3075,6 +3078,63 @@ static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const
30753078 return " " ;
30763079}
30773080
3081+ struct FileID {
3082+ #ifdef _WIN32
3083+ struct {
3084+ std::uint64_t VolumeSerialNumber;
3085+ struct {
3086+ std::uint64_t IdentifierHi;
3087+ std::uint64_t IdentifierLo;
3088+ } FileId;
3089+ } fileIdInfo;
3090+
3091+ bool operator ==(const FileID &that) const noexcept {
3092+ return fileIdInfo.VolumeSerialNumber == that.fileIdInfo .VolumeSerialNumber &&
3093+ fileIdInfo.FileId .IdentifierHi == that.fileIdInfo .FileId .IdentifierHi &&
3094+ fileIdInfo.FileId .IdentifierLo == that.fileIdInfo .FileId .IdentifierLo ;
3095+ }
3096+ #else
3097+ dev_t dev;
3098+ ino_t ino;
3099+
3100+ bool operator ==(const FileID& that) const noexcept {
3101+ return dev == that.dev && ino == that.ino ;
3102+ }
3103+ #endif
3104+ struct Hasher {
3105+ std::size_t operator ()(const FileID &id) const {
3106+ #ifdef _WIN32
3107+ return static_cast <std::size_t >(id.fileIdInfo .FileId .IdentifierHi ^ id.fileIdInfo .FileId .IdentifierLo ^
3108+ id.fileIdInfo .VolumeSerialNumber );
3109+ #else
3110+ return static_cast <std::size_t >(id.dev ) ^ static_cast <std::size_t >(id.ino );
3111+ #endif
3112+ }
3113+ };
3114+ };
3115+
3116+ struct simplecpp ::FileDataCache::Impl
3117+ {
3118+ void clear ()
3119+ {
3120+ mIdMap .clear ();
3121+ }
3122+
3123+ using id_map_type = std::unordered_map<FileID, FileData *, FileID::Hasher>;
3124+
3125+ id_map_type mIdMap ;
3126+ };
3127+
3128+ simplecpp::FileDataCache::FileDataCache ()
3129+ : mImpl(new Impl)
3130+ {}
3131+
3132+ simplecpp::FileDataCache::~FileDataCache () = default ;
3133+ simplecpp::FileDataCache::FileDataCache (FileDataCache &&) noexcept = default;
3134+ simplecpp::FileDataCache &simplecpp::FileDataCache::operator =(simplecpp::FileDataCache &&) noexcept = default ;
3135+
3136+ static bool getFileId (const std::string &path, FileID &id);
3137+
30783138std::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)
30793139{
30803140 const std::string &path = name_it->first ;
@@ -3083,8 +3143,8 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30833143 if (!getFileId (path, fileId))
30843144 return {nullptr , false };
30853145
3086- const auto id_it = mIdMap .find (fileId);
3087- if (id_it != mIdMap .end ()) {
3146+ const auto id_it = mImpl -> mIdMap .find (fileId);
3147+ if (id_it != mImpl -> mIdMap .end ()) {
30883148 name_it->second = id_it->second ;
30893149 return {id_it->second , false };
30903150 }
@@ -3095,7 +3155,7 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::tryload(FileDat
30953155 data->tokens .removeComments ();
30963156
30973157 name_it->second = data;
3098- mIdMap .emplace (fileId, data);
3158+ mImpl -> mIdMap .emplace (fileId, data);
30993159 mData .emplace_back (data);
31003160
31013161 return {data, true };
@@ -3147,7 +3207,14 @@ std::pair<simplecpp::FileData *, bool> simplecpp::FileDataCache::get(const std::
31473207 return {nullptr , false };
31483208}
31493209
3150- bool simplecpp::FileDataCache::getFileId (const std::string &path, FileID &id)
3210+ void simplecpp::FileDataCache::clear ()
3211+ {
3212+ mImpl ->clear ();
3213+ mNameMap .clear ();
3214+ mData .clear ();
3215+ }
3216+
3217+ bool getFileId (const std::string &path, FileID &id)
31513218{
31523219#ifdef _WIN32
31533220 HANDLE hFile = CreateFileA (path.c_str (), 0 , FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr );
0 commit comments