├── .clang-format
├── .gitignore
├── .vscode
└── settings.json
├── FortKit.sln
├── FortKitInsider
├── .clang-format
├── .gitignore
├── FortKitInsider.vcxproj
├── FortKitInsider.vcxproj.filters
├── FortKitInsider.vcxproj.user
├── consts.h
├── cppgenerator.h
├── dllmain.cpp
├── dumper.h
├── enums.h
├── exceptions.h
├── framework.h
├── generic.h
├── memcury.h
├── parallel_hashmap
│ ├── btree.h
│ ├── conanfile.py
│ ├── meminfo.h
│ ├── phmap.h
│ ├── phmap_base.h
│ ├── phmap_bits.h
│ ├── phmap_config.h
│ ├── phmap_dump.h
│ ├── phmap_fwd_decl.h
│ └── phmap_utils.h
├── ue4.cpp
├── ue4.h
├── usmap.h
├── util.h
└── writer.h
└── README.md
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | BasedOnStyle: WebKit
3 | AlignAfterOpenBracket: DontAlign
4 | BreakBeforeBraces: Allman
5 | NamespaceIndentation: All
6 | SortIncludes: false
7 |
8 | ...
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Ll]og/
33 | [Ll]ogs/
34 |
35 | # Visual Studio 2015/2017 cache/options directory
36 | .vs/
37 | # Uncomment if you have tasks that create the project's static files in wwwroot
38 | #wwwroot/
39 |
40 | # Visual Studio 2017 auto generated files
41 | Generated\ Files/
42 |
43 | # MSTest test Results
44 | [Tt]est[Rr]esult*/
45 | [Bb]uild[Ll]og.*
46 |
47 | # NUnit
48 | *.VisualState.xml
49 | TestResult.xml
50 | nunit-*.xml
51 |
52 | # Build Results of an ATL Project
53 | [Dd]ebugPS/
54 | [Rr]eleasePS/
55 | dlldata.c
56 |
57 | # Benchmark Results
58 | BenchmarkDotNet.Artifacts/
59 |
60 | # .NET Core
61 | project.lock.json
62 | project.fragment.lock.json
63 | artifacts/
64 |
65 | # ASP.NET Scaffolding
66 | ScaffoldingReadMe.txt
67 |
68 | # StyleCop
69 | StyleCopReport.xml
70 |
71 | # Files built by Visual Studio
72 | *_i.c
73 | *_p.c
74 | *_h.h
75 | *.ilk
76 | *.meta
77 | *.obj
78 | *.iobj
79 | *.pch
80 | *.pdb
81 | *.ipdb
82 | *.pgc
83 | *.pgd
84 | *.rsp
85 | *.sbr
86 | *.tlb
87 | *.tli
88 | *.tlh
89 | *.tmp
90 | *.tmp_proj
91 | *_wpftmp.csproj
92 | *.log
93 | *.tlog
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
298 | *.vbp
299 |
300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
301 | *.dsw
302 | *.dsp
303 |
304 | # Visual Studio 6 technical files
305 | *.ncb
306 | *.aps
307 |
308 | # Visual Studio LightSwitch build output
309 | **/*.HTMLClient/GeneratedArtifacts
310 | **/*.DesktopClient/GeneratedArtifacts
311 | **/*.DesktopClient/ModelManifest.xml
312 | **/*.Server/GeneratedArtifacts
313 | **/*.Server/ModelManifest.xml
314 | _Pvt_Extensions
315 |
316 | # Paket dependency manager
317 | .paket/paket.exe
318 | paket-files/
319 |
320 | # FAKE - F# Make
321 | .fake/
322 |
323 | # CodeRush personal settings
324 | .cr/personal
325 |
326 | # Python Tools for Visual Studio (PTVS)
327 | __pycache__/
328 | *.pyc
329 |
330 | # Cake - Uncomment if you are using it
331 | # tools/**
332 | # !tools/packages.config
333 |
334 | # Tabs Studio
335 | *.tss
336 |
337 | # Telerik's JustMock configuration file
338 | *.jmconfig
339 |
340 | # BizTalk build output
341 | *.btp.cs
342 | *.btm.cs
343 | *.odx.cs
344 | *.xsd.cs
345 |
346 | # OpenCover UI analysis results
347 | OpenCover/
348 |
349 | # Azure Stream Analytics local run output
350 | ASALocalRun/
351 |
352 | # MSBuild Binary and Structured Log
353 | *.binlog
354 |
355 | # NVidia Nsight GPU debugger configuration file
356 | *.nvuser
357 |
358 | # MFractors (Xamarin productivity tool) working folder
359 | .mfractor/
360 |
361 | # Local History for Visual Studio
362 | .localhistory/
363 |
364 | # Visual Studio History (VSHistory) files
365 | .vshistory/
366 |
367 | # BeatPulse healthcheck temp database
368 | healthchecksdb
369 |
370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
371 | MigrationBackup/
372 |
373 | # Ionide (cross platform F# VS Code tools) working folder
374 | .ionide/
375 |
376 | # Fody - auto-generated XML schema
377 | FodyWeavers.xsd
378 |
379 | # VS Code files for those working on multiple tools
380 | .vscode/*
381 | !.vscode/settings.json
382 | !.vscode/tasks.json
383 | !.vscode/launch.json
384 | !.vscode/extensions.json
385 | *.code-workspace
386 |
387 | # Local History for Visual Studio Code
388 | .history/
389 |
390 | # Windows Installer files from build outputs
391 | *.cab
392 | *.msi
393 | *.msix
394 | *.msm
395 | *.msp
396 |
397 | # JetBrains Rider
398 | *.sln.iml
399 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "xstring": "cpp"
4 | }
5 | }
--------------------------------------------------------------------------------
/FortKit.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32616.157
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FortKitInsider", "FortKitInsider\FortKitInsider.vcxproj", "{09849E3E-CC19-40BD-8D25-DED5D5F7F55C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Debug|x64.ActiveCfg = Debug|x64
17 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Debug|x64.Build.0 = Debug|x64
18 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Debug|x86.ActiveCfg = Debug|Win32
19 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Debug|x86.Build.0 = Debug|Win32
20 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Release|x64.ActiveCfg = Release|x64
21 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Release|x64.Build.0 = Release|x64
22 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Release|x86.ActiveCfg = Release|Win32
23 | {09849E3E-CC19-40BD-8D25-DED5D5F7F55C}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {C6A761A2-5800-490C-BCE0-1D3A1D8FEE14}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/FortKitInsider/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | BasedOnStyle: WebKit
3 | AlignAfterOpenBracket: DontAlign
4 | BreakBeforeBraces: Allman
5 | NamespaceIndentation: All
6 | SortIncludes: false
7 |
8 | ...
9 |
--------------------------------------------------------------------------------
/FortKitInsider/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Ll]og/
33 | [Ll]ogs/
34 |
35 | # Visual Studio 2015/2017 cache/options directory
36 | .vs/
37 | # Uncomment if you have tasks that create the project's static files in wwwroot
38 | #wwwroot/
39 |
40 | # Visual Studio 2017 auto generated files
41 | Generated\ Files/
42 |
43 | # MSTest test Results
44 | [Tt]est[Rr]esult*/
45 | [Bb]uild[Ll]og.*
46 |
47 | # NUnit
48 | *.VisualState.xml
49 | TestResult.xml
50 | nunit-*.xml
51 |
52 | # Build Results of an ATL Project
53 | [Dd]ebugPS/
54 | [Rr]eleasePS/
55 | dlldata.c
56 |
57 | # Benchmark Results
58 | BenchmarkDotNet.Artifacts/
59 |
60 | # .NET Core
61 | project.lock.json
62 | project.fragment.lock.json
63 | artifacts/
64 |
65 | # ASP.NET Scaffolding
66 | ScaffoldingReadMe.txt
67 |
68 | # StyleCop
69 | StyleCopReport.xml
70 |
71 | # Files built by Visual Studio
72 | *_i.c
73 | *_p.c
74 | *_h.h
75 | *.ilk
76 | *.meta
77 | *.obj
78 | *.iobj
79 | *.pch
80 | *.pdb
81 | *.ipdb
82 | *.pgc
83 | *.pgd
84 | *.rsp
85 | *.sbr
86 | *.tlb
87 | *.tli
88 | *.tlh
89 | *.tmp
90 | *.tmp_proj
91 | *_wpftmp.csproj
92 | *.log
93 | *.tlog
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
298 | *.vbp
299 |
300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
301 | *.dsw
302 | *.dsp
303 |
304 | # Visual Studio 6 technical files
305 | *.ncb
306 | *.aps
307 |
308 | # Visual Studio LightSwitch build output
309 | **/*.HTMLClient/GeneratedArtifacts
310 | **/*.DesktopClient/GeneratedArtifacts
311 | **/*.DesktopClient/ModelManifest.xml
312 | **/*.Server/GeneratedArtifacts
313 | **/*.Server/ModelManifest.xml
314 | _Pvt_Extensions
315 |
316 | # Paket dependency manager
317 | .paket/paket.exe
318 | paket-files/
319 |
320 | # FAKE - F# Make
321 | .fake/
322 |
323 | # CodeRush personal settings
324 | .cr/personal
325 |
326 | # Python Tools for Visual Studio (PTVS)
327 | __pycache__/
328 | *.pyc
329 |
330 | # Cake - Uncomment if you are using it
331 | # tools/**
332 | # !tools/packages.config
333 |
334 | # Tabs Studio
335 | *.tss
336 |
337 | # Telerik's JustMock configuration file
338 | *.jmconfig
339 |
340 | # BizTalk build output
341 | *.btp.cs
342 | *.btm.cs
343 | *.odx.cs
344 | *.xsd.cs
345 |
346 | # OpenCover UI analysis results
347 | OpenCover/
348 |
349 | # Azure Stream Analytics local run output
350 | ASALocalRun/
351 |
352 | # MSBuild Binary and Structured Log
353 | *.binlog
354 |
355 | # NVidia Nsight GPU debugger configuration file
356 | *.nvuser
357 |
358 | # MFractors (Xamarin productivity tool) working folder
359 | .mfractor/
360 |
361 | # Local History for Visual Studio
362 | .localhistory/
363 |
364 | # Visual Studio History (VSHistory) files
365 | .vshistory/
366 |
367 | # BeatPulse healthcheck temp database
368 | healthchecksdb
369 |
370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
371 | MigrationBackup/
372 |
373 | # Ionide (cross platform F# VS Code tools) working folder
374 | .ionide/
375 |
376 | # Fody - auto-generated XML schema
377 | FodyWeavers.xsd
378 |
379 | # VS Code files for those working on multiple tools
380 | .vscode/*
381 | !.vscode/settings.json
382 | !.vscode/tasks.json
383 | !.vscode/launch.json
384 | !.vscode/extensions.json
385 | *.code-workspace
386 |
387 | # Local History for Visual Studio Code
388 | .history/
389 |
390 | # Windows Installer files from build outputs
391 | *.cab
392 | *.msi
393 | *.msix
394 | *.msm
395 | *.msp
396 |
397 | # JetBrains Rider
398 | *.sln.iml
399 |
--------------------------------------------------------------------------------
/FortKitInsider/FortKitInsider.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | Win32Proj
24 | {09849e3e-cc19-40bd-8d25-ded5d5f7f55c}
25 | FortKitInsider
26 | 10.0
27 | FortKitInsider
28 |
29 |
30 |
31 | DynamicLibrary
32 | true
33 | v143
34 | Unicode
35 |
36 |
37 | DynamicLibrary
38 | false
39 | v143
40 | true
41 | Unicode
42 |
43 |
44 | DynamicLibrary
45 | true
46 | v143
47 | Unicode
48 |
49 |
50 | DynamicLibrary
51 | false
52 | v143
53 | true
54 | Unicode
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | true
76 | $(SolutionDir)Bin\
77 | FortKitInsider
78 |
79 |
80 | false
81 | $(SolutionDir)Bin\
82 | FortKitInsider
83 |
84 |
85 | true
86 | $(SolutionDir)Bin\
87 | FortKitInsider
88 |
89 |
90 | false
91 | $(SolutionDir)Bin\
92 | FortKitInsider
93 |
94 |
95 |
96 | Level3
97 | true
98 | WIN32;_DEBUG;FORTKITINSIDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
99 | true
100 | NotUsing
101 | pch.h
102 | stdcpplatest
103 |
104 |
105 | Windows
106 | true
107 | false
108 |
109 |
110 |
111 |
112 | Level3
113 | true
114 | true
115 | true
116 | WIN32;NDEBUG;FORTKITINSIDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
117 | true
118 | NotUsing
119 | pch.h
120 | stdcpplatest
121 |
122 |
123 | Windows
124 | true
125 | true
126 | true
127 | false
128 |
129 |
130 |
131 |
132 | Level3
133 | true
134 | _DEBUG;FORTKITINSIDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
135 | true
136 | NotUsing
137 | pch.h
138 | stdcpplatest
139 |
140 |
141 | Windows
142 | true
143 | false
144 |
145 |
146 |
147 |
148 | Level3
149 | true
150 | true
151 | true
152 | NDEBUG;FORTKITINSIDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
153 | true
154 | NotUsing
155 | pch.h
156 | stdcpplatest
157 |
158 |
159 | Windows
160 | true
161 | true
162 | true
163 | false
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/FortKitInsider/FortKitInsider.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Header Files
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 | Header Files
41 |
42 |
43 | Header Files
44 |
45 |
46 | Header Files
47 |
48 |
49 | Header Files
50 |
51 |
52 | Header Files
53 |
54 |
55 |
56 |
57 | Source Files
58 |
59 |
60 | Header Files
61 |
62 |
63 |
--------------------------------------------------------------------------------
/FortKitInsider/FortKitInsider.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
6 |
--------------------------------------------------------------------------------
/FortKitInsider/consts.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace Patterns
4 | {
5 | constexpr auto GObjects = "48 8B 05 ? ? ? ? 48 8B 0C C8 48 8D 04 D1 EB";
6 | }
7 |
8 | namespace StringRefs
9 | {
10 | constexpr auto FNameToString = L"Loading Module %s";
11 | }
--------------------------------------------------------------------------------
/FortKitInsider/cppgenerator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace CPPGenerator
12 | {
13 | // https://ctrpeach.io/posts/cpp20-string-literal-template-parameters/
14 | template
15 | struct StringLiteral
16 | {
17 | constexpr StringLiteral(const char (&str)[N])
18 | {
19 | std::copy_n(str, N, value);
20 | }
21 |
22 | char value[N];
23 | };
24 |
25 | class Variable
26 | {
27 | public:
28 | std::string type;
29 | std::string name;
30 | bool isPtr = false;
31 | bool isRef = false;
32 | bool isStatic = false;
33 | bool isConst = false;
34 | bool isConstexpr = false;
35 | bool isStruct = false;
36 | bool isArray = false;
37 | int arraySize = 1;
38 | bool isBitField = false;
39 | int bitFieldSize = 1;
40 | std::string comment;
41 |
42 | private:
43 | Variable(std ::string Type, std ::string Name)
44 | : type(Type)
45 | , name(Name)
46 | {
47 | }
48 |
49 | public:
50 | template
51 | constexpr static auto New(std::string name) -> Variable
52 | {
53 | constexpr auto typeName = lit.value;
54 | return Variable(typeName, name);
55 | }
56 |
57 | template
58 | constexpr static auto New(std::string name) -> Variable
59 | {
60 | return Variable(typeid(T).name(), name);
61 | }
62 |
63 | static auto New(std::string type, std::string name) -> Variable
64 | {
65 | return Variable(type, name);
66 | }
67 | };
68 |
69 | class Header
70 | {
71 | bool isInNamespace;
72 | bool isInStruct;
73 | bool isInClass;
74 |
75 | std::vector generatedStructs;
76 | std::vector generatedClasses;
77 |
78 | std::queue> queuedStructs;
79 |
80 | std::string fileName;
81 | std::stringstream file;
82 |
83 | public:
84 | Header(std::string _fileName)
85 | : fileName(_fileName)
86 | {
87 | }
88 |
89 | ~Header()
90 | {
91 | std::fstream out;
92 | out.open(fileName + ".h", std::fstream::out | std::fstream::trunc);
93 |
94 | out << file.rdbuf();
95 | out.close();
96 | }
97 |
98 | auto AddText(std::string text)
99 | {
100 | file << text;
101 | }
102 |
103 | auto isAlreadyGeneratedStruct(std::string name)
104 | {
105 | for (auto&& str : generatedStructs)
106 | {
107 | if (str == name)
108 | {
109 | return true;
110 | }
111 | }
112 |
113 | return false;
114 | }
115 |
116 | auto isAlreadyGeneratedClass(std::string name)
117 | {
118 | for (auto&& str : generatedClasses)
119 | {
120 | if (str == name)
121 | {
122 | return true;
123 | }
124 | }
125 |
126 | return false;
127 | }
128 |
129 | auto queueStruct(std::function lambda)
130 | {
131 | queuedStructs.push(lambda);
132 | }
133 |
134 | void flushStructs()
135 | {
136 | while (!queuedStructs.empty())
137 | {
138 | queuedStructs.front()();
139 | queuedStructs.pop();
140 | }
141 | }
142 |
143 | void tab(size_t count)
144 | {
145 | for (size_t i = 0; i < count; i++)
146 | {
147 | file << "\t";
148 | }
149 | }
150 |
151 | void forwardDeclare(std::string name, std::string type = "struct")
152 | {
153 | file << type << " " << name << ";\n";
154 | }
155 |
156 | void pragma(std::string expr)
157 | {
158 | file << "#pragma " << expr << "\n"
159 | << std::endl;
160 | }
161 |
162 | void include(std::string fileName, bool useQuotes = true)
163 | {
164 | if (useQuotes)
165 | file << "#include \"" << fileName << "\"" << std::endl;
166 | else
167 | file << "#include <" << fileName << ">" << std::endl;
168 | }
169 |
170 | void namespaceStart(std::string name)
171 | {
172 | file << "namespace " << name << "\n{" << std::endl;
173 | isInNamespace = true;
174 | }
175 |
176 | void namespaceEnd()
177 | {
178 | if (isInNamespace)
179 | {
180 | file << "}\n"
181 | << std::endl;
182 | isInNamespace = false;
183 | }
184 | }
185 |
186 | void classStart(std::string name, std::string parent)
187 | {
188 | generatedClasses.push_back(name);
189 |
190 | if (isInNamespace)
191 | tab(1);
192 |
193 | file << "class " << name;
194 |
195 | if (!parent.empty())
196 | file << " : public " << parent;
197 |
198 | file << "\n";
199 |
200 | if (isInNamespace)
201 | tab(1);
202 |
203 | file << "{" << std::endl;
204 | isInClass = true;
205 | }
206 |
207 | void definePublic()
208 | {
209 | if (isInClass)
210 | {
211 | file << "public:" << std::endl;
212 | }
213 | }
214 |
215 | void definePrivate()
216 | {
217 | if (isInClass)
218 | {
219 | file << "private:" << std::endl;
220 | }
221 | }
222 |
223 | void classEnd()
224 | {
225 | if (isInClass)
226 | {
227 | if (isInNamespace)
228 | tab(1);
229 |
230 | file << "};\n"
231 | << std::endl;
232 | isInClass = false;
233 | }
234 | }
235 |
236 | void structStart(std::string name, std::string parent = "")
237 | {
238 | generatedStructs.push_back(name);
239 |
240 | if (isInClass)
241 | tab(1);
242 |
243 | if (isInNamespace)
244 | tab(1);
245 |
246 | file << "struct " << name;
247 |
248 | if (!parent.empty())
249 | file << " : " << parent;
250 |
251 | file << "\n";
252 |
253 | if (isInClass)
254 | tab(1);
255 |
256 | if (isInNamespace)
257 | tab(1);
258 |
259 | file << "{" << std::endl;
260 | isInStruct = true;
261 | }
262 |
263 | void structEnd(bool flushQueue = true)
264 | {
265 | if (isInStruct)
266 | {
267 | if (isInClass)
268 | tab(1);
269 |
270 | if (isInNamespace)
271 | tab(1);
272 |
273 | file << "};\n"
274 | << std::endl;
275 | isInStruct = false;
276 | }
277 |
278 | if (flushQueue)
279 | flushStructs();
280 | }
281 |
282 | void variable(Variable& var)
283 | {
284 | if (isInStruct)
285 | tab(1);
286 |
287 | if (isInClass)
288 | tab(1);
289 |
290 | if (isInNamespace)
291 | tab(1);
292 |
293 | if (var.isConstexpr)
294 | file << "constexpr ";
295 |
296 | if (var.isConst)
297 | file << "const ";
298 |
299 | if (var.isStatic)
300 | file << "static ";
301 |
302 | if (var.isStruct)
303 | file << "struct ";
304 |
305 | file << var.type;
306 |
307 | if (var.isPtr)
308 | file << "*";
309 |
310 | if (var.isRef)
311 | file << "&";
312 |
313 | file << " " << var.name
314 | << (var.isArray ? std::format("[0x{:x}]", var.arraySize) : "")
315 | << (var.isBitField ? std::format(": {}", var.bitFieldSize) : "")
316 | << "; "
317 | << (var.comment.empty() ? "" : "// " + var.comment)
318 | << std::endl;
319 | }
320 | };
321 | }
322 |
--------------------------------------------------------------------------------
/FortKitInsider/dllmain.cpp:
--------------------------------------------------------------------------------
1 | #include "consts.h"
2 | #include "dumper.h"
3 | #include "framework.h"
4 | #include "memory.h"
5 | #include "memcury.h"
6 | #include "exceptions.h"
7 |
8 | static void Main(HMODULE hModule)
9 | {
10 | Util::SetupConsole();
11 |
12 | Memcury::Safety::SetExceptionMode();
13 |
14 | auto Start = std::chrono::steady_clock::now();
15 |
16 | GObjects = Memcury::Scanner::FindPattern(Patterns::GObjects)
17 | .RelativeOffset(3)
18 | .GetAs();
19 |
20 | FNameToString = Memcury::Scanner::FindStringRef(StringRefs::FNameToString)
21 | .ScanFor({ Memcury::ASM::CALL }, false)
22 | .RelativeOffset(1)
23 | .GetAs();
24 |
25 | auto End = std::chrono::steady_clock::now();
26 |
27 | printf("[=] Init Time: %.02f ms\n", (End - Start).count() / 1000000.);
28 |
29 | Dumper::Dump();
30 | // Dumper::GenerateUsmap();
31 |
32 | FreeLibraryAndExitThread(hModule, 0);
33 | }
34 |
35 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
36 | {
37 | switch (ul_reason_for_call)
38 | {
39 | case DLL_PROCESS_ATTACH:
40 | {
41 | __try
42 | {
43 | Main(hModule);
44 | }
45 | __except (HandlerForCallStack(GetExceptionInformation()))
46 | {
47 | MessageBoxA(nullptr, "Main function crashed!", "Error", MB_ICONERROR | MB_OK);
48 | }
49 | break;
50 | }
51 | default:
52 | break;
53 | }
54 | return TRUE;
55 | }
56 |
--------------------------------------------------------------------------------
/FortKitInsider/dumper.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "generic.h"
3 | #include "ue4.h"
4 | #include "util.h"
5 | #include "usmap.h"
6 |
7 | #include "cppgenerator.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | uintptr_t ModuleBase = reinterpret_cast(GetModuleHandle(nullptr));
15 |
16 | namespace Dumper
17 | {
18 | static void DumpNames()
19 | {
20 | std::ofstream NamesDump("NamesDump.txt");
21 |
22 | for (size_t i = 0; i < GObjects->NumElements; i++)
23 | {
24 | auto uObj = GObjects->GetByIndex(i);
25 |
26 | if (Util::IsBadReadPtr(uObj))
27 | continue;
28 |
29 | NamesDump << '[' << uObj->InternalIndex << "] " << uObj->GetFullName() << '\n';
30 | }
31 |
32 | NamesDump.close();
33 | }
34 |
35 | static auto GeneratePadding(CPPGenerator::Header& file, const int& size, const int& offset, const std::string& comment, const std::string& name = "unreflected")
36 | {
37 | auto var = CPPGenerator::Variable::New(std::format("{}_{:x}", name, offset));
38 | var.isArray = true;
39 | var.arraySize = size;
40 |
41 | var.comment = std::format("0x{:x} (0x{:x}) {}", offset, size, comment);
42 |
43 | return file.variable(var);
44 | }
45 |
46 | static auto GenerateBitPadding(CPPGenerator::Header& file, const int& size, const int& id, const int& offset, const std::string& name = "unreflectedBit")
47 | {
48 | auto var = CPPGenerator::Variable::New(std::format("{}_{:x}", name, id));
49 |
50 | var.isBitField = true;
51 | var.bitFieldSize = size;
52 | var.comment = std::format("0x{:x} (0x{:x})", offset, size);
53 |
54 | return file.variable(var);
55 | }
56 |
57 | static void GenerateFields(CPPGenerator::Header& file, UStruct* Struct)
58 | {
59 | auto prop = (FProperty*)Struct->ChildProperties;
60 |
61 | if (Struct->PropertiesSize > 0x0 && !Struct->ChildProperties && Util::IsBadReadPtr(Struct->ChildProperties))
62 | {
63 | auto var = CPPGenerator::Variable::New(std::format("unreflected_{:x}", Struct->PropertiesSize));
64 | var.isArray = true;
65 | var.arraySize = Struct->PropertiesSize;
66 |
67 | return file.variable(var);
68 | }
69 |
70 | auto offset = prop->Offset_Internal + prop->ElementSize * prop->ArrayDim;
71 |
72 | if (Struct->SuperStruct->IsValid() && prop->Offset_Internal >= Struct->SuperStruct->PropertiesSize)
73 | {
74 | offset = Struct->SuperStruct->PropertiesSize;
75 | }
76 |
77 | auto bitFieldsCount = 0;
78 | FBoolProperty* lastBoolProp = nullptr;
79 |
80 | while (prop)
81 | {
82 | if (offset < prop->Offset_Internal)
83 | {
84 | lastBoolProp = nullptr;
85 | GeneratePadding(file, prop->Offset_Internal - offset, offset, "");
86 | }
87 |
88 | std::string comment;
89 | auto propName = prop->GetName();
90 | Util::FixName(propName);
91 |
92 | auto cppType = Generic::StringifyPropType(prop);
93 |
94 | if (!cppType.empty())
95 | {
96 | auto var = CPPGenerator::Variable::New(cppType, propName);
97 |
98 | if (lastBoolProp && prop->ClassPrivate->Id == FFieldClassID::Bool && reinterpret_cast(prop)->IsBitfield())
99 | {
100 | auto bprop = reinterpret_cast(prop);
101 | auto missingBits = bprop->GetMissingBitsCount(lastBoolProp);
102 |
103 | if (missingBits.second != -1)
104 | {
105 | if (missingBits.first > 0)
106 | {
107 | GenerateBitPadding(file, missingBits.first, bitFieldsCount++, lastBoolProp->Offset_Internal);
108 | }
109 |
110 | if (missingBits.second > 0)
111 | {
112 | GenerateBitPadding(file, missingBits.second, bitFieldsCount++, prop->Offset_Internal);
113 | }
114 | }
115 | else if (missingBits.first > 0)
116 | {
117 | GenerateBitPadding(file, missingBits.first, bitFieldsCount++, prop->Offset_Internal);
118 | }
119 |
120 | lastBoolProp = bprop;
121 |
122 | var.isBitField = true;
123 | var.bitFieldSize = 1;
124 | }
125 | else
126 | {
127 | lastBoolProp = nullptr;
128 | }
129 |
130 | comment += std::format("0x{:x} (0x{:x})", prop->Offset_Internal, prop->ElementSize);
131 |
132 | if (prop->ArrayDim > 1)
133 | {
134 | var.isArray = true;
135 | var.arraySize = prop->ArrayDim;
136 | comment += " (ARRAY) ";
137 | }
138 |
139 | var.comment = comment;
140 | file.variable(var);
141 | }
142 | else
143 | {
144 | // those are ignored on purpose
145 | if (prop->ClassPrivate->Id != FFieldClassID::MulticastInlineDelegate && prop->ClassPrivate->Id != FFieldClassID::Delegate)
146 | {
147 | comment += "(UNHANDLED PROPERTY TYPE: " + prop->ClassPrivate->Name.ToString() + " UID: " + std::to_string((int)prop->ClassPrivate->Id) + ")";
148 | }
149 |
150 | GeneratePadding(file, prop->ElementSize, prop->Offset_Internal, comment, propName);
151 | }
152 |
153 | offset = prop->Offset_Internal + prop->ElementSize * prop->ArrayDim;
154 | prop = (FProperty*)prop->Next;
155 | }
156 |
157 | if (offset < Struct->PropertiesSize)
158 | {
159 | auto var = CPPGenerator::Variable::New(std::format("padding_{:x}", offset));
160 | var.isArray = true;
161 | var.arraySize = Struct->PropertiesSize - offset;
162 | var.comment = std::format("0x{:x} (0x{:x})", offset, Struct->PropertiesSize - offset);
163 |
164 | file.variable(var);
165 | }
166 | }
167 |
168 | static void GenerateFunctions(CPPGenerator::Header& file, UClass* Struct)
169 | {
170 | auto child = Struct->Children;
171 |
172 | if (!child || Util::IsBadReadPtr(child))
173 | {
174 | return;
175 | }
176 |
177 | // std::vector nativeFunctions;
178 |
179 | // if (Struct->NativeFunctionLookupTable.Num() > 0)
180 | // {
181 | // nativeFunctions = Struct->NativeFunctionLookupTable.ToVector();
182 | // }
183 |
184 | file.AddText("\n\t/* Functions */\n");
185 |
186 | std::string params;
187 |
188 | while (child)
189 | {
190 | if (child->IsA(UFunction::StaticClass()))
191 | {
192 | auto function = child->Cast();
193 |
194 | std::string retType;
195 | std::string functionSig;
196 |
197 | retType = "void";
198 |
199 | auto paramChild = (FProperty*)function->ChildProperties;
200 |
201 | while (paramChild)
202 | {
203 | auto paramType = Generic::StringifyPropType(paramChild);
204 |
205 | if (paramChild->PropertyFlags & CPF_ReturnParm)
206 | {
207 | if (!paramType.empty())
208 | {
209 | retType = paramType;
210 | }
211 |
212 | break;
213 | }
214 |
215 | if (!paramType.empty())
216 | {
217 | if (reinterpret_cast(child)->ArrayDim <= 1)
218 | {
219 | paramType += "&";
220 | }
221 | }
222 | else
223 | {
224 | break;
225 | }
226 |
227 | auto paramName = paramChild->GetName();
228 | Util::FixName(paramName);
229 |
230 | functionSig += paramType + " " + paramName;
231 | params += paramName;
232 |
233 | paramChild = (FProperty*)paramChild->Next;
234 |
235 | if (paramChild && !(paramChild->PropertyFlags & CPF_ReturnParm))
236 | functionSig += ", ";
237 | params += ", ";
238 | }
239 |
240 | auto name = function->GetName();
241 | Util::FixName(name);
242 |
243 | /* auto nativeFunctionLookup = std::find_if(nativeFunctions.begin(), nativeFunctions.end(),
244 | [&](const FNativeFunctionLookup& lookup)
245 | {
246 | return lookup.Name.ToString().starts_with(function->GetName());
247 | });
248 |
249 | std::string nativeFuncComment = " (Has no native function)";
250 |
251 | if (nativeFunctionLookup != std::end(nativeFunctions))
252 | {
253 | nativeFuncComment = std::format(" (Underlying native function: {} 0x{:x})", nativeFunctionLookup->Name.ToString(), (uintptr_t)nativeFunctionLookup->Pointer - ModuleBase);
254 | nativeFunctions.erase(nativeFunctionLookup);
255 | }
256 |
257 | file.AddText(std::format("\n\t// {}{}\n", function->GetFullName(), nativeFuncComment));*/
258 |
259 | file.AddText(std::format("\t{}{} {}({}); // {}\n", (function->FunctionFlags & FUNC_Static ? "static " : ""), retType, name, functionSig, Generic::StringifyFlags(function->FunctionFlags)));
260 |
261 | params.clear();
262 | }
263 |
264 | child = child->Next;
265 | }
266 |
267 | // if (nativeFunctions.size() > 0)
268 | // {
269 | // file.AddText("\n\t/* Unreflected Native Functions */\n");
270 |
271 | // for (auto&& lookup : nativeFunctions)
272 | // {
273 | // file.AddText(std::format("\t// Function: {} 0x{:x}\n", lookup.Name.ToString(), (uintptr_t)lookup.Pointer - ModuleBase));
274 | // }
275 | // }
276 | }
277 |
278 | phmap::flat_hash_map names;
279 |
280 | static void DumpStruct(UStruct* Struct)
281 | {
282 | if (!Struct->ChildProperties && Util::IsBadReadPtr(Struct->ChildProperties) && Struct->PropertiesSize == 0x0)
283 | return;
284 |
285 | auto cppname = Struct->GetCPPName();
286 |
287 | CPPGenerator::Header file("DUMP\\" + cppname + (names.contains(cppname) ? "_" + std::to_string(names[cppname]) : ""));
288 | names[cppname] += 1;
289 |
290 | auto isClass = Struct->IsA(UClass::StaticClass());
291 |
292 | file.AddText(std::format("// {}\n", Struct->GetFullName()));
293 | file.AddText(std::format("// Size: 0x{:x}\n", Struct->PropertiesSize));
294 |
295 | auto name = Struct->GetCPPName();
296 | auto parent = Struct->SuperStruct ? Struct->SuperStruct->GetCPPName() : "";
297 |
298 | isClass ? file.classStart(name, parent) : file.structStart(name, parent);
299 |
300 | if (Struct->SuperStruct)
301 | {
302 | if (Struct->PropertiesSize > Struct->SuperStruct->PropertiesSize)
303 | {
304 | GenerateFields(file, Struct);
305 | }
306 | }
307 | else
308 | GenerateFields(file, Struct);
309 |
310 | if (isClass)
311 | {
312 | GenerateFunctions(file, (UClass*)Struct);
313 | }
314 |
315 | isClass ? file.classEnd() : file.structEnd();
316 | }
317 |
318 | static void DumpEnum(UEnum* Enum)
319 | {
320 | if (!Enum->CppType.IsValid() && Util::IsBadReadPtr((void*)Enum->CppType.ToWString()))
321 | {
322 | return;
323 | }
324 |
325 | auto cppname = Enum->GetCPPString();
326 |
327 | auto fileType = ".h";
328 | auto fileName = "DUMP\\" + cppname + (names.contains(cppname) ? "_" + std::to_string(names[cppname]) : "") + fileType; // UObject::GetName can be used too but this is good
329 | names[cppname] += 1;
330 |
331 | std::ofstream file(fileName);
332 | file << "// " << Enum->GetFullName() << std::endl;
333 | file << "enum class " << Enum->GetCPPString() << " : " << Enum->GetEnumType() << std::endl
334 | << "{\n";
335 |
336 | for (int i = 0; i < Enum->Names.Num(); i++)
337 | {
338 | auto name = Enum->Names[i].Key.ToString();
339 | auto find = name.find(':');
340 |
341 | if (find != std::string::npos)
342 | name = name.substr(find + 2);
343 |
344 | file << " " << name << " = " << std::to_string(Enum->Names[i].Value);
345 |
346 | if (i < (Enum->Names.Num() - 1))
347 | {
348 | file << ',';
349 | }
350 |
351 | file << std::endl;
352 | }
353 |
354 | file << "};";
355 | }
356 |
357 | static void Dump()
358 | {
359 | printf("[=] Dumping.\n");
360 |
361 | std::filesystem::create_directories("DUMP");
362 |
363 | auto Start = std::chrono::steady_clock::now();
364 |
365 | auto dumped = 0;
366 | auto enumsDumped = 0;
367 | for (auto i = 0x0; i < GObjects->NumElements; ++i)
368 | {
369 | auto object = GObjects->GetByIndex(i);
370 | if (object == nullptr)
371 | {
372 | continue;
373 | }
374 |
375 | if (object->IsA(UStruct::StaticClass()))
376 | {
377 | if (object->Class == UFunction::StaticClass())
378 | continue;
379 |
380 | DumpStruct((UStruct*)object);
381 | dumped++;
382 | }
383 | else if (object->IsA(UEnum::StaticClass()))
384 | {
385 | DumpEnum((UEnum*)object);
386 | enumsDumped++;
387 | }
388 | }
389 |
390 | auto End = std::chrono::steady_clock::now();
391 | printf("[+] Dumping done in %.02f ms\n", (End - Start).count() / 1000000.);
392 |
393 | MessageBoxA(nullptr, ("Dumped " + std::to_string(dumped) + " UStruct(s) and " + std::to_string(enumsDumped) + " UEnum(s)").c_str(), "Done!", MB_OK);
394 | }
395 |
396 | static void GenerateUsmap()
397 | {
398 | printf("[=] Generating Usmap.\n");
399 |
400 | auto Start = std::chrono::steady_clock::now();
401 |
402 | Usmap().Generate();
403 |
404 | auto End = std::chrono::steady_clock::now();
405 |
406 | printf("[+] Usmap file generated in %.02f ms\n", (End - Start).count() / 1000000.);
407 | }
408 | }
409 |
--------------------------------------------------------------------------------
/FortKitInsider/enums.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "framework.h"
3 |
4 | enum class EEnumFlags
5 | {
6 | None,
7 | Flags = 0x00000001,
8 | NewerVersionExists = 0x00000002,
9 | };
10 |
11 | enum ASM : DWORD
12 | {
13 | JMP_REL8 = 0xEB,
14 | CALL = 0xE8,
15 | LEA = 0x8D,
16 | CDQ = 0x99,
17 | CMOVL = 0x4C,
18 | CMOVS = 0x48,
19 | INT3 = 0xCC,
20 | RETN = 0xC3,
21 | SKIP
22 | };
23 |
24 | enum DumpType : uint32_t
25 | {
26 | FunctionParamsHeaders,
27 |
28 | };
29 |
30 | enum ELifetimeCondition
31 | {
32 | COND_None = 0,
33 | COND_InitialOnly = 1,
34 | COND_OwnerOnly = 2,
35 | COND_SkipOwner = 3,
36 | COND_SimulatedOnly = 4,
37 | COND_AutonomousOnly = 5,
38 | COND_SimulatedOrPhysics = 6,
39 | COND_InitialOrOwner = 7,
40 | COND_Custom = 8,
41 | COND_ReplayOrOwner = 9,
42 | COND_ReplayOnly = 10,
43 | COND_SimulatedOnlyNoReplay = 11,
44 | COND_SimulatedOrPhysicsNoReplay = 12,
45 | COND_SkipReplay = 13,
46 | COND_Never = 15,
47 | COND_Max = 16,
48 | };
49 |
50 | enum EObjectFlags : uint32_t
51 | {
52 | RF_NoFlags = 0x00000000,
53 | RF_Public = 0x00000001,
54 | RF_Standalone = 0x00000002,
55 | RF_MarkAsNative = 0x00000004,
56 | RF_Transactional = 0x00000008,
57 | RF_ClassDefaultObject = 0x00000010,
58 | RF_ArchetypeObject = 0x00000020,
59 | RF_Transient = 0x00000040,
60 | RF_MarkAsRootSet = 0x00000080,
61 | RF_TagGarbageTemp = 0x00000100,
62 | RF_NeedInitialization = 0x00000200,
63 | RF_NeedLoad = 0x00000400,
64 | RF_KeepForCooker = 0x00000800,
65 | RF_NeedPostLoad = 0x00001000,
66 | RF_NeedPostLoadSubobjects = 0x00002000,
67 | RF_NewerVersionExists = 0x00004000,
68 | RF_BeginDestroyed = 0x00008000,
69 | RF_FinishDestroyed = 0x00010000,
70 | RF_BeingRegenerated = 0x00020000,
71 | RF_DefaultSubObject = 0x00040000,
72 | RF_WasLoaded = 0x00080000,
73 | RF_TextExportTransient = 0x00100000,
74 | RF_LoadCompleted = 0x00200000,
75 | RF_InheritableComponentTemplate = 0x00400000,
76 | RF_DuplicateTransient = 0x00800000,
77 | RF_StrongRefOnFrame = 0x01000000,
78 | RF_NonPIEDuplicateTransient = 0x02000000,
79 | RF_Dynamic = 0x04000000,
80 | RF_WillBeLoaded = 0x08000000,
81 | };
82 |
83 | enum EPropertyFlags : uint64_t
84 | {
85 | CPF_None = 0,
86 |
87 | CPF_Edit = 0x0000000000000001, ///< Property is user-settable in the editor.
88 | CPF_ConstParm = 0x0000000000000002, ///< This is a constant function parameter
89 | CPF_BlueprintVisible = 0x0000000000000004, ///< This property can be read by blueprint code
90 | CPF_ExportObject = 0x0000000000000008, ///< Object can be exported with actor.
91 | CPF_BlueprintReadOnly = 0x0000000000000010, ///< This property cannot be modified by blueprint code
92 | CPF_Net = 0x0000000000000020, ///< Property is relevant to network replication.
93 | CPF_EditFixedSize = 0x0000000000000040, ///< Indicates that elements of an array can be modified, but its size cannot be changed.
94 | CPF_Parm = 0x0000000000000080, ///< Function/When call parameter.
95 | CPF_OutParm = 0x0000000000000100, ///< Value is copied out after function call.
96 | CPF_ZeroConstructor = 0x0000000000000200, ///< memset is fine for construction
97 | CPF_ReturnParm = 0x0000000000000400, ///< Return value.
98 | CPF_DisableEditOnTemplate = 0x0000000000000800, ///< Disable editing of this property on an archetype/sub-blueprint
99 | //CPF_ = 0x0000000000001000, ///<
100 | CPF_Transient = 0x0000000000002000, ///< Property is transient: shouldn't be saved or loaded, except for Blueprint CDOs.
101 | CPF_Config = 0x0000000000004000, ///< Property should be loaded/saved as permanent profile.
102 | //CPF_ = 0x0000000000008000, ///<
103 | CPF_DisableEditOnInstance = 0x0000000000010000, ///< Disable editing on an instance of this class
104 | CPF_EditConst = 0x0000000000020000, ///< Property is uneditable in the editor.
105 | CPF_GlobalConfig = 0x0000000000040000, ///< Load config from base class, not subclass.
106 | CPF_InstancedReference = 0x0000000000080000, ///< Property is a component references.
107 | //CPF_ = 0x0000000000100000, ///<
108 | CPF_DuplicateTransient = 0x0000000000200000, ///< Property should always be reset to the default value during any type of duplication (copy/paste, binary duplication, etc.)
109 | //CPF_ = 0x0000000000400000, ///<
110 | //CPF_ = 0x0000000000800000, ///<
111 | CPF_SaveGame = 0x0000000001000000, ///< Property should be serialized for save games, this is only checked for game-specific archives with ArIsSaveGame
112 | CPF_NoClear = 0x0000000002000000, ///< Hide clear (and browse) button.
113 | //CPF_ = 0x0000000004000000, ///<
114 | CPF_ReferenceParm = 0x0000000008000000, ///< Value is passed by reference; CPF_OutParam and CPF_Param should also be set.
115 | CPF_BlueprintAssignable = 0x0000000010000000, ///< MC Delegates only. Property should be exposed for assigning in blueprint code
116 | CPF_Deprecated = 0x0000000020000000, ///< Property is deprecated. Read it from an archive, but don't save it.
117 | CPF_IsPlainOldData = 0x0000000040000000, ///< If this is set, then the property can be memcopied instead of CopyCompleteValue / CopySingleValue
118 | CPF_RepSkip = 0x0000000080000000, ///< Not replicated. For non replicated properties in replicated structs
119 | CPF_RepNotify = 0x0000000100000000, ///< Notify actors when a property is replicated
120 | CPF_Interp = 0x0000000200000000, ///< interpolatable property for use with cinematics
121 | CPF_NonTransactional = 0x0000000400000000, ///< Property isn't transacted
122 | CPF_EditorOnly = 0x0000000800000000, ///< Property should only be loaded in the editor
123 | CPF_NoDestructor = 0x0000001000000000, ///< No destructor
124 | //CPF_ = 0x0000002000000000, ///<
125 | CPF_AutoWeak = 0x0000004000000000, ///< Only used for weak pointers, means the export type is autoweak
126 | CPF_ContainsInstancedReference = 0x0000008000000000, ///< Property contains component references.
127 | CPF_AssetRegistrySearchable = 0x0000010000000000, ///< asset instances will add properties with this flag to the asset registry automatically
128 | CPF_SimpleDisplay = 0x0000020000000000, ///< The property is visible by default in the editor details view
129 | CPF_AdvancedDisplay = 0x0000040000000000, ///< The property is advanced and not visible by default in the editor details view
130 | CPF_Protected = 0x0000080000000000, ///< property is protected from the perspective of script
131 | CPF_BlueprintCallable = 0x0000100000000000, ///< MC Delegates only. Property should be exposed for calling in blueprint code
132 | CPF_BlueprintAuthorityOnly = 0x0000200000000000, ///< MC Delegates only. This delegate accepts (only in blueprint) only events with BlueprintAuthorityOnly.
133 | CPF_TextExportTransient = 0x0000400000000000, ///< Property shouldn't be exported to text format (e.g. copy/paste)
134 | CPF_NonPIEDuplicateTransient = 0x0000800000000000, ///< Property should only be copied in PIE
135 | CPF_ExposeOnSpawn = 0x0001000000000000, ///< Property is exposed on spawn
136 | CPF_PersistentInstance = 0x0002000000000000, ///< A object referenced by the property is duplicated like a component. (Each actor should have an own instance.)
137 | CPF_UObjectWrapper = 0x0004000000000000, ///< Property was parsed as a wrapper class like TSubclassOf, FScriptInterface etc., rather than a USomething*
138 | CPF_HasGetValueTypeHash = 0x0008000000000000, ///< This property can generate a meaningful hash value.
139 | CPF_NativeAccessSpecifierPublic = 0x0010000000000000, ///< Public native access specifier
140 | CPF_NativeAccessSpecifierProtected = 0x0020000000000000, ///< Protected native access specifier
141 | CPF_NativeAccessSpecifierPrivate = 0x0040000000000000, ///< Private native access specifier
142 | CPF_SkipSerialization = 0x0080000000000000, ///< Property shouldn't be serialized, can still be exported to text
143 | };
144 |
145 |
146 | enum EClassFlags
147 | {
148 | /** No Flags */
149 | CLASS_None = 0x00000000u,
150 | /** Class is abstract and can't be instantiated directly. */
151 | CLASS_Abstract = 0x00000001u,
152 | /** Save object configuration only to Default INIs, never to local INIs. Must be combined with CLASS_Config */
153 | CLASS_DefaultConfig = 0x00000002u,
154 | /** Load object configuration at construction time. */
155 | CLASS_Config = 0x00000004u,
156 | /** This object type can't be saved; null it out at save time. */
157 | CLASS_Transient = 0x00000008u,
158 | /** Successfully parsed. */
159 | CLASS_Parsed = 0x00000010u,
160 | /** */
161 | CLASS_MatchedSerializers = 0x00000020u,
162 | /** Indicates that the config settings for this class will be saved to Project/User*.ini (similar to CLASS_GlobalUserConfig) */
163 | CLASS_ProjectUserConfig = 0x00000040u,
164 | /** Class is a native class - native interfaces will have CLASS_Native set, but not RF_MarkAsNative */
165 | CLASS_Native = 0x00000080u,
166 | /** Don't export to C++ header. */
167 | CLASS_NoExport = 0x00000100u,
168 | /** Do not allow users to create in the editor. */
169 | CLASS_NotPlaceable = 0x00000200u,
170 | /** Handle object configuration on a per-object basis, rather than per-class. */
171 | CLASS_PerObjectConfig = 0x00000400u,
172 |
173 | /** Whether SetUpRuntimeReplicationData still needs to be called for this class */
174 | CLASS_ReplicationDataIsSetUp = 0x00000800u,
175 |
176 | /** Class can be constructed from editinline New button. */
177 | CLASS_EditInlineNew = 0x00001000u,
178 | /** Display properties in the editor without using categories. */
179 | CLASS_CollapseCategories = 0x00002000u,
180 | /** Class is an interface **/
181 | CLASS_Interface = 0x00004000u,
182 | /** Do not export a constructor for this class, assuming it is in the cpptext **/
183 | CLASS_CustomConstructor = 0x00008000u,
184 | /** all properties and functions in this class are const and should be exported as const */
185 | CLASS_Const = 0x00010000u,
186 |
187 | /** Class flag indicating the class is having its layout changed, and therefore is not ready for a CDO to be created */
188 | CLASS_LayoutChanging = 0x00020000u,
189 |
190 | /** Indicates that the class was created from blueprint source material */
191 | CLASS_CompiledFromBlueprint = 0x00040000u,
192 |
193 | /** Indicates that only the bare minimum bits of this class should be DLL exported/imported */
194 | CLASS_MinimalAPI = 0x00080000u,
195 |
196 | /** Indicates this class must be DLL exported/imported (along with all of it's members) */
197 | CLASS_RequiredAPI = 0x00100000u,
198 |
199 | /** Indicates that references to this class default to instanced. Used to be subclasses of UComponent, but now can be any UObject */
200 | CLASS_DefaultToInstanced = 0x00200000u,
201 |
202 | /** Indicates that the parent token stream has been merged with ours. */
203 | CLASS_TokenStreamAssembled = 0x00400000u,
204 | /** Class has component properties. */
205 | CLASS_HasInstancedReference = 0x00800000u,
206 | /** Don't show this class in the editor class browser or edit inline new menus. */
207 | CLASS_Hidden = 0x01000000u,
208 | /** Don't save objects of this class when serializing */
209 | CLASS_Deprecated = 0x02000000u,
210 | /** Class not shown in editor drop down for class selection */
211 | CLASS_HideDropDown = 0x04000000u,
212 | /** Class settings are saved to /..../Blah.ini (as opposed to CLASS_DefaultConfig) */
213 | CLASS_GlobalUserConfig = 0x08000000u,
214 | /** Class was declared directly in C++ and has no boilerplate generated by UnrealHeaderTool */
215 | CLASS_Intrinsic = 0x10000000u,
216 | /** Class has already been constructed (maybe in a previous DLL version before hot-reload). */
217 | CLASS_Constructed = 0x20000000u,
218 | /** Indicates that object configuration will not check against ini base/defaults when serialized */
219 | CLASS_ConfigDoNotCheckDefaults = 0x40000000u,
220 | /** Class has been consigned to oblivion as part of a blueprint recompile, and a newer version currently exists. */
221 | CLASS_NewerVersionExists = 0x80000000u,
222 | };
223 |
224 | enum EClassCastFlags : uint64_t
225 | {
226 | CASTCLASS_None = 0x0000000000000000,
227 | CASTCLASS_UField = 0x0000000000000001,
228 | CASTCLASS_FInt8Property = 0x0000000000000002,
229 | CASTCLASS_UEnum = 0x0000000000000004,
230 | CASTCLASS_UStruct = 0x0000000000000008,
231 | CASTCLASS_UScriptStruct = 0x0000000000000010,
232 | CASTCLASS_UClass = 0x0000000000000020,
233 | CASTCLASS_FByteProperty = 0x0000000000000040,
234 | CASTCLASS_FIntProperty = 0x0000000000000080,
235 | CASTCLASS_FFloatProperty = 0x0000000000000100,
236 | CASTCLASS_FUInt64Property = 0x0000000000000200,
237 | CASTCLASS_FClassProperty = 0x0000000000000400,
238 | CASTCLASS_FUInt32Property = 0x0000000000000800,
239 | CASTCLASS_FInterfaceProperty = 0x0000000000001000,
240 | CASTCLASS_FNameProperty = 0x0000000000002000,
241 | CASTCLASS_FStrProperty = 0x0000000000004000,
242 | CASTCLASS_FProperty = 0x0000000000008000,
243 | CASTCLASS_FObjectProperty = 0x0000000000010000,
244 | CASTCLASS_FBoolProperty = 0x0000000000020000,
245 | CASTCLASS_FUInt16Property = 0x0000000000040000,
246 | CASTCLASS_UFunction = 0x0000000000080000,
247 | CASTCLASS_FStructProperty = 0x0000000000100000,
248 | CASTCLASS_FArrayProperty = 0x0000000000200000,
249 | CASTCLASS_FInt64Property = 0x0000000000400000,
250 | CASTCLASS_FDelegateProperty = 0x0000000000800000,
251 | CASTCLASS_FNumericProperty = 0x0000000001000000,
252 | CASTCLASS_FMulticastDelegateProperty = 0x0000000002000000,
253 | CASTCLASS_FObjectPropertyBase = 0x0000000004000000,
254 | CASTCLASS_FWeakObjectProperty = 0x0000000008000000,
255 | CASTCLASS_FLazyObjectProperty = 0x0000000010000000,
256 | CASTCLASS_FSoftObjectProperty = 0x0000000020000000,
257 | CASTCLASS_FTextProperty = 0x0000000040000000,
258 | CASTCLASS_FInt16Property = 0x0000000080000000,
259 | CASTCLASS_FDoubleProperty = 0x0000000100000000,
260 | CASTCLASS_FSoftClassProperty = 0x0000000200000000,
261 | CASTCLASS_UPackage = 0x0000000400000000,
262 | CASTCLASS_ULevel = 0x0000000800000000,
263 | CASTCLASS_AActor = 0x0000001000000000,
264 | CASTCLASS_APlayerController = 0x0000002000000000,
265 | CASTCLASS_APawn = 0x0000004000000000,
266 | CASTCLASS_USceneComponent = 0x0000008000000000,
267 | CASTCLASS_UPrimitiveComponent = 0x0000010000000000,
268 | CASTCLASS_USkinnedMeshComponent = 0x0000020000000000,
269 | CASTCLASS_USkeletalMeshComponent = 0x0000040000000000,
270 | CASTCLASS_UBlueprint = 0x0000080000000000,
271 | CASTCLASS_UDelegateFunction = 0x0000100000000000,
272 | CASTCLASS_UStaticMeshComponent = 0x0000200000000000,
273 | CASTCLASS_FMapProperty = 0x0000400000000000,
274 | CASTCLASS_FSetProperty = 0x0000800000000000,
275 | CASTCLASS_FEnumProperty = 0x0001000000000000,
276 | CASTCLASS_USparseDelegateFunction = 0x0002000000000000,
277 | CASTCLASS_FMulticastInlineDelegateProperty = 0x0004000000000000,
278 | CASTCLASS_FMulticastSparseDelegateProperty = 0x0008000000000000,
279 | CASTCLASS_FFieldPathProperty = 0x0010000000000000,
280 | };
281 |
282 | enum EFunctionFlags : uint32_t
283 | {
284 | // Function flags.
285 | FUNC_None = 0x00000000,
286 | FUNC_Final = 0x00000001,
287 | // Function is final (prebindable, non-overridable function).
288 | FUNC_RequiredAPI = 0x00000002,
289 | // Indicates this function is DLL exported/imported.
290 | FUNC_BlueprintAuthorityOnly = 0x00000004,
291 | // Function will only run if the object has network authority
292 | FUNC_BlueprintCosmetic = 0x00000008,
293 | // Function is cosmetic in nature and should not be invoked on dedicated servers
294 | // FUNC_ = 0x00000010, // unused.
295 | // FUNC_ = 0x00000020, // unused.
296 | FUNC_Net = 0x00000040,
297 | // Function is network-replicated.
298 | FUNC_NetReliable = 0x00000080,
299 | // Function should be sent reliably on the network.
300 | FUNC_NetRequest = 0x00000100,
301 | // Function is sent to a net service
302 | FUNC_Exec = 0x00000200,
303 | // Executable from command line.
304 | FUNC_Native = 0x00000400,
305 | // Native function.
306 | FUNC_Event = 0x00000800,
307 | // Event function.
308 | FUNC_NetResponse = 0x00001000,
309 | // Function response from a net service
310 | FUNC_Static = 0x00002000,
311 | // Static function.
312 | FUNC_NetMulticast = 0x00004000,
313 | // Function is networked multicast Server -> All Clients
314 | FUNC_UbergraphFunction = 0x00008000,
315 | // Function is used as the merge 'ubergraph' for a blueprint, only assigned when using the persistent 'ubergraph' frame
316 | FUNC_MulticastDelegate = 0x00010000,
317 | // Function is a multi-cast delegate signature (also requires FUNC_Delegate to be set!)
318 | FUNC_Public = 0x00020000,
319 | // Function is accessible in all classes (if overridden, parameters must remain unchanged).
320 | FUNC_Private = 0x00040000,
321 | // Function is accessible only in the class it is defined in (cannot be overridden, but function name may be reused in subclasses. IOW: if overridden, parameters don't need to match, and Super.Func() cannot be accessed since it's private.)
322 | FUNC_Protected = 0x00080000,
323 | // Function is accessible only in the class it is defined in and subclasses (if overridden, parameters much remain unchanged).
324 | FUNC_Delegate = 0x00100000,
325 | // Function is delegate signature (either single-cast or multi-cast, depending on whether FUNC_MulticastDelegate is set.)
326 | FUNC_NetServer = 0x00200000,
327 | // Function is executed on servers (set by replication code if passes check)
328 | FUNC_HasOutParms = 0x00400000,
329 | // function has out (pass by reference) parameters
330 | FUNC_HasDefaults = 0x00800000,
331 | // function has structs that contain defaults
332 | FUNC_NetClient = 0x01000000,
333 | // function is executed on clients
334 | FUNC_DLLImport = 0x02000000,
335 | // function is imported from a DLL
336 | FUNC_BlueprintCallable = 0x04000000,
337 | // function can be called from blueprint code
338 | FUNC_BlueprintEvent = 0x08000000,
339 | // function can be overridden/implemented from a blueprint
340 | FUNC_BlueprintPure = 0x10000000,
341 | // function can be called from blueprint code, and is also pure (produces no side effects). If you set this, you should set FUNC_BlueprintCallable as well.
342 | FUNC_EditorOnly = 0x20000000,
343 | // function can only be called from an editor scrippt.
344 | FUNC_Const = 0x40000000,
345 | // function can be called from blueprint code, and only reads state (never writes state)
346 | FUNC_NetValidate = 0x80000000,
347 | // function must supply a _Validate implementation
348 |
349 | FUNC_AllFlags = 0xFFFFFFFF,
350 | };
351 |
352 | enum class EArrayPropertyFlags
353 | {
354 | None,
355 | UsesMemoryImageAllocator
356 | };
357 |
358 | enum EStructFlags
359 | {
360 | // State flags.
361 | STRUCT_NoFlags = 0x00000000,
362 | STRUCT_Native = 0x00000001,
363 |
364 | /** If set, this struct will be compared using native code */
365 | STRUCT_IdenticalNative = 0x00000002,
366 |
367 | STRUCT_HasInstancedReference = 0x00000004,
368 |
369 | STRUCT_NoExport = 0x00000008,
370 |
371 | /** Indicates that this struct should always be serialized as a single unit */
372 | STRUCT_Atomic = 0x00000010,
373 |
374 | /** Indicates that this struct uses binary serialization; it is unsafe to add/remove members from this struct without incrementing the package version */
375 | STRUCT_Immutable = 0x00000020,
376 |
377 | /** If set, native code needs to be run to find referenced objects */
378 | STRUCT_AddStructReferencedObjects = 0x00000040,
379 |
380 | /** Indicates that this struct should be exportable/importable at the DLL layer. Base structs must also be exportable for this to work. */
381 | STRUCT_RequiredAPI = 0x00000200,
382 |
383 | /** If set, this struct will be serialized using the CPP net serializer */
384 | STRUCT_NetSerializeNative = 0x00000400,
385 |
386 | /** If set, this struct will be serialized using the CPP serializer */
387 | STRUCT_SerializeNative = 0x00000800,
388 |
389 | /** If set, this struct will be copied using the CPP operator= */
390 | STRUCT_CopyNative = 0x00001000,
391 |
392 | /** If set, this struct will be copied using memcpy */
393 | STRUCT_IsPlainOldData = 0x00002000,
394 |
395 | /** If set, this struct has no destructor and non will be called. STRUCT_IsPlainOldData implies STRUCT_NoDestructor */
396 | STRUCT_NoDestructor = 0x00004000,
397 |
398 | /** If set, this struct will not be constructed because it is assumed that memory is zero before construction. */
399 | STRUCT_ZeroConstructor = 0x00008000,
400 |
401 | /** If set, native code will be used to export text */
402 | STRUCT_ExportTextItemNative = 0x00010000,
403 |
404 | /** If set, native code will be used to export text */
405 | STRUCT_ImportTextItemNative = 0x00020000,
406 |
407 | /** If set, this struct will have PostSerialize called on it after CPP serializer or tagged property serialization is complete */
408 | STRUCT_PostSerializeNative = 0x00040000,
409 |
410 | /** If set, this struct will have SerializeFromMismatchedTag called on it if a mismatched tag is encountered. */
411 | STRUCT_SerializeFromMismatchedTag = 0x00080000,
412 |
413 | /** If set, this struct will be serialized using the CPP net delta serializer */
414 | STRUCT_NetDeltaSerializeNative = 0x00100000,
415 |
416 | /** If set, this struct will be have PostScriptConstruct called on it after a temporary object is constructed in a running blueprint */
417 | STRUCT_PostScriptConstruct = 0x00200000,
418 |
419 | /** If set, this struct can share net serialization state across connections */
420 | STRUCT_NetSharedSerialization = 0x00400000,
421 |
422 | /** If set, this struct has been cleaned and sanitized (trashed) and should not be used */
423 | STRUCT_Trashed = 0x00800000,
424 |
425 | /** If set, this structure has been replaced via reinstancing */
426 | STRUCT_NewerVersionExists = 0x01000000,
427 |
428 | /** Struct flags that are automatically inherited */
429 | STRUCT_Inherit = STRUCT_HasInstancedReference | STRUCT_Atomic,
430 |
431 | /** Flags that are always computed, never loaded or done with code generation */
432 | STRUCT_ComputedFlags = STRUCT_NetDeltaSerializeNative | STRUCT_NetSerializeNative | STRUCT_SerializeNative | STRUCT_PostSerializeNative | STRUCT_CopyNative | STRUCT_IsPlainOldData | STRUCT_NoDestructor | STRUCT_ZeroConstructor | STRUCT_IdenticalNative | STRUCT_AddStructReferencedObjects | STRUCT_ExportTextItemNative | STRUCT_ImportTextItemNative | STRUCT_SerializeFromMismatchedTag | STRUCT_PostScriptConstruct | STRUCT_NetSharedSerialization
433 | };
--------------------------------------------------------------------------------
/FortKitInsider/exceptions.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #pragma comment(lib, "Dbghelp.lib")
4 |
5 | void printStack(CONTEXT* ctx)
6 | {
7 | STACKFRAME64 stack;
8 | memset(&stack, 0, sizeof(STACKFRAME64));
9 |
10 | auto process = GetCurrentProcess();
11 | auto thread = GetCurrentThread();
12 |
13 | SymInitialize(process, NULL, TRUE);
14 |
15 | bool result;
16 | DWORD64 displacement = 0;
17 |
18 | char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] { 0 };
19 | char name[512] { 0 };
20 | char module[512] { 0 };
21 |
22 | PSYMBOL_INFO symbolInfo = (PSYMBOL_INFO)buffer;
23 |
24 | for (ULONG frame = 0;; frame++)
25 | {
26 | result = StackWalk64(
27 | IMAGE_FILE_MACHINE_AMD64,
28 | process,
29 | thread,
30 | &stack,
31 | ctx,
32 | NULL,
33 | SymFunctionTableAccess64,
34 | SymGetModuleBase64,
35 | NULL);
36 |
37 | if (!result)
38 | break;
39 |
40 | symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
41 | symbolInfo->MaxNameLen = MAX_SYM_NAME;
42 | SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbolInfo);
43 |
44 | HMODULE hModule = NULL;
45 | lstrcpyA(module, "");
46 | GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (const wchar_t*)(stack.AddrPC.Offset), &hModule);
47 |
48 | if (hModule != NULL)
49 | GetModuleFileNameA(hModule, module, 512);
50 |
51 | printf("[%lu] Name: %s - Address: %p - Module: %s\n", frame, symbolInfo->Name, (void*)symbolInfo->Address, module);
52 | }
53 | }
54 |
55 | int HandlerForCallStack(_EXCEPTION_POINTERS* ex)
56 | {
57 | printStack(ex->ContextRecord);
58 |
59 | return EXCEPTION_EXECUTE_HANDLER;
60 | }
--------------------------------------------------------------------------------
/FortKitInsider/framework.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define WIN32_LEAN_AND_MEAN
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "ue4.h"
--------------------------------------------------------------------------------
/FortKitInsider/generic.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "framework.h"
3 |
4 | namespace Generic
5 | {
6 | std::string StringifyPropType(FProperty* prop)
7 | {
8 | std::string ret;
9 |
10 | switch (prop->ClassPrivate->Id)
11 | {
12 | case FFieldClassID::Object:
13 | case FFieldClassID::ObjectPointer:
14 | case FFieldClassID::Class:
15 | {
16 | ret += "class " + reinterpret_cast(prop)->PropertyClass->GetCPPName() + (prop->ElementSize == 0x8 ? "*" : "");
17 | break;
18 | }
19 |
20 | case FFieldClassID::Struct:
21 | {
22 | ret += "struct " + reinterpret_cast(prop)->Struct->GetCPPName() + (prop->ElementSize == 0x8 ? "*" : "");
23 | break;
24 | }
25 |
26 | case FFieldClassID::Int8:
27 | {
28 | ret += "int8_t";
29 | break;
30 | }
31 |
32 | case FFieldClassID::Int16:
33 | {
34 | ret += "int16_t";
35 | break;
36 | }
37 |
38 | case FFieldClassID::Int:
39 | {
40 | ret += "int";
41 | break;
42 | }
43 |
44 | case FFieldClassID::Int64:
45 | {
46 | ret += "int64_t";
47 | break;
48 | }
49 |
50 | case FFieldClassID::UInt16:
51 | {
52 | ret += "uint16_t";
53 | break;
54 | }
55 |
56 | case FFieldClassID::UInt32:
57 | {
58 | ret += "uint32_t";
59 | break;
60 | }
61 |
62 | case FFieldClassID::UInt64:
63 | {
64 | ret += "uint64_t";
65 | break;
66 | }
67 |
68 | case FFieldClassID::Array:
69 | {
70 | ret += "struct TArray<" + StringifyPropType(reinterpret_cast(prop)->Inner) + ">";
71 |
72 | break;
73 | }
74 |
75 | case FFieldClassID::Float:
76 | {
77 | ret += "float";
78 | break;
79 | }
80 |
81 | case FFieldClassID::Double:
82 | {
83 | ret += "double";
84 | break;
85 | }
86 |
87 | case FFieldClassID::Bool:
88 | {
89 | if (reinterpret_cast(prop)->IsNativeBool())
90 | {
91 | ret += "bool";
92 | }
93 | else
94 | {
95 | ret += "unsigned char";
96 | }
97 | break;
98 | }
99 |
100 | case FFieldClassID::String:
101 | {
102 | ret += "struct FString";
103 | break;
104 | }
105 |
106 | case FFieldClassID::Name:
107 | {
108 | ret += "struct FName";
109 | break;
110 | }
111 |
112 | case FFieldClassID::Text:
113 | {
114 | ret += "struct FText";
115 | break;
116 | }
117 |
118 | case FFieldClassID::Enum:
119 | {
120 | ret += "enum " + reinterpret_cast(prop)->Enum->GetName();
121 | break;
122 | }
123 |
124 | case FFieldClassID::Interface:
125 | {
126 | ret += "struct TScriptInterface(prop)->InterfaceClass->GetCPPName() + ">";
127 | break;
128 | }
129 |
130 | case FFieldClassID::Map:
131 | {
132 | auto mprop = reinterpret_cast(prop);
133 | auto keytype = StringifyPropType(mprop->KeyProp);
134 | auto valuetype = StringifyPropType(mprop->ValueProp);
135 |
136 | if (!keytype.empty() && !valuetype.empty())
137 | {
138 | ret += "struct TMap<" + keytype + ", " + valuetype + ">";
139 | }
140 | break;
141 | }
142 |
143 | case FFieldClassID::Byte:
144 | {
145 | auto bprop = reinterpret_cast(prop);
146 |
147 | if (bprop->Enum->IsValid())
148 | {
149 | ret += "struct TEnumAsByte<" + bprop->Enum->GetName() + ">";
150 | }
151 | else
152 | {
153 | ret += "unsigned char";
154 | }
155 |
156 | break;
157 | }
158 | case FFieldClassID::Delegate:
159 | {
160 | ret += "struct FDelegate";
161 | break;
162 | }
163 | case FFieldClassID::MulticastInlineDelegate:
164 | {
165 | ret += "struct FMulticastInlineDelegate";
166 | break;
167 | }
168 | case FFieldClassID::MulticastSparseDelegate:
169 | {
170 | ret += "struct FMulticastSparseDelegate";
171 | break;
172 | }
173 | /*
174 | case MULTICASTS_INLINE_DELEGATE_PROP_ID:
175 | {
176 | ret += "FMulticastSparseDelegate";
177 | break;
178 | }
179 | */
180 | case FFieldClassID::SoftObject:
181 |
182 | {
183 | ret += "struct TWeakObjectPtr(prop)->PropertyClass->GetCPPName() + ">";
184 | break;
185 | }
186 | case FFieldClassID::SoftClass:
187 |
188 | {
189 | ret += "struct TWeakObjectPtr(prop)->MetaClass->GetCPPName() + ">";
190 | break;
191 | }
192 | case FFieldClassID::WeakObject:
193 |
194 | {
195 | ret += "struct TWeakObjectPtr(prop)->PropertyClass->GetCPPName() + ">";
196 | break;
197 | }
198 | case FFieldClassID::LazyObject:
199 |
200 | {
201 | ret += "struct TLazyObjectPtr(prop)->PropertyClass->GetCPPName() + ">";
202 | break;
203 | }
204 | case FFieldClassID::Set:
205 |
206 | {
207 | ret += "struct TSet<" + StringifyPropType(reinterpret_cast(prop)->ElementProp) + ">";
208 | break;
209 | }
210 | default:;
211 | }
212 |
213 | return ret;
214 | }
215 |
216 | static auto StringifyFlags(uint32_t Flags)
217 | {
218 | constexpr static const char* FunctionFlags[32] = { "Final", "0x00000002", "BlueprintAuthorityOnly", "BlueprintCosmetic", "0x00000010", "0x00000020", "Net", "NetReliable", "NetRequest", "Exec", "Native", "Event", "NetResponse", "Static", "NetMulticast", "0x00008000", "MulticastDelegate", "Public", "Private", "Protected", "Delegate", "NetServer", "HasOutParms", "HasDefaults", "NetClient", "DLLImport", "BlueprintCallable", "BlueprintEvent", "BlueprintPure", "0x20000000", "Const", "0x80000000" };
219 |
220 | std::string FlagsA = "(";
221 |
222 | for (int32_t i = 0; i < 32; ++i)
223 | {
224 | const uint32_t Mask = 1U << i;
225 | if ((Flags & Mask) != 0)
226 | {
227 | FlagsA += FunctionFlags[i];
228 |
229 | FlagsA += " | ";
230 | }
231 | }
232 |
233 | if (FlagsA.size() > 1)
234 | {
235 | FlagsA.pop_back();
236 | FlagsA.pop_back();
237 | FlagsA.pop_back();
238 | }
239 |
240 | FlagsA += ")";
241 |
242 | return FlagsA;
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/conanfile.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | from conans import ConanFile, tools
5 | import os
6 |
7 | class SparseppConan(ConanFile):
8 | name = "parallel_hashmap"
9 | version = "1.36"
10 | description = "A header-only, very fast and memory-friendly hash map"
11 | url = "https://github.com/greg7mdp/parallel-hashmap/blob/master/parallel_hashmap/conanfile.py"
12 |
13 | # Indicates License type of the packaged library
14 | license = "https://github.com/greg7mdp/parallel-hashmap/blob/master/LICENSE"
15 |
16 | # Packages the license for the conanfile.py
17 | exports = ["LICENSE"]
18 |
19 | # Custom attributes for Bincrafters recipe conventions
20 | source_subfolder = "source_subfolder"
21 |
22 | def source(self):
23 | source_url = "https://github.com/greg7mdp/parallel-hashmap"
24 | tools.get("{0}/archive/{1}.tar.gz".format(source_url, self.version))
25 | extracted_dir = self.name + "-" + self.version
26 |
27 | #Rename to "source_folder" is a convention to simplify later steps
28 | os.rename(extracted_dir, self.source_subfolder)
29 |
30 |
31 | def package(self):
32 | include_folder = os.path.join(self.source_subfolder, "parallel_hashmap")
33 | self.copy(pattern="LICENSE")
34 | self.copy(pattern="*", dst="include/parallel_hashmap", src=include_folder)
35 |
36 | def package_id(self):
37 | self.info.header_only()
38 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/meminfo.h:
--------------------------------------------------------------------------------
1 | #if !defined(spp_memory_h_guard)
2 | #define spp_memory_h_guard
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #if defined(_WIN32) || defined( __CYGWIN__)
9 | #define SPP_WIN
10 | #endif
11 |
12 | #ifdef SPP_WIN
13 | #include
14 | #include
15 | #undef min
16 | #undef max
17 | #elif defined(__linux__)
18 | #include
19 | #include
20 | #elif defined(__FreeBSD__)
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #endif
28 |
29 | namespace spp
30 | {
31 | uint64_t GetSystemMemory();
32 | uint64_t GetTotalMemoryUsed();
33 | uint64_t GetProcessMemoryUsed();
34 | uint64_t GetPhysicalMemory();
35 |
36 | uint64_t GetSystemMemory()
37 | {
38 | #ifdef SPP_WIN
39 | MEMORYSTATUSEX memInfo;
40 | memInfo.dwLength = sizeof(MEMORYSTATUSEX);
41 | GlobalMemoryStatusEx(&memInfo);
42 | return static_cast(memInfo.ullTotalPageFile);
43 | #elif defined(__linux__)
44 | struct sysinfo memInfo;
45 | sysinfo (&memInfo);
46 | auto totalVirtualMem = memInfo.totalram;
47 |
48 | totalVirtualMem += memInfo.totalswap;
49 | totalVirtualMem *= memInfo.mem_unit;
50 | return static_cast(totalVirtualMem);
51 | #elif defined(__FreeBSD__)
52 | kvm_t *kd;
53 | u_int pageCnt;
54 | size_t pageCntLen = sizeof(pageCnt);
55 | u_int pageSize;
56 | struct kvm_swap kswap;
57 | uint64_t totalVirtualMem;
58 |
59 | pageSize = static_cast(getpagesize());
60 |
61 | sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0);
62 | totalVirtualMem = pageCnt * pageSize;
63 |
64 | kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
65 | kvm_getswapinfo(kd, &kswap, 1, 0);
66 | kvm_close(kd);
67 | totalVirtualMem += kswap.ksw_total * pageSize;
68 |
69 | return totalVirtualMem;
70 | #else
71 | return 0;
72 | #endif
73 | }
74 |
75 | uint64_t GetTotalMemoryUsed()
76 | {
77 | #ifdef SPP_WIN
78 | MEMORYSTATUSEX memInfo;
79 | memInfo.dwLength = sizeof(MEMORYSTATUSEX);
80 | GlobalMemoryStatusEx(&memInfo);
81 | return static_cast(memInfo.ullTotalPageFile - memInfo.ullAvailPageFile);
82 | #elif defined(__linux__)
83 | struct sysinfo memInfo;
84 | sysinfo(&memInfo);
85 | auto virtualMemUsed = memInfo.totalram - memInfo.freeram;
86 |
87 | virtualMemUsed += memInfo.totalswap - memInfo.freeswap;
88 | virtualMemUsed *= memInfo.mem_unit;
89 |
90 | return static_cast(virtualMemUsed);
91 | #elif defined(__FreeBSD__)
92 | kvm_t *kd;
93 | u_int pageSize;
94 | u_int pageCnt, freeCnt;
95 | size_t pageCntLen = sizeof(pageCnt);
96 | size_t freeCntLen = sizeof(freeCnt);
97 | struct kvm_swap kswap;
98 | uint64_t virtualMemUsed;
99 |
100 | pageSize = static_cast(getpagesize());
101 |
102 | sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0);
103 | sysctlbyname("vm.stats.vm.v_free_count", &freeCnt, &freeCntLen, NULL, 0);
104 | virtualMemUsed = (pageCnt - freeCnt) * pageSize;
105 |
106 | kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
107 | kvm_getswapinfo(kd, &kswap, 1, 0);
108 | kvm_close(kd);
109 | virtualMemUsed += kswap.ksw_used * pageSize;
110 |
111 | return virtualMemUsed;
112 | #else
113 | return 0;
114 | #endif
115 | }
116 |
117 | uint64_t GetProcessMemoryUsed()
118 | {
119 | #ifdef SPP_WIN
120 | PROCESS_MEMORY_COUNTERS_EX pmc;
121 | GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&pmc), sizeof(pmc));
122 | return static_cast(pmc.PrivateUsage);
123 | #elif defined(__linux__)
124 | auto parseLine =
125 | [](char* line)->int
126 | {
127 | auto i = strlen(line);
128 |
129 | while(*line < '0' || *line > '9')
130 | {
131 | line++;
132 | }
133 |
134 | line[i-3] = '\0';
135 | i = atoi(line);
136 | return i;
137 | };
138 |
139 | auto file = fopen("/proc/self/status", "r");
140 | auto result = -1;
141 | char line[128];
142 |
143 | while(fgets(line, 128, file) != nullptr)
144 | {
145 | if(strncmp(line, "VmSize:", 7) == 0)
146 | {
147 | result = parseLine(line);
148 | break;
149 | }
150 | }
151 |
152 | fclose(file);
153 | return static_cast(result) * 1024;
154 | #elif defined(__FreeBSD__)
155 | struct kinfo_proc info;
156 | size_t infoLen = sizeof(info);
157 | int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
158 |
159 | sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &infoLen, NULL, 0);
160 | return static_cast(info.ki_rssize * getpagesize());
161 | #else
162 | return 0;
163 | #endif
164 | }
165 |
166 | uint64_t GetPhysicalMemory()
167 | {
168 | #ifdef SPP_WIN
169 | MEMORYSTATUSEX memInfo;
170 | memInfo.dwLength = sizeof(MEMORYSTATUSEX);
171 | GlobalMemoryStatusEx(&memInfo);
172 | return static_cast(memInfo.ullTotalPhys);
173 | #elif defined(__linux__)
174 | struct sysinfo memInfo;
175 | sysinfo(&memInfo);
176 |
177 | auto totalPhysMem = memInfo.totalram;
178 |
179 | totalPhysMem *= memInfo.mem_unit;
180 | return static_cast(totalPhysMem);
181 | #elif defined(__FreeBSD__)
182 | u_long physMem;
183 | size_t physMemLen = sizeof(physMem);
184 | int mib[] = { CTL_HW, HW_PHYSMEM };
185 |
186 | sysctl(mib, sizeof(mib) / sizeof(*mib), &physMem, &physMemLen, NULL, 0);
187 | return physMem;
188 | #else
189 | return 0;
190 | #endif
191 | }
192 |
193 | }
194 |
195 | #endif // spp_memory_h_guard
196 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/phmap_bits.h:
--------------------------------------------------------------------------------
1 | #if !defined(phmap_bits_h_guard_)
2 | #define phmap_bits_h_guard_
3 |
4 | // ---------------------------------------------------------------------------
5 | // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // https://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 | // Includes work from abseil-cpp (https://github.com/abseil/abseil-cpp)
20 | // with modifications.
21 | //
22 | // Copyright 2018 The Abseil Authors.
23 | //
24 | // Licensed under the Apache License, Version 2.0 (the "License");
25 | // you may not use this file except in compliance with the License.
26 | // You may obtain a copy of the License at
27 | //
28 | // https://www.apache.org/licenses/LICENSE-2.0
29 | //
30 | // Unless required by applicable law or agreed to in writing, software
31 | // distributed under the License is distributed on an "AS IS" BASIS,
32 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 | // See the License for the specific language governing permissions and
34 | // limitations under the License.
35 | // ---------------------------------------------------------------------------
36 |
37 | // The following guarantees declaration of the byte swap functions
38 | #ifdef _MSC_VER
39 | #include // NOLINT(build/include)
40 | #elif defined(__APPLE__)
41 | // Mac OS X / Darwin features
42 | #include
43 | #elif defined(__FreeBSD__)
44 | #include
45 | #elif defined(__GLIBC__)
46 | #include // IWYU pragma: export
47 | #endif
48 |
49 | #include
50 | #include
51 | #include "phmap_config.h"
52 |
53 | #ifdef _MSC_VER
54 | #pragma warning(push)
55 | #pragma warning(disable : 4514) // unreferenced inline function has been removed
56 | #endif
57 |
58 | // -----------------------------------------------------------------------------
59 | // unaligned APIs
60 | // -----------------------------------------------------------------------------
61 | // Portable handling of unaligned loads, stores, and copies.
62 | // On some platforms, like ARM, the copy functions can be more efficient
63 | // then a load and a store.
64 | // -----------------------------------------------------------------------------
65 |
66 | #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\
67 | defined(MEMORY_SANITIZER)
68 | #include
69 |
70 | extern "C" {
71 | uint16_t __sanitizer_unaligned_load16(const void *p);
72 | uint32_t __sanitizer_unaligned_load32(const void *p);
73 | uint64_t __sanitizer_unaligned_load64(const void *p);
74 | void __sanitizer_unaligned_store16(void *p, uint16_t v);
75 | void __sanitizer_unaligned_store32(void *p, uint32_t v);
76 | void __sanitizer_unaligned_store64(void *p, uint64_t v);
77 | } // extern "C"
78 |
79 | namespace phmap {
80 | namespace bits {
81 |
82 | inline uint16_t UnalignedLoad16(const void *p) {
83 | return __sanitizer_unaligned_load16(p);
84 | }
85 |
86 | inline uint32_t UnalignedLoad32(const void *p) {
87 | return __sanitizer_unaligned_load32(p);
88 | }
89 |
90 | inline uint64_t UnalignedLoad64(const void *p) {
91 | return __sanitizer_unaligned_load64(p);
92 | }
93 |
94 | inline void UnalignedStore16(void *p, uint16_t v) {
95 | __sanitizer_unaligned_store16(p, v);
96 | }
97 |
98 | inline void UnalignedStore32(void *p, uint32_t v) {
99 | __sanitizer_unaligned_store32(p, v);
100 | }
101 |
102 | inline void UnalignedStore64(void *p, uint64_t v) {
103 | __sanitizer_unaligned_store64(p, v);
104 | }
105 |
106 | } // namespace bits
107 | } // namespace phmap
108 |
109 | #define PHMAP_INTERNAL_UNALIGNED_LOAD16(_p) (phmap::bits::UnalignedLoad16(_p))
110 | #define PHMAP_INTERNAL_UNALIGNED_LOAD32(_p) (phmap::bits::UnalignedLoad32(_p))
111 | #define PHMAP_INTERNAL_UNALIGNED_LOAD64(_p) (phmap::bits::UnalignedLoad64(_p))
112 |
113 | #define PHMAP_INTERNAL_UNALIGNED_STORE16(_p, _val) (phmap::bits::UnalignedStore16(_p, _val))
114 | #define PHMAP_INTERNAL_UNALIGNED_STORE32(_p, _val) (phmap::bits::UnalignedStore32(_p, _val))
115 | #define PHMAP_INTERNAL_UNALIGNED_STORE64(_p, _val) (phmap::bits::UnalignedStore64(_p, _val))
116 |
117 | #else
118 |
119 | namespace phmap {
120 | namespace bits {
121 |
122 | inline uint16_t UnalignedLoad16(const void *p) {
123 | uint16_t t;
124 | memcpy(&t, p, sizeof t);
125 | return t;
126 | }
127 |
128 | inline uint32_t UnalignedLoad32(const void *p) {
129 | uint32_t t;
130 | memcpy(&t, p, sizeof t);
131 | return t;
132 | }
133 |
134 | inline uint64_t UnalignedLoad64(const void *p) {
135 | uint64_t t;
136 | memcpy(&t, p, sizeof t);
137 | return t;
138 | }
139 |
140 | inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
141 |
142 | inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
143 |
144 | inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
145 |
146 | } // namespace bits
147 | } // namespace phmap
148 |
149 | #define PHMAP_INTERNAL_UNALIGNED_LOAD16(_p) (phmap::bits::UnalignedLoad16(_p))
150 | #define PHMAP_INTERNAL_UNALIGNED_LOAD32(_p) (phmap::bits::UnalignedLoad32(_p))
151 | #define PHMAP_INTERNAL_UNALIGNED_LOAD64(_p) (phmap::bits::UnalignedLoad64(_p))
152 |
153 | #define PHMAP_INTERNAL_UNALIGNED_STORE16(_p, _val) (phmap::bits::UnalignedStore16(_p, _val))
154 | #define PHMAP_INTERNAL_UNALIGNED_STORE32(_p, _val) (phmap::bits::UnalignedStore32(_p, _val))
155 | #define PHMAP_INTERNAL_UNALIGNED_STORE64(_p, _val) (phmap::bits::UnalignedStore64(_p, _val))
156 |
157 | #endif
158 |
159 | // -----------------------------------------------------------------------------
160 | // File: optimization.h
161 | // -----------------------------------------------------------------------------
162 |
163 | #if defined(__pnacl__)
164 | #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
165 | #elif defined(__clang__)
166 | // Clang will not tail call given inline volatile assembly.
167 | #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
168 | #elif defined(__GNUC__)
169 | // GCC will not tail call given inline volatile assembly.
170 | #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
171 | #elif defined(_MSC_VER)
172 | #include
173 | // The __nop() intrinsic blocks the optimisation.
174 | #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __nop()
175 | #else
176 | #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
177 | #endif
178 |
179 | #if defined(__GNUC__)
180 | #pragma GCC diagnostic push
181 | #pragma GCC diagnostic ignored "-Wpedantic"
182 | #endif
183 |
184 | #ifdef PHMAP_HAVE_INTRINSIC_INT128
185 | __extension__ typedef unsigned __int128 phmap_uint128;
186 | inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high)
187 | {
188 | auto result = static_cast(a) * static_cast(b);
189 | *high = static_cast(result >> 64);
190 | return static_cast(result);
191 | }
192 | #define PHMAP_HAS_UMUL128 1
193 | #elif (defined(_MSC_VER))
194 | #if defined(_M_X64)
195 | #pragma intrinsic(_umul128)
196 | inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high)
197 | {
198 | return _umul128(a, b, high);
199 | }
200 | #define PHMAP_HAS_UMUL128 1
201 | #endif
202 | #endif
203 |
204 | #if defined(__GNUC__)
205 | #pragma GCC diagnostic pop
206 | #endif
207 |
208 | #if defined(__GNUC__)
209 | // Cache line alignment
210 | #if defined(__i386__) || defined(__x86_64__)
211 | #define PHMAP_CACHELINE_SIZE 64
212 | #elif defined(__powerpc64__)
213 | #define PHMAP_CACHELINE_SIZE 128
214 | #elif defined(__aarch64__)
215 | // We would need to read special register ctr_el0 to find out L1 dcache size.
216 | // This value is a good estimate based on a real aarch64 machine.
217 | #define PHMAP_CACHELINE_SIZE 64
218 | #elif defined(__arm__)
219 | // Cache line sizes for ARM: These values are not strictly correct since
220 | // cache line sizes depend on implementations, not architectures. There
221 | // are even implementations with cache line sizes configurable at boot
222 | // time.
223 | #if defined(__ARM_ARCH_5T__)
224 | #define PHMAP_CACHELINE_SIZE 32
225 | #elif defined(__ARM_ARCH_7A__)
226 | #define PHMAP_CACHELINE_SIZE 64
227 | #endif
228 | #endif
229 |
230 | #ifndef PHMAP_CACHELINE_SIZE
231 | // A reasonable default guess. Note that overestimates tend to waste more
232 | // space, while underestimates tend to waste more time.
233 | #define PHMAP_CACHELINE_SIZE 64
234 | #endif
235 |
236 | #define PHMAP_CACHELINE_ALIGNED __attribute__((aligned(PHMAP_CACHELINE_SIZE)))
237 | #elif defined(_MSC_VER)
238 | #define PHMAP_CACHELINE_SIZE 64
239 | #define PHMAP_CACHELINE_ALIGNED __declspec(align(PHMAP_CACHELINE_SIZE))
240 | #else
241 | #define PHMAP_CACHELINE_SIZE 64
242 | #define PHMAP_CACHELINE_ALIGNED
243 | #endif
244 |
245 |
246 | #if PHMAP_HAVE_BUILTIN(__builtin_expect) || \
247 | (defined(__GNUC__) && !defined(__clang__))
248 | #define PHMAP_PREDICT_FALSE(x) (__builtin_expect(x, 0))
249 | #define PHMAP_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
250 | #else
251 | #define PHMAP_PREDICT_FALSE(x) (x)
252 | #define PHMAP_PREDICT_TRUE(x) (x)
253 | #endif
254 |
255 | // -----------------------------------------------------------------------------
256 | // File: bits.h
257 | // -----------------------------------------------------------------------------
258 |
259 | #if defined(_MSC_VER)
260 | // We can achieve something similar to attribute((always_inline)) with MSVC by
261 | // using the __forceinline keyword, however this is not perfect. MSVC is
262 | // much less aggressive about inlining, and even with the __forceinline keyword.
263 | #define PHMAP_BASE_INTERNAL_FORCEINLINE __forceinline
264 | #else
265 | // Use default attribute inline.
266 | #define PHMAP_BASE_INTERNAL_FORCEINLINE inline PHMAP_ATTRIBUTE_ALWAYS_INLINE
267 | #endif
268 |
269 |
270 | namespace phmap {
271 | namespace base_internal {
272 |
273 | PHMAP_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) {
274 | int zeroes = 60;
275 | if (n >> 32) zeroes -= 32, n >>= 32;
276 | if (n >> 16) zeroes -= 16, n >>= 16;
277 | if (n >> 8) zeroes -= 8, n >>= 8;
278 | if (n >> 4) zeroes -= 4, n >>= 4;
279 | return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
280 | }
281 |
282 | PHMAP_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) {
283 | #if defined(_MSC_VER) && defined(_M_X64)
284 | // MSVC does not have __buitin_clzll. Use _BitScanReverse64.
285 | unsigned long result = 0; // NOLINT(runtime/int)
286 | if (_BitScanReverse64(&result, n)) {
287 | return (int)(63 - result);
288 | }
289 | return 64;
290 | #elif defined(_MSC_VER) && !defined(__clang__)
291 | // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
292 | unsigned long result = 0; // NOLINT(runtime/int)
293 | if ((n >> 32) && _BitScanReverse(&result, (unsigned long)(n >> 32))) {
294 | return 31 - result;
295 | }
296 | if (_BitScanReverse(&result, (unsigned long)n)) {
297 | return 63 - result;
298 | }
299 | return 64;
300 | #elif defined(__GNUC__) || defined(__clang__)
301 | // Use __builtin_clzll, which uses the following instructions:
302 | // x86: bsr
303 | // ARM64: clz
304 | // PPC: cntlzd
305 | static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
306 | "__builtin_clzll does not take 64-bit arg");
307 |
308 | // Handle 0 as a special case because __builtin_clzll(0) is undefined.
309 | if (n == 0) {
310 | return 64;
311 | }
312 | return __builtin_clzll(n);
313 | #else
314 | return CountLeadingZeros64Slow(n);
315 | #endif
316 | }
317 |
318 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros32Slow(uint64_t n) {
319 | uint32_t zeroes = 28;
320 | if (n >> 16) zeroes -= 16, n >>= 16;
321 | if (n >> 8) zeroes -= 8, n >>= 8;
322 | if (n >> 4) zeroes -= 4, n >>= 4;
323 | return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
324 | }
325 |
326 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros32(uint32_t n) {
327 | #if defined(_MSC_VER) && !defined(__clang__)
328 | unsigned long result = 0; // NOLINT(runtime/int)
329 | if (_BitScanReverse(&result, n)) {
330 | return (uint32_t)(31 - result);
331 | }
332 | return 32;
333 | #elif defined(__GNUC__) || defined(__clang__)
334 | // Use __builtin_clz, which uses the following instructions:
335 | // x86: bsr
336 | // ARM64: clz
337 | // PPC: cntlzd
338 | static_assert(sizeof(int) == sizeof(n),
339 | "__builtin_clz does not take 32-bit arg");
340 |
341 | // Handle 0 as a special case because __builtin_clz(0) is undefined.
342 | if (n == 0) {
343 | return 32;
344 | }
345 | return __builtin_clz(n);
346 | #else
347 | return CountLeadingZeros32Slow(n);
348 | #endif
349 | }
350 |
351 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero64Slow(uint64_t n) {
352 | uint32_t c = 63;
353 | n &= ~n + 1;
354 | if (n & 0x00000000FFFFFFFF) c -= 32;
355 | if (n & 0x0000FFFF0000FFFF) c -= 16;
356 | if (n & 0x00FF00FF00FF00FF) c -= 8;
357 | if (n & 0x0F0F0F0F0F0F0F0F) c -= 4;
358 | if (n & 0x3333333333333333) c -= 2;
359 | if (n & 0x5555555555555555) c -= 1;
360 | return c;
361 | }
362 |
363 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero64(uint64_t n) {
364 | #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
365 | unsigned long result = 0; // NOLINT(runtime/int)
366 | _BitScanForward64(&result, n);
367 | return (uint32_t)result;
368 | #elif defined(_MSC_VER) && !defined(__clang__)
369 | unsigned long result = 0; // NOLINT(runtime/int)
370 | if (static_cast(n) == 0) {
371 | _BitScanForward(&result, (unsigned long)(n >> 32));
372 | return result + 32;
373 | }
374 | _BitScanForward(&result, (unsigned long)n);
375 | return result;
376 | #elif defined(__GNUC__) || defined(__clang__)
377 | static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
378 | "__builtin_ctzll does not take 64-bit arg");
379 | return __builtin_ctzll(n);
380 | #else
381 | return CountTrailingZerosNonZero64Slow(n);
382 | #endif
383 | }
384 |
385 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero32Slow(uint32_t n) {
386 | uint32_t c = 31;
387 | n &= ~n + 1;
388 | if (n & 0x0000FFFF) c -= 16;
389 | if (n & 0x00FF00FF) c -= 8;
390 | if (n & 0x0F0F0F0F) c -= 4;
391 | if (n & 0x33333333) c -= 2;
392 | if (n & 0x55555555) c -= 1;
393 | return c;
394 | }
395 |
396 | PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero32(uint32_t n) {
397 | #if defined(_MSC_VER) && !defined(__clang__)
398 | unsigned long result = 0; // NOLINT(runtime/int)
399 | _BitScanForward(&result, n);
400 | return (uint32_t)result;
401 | #elif defined(__GNUC__) || defined(__clang__)
402 | static_assert(sizeof(int) == sizeof(n),
403 | "__builtin_ctz does not take 32-bit arg");
404 | return __builtin_ctz(n);
405 | #else
406 | return CountTrailingZerosNonZero32Slow(n);
407 | #endif
408 | }
409 |
410 | #undef PHMAP_BASE_INTERNAL_FORCEINLINE
411 |
412 | } // namespace base_internal
413 | } // namespace phmap
414 |
415 | // -----------------------------------------------------------------------------
416 | // File: endian.h
417 | // -----------------------------------------------------------------------------
418 |
419 | namespace phmap {
420 |
421 | // Use compiler byte-swapping intrinsics if they are available. 32-bit
422 | // and 64-bit versions are available in Clang and GCC as of GCC 4.3.0.
423 | // The 16-bit version is available in Clang and GCC only as of GCC 4.8.0.
424 | // For simplicity, we enable them all only for GCC 4.8.0 or later.
425 | #if defined(__clang__) || \
426 | (defined(__GNUC__) && \
427 | ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
428 |
429 | inline uint64_t gbswap_64(uint64_t host_int) {
430 | return __builtin_bswap64(host_int);
431 | }
432 | inline uint32_t gbswap_32(uint32_t host_int) {
433 | return __builtin_bswap32(host_int);
434 | }
435 | inline uint16_t gbswap_16(uint16_t host_int) {
436 | return __builtin_bswap16(host_int);
437 | }
438 |
439 | #elif defined(_MSC_VER)
440 |
441 | inline uint64_t gbswap_64(uint64_t host_int) {
442 | return _byteswap_uint64(host_int);
443 | }
444 | inline uint32_t gbswap_32(uint32_t host_int) {
445 | return _byteswap_ulong(host_int);
446 | }
447 | inline uint16_t gbswap_16(uint16_t host_int) {
448 | return _byteswap_ushort(host_int);
449 | }
450 |
451 | #elif defined(__APPLE__)
452 |
453 | inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); }
454 | inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); }
455 | inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); }
456 |
457 | #else
458 |
459 | inline uint64_t gbswap_64(uint64_t host_int) {
460 | #if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__)
461 | // Adapted from /usr/include/byteswap.h. Not available on Mac.
462 | if (__builtin_constant_p(host_int)) {
463 | return __bswap_constant_64(host_int);
464 | } else {
465 | uint64_t result;
466 | __asm__("bswap %0" : "=r"(result) : "0"(host_int));
467 | return result;
468 | }
469 | #elif defined(__GLIBC__)
470 | return bswap_64(host_int);
471 | #else
472 | return (((host_int & uint64_t{0xFF}) << 56) |
473 | ((host_int & uint64_t{0xFF00}) << 40) |
474 | ((host_int & uint64_t{0xFF0000}) << 24) |
475 | ((host_int & uint64_t{0xFF000000}) << 8) |
476 | ((host_int & uint64_t{0xFF00000000}) >> 8) |
477 | ((host_int & uint64_t{0xFF0000000000}) >> 24) |
478 | ((host_int & uint64_t{0xFF000000000000}) >> 40) |
479 | ((host_int & uint64_t{0xFF00000000000000}) >> 56));
480 | #endif // bswap_64
481 | }
482 |
483 | inline uint32_t gbswap_32(uint32_t host_int) {
484 | #if defined(__GLIBC__)
485 | return bswap_32(host_int);
486 | #else
487 | return (((host_int & uint32_t{0xFF}) << 24) |
488 | ((host_int & uint32_t{0xFF00}) << 8) |
489 | ((host_int & uint32_t{0xFF0000}) >> 8) |
490 | ((host_int & uint32_t{0xFF000000}) >> 24));
491 | #endif
492 | }
493 |
494 | inline uint16_t gbswap_16(uint16_t host_int) {
495 | #if defined(__GLIBC__)
496 | return bswap_16(host_int);
497 | #else
498 | return (((host_int & uint16_t{0xFF}) << 8) |
499 | ((host_int & uint16_t{0xFF00}) >> 8));
500 | #endif
501 | }
502 |
503 | #endif // intrinics available
504 |
505 | #ifdef PHMAP_IS_LITTLE_ENDIAN
506 |
507 | // Definitions for ntohl etc. that don't require us to include
508 | // netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather
509 | // than just #defining them because in debug mode, gcc doesn't
510 | // correctly handle the (rather involved) definitions of bswap_32.
511 | // gcc guarantees that inline functions are as fast as macros, so
512 | // this isn't a performance hit.
513 | inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); }
514 | inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); }
515 | inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); }
516 |
517 | #elif defined PHMAP_IS_BIG_ENDIAN
518 |
519 | // These definitions are simpler on big-endian machines
520 | // These are functions instead of macros to avoid self-assignment warnings
521 | // on calls such as "i = ghtnol(i);". This also provides type checking.
522 | inline uint16_t ghtons(uint16_t x) { return x; }
523 | inline uint32_t ghtonl(uint32_t x) { return x; }
524 | inline uint64_t ghtonll(uint64_t x) { return x; }
525 |
526 | #else
527 | #error \
528 | "Unsupported byte order: Either PHMAP_IS_BIG_ENDIAN or " \
529 | "PHMAP_IS_LITTLE_ENDIAN must be defined"
530 | #endif // byte order
531 |
532 | inline uint16_t gntohs(uint16_t x) { return ghtons(x); }
533 | inline uint32_t gntohl(uint32_t x) { return ghtonl(x); }
534 | inline uint64_t gntohll(uint64_t x) { return ghtonll(x); }
535 |
536 | // Utilities to convert numbers between the current hosts's native byte
537 | // order and little-endian byte order
538 | //
539 | // Load/Store methods are alignment safe
540 | namespace little_endian {
541 | // Conversion functions.
542 | #ifdef PHMAP_IS_LITTLE_ENDIAN
543 |
544 | inline uint16_t FromHost16(uint16_t x) { return x; }
545 | inline uint16_t ToHost16(uint16_t x) { return x; }
546 |
547 | inline uint32_t FromHost32(uint32_t x) { return x; }
548 | inline uint32_t ToHost32(uint32_t x) { return x; }
549 |
550 | inline uint64_t FromHost64(uint64_t x) { return x; }
551 | inline uint64_t ToHost64(uint64_t x) { return x; }
552 |
553 | inline constexpr bool IsLittleEndian() { return true; }
554 |
555 | #elif defined PHMAP_IS_BIG_ENDIAN
556 |
557 | inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
558 | inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
559 |
560 | inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
561 | inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
562 |
563 | inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
564 | inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
565 |
566 | inline constexpr bool IsLittleEndian() { return false; }
567 |
568 | #endif /* ENDIAN */
569 |
570 | // Functions to do unaligned loads and stores in little-endian order.
571 | // ------------------------------------------------------------------
572 | inline uint16_t Load16(const void *p) {
573 | return ToHost16(PHMAP_INTERNAL_UNALIGNED_LOAD16(p));
574 | }
575 |
576 | inline void Store16(void *p, uint16_t v) {
577 | PHMAP_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
578 | }
579 |
580 | inline uint32_t Load32(const void *p) {
581 | return ToHost32(PHMAP_INTERNAL_UNALIGNED_LOAD32(p));
582 | }
583 |
584 | inline void Store32(void *p, uint32_t v) {
585 | PHMAP_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
586 | }
587 |
588 | inline uint64_t Load64(const void *p) {
589 | return ToHost64(PHMAP_INTERNAL_UNALIGNED_LOAD64(p));
590 | }
591 |
592 | inline void Store64(void *p, uint64_t v) {
593 | PHMAP_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
594 | }
595 |
596 | } // namespace little_endian
597 |
598 | // Utilities to convert numbers between the current hosts's native byte
599 | // order and big-endian byte order (same as network byte order)
600 | //
601 | // Load/Store methods are alignment safe
602 | namespace big_endian {
603 | #ifdef PHMAP_IS_LITTLE_ENDIAN
604 |
605 | inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
606 | inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
607 |
608 | inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
609 | inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
610 |
611 | inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
612 | inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
613 |
614 | inline constexpr bool IsLittleEndian() { return true; }
615 |
616 | #elif defined PHMAP_IS_BIG_ENDIAN
617 |
618 | inline uint16_t FromHost16(uint16_t x) { return x; }
619 | inline uint16_t ToHost16(uint16_t x) { return x; }
620 |
621 | inline uint32_t FromHost32(uint32_t x) { return x; }
622 | inline uint32_t ToHost32(uint32_t x) { return x; }
623 |
624 | inline uint64_t FromHost64(uint64_t x) { return x; }
625 | inline uint64_t ToHost64(uint64_t x) { return x; }
626 |
627 | inline constexpr bool IsLittleEndian() { return false; }
628 |
629 | #endif /* ENDIAN */
630 |
631 | // Functions to do unaligned loads and stores in big-endian order.
632 | inline uint16_t Load16(const void *p) {
633 | return ToHost16(PHMAP_INTERNAL_UNALIGNED_LOAD16(p));
634 | }
635 |
636 | inline void Store16(void *p, uint16_t v) {
637 | PHMAP_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
638 | }
639 |
640 | inline uint32_t Load32(const void *p) {
641 | return ToHost32(PHMAP_INTERNAL_UNALIGNED_LOAD32(p));
642 | }
643 |
644 | inline void Store32(void *p, uint32_t v) {
645 | PHMAP_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
646 | }
647 |
648 | inline uint64_t Load64(const void *p) {
649 | return ToHost64(PHMAP_INTERNAL_UNALIGNED_LOAD64(p));
650 | }
651 |
652 | inline void Store64(void *p, uint64_t v) {
653 | PHMAP_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
654 | }
655 |
656 | } // namespace big_endian
657 |
658 | } // namespace phmap
659 |
660 | #ifdef _MSC_VER
661 | #pragma warning(pop)
662 | #endif
663 |
664 | #endif // phmap_bits_h_guard_
665 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/phmap_config.h:
--------------------------------------------------------------------------------
1 | #if !defined(phmap_config_h_guard_)
2 | #define phmap_config_h_guard_
3 |
4 | // ---------------------------------------------------------------------------
5 | // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // https://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 | // Includes work from abseil-cpp (https://github.com/abseil/abseil-cpp)
20 | // with modifications.
21 | //
22 | // Copyright 2018 The Abseil Authors.
23 | //
24 | // Licensed under the Apache License, Version 2.0 (the "License");
25 | // you may not use this file except in compliance with the License.
26 | // You may obtain a copy of the License at
27 | //
28 | // https://www.apache.org/licenses/LICENSE-2.0
29 | //
30 | // Unless required by applicable law or agreed to in writing, software
31 | // distributed under the License is distributed on an "AS IS" BASIS,
32 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 | // See the License for the specific language governing permissions and
34 | // limitations under the License.
35 | // ---------------------------------------------------------------------------
36 |
37 | #define PHMAP_VERSION_MAJOR 1
38 | #define PHMAP_VERSION_MINOR 3
39 | #define PHMAP_VERSION_PATCH 8
40 |
41 | // Included for the __GLIBC__ macro (or similar macros on other systems).
42 | #include
43 |
44 | #ifdef __cplusplus
45 | // Included for __GLIBCXX__, _LIBCPP_VERSION
46 | #include
47 | #endif // __cplusplus
48 |
49 | #if defined(__APPLE__)
50 | // Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED,
51 | // __IPHONE_8_0.
52 | #include
53 | #include
54 | #endif
55 |
56 | #define PHMAP_XSTR(x) PHMAP_STR(x)
57 | #define PHMAP_STR(x) #x
58 | #define PHMAP_VAR_NAME_VALUE(var) #var "=" PHMAP_STR(var)
59 |
60 | // -----------------------------------------------------------------------------
61 | // Some sanity checks
62 | // -----------------------------------------------------------------------------
63 | //#if defined(__CYGWIN__)
64 | // #error "Cygwin is not supported."
65 | //#endif
66 |
67 | #if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__)
68 | #error "phmap requires Visual Studio 2015 Update 2 or higher."
69 | #endif
70 |
71 | // We support gcc 4.7 and later.
72 | #if defined(__GNUC__) && !defined(__clang__)
73 | #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
74 | #error "phmap requires gcc 4.7 or higher."
75 | #endif
76 | #endif
77 |
78 | // We support Apple Xcode clang 4.2.1 (version 421.11.65) and later.
79 | // This corresponds to Apple Xcode version 4.5.
80 | #if defined(__apple_build_version__) && __apple_build_version__ < 4211165
81 | #error "phmap requires __apple_build_version__ of 4211165 or higher."
82 | #endif
83 |
84 | // Enforce C++11 as the minimum.
85 | #if defined(__cplusplus) && !defined(_MSC_VER)
86 | #if __cplusplus < 201103L
87 | #error "C++ versions less than C++11 are not supported."
88 | #endif
89 | #endif
90 |
91 | // We have chosen glibc 2.12 as the minimum
92 | #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
93 | #if !__GLIBC_PREREQ(2, 12)
94 | #error "Minimum required version of glibc is 2.12."
95 | #endif
96 | #endif
97 |
98 | #if defined(_STLPORT_VERSION)
99 | #error "STLPort is not supported."
100 | #endif
101 |
102 | #if CHAR_BIT != 8
103 | #error "phmap assumes CHAR_BIT == 8."
104 | #endif
105 |
106 | // phmap currently assumes that an int is 4 bytes.
107 | #if INT_MAX < 2147483647
108 | #error "phmap assumes that int is at least 4 bytes. "
109 | #endif
110 |
111 |
112 |
113 | // -----------------------------------------------------------------------------
114 | // Compiler Feature Checks
115 | // -----------------------------------------------------------------------------
116 |
117 | #ifdef __has_builtin
118 | #define PHMAP_HAVE_BUILTIN(x) __has_builtin(x)
119 | #else
120 | #define PHMAP_HAVE_BUILTIN(x) 0
121 | #endif
122 |
123 | #if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703) || __cplusplus >= 201703
124 | #define PHMAP_HAVE_CC17 1
125 | #else
126 | #define PHMAP_HAVE_CC17 0
127 | #endif
128 |
129 | #define PHMAP_BRANCHLESS 1
130 |
131 | #ifdef __has_feature
132 | #define PHMAP_HAVE_FEATURE(f) __has_feature(f)
133 | #else
134 | #define PHMAP_HAVE_FEATURE(f) 0
135 | #endif
136 |
137 | // Portable check for GCC minimum version:
138 | // https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
139 | #if defined(__GNUC__) && defined(__GNUC_MINOR__)
140 | #define PHMAP_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
141 | #else
142 | #define PHMAP_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0
143 | #endif
144 |
145 | #if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
146 | #define PHMAP_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
147 | #else
148 | #define PHMAP_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0
149 | #endif
150 |
151 | // -------------------------------------------------------------------
152 | // Checks whether C++11's `thread_local` storage duration specifier is
153 | // supported.
154 | // -------------------------------------------------------------------
155 | #ifdef PHMAP_HAVE_THREAD_LOCAL
156 | #error PHMAP_HAVE_THREAD_LOCAL cannot be directly set
157 | #elif defined(__APPLE__)
158 | #if __has_feature(cxx_thread_local) && \
159 | !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
160 | #define PHMAP_HAVE_THREAD_LOCAL 1
161 | #endif
162 | #else // !defined(__APPLE__)
163 | #define PHMAP_HAVE_THREAD_LOCAL 1
164 | #endif
165 |
166 | #if defined(__ANDROID__) && defined(__clang__)
167 |
168 | #if __has_include()
169 | #include
170 | #endif // __has_include()
171 |
172 | #if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
173 | defined(__NDK_MINOR__) && \
174 | ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
175 | #undef PHMAP_HAVE_TLS
176 | #undef PHMAP_HAVE_THREAD_LOCAL
177 | #endif
178 | #endif
179 |
180 | // ------------------------------------------------------------
181 | // Checks whether the __int128 compiler extension for a 128-bit
182 | // integral type is supported.
183 | // ------------------------------------------------------------
184 | #ifdef PHMAP_HAVE_INTRINSIC_INT128
185 | #error PHMAP_HAVE_INTRINSIC_INT128 cannot be directly set
186 | #elif defined(__SIZEOF_INT128__)
187 | #if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \
188 | (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
189 | (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
190 | #define PHMAP_HAVE_INTRINSIC_INT128 1
191 | #elif defined(__CUDACC__)
192 | #if __CUDACC_VER__ >= 70000
193 | #define PHMAP_HAVE_INTRINSIC_INT128 1
194 | #endif // __CUDACC_VER__ >= 70000
195 | #endif // defined(__CUDACC__)
196 | #endif
197 |
198 | // ------------------------------------------------------------------
199 | // Checks whether the compiler both supports and enables exceptions.
200 | // ------------------------------------------------------------------
201 | #ifdef PHMAP_HAVE_EXCEPTIONS
202 | #error PHMAP_HAVE_EXCEPTIONS cannot be directly set.
203 | #elif defined(__clang__)
204 | #if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
205 | #define PHMAP_HAVE_EXCEPTIONS 1
206 | #endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
207 | #elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \
208 | !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \
209 | !(defined(_MSC_VER) && !defined(_CPPUNWIND))
210 | #define PHMAP_HAVE_EXCEPTIONS 1
211 | #endif
212 |
213 |
214 | // -----------------------------------------------------------------------
215 | // Checks whether the platform has an mmap(2) implementation as defined in
216 | // POSIX.1-2001.
217 | // -----------------------------------------------------------------------
218 | #ifdef PHMAP_HAVE_MMAP
219 | #error PHMAP_HAVE_MMAP cannot be directly set
220 | #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
221 | defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \
222 | defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \
223 | defined(__ASYLO__)
224 | #define PHMAP_HAVE_MMAP 1
225 | #endif
226 |
227 | // -----------------------------------------------------------------------
228 | // Checks the endianness of the platform.
229 | // -----------------------------------------------------------------------
230 | #if defined(PHMAP_IS_BIG_ENDIAN)
231 | #error "PHMAP_IS_BIG_ENDIAN cannot be directly set."
232 | #endif
233 |
234 | #if defined(PHMAP_IS_LITTLE_ENDIAN)
235 | #error "PHMAP_IS_LITTLE_ENDIAN cannot be directly set."
236 | #endif
237 |
238 | #if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
239 | __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
240 | #define PHMAP_IS_LITTLE_ENDIAN 1
241 | #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
242 | __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
243 | #define PHMAP_IS_BIG_ENDIAN 1
244 | #elif defined(_WIN32)
245 | #define PHMAP_IS_LITTLE_ENDIAN 1
246 | #else
247 | #error "phmap endian detection needs to be set up for your compiler"
248 | #endif
249 |
250 | #if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \
251 | defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \
252 | __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400
253 | #define PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1
254 | #else
255 | #define PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 0
256 | #endif
257 |
258 | // ---------------------------------------------------------------------------
259 | // Checks whether C++17 std::any is available by checking whether exists.
260 | // ---------------------------------------------------------------------------
261 | #ifdef PHMAP_HAVE_STD_ANY
262 | #error "PHMAP_HAVE_STD_ANY cannot be directly set."
263 | #endif
264 |
265 | #ifdef __has_include
266 | #if __has_include() && __cplusplus >= 201703L && \
267 | !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
268 | #define PHMAP_HAVE_STD_ANY 1
269 | #endif
270 | #endif
271 |
272 | #ifdef PHMAP_HAVE_STD_OPTIONAL
273 | #error "PHMAP_HAVE_STD_OPTIONAL cannot be directly set."
274 | #endif
275 |
276 | #ifdef __has_include
277 | #if __has_include() && __cplusplus >= 201703L && \
278 | !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
279 | #define PHMAP_HAVE_STD_OPTIONAL 1
280 | #endif
281 | #endif
282 |
283 | #ifdef PHMAP_HAVE_STD_VARIANT
284 | #error "PHMAP_HAVE_STD_VARIANT cannot be directly set."
285 | #endif
286 |
287 | #ifdef __has_include
288 | #if __has_include() && __cplusplus >= 201703L && \
289 | !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
290 | #define PHMAP_HAVE_STD_VARIANT 1
291 | #endif
292 | #endif
293 |
294 | #ifdef PHMAP_HAVE_STD_STRING_VIEW
295 | #error "PHMAP_HAVE_STD_STRING_VIEW cannot be directly set."
296 | #endif
297 |
298 | #ifdef __has_include
299 | #if __has_include() && __cplusplus >= 201703L && \
300 | (!defined(_MSC_VER) || _MSC_VER >= 1920) // vs2019
301 | #define PHMAP_HAVE_STD_STRING_VIEW 1
302 | #endif
303 | #endif
304 |
305 | // #pragma message(PHMAP_VAR_NAME_VALUE(_MSVC_LANG))
306 |
307 | #if defined(_MSC_VER) && _MSC_VER >= 1910 && PHMAP_HAVE_CC17
308 | // #define PHMAP_HAVE_STD_ANY 1
309 | #define PHMAP_HAVE_STD_OPTIONAL 1
310 | #define PHMAP_HAVE_STD_VARIANT 1
311 | #if !defined(PHMAP_HAVE_STD_STRING_VIEW) && _MSC_VER >= 1920
312 | #define PHMAP_HAVE_STD_STRING_VIEW 1
313 | #endif
314 | #endif
315 |
316 | #if PHMAP_HAVE_CC17
317 | #define PHMAP_HAVE_SHARED_MUTEX 1
318 | #endif
319 |
320 | #ifndef PHMAP_HAVE_STD_STRING_VIEW
321 | #define PHMAP_HAVE_STD_STRING_VIEW 0
322 | #endif
323 |
324 | // In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION
325 | // SEH exception from emplace for variant when constructing the
326 | // struct can throw. This defeats some of variant_test and
327 | // variant_exception_safety_test.
328 | #if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG)
329 | #define PHMAP_INTERNAL_MSVC_2017_DBG_MODE
330 | #endif
331 |
332 | // ---------------------------------------------------------------------------
333 | // Checks whether wchar_t is treated as a native type
334 | // (MSVC: /Zc:wchar_t- treats wchar_t as unsigned short)
335 | // ---------------------------------------------------------------------------
336 | #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
337 | #define PHMAP_HAS_NATIVE_WCHAR_T
338 | #endif
339 |
340 | // -----------------------------------------------------------------------------
341 | // Sanitizer Attributes
342 | // -----------------------------------------------------------------------------
343 | //
344 | // Sanitizer-related attributes are not "defined" in this file (and indeed
345 | // are not defined as such in any file). To utilize the following
346 | // sanitizer-related attributes within your builds, define the following macros
347 | // within your build using a `-D` flag, along with the given value for
348 | // `-fsanitize`:
349 | //
350 | // * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8)
351 | // * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only)
352 | // * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+)
353 | // * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+)
354 | // * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only)
355 | // -----------------------------------------------------------------------------
356 |
357 | // -----------------------------------------------------------------------------
358 | // A function-like feature checking macro that is a wrapper around
359 | // `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
360 | // nonzero constant integer if the attribute is supported or 0 if not.
361 | //
362 | // It evaluates to zero if `__has_attribute` is not defined by the compiler.
363 | // -----------------------------------------------------------------------------
364 | #ifdef __has_attribute
365 | #define PHMAP_HAVE_ATTRIBUTE(x) __has_attribute(x)
366 | #else
367 | #define PHMAP_HAVE_ATTRIBUTE(x) 0
368 | #endif
369 |
370 | // -----------------------------------------------------------------------------
371 | // A function-like feature checking macro that accepts C++11 style attributes.
372 | // It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
373 | // (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
374 | // find `__has_cpp_attribute`, will evaluate to 0.
375 | // -----------------------------------------------------------------------------
376 | #if defined(__cplusplus) && defined(__has_cpp_attribute)
377 | #define PHMAP_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
378 | #else
379 | #define PHMAP_HAVE_CPP_ATTRIBUTE(x) 0
380 | #endif
381 |
382 | // -----------------------------------------------------------------------------
383 | // Function Attributes
384 | // -----------------------------------------------------------------------------
385 | #if PHMAP_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__))
386 | #define PHMAP_PRINTF_ATTRIBUTE(string_index, first_to_check) \
387 | __attribute__((__format__(__printf__, string_index, first_to_check)))
388 | #define PHMAP_SCANF_ATTRIBUTE(string_index, first_to_check) \
389 | __attribute__((__format__(__scanf__, string_index, first_to_check)))
390 | #else
391 | #define PHMAP_PRINTF_ATTRIBUTE(string_index, first_to_check)
392 | #define PHMAP_SCANF_ATTRIBUTE(string_index, first_to_check)
393 | #endif
394 |
395 | #if PHMAP_HAVE_ATTRIBUTE(always_inline) || \
396 | (defined(__GNUC__) && !defined(__clang__))
397 | #define PHMAP_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
398 | #define PHMAP_HAVE_ATTRIBUTE_ALWAYS_INLINE 1
399 | #else
400 | #define PHMAP_ATTRIBUTE_ALWAYS_INLINE
401 | #endif
402 |
403 | #if !defined(__INTEL_COMPILER) && (PHMAP_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)))
404 | #define PHMAP_ATTRIBUTE_NOINLINE __attribute__((noinline))
405 | #define PHMAP_HAVE_ATTRIBUTE_NOINLINE 1
406 | #else
407 | #define PHMAP_ATTRIBUTE_NOINLINE
408 | #endif
409 |
410 | #if PHMAP_HAVE_ATTRIBUTE(disable_tail_calls)
411 | #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
412 | #define PHMAP_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls))
413 | #elif defined(__GNUC__) && !defined(__clang__)
414 | #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
415 | #define PHMAP_ATTRIBUTE_NO_TAIL_CALL \
416 | __attribute__((optimize("no-optimize-sibling-calls")))
417 | #else
418 | #define PHMAP_ATTRIBUTE_NO_TAIL_CALL
419 | #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 0
420 | #endif
421 |
422 | #if (PHMAP_HAVE_ATTRIBUTE(weak) || \
423 | (defined(__GNUC__) && !defined(__clang__))) && \
424 | !(defined(__llvm__) && defined(_WIN32))
425 | #undef PHMAP_ATTRIBUTE_WEAK
426 | #define PHMAP_ATTRIBUTE_WEAK __attribute__((weak))
427 | #define PHMAP_HAVE_ATTRIBUTE_WEAK 1
428 | #else
429 | #define PHMAP_ATTRIBUTE_WEAK
430 | #define PHMAP_HAVE_ATTRIBUTE_WEAK 0
431 | #endif
432 |
433 | #if PHMAP_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__))
434 | #define PHMAP_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index)))
435 | #else
436 | #define PHMAP_ATTRIBUTE_NONNULL(...)
437 | #endif
438 |
439 | #if PHMAP_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__))
440 | #define PHMAP_ATTRIBUTE_NORETURN __attribute__((noreturn))
441 | #elif defined(_MSC_VER)
442 | #define PHMAP_ATTRIBUTE_NORETURN __declspec(noreturn)
443 | #else
444 | #define PHMAP_ATTRIBUTE_NORETURN
445 | #endif
446 |
447 | #if defined(__GNUC__) && defined(ADDRESS_SANITIZER)
448 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
449 | #else
450 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_ADDRESS
451 | #endif
452 |
453 | #if defined(__GNUC__) && defined(MEMORY_SANITIZER)
454 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
455 | #else
456 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_MEMORY
457 | #endif
458 |
459 | #if defined(__GNUC__) && defined(THREAD_SANITIZER)
460 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
461 | #else
462 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_THREAD
463 | #endif
464 |
465 | #if defined(__GNUC__) && \
466 | (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER))
467 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
468 | __attribute__((no_sanitize("undefined")))
469 | #else
470 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_UNDEFINED
471 | #endif
472 |
473 | #if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY)
474 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi")))
475 | #else
476 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_CFI
477 | #endif
478 |
479 | #if defined(__GNUC__) && defined(SAFESTACK_SANITIZER)
480 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_SAFESTACK \
481 | __attribute__((no_sanitize("safe-stack")))
482 | #else
483 | #define PHMAP_ATTRIBUTE_NO_SANITIZE_SAFESTACK
484 | #endif
485 |
486 | #if PHMAP_HAVE_ATTRIBUTE(returns_nonnull) || \
487 | (defined(__GNUC__) && \
488 | (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \
489 | !defined(__clang__))
490 | #define PHMAP_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
491 | #else
492 | #define PHMAP_ATTRIBUTE_RETURNS_NONNULL
493 | #endif
494 |
495 | #ifdef PHMAP_HAVE_ATTRIBUTE_SECTION
496 | #error PHMAP_HAVE_ATTRIBUTE_SECTION cannot be directly set
497 | #elif (PHMAP_HAVE_ATTRIBUTE(section) || \
498 | (defined(__GNUC__) && !defined(__clang__))) && \
499 | !defined(__APPLE__) && PHMAP_HAVE_ATTRIBUTE_WEAK
500 | #define PHMAP_HAVE_ATTRIBUTE_SECTION 1
501 | #ifndef PHMAP_ATTRIBUTE_SECTION
502 | #define PHMAP_ATTRIBUTE_SECTION(name) \
503 | __attribute__((section(#name))) __attribute__((noinline))
504 | #endif
505 | #ifndef PHMAP_ATTRIBUTE_SECTION_VARIABLE
506 | #define PHMAP_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name)))
507 | #endif
508 | #ifndef PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS
509 | #define PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS(name) \
510 | extern char __start_##name[] PHMAP_ATTRIBUTE_WEAK; \
511 | extern char __stop_##name[] PHMAP_ATTRIBUTE_WEAK
512 | #endif
513 | #ifndef PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS
514 | #define PHMAP_INIT_ATTRIBUTE_SECTION_VARS(name)
515 | #define PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS(name)
516 | #endif
517 | #define PHMAP_ATTRIBUTE_SECTION_START(name) \
518 | (reinterpret_cast(__start_##name))
519 | #define PHMAP_ATTRIBUTE_SECTION_STOP(name) \
520 | (reinterpret_cast(__stop_##name))
521 | #else // !PHMAP_HAVE_ATTRIBUTE_SECTION
522 | #define PHMAP_HAVE_ATTRIBUTE_SECTION 0
523 | #define PHMAP_ATTRIBUTE_SECTION(name)
524 | #define PHMAP_ATTRIBUTE_SECTION_VARIABLE(name)
525 | #define PHMAP_INIT_ATTRIBUTE_SECTION_VARS(name)
526 | #define PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS(name)
527 | #define PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS(name)
528 | #define PHMAP_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0))
529 | #define PHMAP_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0))
530 | #endif // PHMAP_ATTRIBUTE_SECTION
531 |
532 | #if PHMAP_HAVE_ATTRIBUTE(force_align_arg_pointer) || \
533 | (defined(__GNUC__) && !defined(__clang__))
534 | #if defined(__i386__)
535 | #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \
536 | __attribute__((force_align_arg_pointer))
537 | #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
538 | #elif defined(__x86_64__)
539 | #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (1)
540 | #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
541 | #else // !__i386__ && !__x86_64
542 | #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
543 | #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
544 | #endif // __i386__
545 | #else
546 | #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
547 | #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
548 | #endif
549 |
550 | #if PHMAP_HAVE_ATTRIBUTE(nodiscard)
551 | #define PHMAP_MUST_USE_RESULT [[nodiscard]]
552 | #elif defined(__clang__) && PHMAP_HAVE_ATTRIBUTE(warn_unused_result)
553 | #define PHMAP_MUST_USE_RESULT __attribute__((warn_unused_result))
554 | #else
555 | #define PHMAP_MUST_USE_RESULT
556 | #endif
557 |
558 | #if PHMAP_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__))
559 | #define PHMAP_ATTRIBUTE_HOT __attribute__((hot))
560 | #else
561 | #define PHMAP_ATTRIBUTE_HOT
562 | #endif
563 |
564 | #if PHMAP_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__))
565 | #define PHMAP_ATTRIBUTE_COLD __attribute__((cold))
566 | #else
567 | #define PHMAP_ATTRIBUTE_COLD
568 | #endif
569 |
570 | #if defined(__clang__)
571 | #if PHMAP_HAVE_CPP_ATTRIBUTE(clang::reinitializes)
572 | #define PHMAP_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
573 | #else
574 | #define PHMAP_ATTRIBUTE_REINITIALIZES
575 | #endif
576 | #else
577 | #define PHMAP_ATTRIBUTE_REINITIALIZES
578 | #endif
579 |
580 | #if PHMAP_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
581 | #undef PHMAP_ATTRIBUTE_UNUSED
582 | #define PHMAP_ATTRIBUTE_UNUSED __attribute__((__unused__))
583 | #else
584 | #define PHMAP_ATTRIBUTE_UNUSED
585 | #endif
586 |
587 | #if PHMAP_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__))
588 | #define PHMAP_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec")))
589 | #else
590 | #define PHMAP_ATTRIBUTE_INITIAL_EXEC
591 | #endif
592 |
593 | #if PHMAP_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
594 | #define PHMAP_ATTRIBUTE_PACKED __attribute__((__packed__))
595 | #else
596 | #define PHMAP_ATTRIBUTE_PACKED
597 | #endif
598 |
599 | #if PHMAP_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__))
600 | #define PHMAP_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes)))
601 | #else
602 | #define PHMAP_ATTRIBUTE_FUNC_ALIGN(bytes)
603 | #endif
604 |
605 | // ----------------------------------------------------------------------
606 | // Figure out SSE support
607 | // ----------------------------------------------------------------------
608 | #ifndef PHMAP_HAVE_SSE2
609 | #if defined(__SSE2__) || \
610 | (defined(_MSC_VER) && \
611 | (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2)))
612 | #define PHMAP_HAVE_SSE2 1
613 | #else
614 | #define PHMAP_HAVE_SSE2 0
615 | #endif
616 | #endif
617 |
618 | #ifndef PHMAP_HAVE_SSSE3
619 | #if defined(__SSSE3__) || defined(__AVX2__)
620 | #define PHMAP_HAVE_SSSE3 1
621 | #else
622 | #define PHMAP_HAVE_SSSE3 0
623 | #endif
624 | #endif
625 |
626 | #if PHMAP_HAVE_SSSE3 && !PHMAP_HAVE_SSE2
627 | #error "Bad configuration!"
628 | #endif
629 |
630 | #if PHMAP_HAVE_SSE2
631 | #include
632 | #endif
633 |
634 | #if PHMAP_HAVE_SSSE3
635 | #include
636 | #endif
637 |
638 |
639 | // ----------------------------------------------------------------------
640 | // constexpr if
641 | // ----------------------------------------------------------------------
642 | #if PHMAP_HAVE_CC17
643 | #define PHMAP_IF_CONSTEXPR(expr) if constexpr ((expr))
644 | #else
645 | #define PHMAP_IF_CONSTEXPR(expr) if ((expr))
646 | #endif
647 |
648 | // ----------------------------------------------------------------------
649 | // base/macros.h
650 | // ----------------------------------------------------------------------
651 |
652 | // PHMAP_ARRAYSIZE()
653 | //
654 | // Returns the number of elements in an array as a compile-time constant, which
655 | // can be used in defining new arrays. If you use this macro on a pointer by
656 | // mistake, you will get a compile-time error.
657 | #define PHMAP_ARRAYSIZE(array) \
658 | (sizeof(::phmap::macros_internal::ArraySizeHelper(array)))
659 |
660 | namespace phmap {
661 | namespace macros_internal {
662 | // Note: this internal template function declaration is used by PHMAP_ARRAYSIZE.
663 | // The function doesn't need a definition, as we only use its type.
664 | template
665 | auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
666 | } // namespace macros_internal
667 | } // namespace phmap
668 |
669 | // TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported.
670 | #if defined(__clang__) && defined(__has_warning)
671 | #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
672 | #define PHMAP_FALLTHROUGH_INTENDED [[clang::fallthrough]]
673 | #endif
674 | #elif defined(__GNUC__) && __GNUC__ >= 7
675 | #define PHMAP_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
676 | #endif
677 |
678 | #ifndef PHMAP_FALLTHROUGH_INTENDED
679 | #define PHMAP_FALLTHROUGH_INTENDED \
680 | do { } while (0)
681 | #endif
682 |
683 | // PHMAP_DEPRECATED()
684 | //
685 | // Marks a deprecated class, struct, enum, function, method and variable
686 | // declarations. The macro argument is used as a custom diagnostic message (e.g.
687 | // suggestion of a better alternative).
688 | //
689 | // Example:
690 | //
691 | // class PHMAP_DEPRECATED("Use Bar instead") Foo {...};
692 | // PHMAP_DEPRECATED("Use Baz instead") void Bar() {...}
693 | //
694 | // Every usage of a deprecated entity will trigger a warning when compiled with
695 | // clang's `-Wdeprecated-declarations` option. This option is turned off by
696 | // default, but the warnings will be reported by clang-tidy.
697 | #if defined(__clang__) && __cplusplus >= 201103L
698 | #define PHMAP_DEPRECATED(message) __attribute__((deprecated(message)))
699 | #endif
700 |
701 | #ifndef PHMAP_DEPRECATED
702 | #define PHMAP_DEPRECATED(message)
703 | #endif
704 |
705 | // PHMAP_BAD_CALL_IF()
706 | //
707 | // Used on a function overload to trap bad calls: any call that matches the
708 | // overload will cause a compile-time error. This macro uses a clang-specific
709 | // "enable_if" attribute, as described at
710 | // http://clang.llvm.org/docs/AttributeReference.html#enable-if
711 | //
712 | // Overloads which use this macro should be bracketed by
713 | // `#ifdef PHMAP_BAD_CALL_IF`.
714 | //
715 | // Example:
716 | //
717 | // int isdigit(int c);
718 | // #ifdef PHMAP_BAD_CALL_IF
719 | // int isdigit(int c)
720 | // PHMAP_BAD_CALL_IF(c <= -1 || c > 255,
721 | // "'c' must have the value of an unsigned char or EOF");
722 | // #endif // PHMAP_BAD_CALL_IF
723 |
724 | #if defined(__clang__)
725 | #if __has_attribute(enable_if)
726 | #define PHMAP_BAD_CALL_IF(expr, msg) \
727 | __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
728 | #endif
729 | #endif
730 |
731 | // PHMAP_ASSERT()
732 | //
733 | // In C++11, `assert` can't be used portably within constexpr functions.
734 | // PHMAP_ASSERT functions as a runtime assert but works in C++11 constexpr
735 | // functions. Example:
736 | //
737 | // constexpr double Divide(double a, double b) {
738 | // return PHMAP_ASSERT(b != 0), a / b;
739 | // }
740 | //
741 | // This macro is inspired by
742 | // https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
743 | #if defined(NDEBUG)
744 | #define PHMAP_ASSERT(expr) (false ? (void)(expr) : (void)0)
745 | #else
746 | #define PHMAP_ASSERT(expr) \
747 | (PHMAP_PREDICT_TRUE((expr)) ? (void)0 \
748 | : [] { assert(false && #expr); }()) // NOLINT
749 | #endif
750 |
751 | #ifdef PHMAP_HAVE_EXCEPTIONS
752 | #define PHMAP_INTERNAL_TRY try
753 | #define PHMAP_INTERNAL_CATCH_ANY catch (...)
754 | #define PHMAP_INTERNAL_RETHROW do { throw; } while (false)
755 | #else // PHMAP_HAVE_EXCEPTIONS
756 | #define PHMAP_INTERNAL_TRY if (true)
757 | #define PHMAP_INTERNAL_CATCH_ANY else if (false)
758 | #define PHMAP_INTERNAL_RETHROW do {} while (false)
759 | #endif // PHMAP_HAVE_EXCEPTIONS
760 |
761 |
762 | #endif // phmap_config_h_guard_
763 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/phmap_dump.h:
--------------------------------------------------------------------------------
1 | #if !defined(phmap_dump_h_guard_)
2 | #define phmap_dump_h_guard_
3 |
4 | // ---------------------------------------------------------------------------
5 | // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6 | //
7 | // providing dump/load/mmap_load
8 | //
9 | // Licensed under the Apache License, Version 2.0 (the "License");
10 | // you may not use this file except in compliance with the License.
11 | // You may obtain a copy of the License at
12 | //
13 | // https://www.apache.org/licenses/LICENSE-2.0
14 | //
15 | // Unless required by applicable law or agreed to in writing, software
16 | // distributed under the License is distributed on an "AS IS" BASIS,
17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | // See the License for the specific language governing permissions and
19 | // limitations under the License.
20 | // ---------------------------------------------------------------------------
21 |
22 | #include
23 | #include
24 | #include
25 | #include "phmap.h"
26 | namespace phmap
27 | {
28 |
29 | namespace type_traits_internal {
30 |
31 | #if defined(__GLIBCXX__) && __GLIBCXX__ < 20150801
32 | template struct IsTriviallyCopyable : public std::integral_constant {};
33 | #else
34 | template struct IsTriviallyCopyable : public std::is_trivially_copyable {};
35 | #endif
36 |
37 | template
38 | struct IsTriviallyCopyable> {
39 | static constexpr bool value = IsTriviallyCopyable::value && IsTriviallyCopyable::value;
40 | };
41 | }
42 |
43 | namespace priv {
44 |
45 | #if !defined(PHMAP_NON_DETERMINISTIC) && !defined(PHMAP_DISABLE_DUMP)
46 |
47 | // ------------------------------------------------------------------------
48 | // dump/load for raw_hash_set
49 | // ------------------------------------------------------------------------
50 | template
51 | template
52 | bool raw_hash_set::phmap_dump(OutputArchive& ar) const {
53 | static_assert(type_traits_internal::IsTriviallyCopyable::value,
54 | "value_type should be trivially copyable");
55 |
56 | ar.saveBinary(&size_, sizeof(size_t));
57 | ar.saveBinary(&capacity_, sizeof(size_t));
58 | if (size_ == 0)
59 | return true;
60 | ar.saveBinary(ctrl_, sizeof(ctrl_t) * (capacity_ + Group::kWidth + 1));
61 | ar.saveBinary(slots_, sizeof(slot_type) * capacity_);
62 | return true;
63 | }
64 |
65 | template
66 | template
67 | bool raw_hash_set::phmap_load(InputArchive& ar) {
68 | static_assert(type_traits_internal::IsTriviallyCopyable::value,
69 | "value_type should be trivially copyable");
70 | raw_hash_set().swap(*this); // clear any existing content
71 | ar.loadBinary(&size_, sizeof(size_t));
72 | ar.loadBinary(&capacity_, sizeof(size_t));
73 |
74 | if (capacity_) {
75 | // allocate memory for ctrl_ and slots_
76 | initialize_slots(capacity_);
77 | }
78 | if (size_ == 0)
79 | return true;
80 | ar.loadBinary(ctrl_, sizeof(ctrl_t) * (capacity_ + Group::kWidth + 1));
81 | ar.loadBinary(slots_, sizeof(slot_type) * capacity_);
82 | return true;
83 | }
84 |
85 | // ------------------------------------------------------------------------
86 | // dump/load for parallel_hash_set
87 | // ------------------------------------------------------------------------
88 | template class RefSet,
90 | class Mtx_,
91 | class Policy, class Hash, class Eq, class Alloc>
92 | template
93 | bool parallel_hash_set::phmap_dump(OutputArchive& ar) const {
94 | static_assert(type_traits_internal::IsTriviallyCopyable::value,
95 | "value_type should be trivially copyable");
96 |
97 | size_t submap_count = subcnt();
98 | ar.saveBinary(&submap_count, sizeof(size_t));
99 | for (size_t i = 0; i < sets_.size(); ++i) {
100 | auto& inner = sets_[i];
101 | typename Lockable::UniqueLock m(const_cast(inner));
102 | if (!inner.set_.phmap_dump(ar)) {
103 | std::cerr << "Failed to dump submap " << i << std::endl;
104 | return false;
105 | }
106 | }
107 | return true;
108 | }
109 |
110 | template class RefSet,
112 | class Mtx_,
113 | class Policy, class Hash, class Eq, class Alloc>
114 | template
115 | bool parallel_hash_set::phmap_load(InputArchive& ar) {
116 | static_assert(type_traits_internal::IsTriviallyCopyable::value,
117 | "value_type should be trivially copyable");
118 |
119 | size_t submap_count = 0;
120 | ar.loadBinary(&submap_count, sizeof(size_t));
121 | if (submap_count != subcnt()) {
122 | std::cerr << "submap count(" << submap_count << ") != N(" << N << ")" << std::endl;
123 | return false;
124 | }
125 |
126 | for (size_t i = 0; i < submap_count; ++i) {
127 | auto& inner = sets_[i];
128 | typename Lockable::UniqueLock m(const_cast(inner));
129 | if (!inner.set_.phmap_load(ar)) {
130 | std::cerr << "Failed to load submap " << i << std::endl;
131 | return false;
132 | }
133 | }
134 | return true;
135 | }
136 |
137 | #endif // !defined(PHMAP_NON_DETERMINISTIC) && !defined(PHMAP_DISABLE_DUMP)
138 |
139 | } // namespace priv
140 |
141 |
142 |
143 | // ------------------------------------------------------------------------
144 | // BinaryArchive
145 | // File is closed when archive object is destroyed
146 | // ------------------------------------------------------------------------
147 |
148 | // ------------------------------------------------------------------------
149 | // ------------------------------------------------------------------------
150 | class BinaryOutputArchive {
151 | public:
152 | BinaryOutputArchive(const char *file_path) {
153 | ofs_.open(file_path, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
154 | }
155 |
156 | bool saveBinary(const void *p, size_t sz) {
157 | ofs_.write(reinterpret_cast(p), sz);
158 | return true;
159 | }
160 |
161 | template
162 | typename std::enable_if::value, bool>::type
163 | saveBinary(const V& v) {
164 | ofs_.write(reinterpret_cast(&v), sizeof(V));
165 | return true;
166 | }
167 |
168 | template
169 | auto saveBinary(const Map& v) -> decltype(v.phmap_dump(*this), bool())
170 | {
171 | return v.phmap_dump(*this);
172 | }
173 |
174 | private:
175 | std::ofstream ofs_;
176 | };
177 |
178 |
179 | class BinaryInputArchive {
180 | public:
181 | BinaryInputArchive(const char * file_path) {
182 | ifs_.open(file_path, std::ofstream::in | std::ofstream::binary);
183 | }
184 |
185 | bool loadBinary(void* p, size_t sz) {
186 | ifs_.read(reinterpret_cast(p), sz);
187 | return true;
188 | }
189 |
190 | template
191 | typename std::enable_if::value, bool>::type
192 | loadBinary(V* v) {
193 | ifs_.read(reinterpret_cast(v), sizeof(V));
194 | return true;
195 | }
196 |
197 | template
198 | auto loadBinary(Map* v) -> decltype(v->phmap_load(*this), bool())
199 | {
200 | return v->phmap_load(*this);
201 | }
202 |
203 | private:
204 | std::ifstream ifs_;
205 | };
206 |
207 | } // namespace phmap
208 |
209 |
210 | #ifdef CEREAL_SIZE_TYPE
211 |
212 | template
213 | using PhmapTrivCopyable = typename phmap::type_traits_internal::IsTriviallyCopyable;
214 |
215 | namespace cereal
216 | {
217 | // Overload Cereal serialization code for phmap::flat_hash_map
218 | // -----------------------------------------------------------
219 | template
220 | void save(typename std::enable_if::value && PhmapTrivCopyable::value, typename cereal::BinaryOutputArchive>::type &ar,
221 | phmap::flat_hash_map const &hmap)
222 | {
223 | hmap.phmap_dump(ar);
224 | }
225 |
226 | template
227 | void load(typename std::enable_if::value && PhmapTrivCopyable::value, typename cereal::BinaryInputArchive>::type &ar,
228 | phmap::flat_hash_map &hmap)
229 | {
230 | hmap.phmap_load(ar);
231 | }
232 |
233 |
234 | // Overload Cereal serialization code for phmap::parallel_flat_hash_map
235 | // --------------------------------------------------------------------
236 | template
237 | void save(typename std::enable_if::value && PhmapTrivCopyable::value, typename cereal::BinaryOutputArchive>::type &ar,
238 | phmap::parallel_flat_hash_map const &hmap)
239 | {
240 | hmap.phmap_dump(ar);
241 | }
242 |
243 | template
244 | void load(typename std::enable_if::value && PhmapTrivCopyable::value, typename cereal::BinaryInputArchive>::type &ar,
245 | phmap::parallel_flat_hash_map &hmap)
246 | {
247 | hmap.phmap_load(ar);
248 | }
249 |
250 | // Overload Cereal serialization code for phmap::flat_hash_set
251 | // -----------------------------------------------------------
252 | template
253 | void save(typename std::enable_if::value, typename cereal::BinaryOutputArchive>::type &ar,
254 | phmap::flat_hash_set const &hset)
255 | {
256 | hset.phmap_dump(ar);
257 | }
258 |
259 | template
260 | void load(typename std::enable_if::value, typename cereal::BinaryInputArchive>::type &ar,
261 | phmap::flat_hash_set &hset)
262 | {
263 | hset.phmap_load(ar);
264 | }
265 |
266 | // Overload Cereal serialization code for phmap::parallel_flat_hash_set
267 | // --------------------------------------------------------------------
268 | template
269 | void save(typename std::enable_if::value, typename cereal::BinaryOutputArchive>::type &ar,
270 | phmap::parallel_flat_hash_set const &hset)
271 | {
272 | hset.phmap_dump(ar);
273 | }
274 |
275 | template
276 | void load(typename std::enable_if::value, typename cereal::BinaryInputArchive>::type &ar,
277 | phmap::parallel_flat_hash_set &hset)
278 | {
279 | hset.phmap_load(ar);
280 | }
281 | }
282 |
283 | #endif
284 |
285 |
286 |
287 |
288 | #endif // phmap_dump_h_guard_
289 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/phmap_fwd_decl.h:
--------------------------------------------------------------------------------
1 | #if !defined(phmap_fwd_decl_h_guard_)
2 | #define phmap_fwd_decl_h_guard_
3 |
4 | // ---------------------------------------------------------------------------
5 | // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // https://www.apache.org/licenses/LICENSE-2.0
12 | // ---------------------------------------------------------------------------
13 |
14 | #ifdef _MSC_VER
15 | #pragma warning(push)
16 | #pragma warning(disable : 4514) // unreferenced inline function has been removed
17 | #pragma warning(disable : 4710) // function not inlined
18 | #pragma warning(disable : 4711) // selected for automatic inline expansion
19 | #endif
20 |
21 | #include
22 | #include
23 |
24 | #if defined(PHMAP_USE_ABSL_HASH) && !defined(ABSL_HASH_HASH_H_)
25 | namespace absl { template struct Hash; };
26 | #endif
27 |
28 | namespace phmap {
29 |
30 | #if defined(PHMAP_USE_ABSL_HASH)
31 | template using Hash = ::absl::Hash;
32 | #else
33 | template struct Hash;
34 | #endif
35 |
36 | template struct EqualTo;
37 | template struct Less;
38 | template using Allocator = typename std::allocator;
39 | template using Pair = typename std::pair;
40 |
41 | class NullMutex;
42 |
43 | namespace priv {
44 |
45 | // The hash of an object of type T is computed by using phmap::Hash.
46 | template
47 | struct HashEq
48 | {
49 | using Hash = phmap::Hash;
50 | using Eq = phmap::EqualTo;
51 | };
52 |
53 | template
54 | using hash_default_hash = typename priv::HashEq::Hash;
55 |
56 | template
57 | using hash_default_eq = typename priv::HashEq::Eq;
58 |
59 | // type alias for std::allocator so we can forward declare without including other headers
60 | template
61 | using Allocator = typename phmap::Allocator;
62 |
63 | // type alias for std::pair so we can forward declare without including other headers
64 | template
65 | using Pair = typename phmap::Pair;
66 |
67 | } // namespace priv
68 |
69 | // ------------- forward declarations for hash containers ----------------------------------
70 | template ,
72 | class Eq = phmap::priv::hash_default_eq,
73 | class Alloc = phmap::priv::Allocator> // alias for std::allocator
74 | class flat_hash_set;
75 |
76 | template ,
78 | class Eq = phmap::priv::hash_default_eq,
79 | class Alloc = phmap::priv::Allocator<
80 | phmap::priv::Pair>> // alias for std::allocator
81 | class flat_hash_map;
82 |
83 | template ,
85 | class Eq = phmap::priv::hash_default_eq,
86 | class Alloc = phmap::priv::Allocator> // alias for std::allocator
87 | class node_hash_set;
88 |
89 | template ,
91 | class Eq = phmap::priv::hash_default_eq,
92 | class Alloc = phmap::priv::Allocator<
93 | phmap::priv::Pair>> // alias for std::allocator
94 | class node_hash_map;
95 |
96 | template ,
98 | class Eq = phmap::priv::hash_default_eq,
99 | class Alloc = phmap::priv::Allocator, // alias for std::allocator
100 | size_t N = 4, // 2**N submaps
101 | class Mutex = phmap::NullMutex> // use std::mutex to enable internal locks
102 | class parallel_flat_hash_set;
103 |
104 | template ,
106 | class Eq = phmap::priv::hash_default_eq,
107 | class Alloc = phmap::priv::Allocator<
108 | phmap::priv::Pair>, // alias for std::allocator
109 | size_t N = 4, // 2**N submaps
110 | class Mutex = phmap::NullMutex> // use std::mutex to enable internal locks
111 | class parallel_flat_hash_map;
112 |
113 | template ,
115 | class Eq = phmap::priv::hash_default_eq,
116 | class Alloc = phmap::priv::Allocator, // alias for std::allocator
117 | size_t N = 4, // 2**N submaps
118 | class Mutex = phmap::NullMutex> // use std::mutex to enable internal locks
119 | class parallel_node_hash_set;
120 |
121 | template ,
123 | class Eq = phmap::priv::hash_default_eq,
124 | class Alloc = phmap::priv::Allocator<
125 | phmap::priv::Pair>, // alias for std::allocator
126 | size_t N = 4, // 2**N submaps
127 | class Mutex = phmap::NullMutex> // use std::mutex to enable internal locks
128 | class parallel_node_hash_map;
129 |
130 | // ------------- forward declarations for btree containers ----------------------------------
131 | template ,
132 | typename Alloc = phmap::Allocator>
133 | class btree_set;
134 |
135 | template ,
136 | typename Alloc = phmap::Allocator>
137 | class btree_multiset;
138 |
139 | template ,
140 | typename Alloc = phmap::Allocator>>
141 | class btree_map;
142 |
143 | template ,
144 | typename Alloc = phmap::Allocator>>
145 | class btree_multimap;
146 |
147 | } // namespace phmap
148 |
149 |
150 | #ifdef _MSC_VER
151 | #pragma warning(pop)
152 | #endif
153 |
154 | #endif // phmap_fwd_decl_h_guard_
155 |
--------------------------------------------------------------------------------
/FortKitInsider/parallel_hashmap/phmap_utils.h:
--------------------------------------------------------------------------------
1 | #if !defined(phmap_utils_h_guard_)
2 | #define phmap_utils_h_guard_
3 |
4 | // ---------------------------------------------------------------------------
5 | // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6 | //
7 | // minimal header providing phmap::HashState
8 | //
9 | // use as: phmap::HashState().combine(0, _first_name, _last_name, _age);
10 | //
11 | // Licensed under the Apache License, Version 2.0 (the "License");
12 | // you may not use this file except in compliance with the License.
13 | // You may obtain a copy of the License at
14 | //
15 | // https://www.apache.org/licenses/LICENSE-2.0
16 | //
17 | // Unless required by applicable law or agreed to in writing, software
18 | // distributed under the License is distributed on an "AS IS" BASIS,
19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | // See the License for the specific language governing permissions and
21 | // limitations under the License.
22 | // ---------------------------------------------------------------------------
23 |
24 | #ifdef _MSC_VER
25 | #pragma warning(push)
26 | #pragma warning(disable : 4514) // unreferenced inline function has been removed
27 | #pragma warning(disable : 4710) // function not inlined
28 | #pragma warning(disable : 4711) // selected for automatic inline expansion
29 | #endif
30 |
31 | #include
32 | #include
33 | #include
34 | #include "phmap_bits.h"
35 |
36 | // ---------------------------------------------------------------
37 | // Absl forward declaration requires global scope.
38 | // ---------------------------------------------------------------
39 | #if defined(PHMAP_USE_ABSL_HASH) && !defined(phmap_fwd_decl_h_guard_) && !defined(ABSL_HASH_HASH_H_)
40 | namespace absl { template struct Hash; };
41 | #endif
42 |
43 | namespace phmap
44 | {
45 |
46 | // ---------------------------------------------------------------
47 | // ---------------------------------------------------------------
48 | template
49 | struct phmap_mix
50 | {
51 | inline size_t operator()(size_t) const;
52 | };
53 |
54 | template<>
55 | struct phmap_mix<4>
56 | {
57 | inline size_t operator()(size_t a) const
58 | {
59 | static constexpr uint64_t kmul = 0xcc9e2d51UL;
60 | // static constexpr uint64_t kmul = 0x3B9ACB93UL; // [greg] my own random prime
61 | uint64_t l = a * kmul;
62 | return static_cast(l ^ (l >> 32));
63 | }
64 | };
65 |
66 | #if defined(PHMAP_HAS_UMUL128)
67 | template<>
68 | struct phmap_mix<8>
69 | {
70 | // Very fast mixing (similar to Abseil)
71 | inline size_t operator()(size_t a) const
72 | {
73 | static constexpr uint64_t k = 0xde5fb9d2630458e9ULL;
74 | // static constexpr uint64_t k = 0x7C9D0BF0567102A5ULL; // [greg] my own random prime
75 | uint64_t h;
76 | uint64_t l = umul128(a, k, &h);
77 | return static_cast(h + l);
78 | }
79 | };
80 | #else
81 | template<>
82 | struct phmap_mix<8>
83 | {
84 | inline size_t operator()(size_t a) const
85 | {
86 | a = (~a) + (a << 21); // a = (a << 21) - a - 1;
87 | a = a ^ (a >> 24);
88 | a = (a + (a << 3)) + (a << 8); // a * 265
89 | a = a ^ (a >> 14);
90 | a = (a + (a << 2)) + (a << 4); // a * 21
91 | a = a ^ (a >> 28);
92 | a = a + (a << 31);
93 | return static_cast(a);
94 | }
95 | };
96 | #endif
97 |
98 | // --------------------------------------------
99 | template
100 | struct fold_if_needed
101 | {
102 | inline size_t operator()(uint64_t) const;
103 | };
104 |
105 | template<>
106 | struct fold_if_needed<4>
107 | {
108 | inline size_t operator()(uint64_t a) const
109 | {
110 | return static_cast(a ^ (a >> 32));
111 | }
112 | };
113 |
114 | template<>
115 | struct fold_if_needed<8>
116 | {
117 | inline size_t operator()(uint64_t a) const
118 | {
119 | return static_cast(a);
120 | }
121 | };
122 |
123 | // ---------------------------------------------------------------
124 | // see if class T has a hash_value() friend method
125 | // ---------------------------------------------------------------
126 | template
127 | struct has_hash_value
128 | {
129 | private:
130 | typedef std::true_type yes;
131 | typedef std::false_type no;
132 |
133 | template static auto test(int) -> decltype(hash_value(std::declval