Merge pull request #218 from Arkshine/feature/amtl-upstream
Use upstream AMTL as a submodule
This commit is contained in:
commit
dcae6a8a20
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "public/amtl"]
|
||||||
|
path = public/amtl
|
||||||
|
url = https://github.com/alliedmodders/amtl
|
|
@ -266,7 +266,7 @@ class AMXXConfig(object):
|
||||||
|
|
||||||
cfg.includes += [os.path.join(builder.sourcePath, 'public')]
|
cfg.includes += [os.path.join(builder.sourcePath, 'public')]
|
||||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'sdk')]
|
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'sdk')]
|
||||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'amtl')]
|
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'amtl', 'include')]
|
||||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'memtools')]
|
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'memtools')]
|
||||||
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'hashing')]
|
cfg.includes += [os.path.join(builder.sourcePath, 'public', 'hashing')]
|
||||||
return
|
return
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\hashing;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\hashing;..\..\public\sdk;..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\public\sdk;..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HAVE_STDINT_H;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;HAVE_STDINT_H;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
|
|
18
appveyor.yml
Normal file
18
appveyor.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
version: 1.0.{build}
|
||||||
|
clone_folder: c:\projects\amxmodx
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- 'c:'
|
||||||
|
- chdir c:\projects
|
||||||
|
- git clone https://github.com/alliedmodders/ambuild
|
||||||
|
- git clone https://github.com/alliedmodders/metamod-hl1
|
||||||
|
- git clone https://github.com/alliedmodders/hlsdk
|
||||||
|
- cd ambuild
|
||||||
|
- c:\python27\python setup.py install
|
||||||
|
- cd ..\amxmodx
|
||||||
|
build_script:
|
||||||
|
- '"%VS120COMNTOOLS%\vsvars32.bat"'
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- c:\python27\python ../configure.py --enable-optimize --no-mysql
|
||||||
|
- c:\python27\scripts\ambuild
|
|
@ -64,7 +64,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -146,6 +146,7 @@
|
||||||
<ClCompile Include="..\..\..\..\public\memtools\MemoryUtils.cpp" />
|
<ClCompile Include="..\..\..\..\public\memtools\MemoryUtils.cpp" />
|
||||||
<ClCompile Include="..\amxx_api.cpp" />
|
<ClCompile Include="..\amxx_api.cpp" />
|
||||||
<ClCompile Include="..\CstrikeHacks.cpp" />
|
<ClCompile Include="..\CstrikeHacks.cpp" />
|
||||||
|
<ClCompile Include="..\CstrikeHLTypeConversion.cpp" />
|
||||||
<ClCompile Include="..\CstrikeNatives.cpp" />
|
<ClCompile Include="..\CstrikeNatives.cpp" />
|
||||||
<ClCompile Include="..\CstrikePlayer.cpp" />
|
<ClCompile Include="..\CstrikePlayer.cpp" />
|
||||||
<ClCompile Include="..\CstrikeUtils.cpp" />
|
<ClCompile Include="..\CstrikeUtils.cpp" />
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
<ClCompile Include="..\..\..\..\public\sdk\amxxmodule.cpp">
|
<ClCompile Include="..\..\..\..\public\sdk\amxxmodule.cpp">
|
||||||
<Filter>Module SDK\SDK Base</Filter>
|
<Filter>Module SDK\SDK Base</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\CstrikeHLTypeConversion.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\CstrikePlayer.h">
|
<ClInclude Include="..\CstrikePlayer.h">
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\..\public;..\..\..\..\..\public\sdk; ..\..\..\..\..\public\amtl;..\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\..\public;..\..\..\..\..\public\sdk; ..\..\..\..\..\public\amtl\include;..\..\public\hashing;..\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\..\public;..\..\..\..\..\public\sdk; ..\..\..\..\..\public\amtl;..\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\..\public;..\..\..\..\..\public\sdk; ..\..\..\..\..\public\amtl\include;..\..\public\hashing;..\resources;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;JIT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;JIT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>dodfun_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>dodfun_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;dodfun_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;dodfun_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>dodx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>dodx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;dodx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;dodx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\sdk;..\..\..\public;..\..\..\public\amtl;..\..\..\public\sdk;..\GeoIP2;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\sdk;..\..\..\public;..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\public\sdk;..\GeoIP2;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\sdk;..\..\..\public;..\..\..\public\amtl;..\..\..\public\sdk;..\GeoIP2;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\sdk;..\..\..\public;..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\public\sdk;..\GeoIP2;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;GEOIP_EXPORTS;HAVE_STDINT_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HAMSANDWICH_EXPORTS; HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HAMSANDWICH_EXPORTS; HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAMSANDWICH_EXPORTS; HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAMSANDWICH_EXPORTS; HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;NDEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;NDEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;_DEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;_DEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;NVAULT_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SOCKETS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalOptions>/D "NO_TCL" %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/D "NO_TCL" %(AdditionalOptions)</AdditionalOptions>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;..\sqlite-source;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;..\sqlite-source;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;..\sqlite-source;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;..\sqlite-source;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;tfcx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;tfcx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;tfcx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;tfcx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TSFUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TSFUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TSFUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TSFUN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;tsx_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;tsx_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\;..\..\..\..\public;..\..\..\..\public\sdk; ..\..\..\..\public\amtl\include;..\..\public\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>tsx_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>tsx_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|
1
public/amtl
Submodule
1
public/amtl
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1bb5196ce39ff3ed59445e51f9223734d4bcf886
|
|
@ -1,58 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013-2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _include_amtl_algorithm_h_
|
|
||||||
#define _include_amtl_algorithm_h_
|
|
||||||
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T> static inline T
|
|
||||||
Min(const T &t1, const T &t2)
|
|
||||||
{
|
|
||||||
return t1 < t2 ? t1 : t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline T
|
|
||||||
Max(const T &t1, const T &t2)
|
|
||||||
{
|
|
||||||
return t1 > t2 ? t1 : t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline void
|
|
||||||
Swap(T &left, T &right)
|
|
||||||
{
|
|
||||||
T tmp(Move(left));
|
|
||||||
left = Move(right);
|
|
||||||
right = Move(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_algorithm_h_
|
|
|
@ -1,65 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_allocatorpolicies_h_
|
|
||||||
#define _include_amtl_allocatorpolicies_h_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// The default system allocator policy will crash on out-of-memory.
|
|
||||||
class SystemAllocatorPolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void reportOutOfMemory() {
|
|
||||||
fprintf(stderr, "OUT OF MEMORY\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
void reportAllocationOverflow() {
|
|
||||||
fprintf(stderr, "OUT OF MEMORY\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void free(void *memory) {
|
|
||||||
::free(memory);
|
|
||||||
}
|
|
||||||
void *malloc(size_t bytes) {
|
|
||||||
void *ptr = ::malloc(bytes);
|
|
||||||
if (!ptr)
|
|
||||||
reportOutOfMemory();
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_allocatorpolicies_h_
|
|
|
@ -1,67 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013-2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _include_amtl_bits_h_
|
|
||||||
#define _include_amtl_bits_h_
|
|
||||||
|
|
||||||
#include <am-algorithm.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
TryUint64Multiply(uint64_t left, uint64_t right, uint64_t *out)
|
|
||||||
{
|
|
||||||
uint64_t r = left * right;
|
|
||||||
if (r != 0 && ((r / left) != right))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*out = r;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
TryUint32Add(uint32_t left, uint32_t right, uint32_t *out)
|
|
||||||
{
|
|
||||||
if (left + right < Max(left, right))
|
|
||||||
return false;
|
|
||||||
*out = left + right;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
TryUint64Add(uint64_t left, uint64_t right, uint64_t *out)
|
|
||||||
{
|
|
||||||
if (left + right < Max(left, right))
|
|
||||||
return false;
|
|
||||||
*out = left + right;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_bits_h_
|
|
|
@ -1,189 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_atomics_h_
|
|
||||||
#define _include_amtl_atomics_h_
|
|
||||||
|
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
extern "C" {
|
|
||||||
long __cdecl _InterlockedIncrement(long volatile *dest);
|
|
||||||
long __cdecl _InterlockedDecrement(long volatile *dest);
|
|
||||||
long long __cdecl _InterlockedIncrement64(long long volatile *dest);
|
|
||||||
long long __cdecl _InterlockedDecrement64(long long volatile *dest);
|
|
||||||
long __cdecl _InterlockedCompareExchange(long volatile *dest, long exchange, long comparand);
|
|
||||||
# if _MSC_VER > 1600 || (_MSC_VER == 1600 && !defined(_M_IX86))
|
|
||||||
void * __cdecl _InterlockedCompareExchangePointer(
|
|
||||||
void * volatile *Destination,
|
|
||||||
void * Exchange,
|
|
||||||
void * Comparand
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
static inline void * _InterlockedCompareExchangePointer(
|
|
||||||
void * volatile *Destination,
|
|
||||||
void * Exchange,
|
|
||||||
void * Comparand)
|
|
||||||
{
|
|
||||||
return (void *)_InterlockedCompareExchange((long volatile *)Destination, (long)Exchange, (long)Comparand);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
# pragma intrinsic(_InterlockedIncrement)
|
|
||||||
# pragma intrinsic(_InterlockedDecrement)
|
|
||||||
# pragma intrinsic(_InterlockedCompareExchange)
|
|
||||||
# if _MSC_VER > 1600 || (_MSC_VER == 1600 && !defined(_M_IX86))
|
|
||||||
# pragma intrinsic(_InterlockedCompareExchangePointer)
|
|
||||||
# endif
|
|
||||||
# if defined(_WIN64)
|
|
||||||
# pragma intrinsic(_InterlockedIncrement64)
|
|
||||||
# pragma intrinsic(_InterlockedDecrement64)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# if defined(i386) || defined(__x86_64__)
|
|
||||||
# if defined(__clang__)
|
|
||||||
static inline void YieldProcessor() { asm("pause"); }
|
|
||||||
# else
|
|
||||||
# if KE_GCC_AT_LEAST(4, 7)
|
|
||||||
# define YieldProcessor() __builtin_ia32_pause()
|
|
||||||
# else
|
|
||||||
static inline void YieldProcessor() { asm("pause"); }
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define YieldProcessor()
|
|
||||||
# endif
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# if !defined(YieldProcessor)
|
|
||||||
# define YieldProcessor _mm_pause
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
static inline void *
|
|
||||||
CompareAndSwapPtr(void *volatile *Destination, void *Exchange, void *Comparand)
|
|
||||||
{
|
|
||||||
return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline void *
|
|
||||||
CompareAndSwapPtr(void *volatile *dest, void *newval, void *oldval)
|
|
||||||
{
|
|
||||||
return __sync_val_compare_and_swap(dest, oldval, newval);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <size_t Width>
|
|
||||||
struct AtomicOps;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct AtomicOps<4>
|
|
||||||
{
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
typedef volatile long Type;
|
|
||||||
|
|
||||||
static Type Increment(Type *ptr) {
|
|
||||||
return _InterlockedIncrement(ptr);
|
|
||||||
}
|
|
||||||
static Type Decrement(Type *ptr) {
|
|
||||||
return _InterlockedDecrement(ptr);
|
|
||||||
};
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
typedef volatile int Type;
|
|
||||||
|
|
||||||
// x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock.
|
|
||||||
// On 4.8+, or when using Clang, we'll get the more optimal "lock addl"
|
|
||||||
// variant.
|
|
||||||
static Type Increment(Type *ptr) {
|
|
||||||
return __sync_add_and_fetch(ptr, 1);
|
|
||||||
}
|
|
||||||
static Type Decrement(Type *ptr) {
|
|
||||||
return __sync_sub_and_fetch(ptr, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct AtomicOps<8>
|
|
||||||
{
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
typedef volatile long long Type;
|
|
||||||
|
|
||||||
static Type Increment(Type *ptr) {
|
|
||||||
return _InterlockedIncrement64(ptr);
|
|
||||||
}
|
|
||||||
static Type Decrement(Type *ptr) {
|
|
||||||
return _InterlockedDecrement64(ptr);
|
|
||||||
};
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
typedef volatile int64_t Type;
|
|
||||||
|
|
||||||
// x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock.
|
|
||||||
// On 4.8+, or when using Clang, we'll get the more optimal "lock addl"
|
|
||||||
// variant.
|
|
||||||
static Type Increment(Type *ptr) {
|
|
||||||
return __sync_add_and_fetch(ptr, 1);
|
|
||||||
}
|
|
||||||
static Type Decrement(Type *ptr) {
|
|
||||||
return __sync_sub_and_fetch(ptr, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class KE_LINK AtomicRefcount
|
|
||||||
{
|
|
||||||
typedef AtomicOps<sizeof(uintptr_t)> Ops;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AtomicRefcount(uintptr_t value)
|
|
||||||
: value_(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment() {
|
|
||||||
Ops::Increment(&value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return false if all references are gone.
|
|
||||||
bool decrement() {
|
|
||||||
return Ops::Decrement(&value_) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ops::Type value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_atomics_h_
|
|
||||||
|
|
|
@ -1,213 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _include_amtl_cxx_support_h_
|
|
||||||
#define _include_amtl_cxx_support_h_
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
# if !(defined(__clang_major__) && defined(__clang_minor__))
|
|
||||||
# define KE_CLANG_MAJOR 1
|
|
||||||
# define KE_CLANG_MINOR __GNUC_MINOR__
|
|
||||||
# else
|
|
||||||
# if defined(__apple_build_version__) && clang_major__ > 3
|
|
||||||
// 4.0 => 3.1, 4.1 => 3.2
|
|
||||||
# if __clang_major__ == 4
|
|
||||||
# define KE_CLANG_MAJOR 3
|
|
||||||
# if __clang_minor__ == 0
|
|
||||||
# define KE_CLANG_MINOR 1
|
|
||||||
# else
|
|
||||||
# define KE_CLANG_MINOR 2
|
|
||||||
# endif
|
|
||||||
// 5.0 => 3.3, 5.1 => 3.4
|
|
||||||
# elif __clang_major__ == 5
|
|
||||||
# define KE_CLANG_MAJOR 3
|
|
||||||
# if __clang_minor__ == 0
|
|
||||||
# define KE_CLANG_MINOR 3
|
|
||||||
# else
|
|
||||||
# define KE_CLANG_MINOR 4
|
|
||||||
# endif
|
|
||||||
# elif __clang_major__ == 6
|
|
||||||
# define KE_CLANG_MAJOR 3
|
|
||||||
# define KE_CLANG_MINOR 5
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if !defined(KE_CLANG_MAJOR)
|
|
||||||
# define KE_CLANG_MAJOR __clang_major__
|
|
||||||
# endif
|
|
||||||
# if !defined(KE_CLANG_MINOR)
|
|
||||||
# define KE_CLANG_MINOR __clang_minor__
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Done with horrible clang version detection.
|
|
||||||
# define KE_CLANG_AT_LEAST(x, y) \
|
|
||||||
((__clang_major__ > (x)) || (__clang_major__ == x && __clang_minor__ >= y))
|
|
||||||
|
|
||||||
# if KE_CLANG_AT_LEAST(2, 9)
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 30
|
|
||||||
# define KE_CXX_HAS_DELETE
|
|
||||||
# define KE_CXX_HAS_STATIC_ASSERT
|
|
||||||
# define KE_CXX_HAS_DOUBLE_GT
|
|
||||||
# define KE_CXX_HAS_ENUM_CLASS
|
|
||||||
# endif
|
|
||||||
# if KE_CLANG_AT_LEAST(3, 0)
|
|
||||||
# define KE_CXX_HAS_OVERRIDE
|
|
||||||
# define KE_CXX_HAS_EXPLICIT_BOOL
|
|
||||||
# define KE_CXX_HAS_NULLPTR
|
|
||||||
# define KE_CXX_HAS_NOEXCEPT
|
|
||||||
# endif
|
|
||||||
# if KE_CLANG_AT_LEAST(3, 1)
|
|
||||||
# define KE_CXX_HAS_CONSTEXPR
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define KE_GCC_AT_LEAST(x, y) ((__GNUC__ > (x)) || (__GNUC__ == x && __GNUC_MINOR__ >= y))
|
|
||||||
|
|
||||||
# if KE_GCC_AT_LEAST(4, 3)
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 10
|
|
||||||
# define KE_CXX_HAS_STATIC_ASSERT
|
|
||||||
# define KE_CXX_HAS_DOUBLE_GT
|
|
||||||
# endif
|
|
||||||
# if KE_GCC_AT_LEAST(4, 4)
|
|
||||||
# define KE_CXX_HAS_DELETE
|
|
||||||
# define KE_CXX_HAS_ENUM_CLASS
|
|
||||||
# endif
|
|
||||||
# if KE_GCC_AT_LEAST(4, 5)
|
|
||||||
# define KE_CXX_HAS_EXPLICIT_BOOL
|
|
||||||
# undef KE_CXX_HAS_RVAL_REFS
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 21
|
|
||||||
# endif
|
|
||||||
# if KE_GCC_AT_LEAST(4, 6)
|
|
||||||
# define KE_CXX_HAS_NULLPTR
|
|
||||||
# define KE_CXX_HAS_NOEXCEPT
|
|
||||||
# define KE_CXX_HAS_CONSTEXPR
|
|
||||||
# undef KE_CXX_HAS_RVAL_REFS
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 30
|
|
||||||
# endif
|
|
||||||
# if KE_GCC_AT_LEAST(4, 7)
|
|
||||||
# define KE_CXX_HAS_OVERRIDE
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# if _MSC_VER >= 1600
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 20
|
|
||||||
# define KE_CXX_HAS_STATIC_ASSERT
|
|
||||||
# define KE_CXX_HAS_DOUBLE_GT
|
|
||||||
# define KE_CXX_HAS_NULLPTR
|
|
||||||
# endif
|
|
||||||
# if _MSC_VER >= 1700
|
|
||||||
# undef KE_CXX_HAS_RVAL_REFS
|
|
||||||
# define KE_CXX_HAS_RVAL_REFS 21
|
|
||||||
# define KE_CXX_HAS_OVERRIDE
|
|
||||||
# define KE_CXX_HAS_ENUM_CLASS
|
|
||||||
# endif
|
|
||||||
# if _MSC_VER >= 1800
|
|
||||||
# define KE_CXX_HAS_DELETE
|
|
||||||
# define KE_CXX_HAS_EXPLICIT_BOOL
|
|
||||||
# endif
|
|
||||||
# if _MSC_VER == 1800 && _MSC_FULL_VER == 180021114
|
|
||||||
# define KE_CXX_HAS_CONSTEXPR
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# error Unrecognized compiler.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Done with compiler feature detection.
|
|
||||||
|
|
||||||
#if defined(KE_CXX_HAS_OVERRIDE)
|
|
||||||
# define KE_OVERRIDE override
|
|
||||||
#else
|
|
||||||
# define KE_OVERRIDE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_CXX_HAS_DELETE)
|
|
||||||
# define KE_DELETE = delete
|
|
||||||
#else
|
|
||||||
# define KE_DELETE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_CXX_HAS_NOEXCEPT)
|
|
||||||
# define KE_NOEXCEPT noexcept
|
|
||||||
#else
|
|
||||||
# define KE_NOEXCEPT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_CXX_HAS_CONSTEXPR)
|
|
||||||
# define KE_CONSTEXPR constexpr
|
|
||||||
#else
|
|
||||||
# define KE_CONSTEXPR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_CXX_HAS_STATIC_ASSERT)
|
|
||||||
# define KE_STATIC_ASSERT(cond) static_assert(cond, #cond)
|
|
||||||
#else
|
|
||||||
# define KE_STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(KE_CXX_HAS_RVAL_REFS) || KE_CXX_HAS_RVAL_REFS < 21
|
|
||||||
//# error AMTL requires rvalue reference 2.1 support (N2844+)
|
|
||||||
#endif
|
|
||||||
#if !defined(KE_CXX_HAS_DOUBLE_GT)
|
|
||||||
# error AMTL requires support for >> in template names
|
|
||||||
#endif
|
|
||||||
#if !defined(KE_CXX_HAS_NULLPTR)
|
|
||||||
# if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
# define nullptr __null
|
|
||||||
# define KE_CXX_HAS_NULLPTR
|
|
||||||
# else
|
|
||||||
# error AMTL requires nullptr support
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KE_DEFINE_ENUM_OPERATORS(EnumName) \
|
|
||||||
static inline EnumName operator |(const EnumName &left, const EnumName &right) { \
|
|
||||||
return EnumName(uint32_t(left) | uint32_t(right)); \
|
|
||||||
} \
|
|
||||||
static inline EnumName operator &(const EnumName &left, const EnumName &right) { \
|
|
||||||
return EnumName(uint32_t(left) & uint32_t(right)); \
|
|
||||||
} \
|
|
||||||
static inline EnumName operator ^(const EnumName &left, const EnumName &right) { \
|
|
||||||
return EnumName(uint32_t(left) ^ uint32_t(right)); \
|
|
||||||
} \
|
|
||||||
static inline EnumName operator ~(const EnumName &flags) { \
|
|
||||||
return EnumName(~uint32_t(flags)); \
|
|
||||||
} \
|
|
||||||
static inline EnumName & operator |=(EnumName &left, const EnumName &right) { \
|
|
||||||
return left = left | right; \
|
|
||||||
} \
|
|
||||||
static inline EnumName & operator &=(EnumName &left, const EnumName &right) { \
|
|
||||||
return left = left & right; \
|
|
||||||
} \
|
|
||||||
static inline EnumName & operator ^=(EnumName &left, const EnumName &right) { \
|
|
||||||
return left = left ^ right; \
|
|
||||||
} \
|
|
||||||
static inline bool operator !(const EnumName &obj) { \
|
|
||||||
return uint32_t(obj) == 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_cxx_support_h_
|
|
|
@ -1,260 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _INCLUDE_KEIMA_TPL_CPP_DEQUE_H_
|
|
||||||
#define _INCLUDE_KEIMA_TPL_CPP_DEQUE_H_
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <am-cxx.h>
|
|
||||||
#include <am-allocator-policies.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class Deque : public AllocPolicy
|
|
||||||
{
|
|
||||||
static const size_t kInvalidIndex = ~size_t(0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Deque(AllocPolicy = AllocPolicy())
|
|
||||||
: buffer_(NULL),
|
|
||||||
maxlength_(0),
|
|
||||||
first_(0),
|
|
||||||
last_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Deque(Deque &&other)
|
|
||||||
: buffer_(other.buffer_),
|
|
||||||
maxlength_(other.maxlength_),
|
|
||||||
first_(other.first_),
|
|
||||||
last_(other.last_)
|
|
||||||
{
|
|
||||||
other.reset();
|
|
||||||
}
|
|
||||||
~Deque() {
|
|
||||||
zap();
|
|
||||||
}
|
|
||||||
|
|
||||||
Deque &operator =(Deque &&other) {
|
|
||||||
zap();
|
|
||||||
buffer_ = other.buffer_;
|
|
||||||
maxlength_ = other.maxlength_;
|
|
||||||
first_ = other.first_;
|
|
||||||
last_ = other.last_;
|
|
||||||
other.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return first_ == last_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool append(U &&other) {
|
|
||||||
size_t next = ensureCanAppend();
|
|
||||||
if (next == kInvalidIndex)
|
|
||||||
return false;
|
|
||||||
new (&buffer_[last_]) T(ke::Forward<U>(other));
|
|
||||||
last_ = next;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool prepend(U &&other) {
|
|
||||||
size_t prev = ensureCanPrepend();
|
|
||||||
if (prev == kInvalidIndex)
|
|
||||||
return false;
|
|
||||||
first_ = prev;
|
|
||||||
new (&buffer_[first_]) T(ke::Forward<U>(other));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void popFront() {
|
|
||||||
assert(!empty());
|
|
||||||
buffer_[first_].~T();
|
|
||||||
if (first_ == maxlength_ - 1)
|
|
||||||
first_ = 0;
|
|
||||||
else
|
|
||||||
first_++;
|
|
||||||
}
|
|
||||||
void popBack() {
|
|
||||||
assert(!empty());
|
|
||||||
if (last_ == 0)
|
|
||||||
last_ = maxlength_ - 1;
|
|
||||||
else
|
|
||||||
last_--;
|
|
||||||
buffer_[last_].~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
T popFrontCopy() {
|
|
||||||
T t = front();
|
|
||||||
popFront();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
T popBackCopy() {
|
|
||||||
T t = back();
|
|
||||||
popBack();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T &front() const {
|
|
||||||
assert(!empty());
|
|
||||||
return buffer_[first_];
|
|
||||||
}
|
|
||||||
T &front() {
|
|
||||||
assert(!empty());
|
|
||||||
return buffer_[first_];
|
|
||||||
}
|
|
||||||
const T &back() const {
|
|
||||||
assert(!empty());
|
|
||||||
if (last_ == 0)
|
|
||||||
return buffer_[maxlength_ - 1];
|
|
||||||
return buffer_[last_ - 1];
|
|
||||||
}
|
|
||||||
T &back() {
|
|
||||||
assert(!empty());
|
|
||||||
if (last_ == 0)
|
|
||||||
return buffer_[maxlength_ - 1];
|
|
||||||
return buffer_[last_ - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t length() const {
|
|
||||||
if (first_ == last_)
|
|
||||||
return 0;
|
|
||||||
return first_ < last_
|
|
||||||
? (last_ - first_)
|
|
||||||
: (last_ + (maxlength_ - first_));
|
|
||||||
}
|
|
||||||
size_t capacity() const {
|
|
||||||
return maxlength_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Deque(const Deque<T> &other) KE_DELETE;
|
|
||||||
Deque &operator =(const Deque<T> &other) KE_DELETE;
|
|
||||||
|
|
||||||
// Return the next value of first_.
|
|
||||||
size_t ensureCanPrepend() {
|
|
||||||
if (first_ == 0) {
|
|
||||||
if (maxlength_ && (last_ != maxlength_ - 1))
|
|
||||||
return maxlength_ - 1;
|
|
||||||
} else if (first_ - 1 != last_) {
|
|
||||||
return first_ - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ring is full.
|
|
||||||
if (!growByOne())
|
|
||||||
return kInvalidIndex;
|
|
||||||
return maxlength_ - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the next value of last_.
|
|
||||||
size_t ensureCanAppend() {
|
|
||||||
if (last_ < first_) {
|
|
||||||
if (last_ + 1 != first_)
|
|
||||||
return last_ + 1;
|
|
||||||
} else{
|
|
||||||
if (last_ + 1 < maxlength_)
|
|
||||||
return last_ + 1;
|
|
||||||
if (first_ != 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ring is full.
|
|
||||||
if (!growByOne())
|
|
||||||
return kInvalidIndex;
|
|
||||||
return last_ + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool growByOne() {
|
|
||||||
if (!IsUintPtrMultiplySafe(maxlength_, 2)) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t new_maxlength = maxlength_ ? maxlength_ * 2 : 8;
|
|
||||||
T *new_buffer = (T *)this->malloc(sizeof(T) * new_maxlength);
|
|
||||||
if (!new_buffer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Move everything to the bottom of the new buffer, and reset our indices
|
|
||||||
// so that first is at 0.
|
|
||||||
if (first_ < last_) {
|
|
||||||
MoveRange(new_buffer, buffer_ + first_, last_ - first_);
|
|
||||||
last_ = last_ - first_;
|
|
||||||
first_ = 0;
|
|
||||||
} else {
|
|
||||||
MoveRange(new_buffer, buffer_ + first_, maxlength_ - first_);
|
|
||||||
MoveRange(new_buffer + (maxlength_ - first_), buffer_, last_);
|
|
||||||
last_ = last_ + (maxlength_ - first_);
|
|
||||||
first_ = 0;
|
|
||||||
}
|
|
||||||
this->free(buffer_);
|
|
||||||
|
|
||||||
buffer_ = new_buffer;
|
|
||||||
maxlength_ = new_maxlength;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
buffer_ = NULL;
|
|
||||||
maxlength_ = 0;
|
|
||||||
first_ = 0;
|
|
||||||
last_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void zap() {
|
|
||||||
if (first_ < last_) {
|
|
||||||
for (size_t i = first_; i < last_; i++)
|
|
||||||
buffer_[i].~T();
|
|
||||||
} else {
|
|
||||||
for (size_t i = first_; i < maxlength_; i++)
|
|
||||||
buffer_[i].~T();
|
|
||||||
for (size_t i = 0; i < last_; i++)
|
|
||||||
buffer_[i].~T();
|
|
||||||
}
|
|
||||||
this->free(buffer_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T *buffer_;
|
|
||||||
size_t maxlength_;
|
|
||||||
|
|
||||||
// Always points to the first readable item.
|
|
||||||
size_t first_;
|
|
||||||
|
|
||||||
// Always points to where the next item can be appended.
|
|
||||||
size_t last_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _INCLUDE_KEIMA_TPL_CPP_DEQUE_H_
|
|
|
@ -1,103 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013-2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _include_amtl_fixedarray_h_
|
|
||||||
#define _include_amtl_fixedarray_h_
|
|
||||||
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-allocator-policies.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class FixedArray : public AllocPolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FixedArray(size_t length, AllocPolicy = AllocPolicy()) {
|
|
||||||
length_ = length;
|
|
||||||
data_ = (T *)this->malloc(sizeof(T) * length_);
|
|
||||||
if (!data_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < length_; i++)
|
|
||||||
new (&data_[i]) T();
|
|
||||||
}
|
|
||||||
~FixedArray() {
|
|
||||||
for (size_t i = 0; i < length_; i++)
|
|
||||||
data_[i].~T();
|
|
||||||
this->free(data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This call may be skipped if the allocator policy is infallible.
|
|
||||||
bool initialize() {
|
|
||||||
return length_ == 0 || !!data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t length() const {
|
|
||||||
return length_;
|
|
||||||
}
|
|
||||||
T &operator [](size_t index) {
|
|
||||||
return at(index);
|
|
||||||
}
|
|
||||||
const T &operator [](size_t index) const {
|
|
||||||
return at(index);
|
|
||||||
}
|
|
||||||
T &at(size_t index) {
|
|
||||||
assert(index < length());
|
|
||||||
return data_[index];
|
|
||||||
}
|
|
||||||
const T &at(size_t index) const {
|
|
||||||
assert(index < length());
|
|
||||||
return data_[index];
|
|
||||||
}
|
|
||||||
T &back() {
|
|
||||||
assert(length() > 0);
|
|
||||||
return data_[length() - 1];
|
|
||||||
}
|
|
||||||
const T &back() const {
|
|
||||||
assert(length() > 0);
|
|
||||||
return data_[length() - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
T *buffer() const {
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FixedArray(const FixedArray &other) KE_DELETE;
|
|
||||||
FixedArray &operator =(const FixedArray &other) KE_DELETE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t length_;
|
|
||||||
T *data_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_fixedarray_h_
|
|
|
@ -1,139 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_float_h_
|
|
||||||
#define _include_amtl_float_h_
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <float.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
static const uint32_t kFloat32ExponentMask = 0x7F800000;
|
|
||||||
static const uint64_t kFloat64ExponentMask = 0x7FFF000000000000ULL;
|
|
||||||
|
|
||||||
struct float32_bits
|
|
||||||
{
|
|
||||||
static const uint32_t kExponentMask = kFloat32ExponentMask;
|
|
||||||
|
|
||||||
typedef uint32_t Bits;
|
|
||||||
|
|
||||||
union layout {
|
|
||||||
uint32_t bits;
|
|
||||||
float value;
|
|
||||||
};
|
|
||||||
|
|
||||||
static layout to_layout(float value) {
|
|
||||||
layout impl;
|
|
||||||
impl.value = value;
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct float64_bits
|
|
||||||
{
|
|
||||||
static const uint64_t kExponentMask = kFloat64ExponentMask;
|
|
||||||
|
|
||||||
typedef uint64_t Bits;
|
|
||||||
|
|
||||||
union layout {
|
|
||||||
uint64_t bits;
|
|
||||||
float value;
|
|
||||||
};
|
|
||||||
|
|
||||||
static layout to_layout(float value) {
|
|
||||||
layout impl;
|
|
||||||
impl.value = value;
|
|
||||||
return impl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct float_bits;
|
|
||||||
template <>
|
|
||||||
struct float_bits<float> : public float32_bits {};
|
|
||||||
template <>
|
|
||||||
struct float_bits<double> : public float64_bits {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline bool
|
|
||||||
IsNaN(T v)
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
return !!_isnan(v);
|
|
||||||
#else
|
|
||||||
return isnan(v);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline bool
|
|
||||||
IsInfinite(T value)
|
|
||||||
{
|
|
||||||
typedef float_bits<T> Properties;
|
|
||||||
typedef typename Properties::Bits Bits;
|
|
||||||
Bits bits = Properties::to_layout(value).bits;
|
|
||||||
return (bits & Properties::kExponentMask) == Properties::kExponentMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Performs the operation (x % y) where x and y are floating-point values.
|
|
||||||
//
|
|
||||||
// To compute a floating point modulus, this function returns "r", where r
|
|
||||||
// satisfies the following equation:
|
|
||||||
//
|
|
||||||
// x = (I * y) + r
|
|
||||||
//
|
|
||||||
// Where I is an integer <= x, and r is a value less than y. If no such
|
|
||||||
// integer I exists, the result is NaN.
|
|
||||||
//
|
|
||||||
// If x or y are NaN, the result is NaN.
|
|
||||||
// If x is +/-Infinity, the result is NaN.
|
|
||||||
// If y is 0, the result is NaN (as a divide by zero is implied).
|
|
||||||
//
|
|
||||||
// If y is Infinity, then r = x (and I = 0).
|
|
||||||
// If x is +/-0, then r = +/-0.
|
|
||||||
template <typename T> static inline T
|
|
||||||
FloatModulo(T left, T right)
|
|
||||||
{
|
|
||||||
#if defined(KE_WINDOWS)
|
|
||||||
// Windows fmod() does not follow the contract above, in that:
|
|
||||||
// 42 % Infinity => NaN, instead of 42, and
|
|
||||||
// -0 % -N => 0, instead of -0.
|
|
||||||
if ((!IsInfinite(left) && IsInfinite(right)) ||
|
|
||||||
(left == 0 && !IsInfinite(right)))
|
|
||||||
{
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return fmod(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_float_h_
|
|
|
@ -1,182 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_hashmap_h_
|
|
||||||
#define _include_amtl_hashmap_h_
|
|
||||||
|
|
||||||
#include <am-hashtable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Template parameters:
|
|
||||||
//
|
|
||||||
// K - Key type.
|
|
||||||
// V - Value type.
|
|
||||||
// HashPolicy - A struct with a hash and comparator function for each lookup type:
|
|
||||||
// static uint32_t hash(const Type &value);
|
|
||||||
// static bool matches(const Type &value, const K &key);
|
|
||||||
//
|
|
||||||
// All types that match a given key, must compute the same hash.
|
|
||||||
//
|
|
||||||
// Note that like HashTable, a HashMap is not usable until init() has been called.
|
|
||||||
template <typename K,
|
|
||||||
typename V,
|
|
||||||
typename HashPolicy,
|
|
||||||
typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class HashMap : public AllocPolicy
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
struct Entry
|
|
||||||
{
|
|
||||||
K key;
|
|
||||||
V value;
|
|
||||||
|
|
||||||
Entry()
|
|
||||||
{}
|
|
||||||
Entry(const Entry &other)
|
|
||||||
: key(other.key),
|
|
||||||
value(other.value)
|
|
||||||
{}
|
|
||||||
Entry(Entry &&other)
|
|
||||||
: key(ke::Move(other.key)),
|
|
||||||
value(ke::Move(other.value))
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename UK, typename UV>
|
|
||||||
Entry(UK &&aKey, UV &&aValue)
|
|
||||||
: key(ke::Forward<UK>(aKey)),
|
|
||||||
value(ke::Forward<UV>(aValue))
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Policy
|
|
||||||
{
|
|
||||||
typedef Entry Payload;
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
static uint32_t hash(const Lookup &key) {
|
|
||||||
return HashPolicy::hash(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
static bool matches(const Lookup &key, const Payload &payload) {
|
|
||||||
return HashPolicy::matches(key, payload.key);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HashTable<Policy, AllocPolicy> Internal;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HashMap(AllocPolicy ap = AllocPolicy())
|
|
||||||
: table_(ap)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// capacity must be a power of two.
|
|
||||||
bool init(size_t capacity = 16) {
|
|
||||||
return table_.init(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename Internal::Result Result;
|
|
||||||
typedef typename Internal::Insert Insert;
|
|
||||||
typedef typename Internal::iterator iterator;
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
Result find(const Lookup &key) {
|
|
||||||
return table_.find(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
Insert findForAdd(const Lookup &key) {
|
|
||||||
return table_.findForAdd(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
void removeIfExists(const Lookup &key) {
|
|
||||||
return table_.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(Result &r) {
|
|
||||||
table_.remove(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The map must not have been mutated in between findForAdd() and add().
|
|
||||||
// The Insert object is still valid after add() returns, however.
|
|
||||||
template <typename UK, typename UV>
|
|
||||||
bool add(Insert &i, UK &&key, UV &&value) {
|
|
||||||
Entry entry(ke::Forward<UK>(key), ke::Forward<UV>(value));
|
|
||||||
return table_.add(i, ke::Move(entry));
|
|
||||||
}
|
|
||||||
template <typename UK>
|
|
||||||
bool add(Insert &i, UK &&key) {
|
|
||||||
Entry entry(ke::Forward<UK>(key), V());
|
|
||||||
return table_.add(i, ke::Move(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can be used to avoid compiler constructed temporaries, since AMTL
|
|
||||||
// does not yet support move semantics. If you use this, the key and value
|
|
||||||
// must be set after.
|
|
||||||
bool add(Insert &i) {
|
|
||||||
return table_.add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator iter() {
|
|
||||||
return iterator(&table_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
table_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t elements() const {
|
|
||||||
return table_.elements();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t estimateMemoryUse() const {
|
|
||||||
return table_.estimateMemoryUse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Internal table_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct PointerPolicy
|
|
||||||
{
|
|
||||||
static inline uint32_t hash(T *p) {
|
|
||||||
return HashPointer(p);
|
|
||||||
}
|
|
||||||
static inline bool matches(T *p1, T *p2) {
|
|
||||||
return p1 == p2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_hashmap_h_
|
|
|
@ -1,131 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_hashset_h_
|
|
||||||
#define _include_amtl_hashset_h_
|
|
||||||
|
|
||||||
#include <am-hashtable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Template parameters:
|
|
||||||
//
|
|
||||||
// K - Key type.
|
|
||||||
// HashPolicy - A struct with a hash and comparator function for each lookup type:
|
|
||||||
// static uint32_t hash(const Type &value);
|
|
||||||
// static bool matches(const Type &value, const K &key);
|
|
||||||
//
|
|
||||||
// Like HashMap and HashTable, init() must be called to construct the set.
|
|
||||||
template <typename K,
|
|
||||||
typename HashPolicy,
|
|
||||||
typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class HashSet : public AllocPolicy
|
|
||||||
{
|
|
||||||
struct Policy {
|
|
||||||
typedef K Payload;
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
static uint32_t hash(const Lookup &key) {
|
|
||||||
return HashPolicy::hash(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
static bool matches(const Lookup &key, const Payload &payload) {
|
|
||||||
return HashPolicy::matches(key, payload);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HashTable<Policy, AllocPolicy> Internal;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HashSet(AllocPolicy ap = AllocPolicy())
|
|
||||||
: table_(ap)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// capacity must be a power of two.
|
|
||||||
bool init(size_t capacity = 16) {
|
|
||||||
return table_.init(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename Internal::Result Result;
|
|
||||||
typedef typename Internal::Insert Insert;
|
|
||||||
typedef typename Internal::iterator iterator;
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
Result find(const Lookup &key) {
|
|
||||||
return table_.find(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
Insert findForAdd(const Lookup &key) {
|
|
||||||
return table_.findForAdd(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lookup>
|
|
||||||
void removeIfExists(const Lookup &key) {
|
|
||||||
return table_.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(Result &r) {
|
|
||||||
table_.remove(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The map must not have been mutated in between findForAdd() and add().
|
|
||||||
// The Insert object is still valid after add() returns, however.
|
|
||||||
template <typename UK>
|
|
||||||
bool add(Insert &i, UK &&key) {
|
|
||||||
return table_.add(i, ke::Forward<UK>(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can be used to avoid compiler constructed temporaries, since AMTL
|
|
||||||
// does not yet support move semantics. If you use this, the key and value
|
|
||||||
// must be set after.
|
|
||||||
bool add(Insert &i) {
|
|
||||||
return table_.add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator iter() {
|
|
||||||
return iterator(&table_);
|
|
||||||
}
|
|
||||||
void clear() {
|
|
||||||
table_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t estimateMemoryUse() const {
|
|
||||||
return table_.estimateMemoryUse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Internal table_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_hashset_h_
|
|
|
@ -1,621 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_KEIMA_HASHTABLE_H_
|
|
||||||
#define _INCLUDE_KEIMA_HASHTABLE_H_
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "am-allocator-policies.h"
|
|
||||||
#include "am-utility.h"
|
|
||||||
#include "am-moveable.h"
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template <typename T>
|
|
||||||
class HashTableEntry
|
|
||||||
{
|
|
||||||
uint32_t hash_;
|
|
||||||
T t_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const uint32_t kFreeHash = 0;
|
|
||||||
static const uint32_t kRemovedHash = 1;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void setHash(uint32_t hash) {
|
|
||||||
hash_ = hash;
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
void construct(U &&u) {
|
|
||||||
new (&t_) T(ke::Forward<U>(u));
|
|
||||||
}
|
|
||||||
uint32_t hash() const {
|
|
||||||
return hash_;
|
|
||||||
}
|
|
||||||
void setRemoved() {
|
|
||||||
destruct();
|
|
||||||
hash_ = kRemovedHash;
|
|
||||||
}
|
|
||||||
void setFree() {
|
|
||||||
destruct();
|
|
||||||
hash_ = kFreeHash;
|
|
||||||
}
|
|
||||||
void initialize() {
|
|
||||||
hash_ = kFreeHash;
|
|
||||||
}
|
|
||||||
void destruct() {
|
|
||||||
if (isLive())
|
|
||||||
t_.~T();
|
|
||||||
}
|
|
||||||
bool removed() const {
|
|
||||||
return hash_ == kRemovedHash;
|
|
||||||
}
|
|
||||||
bool free() const {
|
|
||||||
return hash_ == kFreeHash;
|
|
||||||
}
|
|
||||||
bool isLive() const {
|
|
||||||
return hash_ > kRemovedHash;
|
|
||||||
}
|
|
||||||
T &payload() {
|
|
||||||
assert(isLive());
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
bool sameHash(uint32_t hash) const {
|
|
||||||
return hash_ == hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HashTableEntry(const HashTableEntry &other) KE_DELETE;
|
|
||||||
HashTableEntry &operator =(const HashTableEntry &other) KE_DELETE;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// The HashPolicy for the table must have the following members:
|
|
||||||
//
|
|
||||||
// Payload
|
|
||||||
// static uint32_t hash(const LookupType &key);
|
|
||||||
// static bool matches(const LookupType &key, const Payload &other);
|
|
||||||
//
|
|
||||||
// Payload must be a type, and LookupType is any type that lookups will be
|
|
||||||
// performed with (these functions can be overloaded). Example:
|
|
||||||
//
|
|
||||||
// struct Policy {
|
|
||||||
// typedef KeyValuePair Payload;
|
|
||||||
// static uint32 hash(const Key &key) {
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
// static bool matches(const Key &key, const KeyValuePair &pair) {
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// Note that the table is not usable until init() has been called.
|
|
||||||
//
|
|
||||||
template <typename HashPolicy, typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class HashTable : public AllocPolicy
|
|
||||||
{
|
|
||||||
friend class iterator;
|
|
||||||
|
|
||||||
typedef typename HashPolicy::Payload Payload;
|
|
||||||
typedef detail::HashTableEntry<Payload> Entry;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const uint32_t kMinCapacity = 16;
|
|
||||||
static const uint32_t kMaxCapacity = INT_MAX / sizeof(Entry);
|
|
||||||
|
|
||||||
template <typename Key>
|
|
||||||
uint32_t computeHash(const Key &key) {
|
|
||||||
// Multiply by golden ratio.
|
|
||||||
uint32_t hash = HashPolicy::hash(key) * 0x9E3779B9;
|
|
||||||
if (hash == Entry::kFreeHash || hash == Entry::kRemovedHash)
|
|
||||||
hash += 2;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry *createTable(uint32_t capacity) {
|
|
||||||
assert(capacity <= kMaxCapacity);
|
|
||||||
|
|
||||||
Entry *table = (Entry *)this->malloc(capacity * sizeof(Entry));
|
|
||||||
if (!table)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < capacity; i++)
|
|
||||||
table[i].initialize();
|
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
class Result
|
|
||||||
{
|
|
||||||
friend class HashTable;
|
|
||||||
|
|
||||||
Entry *entry_;
|
|
||||||
|
|
||||||
Entry &entry() {
|
|
||||||
return *entry_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
Result(Entry *entry)
|
|
||||||
: entry_(entry)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Payload * operator ->() {
|
|
||||||
return &entry_->payload();
|
|
||||||
}
|
|
||||||
Payload & operator *() {
|
|
||||||
return entry_->payload();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found() const {
|
|
||||||
return entry_->isLive();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Insert : public Result
|
|
||||||
{
|
|
||||||
uint32_t hash_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Insert(Entry *entry, uint32_t hash)
|
|
||||||
: Result(entry),
|
|
||||||
hash_(hash)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t hash() const {
|
|
||||||
return hash_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Probulator {
|
|
||||||
uint32_t hash_;
|
|
||||||
uint32_t capacity_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Probulator(uint32_t hash, uint32_t capacity)
|
|
||||||
: hash_(hash),
|
|
||||||
capacity_(capacity)
|
|
||||||
{
|
|
||||||
assert(IsPowerOfTwo(capacity_));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t entry() const {
|
|
||||||
return hash_ & (capacity_ - 1);
|
|
||||||
}
|
|
||||||
uint32_t next() {
|
|
||||||
hash_++;
|
|
||||||
return entry();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool underloaded() const {
|
|
||||||
// Check if the table is underloaded: < 25% entries used.
|
|
||||||
return (capacity_ > kMinCapacity) && (nelements_ + ndeleted_ < capacity_ / 4);
|
|
||||||
}
|
|
||||||
bool overloaded() const {
|
|
||||||
// Grow if the table is overloaded: > 75% entries used.
|
|
||||||
return (nelements_ + ndeleted_) > ((capacity_ / 2) + (capacity_ / 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool shrink() {
|
|
||||||
if ((capacity_ >> 1) < minCapacity_)
|
|
||||||
return true;
|
|
||||||
return changeCapacity(capacity_ >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool grow() {
|
|
||||||
if (capacity_ >= kMaxCapacity) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return changeCapacity(capacity_ << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool changeCapacity(uint32_t newCapacity) {
|
|
||||||
assert(newCapacity <= kMaxCapacity);
|
|
||||||
|
|
||||||
Entry *newTable = createTable(newCapacity);
|
|
||||||
if (!newTable)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Entry *oldTable = table_;
|
|
||||||
uint32_t oldCapacity = capacity_;
|
|
||||||
|
|
||||||
table_ = newTable;
|
|
||||||
capacity_ = newCapacity;
|
|
||||||
ndeleted_ = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < oldCapacity; i++) {
|
|
||||||
Entry &oldEntry = oldTable[i];
|
|
||||||
if (oldEntry.isLive()) {
|
|
||||||
Insert p = insertUnique(oldEntry.hash());
|
|
||||||
p.entry().setHash(p.hash());
|
|
||||||
p.entry().construct(ke::Move(oldEntry.payload()));
|
|
||||||
}
|
|
||||||
oldEntry.destruct();
|
|
||||||
}
|
|
||||||
this->free(oldTable);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For use when the key is known to be unique.
|
|
||||||
Insert insertUnique(uint32_t hash) {
|
|
||||||
Probulator probulator(hash, capacity_);
|
|
||||||
|
|
||||||
Entry *e = &table_[probulator.entry()];
|
|
||||||
for (;;) {
|
|
||||||
if (e->free() || e->removed())
|
|
||||||
break;
|
|
||||||
e = &table_[probulator.next()];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Insert(e, hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Key>
|
|
||||||
Result lookup(const Key &key) {
|
|
||||||
uint32_t hash = computeHash(key);
|
|
||||||
Probulator probulator(hash, capacity_);
|
|
||||||
|
|
||||||
Entry *e = &table_[probulator.entry()];
|
|
||||||
for (;;) {
|
|
||||||
if (e->free())
|
|
||||||
break;
|
|
||||||
if (e->isLive() &&
|
|
||||||
e->sameHash(hash) &&
|
|
||||||
HashPolicy::matches(key, e->payload()))
|
|
||||||
{
|
|
||||||
return Result(e);
|
|
||||||
}
|
|
||||||
e = &table_[probulator.next()];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Key>
|
|
||||||
Insert lookupForAdd(const Key &key) {
|
|
||||||
uint32_t hash = computeHash(key);
|
|
||||||
Probulator probulator(hash, capacity_);
|
|
||||||
|
|
||||||
Entry *e = &table_[probulator.entry()];
|
|
||||||
for (;;) {
|
|
||||||
if (!e->isLive())
|
|
||||||
break;
|
|
||||||
if (e->sameHash(hash) && HashPolicy::matches(key, e->payload()))
|
|
||||||
break;
|
|
||||||
e = &table_[probulator.next()];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Insert(e, hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool internalAdd(Insert &i) {
|
|
||||||
assert(!i.found());
|
|
||||||
|
|
||||||
// If the entry is deleted, just re-use the slot.
|
|
||||||
if (i.entry().removed()) {
|
|
||||||
ndeleted_--;
|
|
||||||
} else {
|
|
||||||
// Otherwise, see if we're at max capacity.
|
|
||||||
if (nelements_ == kMaxCapacity) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the table is over or underloaded. The table is always at
|
|
||||||
// least 25% free, so this check is enough to guarantee one free slot.
|
|
||||||
// (Without one free slot, insertion search could infinite loop.)
|
|
||||||
uint32_t oldCapacity = capacity_;
|
|
||||||
if (!checkDensity())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If the table changed size, we need to find a new insertion point.
|
|
||||||
// Note that a removed entry is impossible: either we caught it above,
|
|
||||||
// or we just resized and no entries are removed.
|
|
||||||
if (capacity_ != oldCapacity)
|
|
||||||
i = insertUnique(i.hash());
|
|
||||||
}
|
|
||||||
|
|
||||||
nelements_++;
|
|
||||||
i.entry().setHash(i.hash());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeEntry(Entry &e) {
|
|
||||||
assert(e.isLive());
|
|
||||||
e.setRemoved();
|
|
||||||
ndeleted_++;
|
|
||||||
nelements_--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
HashTable(AllocPolicy ap = AllocPolicy())
|
|
||||||
: AllocPolicy(ap),
|
|
||||||
capacity_(0),
|
|
||||||
nelements_(0),
|
|
||||||
ndeleted_(0),
|
|
||||||
table_(nullptr),
|
|
||||||
minCapacity_(kMinCapacity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~HashTable()
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < capacity_; i++)
|
|
||||||
table_[i].destruct();
|
|
||||||
this->free(table_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool init(size_t capacity = 0) {
|
|
||||||
if (capacity < kMinCapacity) {
|
|
||||||
capacity = kMinCapacity;
|
|
||||||
} else if (capacity > kMaxCapacity) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
minCapacity_ = uint32_t(capacity);
|
|
||||||
|
|
||||||
assert(IsPowerOfTwo(capacity));
|
|
||||||
capacity_ = uint32_t(capacity);
|
|
||||||
|
|
||||||
table_ = createTable(capacity_);
|
|
||||||
if (!table_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Result object must not be used past mutating table operations.
|
|
||||||
template <typename Key>
|
|
||||||
Result find(const Key &key) {
|
|
||||||
return lookup(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Insert object must not be used past mutating table operations.
|
|
||||||
template <typename Key>
|
|
||||||
Insert findForAdd(const Key &key) {
|
|
||||||
return lookupForAdd(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Key>
|
|
||||||
void removeIfExists(const Key &key) {
|
|
||||||
Result r = find(key);
|
|
||||||
if (!r.found())
|
|
||||||
return;
|
|
||||||
remove(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(Result &r) {
|
|
||||||
assert(r.found());
|
|
||||||
removeEntry(r.entry());
|
|
||||||
}
|
|
||||||
|
|
||||||
// The table must not have been mutated in between findForAdd() and add().
|
|
||||||
// The Insert object is still valid after add() returns, however.
|
|
||||||
template <typename U>
|
|
||||||
bool add(Insert &i, U &&payload) {
|
|
||||||
if (!internalAdd(i))
|
|
||||||
return false;
|
|
||||||
i.entry().construct(ke::Forward<U>(payload));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool add(Insert &i) {
|
|
||||||
if (!internalAdd(i))
|
|
||||||
return false;
|
|
||||||
i.entry().construct();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkDensity() {
|
|
||||||
if (underloaded())
|
|
||||||
return shrink();
|
|
||||||
if (overloaded())
|
|
||||||
return grow();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
for (size_t i = 0; i < capacity_; i++) {
|
|
||||||
table_[i].setFree();
|
|
||||||
}
|
|
||||||
ndeleted_ = 0;
|
|
||||||
nelements_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t elements() const {
|
|
||||||
return nelements_;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t estimateMemoryUse() const {
|
|
||||||
return sizeof(Entry) * capacity_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// It is illegal to mutate a HashTable during iteration.
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
iterator(HashTable *table)
|
|
||||||
: table_(table),
|
|
||||||
i_(table->table_),
|
|
||||||
end_(table->table_ + table->capacity_)
|
|
||||||
{
|
|
||||||
while (i_ < end_ && !i_->isLive())
|
|
||||||
i_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return i_ == end_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase() {
|
|
||||||
assert(!empty());
|
|
||||||
table_->removeEntry(*i_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Payload *operator ->() const {
|
|
||||||
return &i_->payload();
|
|
||||||
}
|
|
||||||
Payload &operator *() const {
|
|
||||||
return i_->payload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void next() {
|
|
||||||
do {
|
|
||||||
i_++;
|
|
||||||
} while (i_ < end_ && !i_->isLive());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HashTable *table_;
|
|
||||||
Entry *i_;
|
|
||||||
Entry *end_;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
HashTable(const HashTable &other) KE_DELETE;
|
|
||||||
HashTable &operator =(const HashTable &other) KE_DELETE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t capacity_;
|
|
||||||
uint32_t nelements_;
|
|
||||||
uint32_t ndeleted_;
|
|
||||||
Entry *table_;
|
|
||||||
uint32_t minCapacity_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bob Jenkin's one-at-a-time hash function[1].
|
|
||||||
//
|
|
||||||
// [1] http://burtleburtle.net/bob/hash/doobs.html
|
|
||||||
class CharacterStreamHasher
|
|
||||||
{
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CharacterStreamHasher()
|
|
||||||
: hash(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void add(char c) {
|
|
||||||
hash += c;
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(const char *s, size_t length) {
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
add(s[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t result() {
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
HashCharSequence(const char *s, size_t length)
|
|
||||||
{
|
|
||||||
CharacterStreamHasher hasher;
|
|
||||||
hasher.add(s, length);
|
|
||||||
return hasher.result();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
FastHashCharSequence(const char *s, size_t length)
|
|
||||||
{
|
|
||||||
uint32_t hash = 0;
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
hash = s[i] + (hash << 6) + (hash << 16) - hash;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From http://burtleburtle.net/bob/hash/integer.html
|
|
||||||
static inline uint32_t
|
|
||||||
HashInt32(int32_t a)
|
|
||||||
{
|
|
||||||
a = (a ^ 61) ^ (a >> 16);
|
|
||||||
a = a + (a << 3);
|
|
||||||
a = a ^ (a >> 4);
|
|
||||||
a = a * 0x27d4eb2d;
|
|
||||||
a = a ^ (a >> 15);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From http://www.cris.com/~Ttwang/tech/inthash.htm
|
|
||||||
static inline uint32_t
|
|
||||||
HashInt64(int64_t key)
|
|
||||||
{
|
|
||||||
key = (~key) + (key << 18); // key = (key << 18) - key - 1;
|
|
||||||
key = key ^ (uint64_t(key) >> 31);
|
|
||||||
key = key * 21; // key = (key + (key << 2)) + (key << 4);
|
|
||||||
key = key ^ (uint64_t(key) >> 11);
|
|
||||||
key = key + (key << 6);
|
|
||||||
key = key ^ (uint64_t(key) >> 22);
|
|
||||||
return uint32_t(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t Size>
|
|
||||||
static inline uint32_t
|
|
||||||
HashInteger(uintptr_t value);
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline uint32_t
|
|
||||||
HashInteger<4>(uintptr_t value)
|
|
||||||
{
|
|
||||||
return HashInt32(uint32_t(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline uint32_t
|
|
||||||
HashInteger<8>(uintptr_t value)
|
|
||||||
{
|
|
||||||
return HashInt64(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
HashPointer(void *ptr)
|
|
||||||
{
|
|
||||||
return HashInteger<sizeof(ptr)>(reinterpret_cast<uintptr_t>(ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _INCLUDE_KEIMA_HASHTABLE_H_
|
|
|
@ -1,184 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_inline_list_h_
|
|
||||||
#define _include_amtl_inline_list_h_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <am-cxx.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T> class InlineList;
|
|
||||||
|
|
||||||
// Objects can recursively inherit from InlineListNode in order to have
|
|
||||||
// membership in an InlineList<T>.
|
|
||||||
template <typename T>
|
|
||||||
class InlineListNode
|
|
||||||
{
|
|
||||||
friend class InlineList<T>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
InlineListNode()
|
|
||||||
: next_(nullptr),
|
|
||||||
prev_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InlineListNode(InlineListNode *next, InlineListNode *prev)
|
|
||||||
: next_(next),
|
|
||||||
prev_(prev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
InlineListNode *next_;
|
|
||||||
InlineListNode *prev_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// An InlineList is a linked list that threads link pointers through objects,
|
|
||||||
// rather than allocating node memory. A node can be in at most one list at
|
|
||||||
// any time.
|
|
||||||
//
|
|
||||||
// Since InlineLists are designed to be very cheap, there is no requirement
|
|
||||||
// that elements be removed from a list once the list is destructed. However,
|
|
||||||
// for as long as the list is alive, all of its contained nodes must also
|
|
||||||
// be alive.
|
|
||||||
template <typename T>
|
|
||||||
class InlineList
|
|
||||||
{
|
|
||||||
typedef InlineListNode<T> Node;
|
|
||||||
|
|
||||||
Node head_;
|
|
||||||
|
|
||||||
// Work around a clang bug where we can't initialize with &head_ in the ctor.
|
|
||||||
inline Node *head() {
|
|
||||||
return &head_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
InlineList()
|
|
||||||
: head_(head(), head())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~InlineList()
|
|
||||||
{
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
// Remove all items to clear their next/prev fields.
|
|
||||||
while (begin() != end())
|
|
||||||
remove(*begin());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
friend class InlineList;
|
|
||||||
Node *iter_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator(Node *iter)
|
|
||||||
: iter_(iter)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator & operator ++() {
|
|
||||||
iter_ = iter_->next;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
iterator operator ++(int) {
|
|
||||||
iterator old(*this);
|
|
||||||
iter_ = iter_->next_;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
T * operator *() {
|
|
||||||
return static_cast<T *>(iter_);
|
|
||||||
}
|
|
||||||
T * operator ->() {
|
|
||||||
return static_cast<T *>(iter_);
|
|
||||||
}
|
|
||||||
bool operator !=(const iterator &where) const {
|
|
||||||
return iter_ != where.iter_;
|
|
||||||
}
|
|
||||||
bool operator ==(const iterator &where) const {
|
|
||||||
return iter_ == where.iter_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return iterator(head_.next_);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return iterator(&head_);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase(iterator &at) {
|
|
||||||
iterator next = at;
|
|
||||||
next++;
|
|
||||||
|
|
||||||
remove(at.iter_);
|
|
||||||
|
|
||||||
// Iterator is no longer valid.
|
|
||||||
at.iter_ = nullptr;
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return head_.next_ == &head_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(Node *t) {
|
|
||||||
t->prev_->next_ = t->next_;
|
|
||||||
t->next_->prev_ = t->prev_;
|
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
t->next_ = nullptr;
|
|
||||||
t->prev_ = nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(Node *t) {
|
|
||||||
assert(!t->next_);
|
|
||||||
assert(!t->prev_);
|
|
||||||
|
|
||||||
t->prev_ = head_.prev_;
|
|
||||||
t->next_ = &head_;
|
|
||||||
head_.prev_->next_ = t;
|
|
||||||
head_.prev_ = t;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_inline_list_h_
|
|
||||||
|
|
|
@ -1,287 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_linkedlist_h_
|
|
||||||
#define _include_amtl_linkedlist_h_
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <am-allocator-policies.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// LinkedList, analagous to std::list or SourceHook::List. Since it performs a
|
|
||||||
// malloc() and free() on every contained node, it should be avoided unless
|
|
||||||
// absolutely necessary, or for when allocation performance is not a factor. It
|
|
||||||
// is provided here to safely port old AlliedModders code to AMTL.
|
|
||||||
//
|
|
||||||
// In order to use a circular chain, LinkedList's allocation size includes
|
|
||||||
// exactly one T. If T is very large, LinkedList should be allocated on the
|
|
||||||
// heap, to avoid using the stack.
|
|
||||||
template <class T, class AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class LinkedList : public AllocPolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
friend class iterator;
|
|
||||||
|
|
||||||
struct Node
|
|
||||||
{
|
|
||||||
T obj;
|
|
||||||
Node *next;
|
|
||||||
Node *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
LinkedList(AllocPolicy = AllocPolicy())
|
|
||||||
: length_(0)
|
|
||||||
{
|
|
||||||
head()->prev = head();
|
|
||||||
head()->next = head();
|
|
||||||
}
|
|
||||||
~LinkedList() {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool append(U &&obj) {
|
|
||||||
return insertBefore(end(), ke::Forward<U>(obj)) != end();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool prepend(U &&obj) {
|
|
||||||
return insertBefore(begin(), ke::Forward<U>(obj)) != begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t length() const {
|
|
||||||
return length_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
Node *node = head()->next;
|
|
||||||
Node *temp;
|
|
||||||
head()->next = head();
|
|
||||||
head()->prev = head();
|
|
||||||
|
|
||||||
// Iterate through the nodes until we find the sentinel again.
|
|
||||||
while (node != head()) {
|
|
||||||
temp = node->next;
|
|
||||||
freeNode(node);
|
|
||||||
node = temp;
|
|
||||||
}
|
|
||||||
length_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return (length_ == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
T &front() {
|
|
||||||
assert(!empty());
|
|
||||||
return head()->next->obj;
|
|
||||||
}
|
|
||||||
T &back() {
|
|
||||||
assert(!empty());
|
|
||||||
return head()->prev->obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Node *head() const {
|
|
||||||
return sentinel_.address();
|
|
||||||
}
|
|
||||||
Node *head() {
|
|
||||||
return sentinel_.address();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
Node *allocNode(U &&obj) {
|
|
||||||
Node *node = (Node *)this->malloc(sizeof(Node));
|
|
||||||
if (!node)
|
|
||||||
return nullptr;
|
|
||||||
new (&node->obj) T(ke::Forward<U>(obj));
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeNode(Node *node) {
|
|
||||||
node->obj.~T();
|
|
||||||
this->free(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
StorageBuffer<Node> sentinel_;
|
|
||||||
size_t length_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
friend class LinkedList;
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator()
|
|
||||||
: this_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
iterator(const LinkedList &src)
|
|
||||||
: this_(src.head())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
iterator(Node *n)
|
|
||||||
: this_(n)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
iterator(const iterator &where)
|
|
||||||
: this_(where.this_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator &operator --() {
|
|
||||||
if (this_)
|
|
||||||
this_ = this_->prev;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
iterator operator --(int) {
|
|
||||||
iterator old(*this);
|
|
||||||
if (this_)
|
|
||||||
this_ = this_->prev;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
iterator &operator ++() {
|
|
||||||
if (this_)
|
|
||||||
this_ = this_->next;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
iterator operator ++(int) {
|
|
||||||
iterator old(*this);
|
|
||||||
if (this_)
|
|
||||||
this_ = this_->next;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T &operator * () const {
|
|
||||||
return this_->obj;
|
|
||||||
}
|
|
||||||
T &operator * () {
|
|
||||||
return this_->obj;
|
|
||||||
}
|
|
||||||
T *operator ->() {
|
|
||||||
return &this_->obj;
|
|
||||||
}
|
|
||||||
const T *operator ->() const {
|
|
||||||
return &(this_->obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator !=(const iterator &where) const {
|
|
||||||
return (this_ != where.this_);
|
|
||||||
}
|
|
||||||
bool operator ==(const iterator &where) const {
|
|
||||||
return (this_ == where.this_);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() {
|
|
||||||
return !!this_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Node *this_;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Insert obj right before where.
|
|
||||||
iterator insert(iterator where, Node *node) {
|
|
||||||
if (!node)
|
|
||||||
return where;
|
|
||||||
|
|
||||||
Node *pWhereNode = where.this_;
|
|
||||||
|
|
||||||
pWhereNode->prev->next = node;
|
|
||||||
node->prev = pWhereNode->prev;
|
|
||||||
pWhereNode->prev = node;
|
|
||||||
node->next = pWhereNode;
|
|
||||||
|
|
||||||
length_++;
|
|
||||||
return iterator(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator begin() {
|
|
||||||
return iterator(head()->next);
|
|
||||||
}
|
|
||||||
iterator end() {
|
|
||||||
return iterator(head());
|
|
||||||
}
|
|
||||||
iterator erase(iterator where) {
|
|
||||||
Node *pNode = where.this_;
|
|
||||||
iterator iter(where);
|
|
||||||
iter++;
|
|
||||||
|
|
||||||
pNode->prev->next = pNode->next;
|
|
||||||
pNode->next->prev = pNode->prev;
|
|
||||||
|
|
||||||
freeNode(pNode);
|
|
||||||
length_--;
|
|
||||||
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
iterator insertBefore(iterator where, U &&obj) {
|
|
||||||
return insert(where, allocNode(ke::Forward<U>(obj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Removes one instance of |obj| from the list, if found.
|
|
||||||
void remove(const T &obj) {
|
|
||||||
for (iterator b = begin(); b != end(); b++) {
|
|
||||||
if (*b == obj) {
|
|
||||||
erase(b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
iterator find(const U &equ) {
|
|
||||||
for (iterator iter = begin(); iter != end(); iter++) {
|
|
||||||
if (*iter == equ)
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// These are disallowed because they basically violate the failure handling
|
|
||||||
// model for AllocPolicies and are also likely to have abysmal performance.
|
|
||||||
LinkedList &operator =(const LinkedList<T> &other) KE_DELETE;
|
|
||||||
LinkedList(const LinkedList<T> &other) KE_DELETE;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif //_INCLUDE_CSDM_LIST_H
|
|
|
@ -1,75 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_moveable_h_
|
|
||||||
#define _include_amtl_moveable_h_
|
|
||||||
|
|
||||||
#include <am-type-traits.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Previously, we implemented Move semantics without C++11. Now that we use
|
|
||||||
// C++11, we implement this as STL does for std::move.
|
|
||||||
template <typename T>
|
|
||||||
static inline typename remove_reference<T>::type &&
|
|
||||||
Move(T &&t)
|
|
||||||
{
|
|
||||||
return static_cast<typename remove_reference<T>::type &&>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::forward replacement. See:
|
|
||||||
// http://thbecker.net/articles/rvalue_references/section_07.html and
|
|
||||||
// http://thbecker.net/articles/rvalue_references/section_08.html
|
|
||||||
template <typename T>
|
|
||||||
static KE_CONSTEXPR inline T &&
|
|
||||||
Forward(typename remove_reference<T>::type &t) KE_NOEXCEPT
|
|
||||||
{
|
|
||||||
return static_cast<T &&>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static KE_CONSTEXPR inline T &&
|
|
||||||
Forward(typename remove_reference<T>::type &&t) KE_NOEXCEPT
|
|
||||||
{
|
|
||||||
return static_cast<T &&>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline void
|
|
||||||
MoveRange(T *dest, T *src, size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++) {
|
|
||||||
new (&dest[i]) T(ke::Move(src[i]));
|
|
||||||
src[i].~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_moveable_h_
|
|
|
@ -1,66 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
#ifndef _include_amtl_platform_h_
|
|
||||||
#define _include_amtl_platform_h_
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
#if defined(__NetBSD__)
|
|
||||||
# define KE_NETBSD
|
|
||||||
# define KE_BSD
|
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
# define KE_FREEBSD
|
|
||||||
# define KE_BSD
|
|
||||||
#elif defined(__OpenBSD__)
|
|
||||||
# define KE_OPENBSD
|
|
||||||
# define KE_BSD
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
# define KE_MACOSX
|
|
||||||
# define KE_MACH
|
|
||||||
# define KE_BSD
|
|
||||||
#elif defined(__MACH__)
|
|
||||||
# define KE_MACH
|
|
||||||
# define KE_BSD
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
# define KE_WINDOWS
|
|
||||||
#elif defined(__linux__)
|
|
||||||
# define KE_LINUX
|
|
||||||
# define KE_POSIX
|
|
||||||
#elif defined(__sun__)
|
|
||||||
# define KE_SOLARIS
|
|
||||||
# define KE_POSIX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_BSD)
|
|
||||||
# define KE_POSIX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_platform_h_
|
|
|
@ -1,196 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_ts_refcounting_h_
|
|
||||||
#define _include_amtl_ts_refcounting_h_
|
|
||||||
|
|
||||||
#include <am-refcounting.h>
|
|
||||||
#include <am-atomics.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// See the comment above Refcounted<T> for more information. This class is
|
|
||||||
// identical, except changing the reference count is guaranteed to be atomic
|
|
||||||
// with respect to other threads changing the reference count.
|
|
||||||
template <typename T>
|
|
||||||
class KE_LINK RefcountedThreadsafe
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RefcountedThreadsafe()
|
|
||||||
: refcount_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddRef() {
|
|
||||||
refcount_.increment();
|
|
||||||
}
|
|
||||||
bool Release() {
|
|
||||||
if (!refcount_.decrement()) {
|
|
||||||
delete static_cast<T *>(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~RefcountedThreadsafe() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicRefcount refcount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use this to forward to ke::Refcounted<X>, when implementing IRefcounted.
|
|
||||||
#define KE_IMPL_REFCOUNTING_TS(classname) \
|
|
||||||
void AddRef() { \
|
|
||||||
ke::RefcountedThreadsafe<classname>::AddRef(); \
|
|
||||||
} \
|
|
||||||
void Release() { \
|
|
||||||
ke::RefcountedThreadsafe<classname>::Release(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Classes may be multiply-inherited may wish to derive from this Refcounted
|
|
||||||
// instead.
|
|
||||||
class VirtualRefcountedThreadsafe : public IRefcounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VirtualRefcountedThreadsafe() : refcount_(0)
|
|
||||||
{
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
destroying_ = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
virtual ~VirtualRefcountedThreadsafe()
|
|
||||||
{}
|
|
||||||
void AddRef() KE_OVERRIDE {
|
|
||||||
assert(!destroying_);
|
|
||||||
refcount_.increment();
|
|
||||||
}
|
|
||||||
void Release() KE_OVERRIDE {
|
|
||||||
if (!refcount_.decrement()) {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
destroying_ = true;
|
|
||||||
#endif
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicRefcount refcount_;
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
bool destroying_;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a specialized version of Ref<> that is safe to read and write from
|
|
||||||
// multiple threads. It is not recommended for general use, since it imposes
|
|
||||||
// a CAS spin-lock on every read/write.
|
|
||||||
//
|
|
||||||
// Normally, assigning Ref<> to Ref<> has a race condition where in between
|
|
||||||
// the read and incref, another thread can assign, decref, and ultimately
|
|
||||||
// destroy the left-hand side. This prevents such a scenario by making reads
|
|
||||||
// atomic with respect to the incref operation.
|
|
||||||
//
|
|
||||||
// Pointers stored in an AtomicRef<> must be at least sizeof(void *) aligned.
|
|
||||||
template <typename T>
|
|
||||||
class AtomicRef
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AtomicRef()
|
|
||||||
: thing_(nullptr)
|
|
||||||
{}
|
|
||||||
AtomicRef(T *thing)
|
|
||||||
: thing_(thing)
|
|
||||||
{
|
|
||||||
assert(IsAligned(thing, sizeof(void *)));
|
|
||||||
if (thing)
|
|
||||||
thing->AddRef();
|
|
||||||
}
|
|
||||||
~AtomicRef() {
|
|
||||||
assert(thing_ == untagged(thing_));
|
|
||||||
if (thing_)
|
|
||||||
reinterpret_cast<T *>(thing_)->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Atomically retrieve and add a reference to the contained value.
|
|
||||||
AlreadyRefed<T> get() {
|
|
||||||
T *value = lock();
|
|
||||||
if (value)
|
|
||||||
value->AddRef();
|
|
||||||
unlock(value);
|
|
||||||
return AdoptRef(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Atomically incref the new value and replace the old value.
|
|
||||||
void operator =(T *other) {
|
|
||||||
T *value = lock();
|
|
||||||
if (other)
|
|
||||||
other->AddRef();
|
|
||||||
unlock(other);
|
|
||||||
if (value)
|
|
||||||
value->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicRef(const AtomicRef &other) KE_DELETE;
|
|
||||||
void operator =(const AtomicRef &other) KE_DELETE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// We represent a locked state with a tag bit.
|
|
||||||
void *tagged(void *ptr) {
|
|
||||||
return reinterpret_cast<void *>(uintptr_t(ptr) | 1);
|
|
||||||
}
|
|
||||||
void *untagged(void *ptr) {
|
|
||||||
return reinterpret_cast<void *>(uintptr_t(ptr) & ~uintptr_t(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
T *lock() {
|
|
||||||
// Spin until we can replace an untagged ptr with the tagged version.
|
|
||||||
void *oldval = untagged(thing_);
|
|
||||||
while (CompareAndSwapPtr(&thing_, tagged(oldval), oldval) != oldval) {
|
|
||||||
YieldProcessor();
|
|
||||||
oldval = untagged(thing_);
|
|
||||||
}
|
|
||||||
return reinterpret_cast<T *>(oldval);
|
|
||||||
}
|
|
||||||
void unlock(T *ptr) {
|
|
||||||
// Nothing should have mutated the value, and the new value should be
|
|
||||||
// untagged.
|
|
||||||
assert(thing_ == tagged(thing_));
|
|
||||||
assert(ptr == untagged(ptr));
|
|
||||||
thing_ = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void * volatile thing_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_ts_refcounting_h_
|
|
|
@ -1,423 +0,0 @@
|
||||||
// vim: set sts=8 ts=4 sw=4 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_refcounting_h_
|
|
||||||
#define _include_amtl_refcounting_h_
|
|
||||||
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T> class Ref;
|
|
||||||
|
|
||||||
// Objects in AMTL inheriting from Refcounted will have an initial refcount
|
|
||||||
// of 0. However, in some systems (such as COM), the initial refcount is 1,
|
|
||||||
// or functions may return raw pointers that have been AddRef'd. In these
|
|
||||||
// cases it would be a mistake to use Ref<> or PassRef<>, since the object
|
|
||||||
// would leak an extra reference.
|
|
||||||
//
|
|
||||||
// This container holds a refcounted object without addrefing it. This is
|
|
||||||
// intended only for interacting with functions which return an object that
|
|
||||||
// has been manually AddRef'd. Note that this will perform a Release(), so
|
|
||||||
// so it is necessary to assign it to retain the object.
|
|
||||||
template <typename T>
|
|
||||||
class AlreadyRefed
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AlreadyRefed(T *t)
|
|
||||||
: thing_(t)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
AlreadyRefed(const AlreadyRefed<T> &other)
|
|
||||||
: thing_(other.thing_)
|
|
||||||
{
|
|
||||||
// If copy elision for some reason doesn't happen (for example, when
|
|
||||||
// returning from AdoptRef), just null out the source ref.
|
|
||||||
other.thing_ = nullptr;
|
|
||||||
}
|
|
||||||
~AlreadyRefed() {
|
|
||||||
if (thing_)
|
|
||||||
thing_->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator !() const {
|
|
||||||
return !thing_;
|
|
||||||
}
|
|
||||||
T *operator ->() const {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
bool operator ==(T *other) const {
|
|
||||||
return thing_ == other;
|
|
||||||
}
|
|
||||||
bool operator !=(T *other) const {
|
|
||||||
return thing_ != other;
|
|
||||||
}
|
|
||||||
|
|
||||||
T *release() const {
|
|
||||||
return ReturnAndVoid(thing_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable T *thing_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline AlreadyRefed<T>
|
|
||||||
AdoptRef(T *t)
|
|
||||||
{
|
|
||||||
return AlreadyRefed<T>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When returning a value, we'd rather not be needlessly changing the refcount,
|
|
||||||
// so we have a special type to use for returns.
|
|
||||||
template <typename T>
|
|
||||||
class PassRef
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PassRef(T *thing)
|
|
||||||
: thing_(thing)
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
PassRef()
|
|
||||||
: thing_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PassRef(const AlreadyRefed<T> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
// Don't addref, newborn means already addref'd.
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
PassRef(const AlreadyRefed<S> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
// Don't addref, newborn means already addref'd.
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
inline PassRef(const Ref<S> &other);
|
|
||||||
|
|
||||||
PassRef(const PassRef &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
template <typename S>
|
|
||||||
PassRef(const PassRef<S> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~PassRef()
|
|
||||||
{
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T &() {
|
|
||||||
return *thing_;
|
|
||||||
}
|
|
||||||
operator T *() const {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
T *operator ->() const {
|
|
||||||
return operator *();
|
|
||||||
}
|
|
||||||
T *operator *() const {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
bool operator !() const {
|
|
||||||
return !thing_;
|
|
||||||
}
|
|
||||||
#if defined(KE_CXX11)
|
|
||||||
explicit operator bool() const {
|
|
||||||
return !!thing_;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
T *release() const {
|
|
||||||
return ReturnAndVoid(thing_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
PassRef &operator =(const PassRef<S> &other) {
|
|
||||||
Release();
|
|
||||||
thing_ = other.release();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Disallowed operators.
|
|
||||||
PassRef &operator =(T *other);
|
|
||||||
PassRef &operator =(AlreadyRefed<T> &other);
|
|
||||||
|
|
||||||
void AddRef() {
|
|
||||||
if (thing_)
|
|
||||||
thing_->AddRef();
|
|
||||||
}
|
|
||||||
void Release() {
|
|
||||||
if (thing_)
|
|
||||||
thing_->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable T *thing_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Classes which are refcounted should inherit from this. Note that reference
|
|
||||||
// counts start at 0 in AMTL, rather than 1. This avoids the complexity of
|
|
||||||
// having to adopt the initial ref upon allocation. However, this also means
|
|
||||||
// invoking Release() on a newly allocated object is illegal. Newborn objects
|
|
||||||
// must either be assigned to a Ref or PassRef (NOT an AdoptRef/AlreadyRefed),
|
|
||||||
// or must be deleted using |delete|.
|
|
||||||
template <typename T>
|
|
||||||
class KE_LINK Refcounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Refcounted()
|
|
||||||
: refcount_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddRef() {
|
|
||||||
refcount_++;
|
|
||||||
}
|
|
||||||
void Release() {
|
|
||||||
assert(refcount_ > 0);
|
|
||||||
if (--refcount_ == 0)
|
|
||||||
delete static_cast<T *>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~Refcounted() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uintptr_t refcount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use this to forward to ke::Refcounted<X>, when implementing IRefcounted.
|
|
||||||
#define KE_IMPL_REFCOUNTING(classname) \
|
|
||||||
void AddRef() { \
|
|
||||||
ke::Refcounted<classname>::AddRef(); \
|
|
||||||
} \
|
|
||||||
void Release() { \
|
|
||||||
ke::Refcounted<classname>::Release(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can be used for classes which will inherit from VirtualRefcounted.
|
|
||||||
class KE_LINK IRefcounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IRefcounted() {}
|
|
||||||
virtual void AddRef() = 0;
|
|
||||||
virtual void Release() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Classes may be multiply-inherited may wish to derive from this Refcounted
|
|
||||||
// instead.
|
|
||||||
class KE_LINK VirtualRefcounted : public IRefcounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VirtualRefcounted() : refcount_(0)
|
|
||||||
{
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
destroying_ = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
virtual ~VirtualRefcounted()
|
|
||||||
{}
|
|
||||||
void AddRef() KE_OVERRIDE {
|
|
||||||
assert(!destroying_);
|
|
||||||
refcount_++;
|
|
||||||
}
|
|
||||||
void Release() KE_OVERRIDE {
|
|
||||||
assert(refcount_ > 0);
|
|
||||||
if (--refcount_ == 0) {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
destroying_ = true;
|
|
||||||
#endif
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uintptr_t refcount_;
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
bool destroying_;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Simple class for automatic refcounting.
|
|
||||||
template <typename T>
|
|
||||||
class Ref
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Ref(T *thing)
|
|
||||||
: thing_(thing)
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref()
|
|
||||||
: thing_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref(const Ref &other)
|
|
||||||
: thing_(other.thing_)
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
Ref(Ref &&other)
|
|
||||||
: thing_(other.thing_)
|
|
||||||
{
|
|
||||||
other.thing_ = nullptr;
|
|
||||||
}
|
|
||||||
template <typename S>
|
|
||||||
Ref(const Ref<S> &other)
|
|
||||||
: thing_(*other)
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
Ref(const PassRef<T> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
template <typename S>
|
|
||||||
Ref(const PassRef<S> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Ref(const AlreadyRefed<T> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
template <typename S>
|
|
||||||
Ref(const AlreadyRefed<S> &other)
|
|
||||||
: thing_(other.release())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~Ref()
|
|
||||||
{
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
T *operator ->() const {
|
|
||||||
return operator *();
|
|
||||||
}
|
|
||||||
T *operator *() const {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
operator T *() {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
operator T *() const {
|
|
||||||
return thing_;
|
|
||||||
}
|
|
||||||
bool operator !() const {
|
|
||||||
return !thing_;
|
|
||||||
}
|
|
||||||
|
|
||||||
AlreadyRefed<T> take() {
|
|
||||||
return AlreadyRefed<T>(ReturnAndVoid(thing_));
|
|
||||||
}
|
|
||||||
AlreadyRefed<T> forget() {
|
|
||||||
return AlreadyRefed<T>(ReturnAndVoid(thing_));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const Ref &other) {
|
|
||||||
return thing_ == other.thing_;
|
|
||||||
}
|
|
||||||
bool operator !=(const Ref &other) {
|
|
||||||
return thing_ != other.thing_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
Ref &operator =(S *thing) {
|
|
||||||
Release();
|
|
||||||
thing_ = thing;
|
|
||||||
AddRef();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
Ref &operator =(const PassRef<S> &other) {
|
|
||||||
Release();
|
|
||||||
thing_ = other.release();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
Ref &operator =(const AlreadyRefed<S> &other) {
|
|
||||||
Release();
|
|
||||||
thing_ = other.release();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref &operator =(const Ref &other) {
|
|
||||||
Release();
|
|
||||||
thing_ = other.thing_;
|
|
||||||
AddRef();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref &operator =(Ref &&other) {
|
|
||||||
Release();
|
|
||||||
thing_ = other.thing_;
|
|
||||||
other.thing_ = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void AddRef() {
|
|
||||||
if (thing_)
|
|
||||||
thing_->AddRef();
|
|
||||||
}
|
|
||||||
void Release() {
|
|
||||||
if (thing_)
|
|
||||||
thing_->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
T *thing_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> template <typename S>
|
|
||||||
PassRef<T>::PassRef(const Ref<S> &other)
|
|
||||||
: thing_(*other)
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_refcounting_h_
|
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_string_h_
|
|
||||||
#define _include_amtl_string_h_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// ASCII string.
|
|
||||||
class AString
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AString()
|
|
||||||
: length_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit AString(const char *str) {
|
|
||||||
set(str, strlen(str));
|
|
||||||
}
|
|
||||||
AString(const char *str, size_t length) {
|
|
||||||
set(str, length);
|
|
||||||
}
|
|
||||||
AString(const AString &other) {
|
|
||||||
if (other.length_)
|
|
||||||
set(other.chars_, other.length_);
|
|
||||||
else
|
|
||||||
length_ = 0;
|
|
||||||
}
|
|
||||||
AString(AString &&other)
|
|
||||||
: chars_(other.chars_.take()),
|
|
||||||
length_(other.length_)
|
|
||||||
{
|
|
||||||
other.length_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
AString &operator =(const char *str) {
|
|
||||||
if (str && str[0]) {
|
|
||||||
set(str, strlen(str));
|
|
||||||
} else {
|
|
||||||
chars_ = nullptr;
|
|
||||||
length_ = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
AString &operator =(const AString &other) {
|
|
||||||
if (other.length_) {
|
|
||||||
set(other.chars_, other.length_);
|
|
||||||
} else {
|
|
||||||
chars_ = nullptr;
|
|
||||||
length_ = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
AString &operator =(AString &&other) {
|
|
||||||
chars_ = other.chars_.take();
|
|
||||||
length_ = other.length_;
|
|
||||||
other.length_ = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int compare(const char *str) const {
|
|
||||||
return strcmp(chars(), str);
|
|
||||||
}
|
|
||||||
int compare(const AString &other) const {
|
|
||||||
return strcmp(chars(), other.chars());
|
|
||||||
}
|
|
||||||
bool operator ==(const AString &other) const {
|
|
||||||
return other.length() == length() &&
|
|
||||||
memcmp(other.chars(), chars(), length()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char operator [](size_t index) const {
|
|
||||||
assert(index < length());
|
|
||||||
return chars()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t length() const {
|
|
||||||
return length_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *chars() const {
|
|
||||||
if (!chars_)
|
|
||||||
return "";
|
|
||||||
return chars_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const size_t kInvalidLength = (size_t)-1;
|
|
||||||
|
|
||||||
void set(const char *str, size_t length) {
|
|
||||||
chars_ = new char[length + 1];
|
|
||||||
length_ = length;
|
|
||||||
memcpy(chars_, str, length);
|
|
||||||
chars_[length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoArray<char> chars_;
|
|
||||||
size_t length_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _include_amtl_string_h_
|
|
|
@ -1,213 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_thread_posix_h_
|
|
||||||
#define _include_amtl_thread_posix_h_
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#if defined(__linux__)
|
|
||||||
# include <sys/prctl.h>
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
# include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
class Mutex : public Lockable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Mutex() {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
int rv =
|
|
||||||
#endif
|
|
||||||
pthread_mutex_init(&mutex_, nullptr);
|
|
||||||
assert(rv == 0);
|
|
||||||
}
|
|
||||||
~Mutex() {
|
|
||||||
pthread_mutex_destroy(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DoTryLock() KE_OVERRIDE {
|
|
||||||
return pthread_mutex_trylock(&mutex_) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoLock() KE_OVERRIDE {
|
|
||||||
pthread_mutex_lock(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoUnlock() KE_OVERRIDE {
|
|
||||||
pthread_mutex_unlock(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_t *raw() {
|
|
||||||
return &mutex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
pthread_mutex_t mutex_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Currently, this class only supports single-listener CVs.
|
|
||||||
class ConditionVariable : public Lockable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConditionVariable() {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
int rv =
|
|
||||||
#endif
|
|
||||||
pthread_cond_init(&cv_, nullptr);
|
|
||||||
assert(rv == 0);
|
|
||||||
}
|
|
||||||
~ConditionVariable() {
|
|
||||||
pthread_cond_destroy(&cv_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DoTryLock() KE_OVERRIDE {
|
|
||||||
return mutex_.DoTryLock();
|
|
||||||
}
|
|
||||||
void DoLock() KE_OVERRIDE {
|
|
||||||
mutex_.DoLock();
|
|
||||||
}
|
|
||||||
void DoUnlock() KE_OVERRIDE {
|
|
||||||
mutex_.DoUnlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notify() {
|
|
||||||
AssertCurrentThreadOwns();
|
|
||||||
pthread_cond_signal(&cv_);
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitResult Wait(size_t timeout_ms) {
|
|
||||||
AssertCurrentThreadOwns();
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
struct timespec ts;
|
|
||||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
|
|
||||||
return Wait_Error;
|
|
||||||
#else
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, nullptr);
|
|
||||||
|
|
||||||
struct timespec ts;
|
|
||||||
ts.tv_sec = tv.tv_sec;
|
|
||||||
ts.tv_nsec = tv.tv_usec * 1000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ts.tv_sec += timeout_ms / 1000;
|
|
||||||
ts.tv_nsec += (timeout_ms % 1000) * 1000000;
|
|
||||||
if (ts.tv_nsec >= 1000000000) {
|
|
||||||
ts.tv_sec++;
|
|
||||||
ts.tv_nsec -= 1000000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugSetUnlocked();
|
|
||||||
int rv = pthread_cond_timedwait(&cv_, mutex_.raw(), &ts);
|
|
||||||
DebugSetLocked();
|
|
||||||
|
|
||||||
if (rv == ETIMEDOUT)
|
|
||||||
return Wait_Timeout;
|
|
||||||
if (rv == 0)
|
|
||||||
return Wait_Signaled;
|
|
||||||
return Wait_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitResult Wait() {
|
|
||||||
AssertCurrentThreadOwns();
|
|
||||||
|
|
||||||
DebugSetUnlocked();
|
|
||||||
int rv = pthread_cond_wait(&cv_, mutex_.raw());
|
|
||||||
DebugSetLocked();
|
|
||||||
|
|
||||||
if (rv == 0)
|
|
||||||
return Wait_Signaled;
|
|
||||||
return Wait_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mutex mutex_;
|
|
||||||
pthread_cond_t cv_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Thread
|
|
||||||
{
|
|
||||||
struct ThreadData {
|
|
||||||
IRunnable *run;
|
|
||||||
char name[17];
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
Thread(IRunnable *run, const char *name = nullptr) {
|
|
||||||
ThreadData *data = new ThreadData;
|
|
||||||
data->run = run;
|
|
||||||
snprintf(data->name, sizeof(data->name), "%s", name ? name : "");
|
|
||||||
|
|
||||||
initialized_ = (pthread_create(&thread_, nullptr, Main, data) == 0);
|
|
||||||
if (!initialized_)
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Succeeded() const {
|
|
||||||
return initialized_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Join() {
|
|
||||||
if (!Succeeded())
|
|
||||||
return;
|
|
||||||
pthread_join(thread_, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void *Main(void *arg) {
|
|
||||||
AutoPtr<ThreadData> data((ThreadData *)arg);
|
|
||||||
|
|
||||||
if (data->name[0]) {
|
|
||||||
#if defined(__linux__)
|
|
||||||
prctl(PR_SET_NAME, (unsigned long)data->name);
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
int (*fn)(const char *) = (int (*)(const char *))dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
|
||||||
if (fn)
|
|
||||||
fn(data->name);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
data->run->Run();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool initialized_;
|
|
||||||
pthread_t thread_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_thread_posix_h_
|
|
||||||
|
|
|
@ -1,327 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_threads_
|
|
||||||
#define _include_amtl_threads_
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# include <windows.h>
|
|
||||||
# include <WinBase.h>
|
|
||||||
#else
|
|
||||||
# include <pthread.h>
|
|
||||||
#endif
|
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
// Thread primitives for SourcePawn.
|
|
||||||
//
|
|
||||||
// Linking Requirements:
|
|
||||||
//
|
|
||||||
// OS X: None (-lpthread and -ldl are optional)
|
|
||||||
// Windows: None
|
|
||||||
// Linux: -lpthread -lrt required
|
|
||||||
//
|
|
||||||
// -- Mutexes --
|
|
||||||
//
|
|
||||||
// A Lockable is a mutual exclusion primitive. It can be owned by at most one
|
|
||||||
// thread at a time, and ownership blocks any other thread from taking taking
|
|
||||||
// ownership. Ownership must be acquired and released on the same thread.
|
|
||||||
// Lockables are not re-entrant.
|
|
||||||
//
|
|
||||||
// While a few classes support the Lockable interface, the simplest Lockable
|
|
||||||
// object that can be instantiated is a Mutex.
|
|
||||||
//
|
|
||||||
// -- Condition Variables --
|
|
||||||
//
|
|
||||||
// A ConditionVariable provides mutually exclusive access based on a
|
|
||||||
// condition ocurring. CVs provide two capabilities: Wait(), which will block
|
|
||||||
// until the condition is triggered, and Notify(), which signals any blocking
|
|
||||||
// thread that the condition has occurred.
|
|
||||||
//
|
|
||||||
// Condition variables have an underlying mutex lock. This lock must be
|
|
||||||
// acquired before calling Wait() or Notify(). It is automatically released
|
|
||||||
// once Wait begins blocking. This operation is atomic with respect to other
|
|
||||||
// threads and the mutex. For example, it is not possible for the lock to be
|
|
||||||
// acquired by another thread in between unlocking and blocking. Since Notify
|
|
||||||
// also requires the lock to be acquired, there is no risk of an event
|
|
||||||
// accidentally dissipating into thin air because it was sent before the other
|
|
||||||
// thread began blocking.
|
|
||||||
//
|
|
||||||
// When Wait() returns, the lock is automatically re-acquired. This operation
|
|
||||||
// is NOT atomic. In between waking up and re-acquiring the lock, another
|
|
||||||
// thread may steal the lock and issue another event. Applications must
|
|
||||||
// account for this. For example, a message pump should check that there are
|
|
||||||
// no messages left to process before blocking again.
|
|
||||||
//
|
|
||||||
// Likewise, it is also not defined whether a Signal() will have any effect
|
|
||||||
// while a thread is not waiting on the monitor. This is yet another reason
|
|
||||||
// the above paragraph is so important - applications should, under a lock of
|
|
||||||
// the condition variable - check for state changes before waiting.
|
|
||||||
//
|
|
||||||
// -- Threads --
|
|
||||||
//
|
|
||||||
// A Thread object, when created, spawns a new thread with the given callback
|
|
||||||
// (the callbacks must implement IRunnable). Threads have one method of
|
|
||||||
// interest, Join(), which will block until the thread's execution finishes.
|
|
||||||
// Deleting a thread object will free any operating system resources associated
|
|
||||||
// with that thread, if the thread has finished executing.
|
|
||||||
//
|
|
||||||
// Threads can fail to spawn; make sure to check Succeeded().
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Abstraction for getting a unique thread identifier. Debug-only.
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
typedef DWORD ThreadId;
|
|
||||||
|
|
||||||
static inline ThreadId GetCurrentThreadId()
|
|
||||||
{
|
|
||||||
return ::GetCurrentThreadId();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
typedef pthread_t ThreadId;
|
|
||||||
|
|
||||||
static inline ThreadId GetCurrentThreadId()
|
|
||||||
{
|
|
||||||
return pthread_self();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Classes which use non-reentrant, same-thread lock/unlock semantics should
|
|
||||||
// inherit from this and implement DoLock/DoUnlock.
|
|
||||||
class Lockable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Lockable()
|
|
||||||
{
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
owner_ = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
virtual ~Lockable() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryLock() {
|
|
||||||
if (DoTryLock()) {
|
|
||||||
DebugSetLocked();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lock() {
|
|
||||||
assert(Owner() != GetCurrentThreadId());
|
|
||||||
DoLock();
|
|
||||||
DebugSetLocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unlock() {
|
|
||||||
assert(Owner() == GetCurrentThreadId());
|
|
||||||
DebugSetUnlocked();
|
|
||||||
DoUnlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssertCurrentThreadOwns() const {
|
|
||||||
assert(Owner() == GetCurrentThreadId());
|
|
||||||
}
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
bool Locked() const {
|
|
||||||
return owner_ != 0;
|
|
||||||
}
|
|
||||||
ThreadId Owner() const {
|
|
||||||
return owner_;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual bool DoTryLock() = 0;
|
|
||||||
virtual void DoLock() = 0;
|
|
||||||
virtual void DoUnlock() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void DebugSetUnlocked() {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
owner_ = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
void DebugSetLocked() {
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
owner_ = GetCurrentThreadId();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
ThreadId owner_;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// RAII for automatically locking and unlocking an object.
|
|
||||||
class AutoLock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoLock(Lockable *lock)
|
|
||||||
: lock_(lock)
|
|
||||||
{
|
|
||||||
lock_->Lock();
|
|
||||||
}
|
|
||||||
~AutoLock() {
|
|
||||||
lock_->Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lockable *lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoMaybeLock
|
|
||||||
{
|
|
||||||
friend class AutoMaybeUnlock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AutoMaybeLock(Lockable *lock)
|
|
||||||
: lock_(lock)
|
|
||||||
{
|
|
||||||
if (lock_)
|
|
||||||
lock_->Lock();
|
|
||||||
}
|
|
||||||
~AutoMaybeLock() {
|
|
||||||
if (lock_)
|
|
||||||
lock_->Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock and void the locked object. After calling this, the region covered
|
|
||||||
// by the AutoMaybeLocked is not guaranteed to be locked! This is useful for
|
|
||||||
// patterns like:
|
|
||||||
//
|
|
||||||
// AutoMaybeLock lock(x);
|
|
||||||
// {
|
|
||||||
// ...
|
|
||||||
// return helper(&lock);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// helper_while_locked(AutoMaybeLock *mlock) {
|
|
||||||
// ...
|
|
||||||
// mlock->unlock();
|
|
||||||
// callback
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// In this situation, we can avoid using AutoMaybeUnlock which would re-lock
|
|
||||||
// only to unlock again immediately.
|
|
||||||
void unlock() {
|
|
||||||
if (lock_) {
|
|
||||||
lock_->Unlock();
|
|
||||||
lock_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lockable *lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoMaybeUnlock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoMaybeUnlock(Lockable *lock)
|
|
||||||
: lock_(lock)
|
|
||||||
{
|
|
||||||
if (lock_)
|
|
||||||
lock_->Unlock();
|
|
||||||
}
|
|
||||||
~AutoMaybeUnlock() {
|
|
||||||
if (lock_)
|
|
||||||
lock_->Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lockable *lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoTryLock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoTryLock(Lockable *lock) {
|
|
||||||
lock_ = lock->TryLock() ? lock : nullptr;
|
|
||||||
}
|
|
||||||
~AutoTryLock() {
|
|
||||||
if (lock_)
|
|
||||||
lock_->Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lockable *lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// RAII for automatically unlocking and relocking an object.
|
|
||||||
class AutoUnlock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoUnlock(Lockable *lock)
|
|
||||||
: lock_(lock)
|
|
||||||
{
|
|
||||||
lock_->Unlock();
|
|
||||||
}
|
|
||||||
~AutoUnlock() {
|
|
||||||
lock_->Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lockable *lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WaitResult {
|
|
||||||
// Woke up because something happened.
|
|
||||||
Wait_Signaled,
|
|
||||||
|
|
||||||
// Woke up because nothing happened and a timeout was specified.
|
|
||||||
Wait_Timeout,
|
|
||||||
|
|
||||||
// Woke up, but because of an error.
|
|
||||||
Wait_Error
|
|
||||||
};
|
|
||||||
|
|
||||||
// This must be implemented in order to spawn a new thread.
|
|
||||||
class IRunnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IRunnable() {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Run() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
// Include the actual thread implementations.
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# include "am-thread-windows.h"
|
|
||||||
#else
|
|
||||||
# include "am-thread-posix.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _include_amtl_threads_
|
|
|
@ -1,161 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_thread_windows_h_
|
|
||||||
#define _include_amtl_thread_windows_h_
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
class CriticalSection : public Lockable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CriticalSection() {
|
|
||||||
InitializeCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
~CriticalSection() {
|
|
||||||
DeleteCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DoTryLock() KE_OVERRIDE {
|
|
||||||
return !!TryEnterCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
void DoLock() KE_OVERRIDE {
|
|
||||||
EnterCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoUnlock() KE_OVERRIDE {
|
|
||||||
LeaveCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CRITICAL_SECTION cs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef CriticalSection Mutex;
|
|
||||||
|
|
||||||
// Currently, this class only supports single-listener CVs.
|
|
||||||
class ConditionVariable : public Lockable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConditionVariable() {
|
|
||||||
event_ = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
|
||||||
}
|
|
||||||
~ConditionVariable() {
|
|
||||||
CloseHandle(event_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DoTryLock() KE_OVERRIDE {
|
|
||||||
return cs_.DoTryLock();
|
|
||||||
}
|
|
||||||
void DoLock() KE_OVERRIDE {
|
|
||||||
cs_.DoLock();
|
|
||||||
}
|
|
||||||
void DoUnlock() KE_OVERRIDE {
|
|
||||||
cs_.DoUnlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notify() {
|
|
||||||
AssertCurrentThreadOwns();
|
|
||||||
SetEvent(event_);
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitResult Wait(size_t timeoutMs) {
|
|
||||||
// This will assert if the lock has not been acquired. We don't need to be
|
|
||||||
// atomic here, like pthread_cond_wait, because the event bit will stick
|
|
||||||
// until reset by a wait function.
|
|
||||||
Unlock();
|
|
||||||
DWORD rv = WaitForSingleObject(event_, int(timeoutMs));
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
if (rv == WAIT_TIMEOUT)
|
|
||||||
return Wait_Timeout;
|
|
||||||
if (rv == WAIT_FAILED)
|
|
||||||
return Wait_Error;
|
|
||||||
return Wait_Signaled;
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitResult Wait() {
|
|
||||||
return Wait(INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CriticalSection cs_;
|
|
||||||
HANDLE event_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Thread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Thread(IRunnable *run, const char *name = nullptr) {
|
|
||||||
thread_ = CreateThread(nullptr, 0, Main, run, 0, nullptr);
|
|
||||||
}
|
|
||||||
~Thread() {
|
|
||||||
if (!thread_)
|
|
||||||
return;
|
|
||||||
CloseHandle(thread_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Succeeded() const {
|
|
||||||
return !!thread_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Join() {
|
|
||||||
if (!Succeeded())
|
|
||||||
return;
|
|
||||||
WaitForSingleObject(thread_, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE handle() const {
|
|
||||||
return thread_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static DWORD WINAPI Main(LPVOID arg) {
|
|
||||||
((IRunnable *)arg)->Run();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma pack(push, 8)
|
|
||||||
struct ThreadNameInfo {
|
|
||||||
DWORD dwType;
|
|
||||||
LPCSTR szName;
|
|
||||||
DWORD dwThreadID;
|
|
||||||
DWORD dwFlags;
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
private:
|
|
||||||
HANDLE thread_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_thread_windows_h_
|
|
|
@ -1,176 +0,0 @@
|
||||||
// vim: set sts=2 ts=8 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_thread_local_h_
|
|
||||||
#define _include_amtl_thread_local_h_
|
|
||||||
|
|
||||||
#include <am-thread-utils.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Stores a per-thread value. In single-threaded mode (KE_SINGLE_THREADED),
|
|
||||||
// this is a no-op container wrapper.
|
|
||||||
//
|
|
||||||
// T must be castable to uintptr_t.
|
|
||||||
//
|
|
||||||
// When assigning to a ThreadLocal<T>, the assigment will automatically attempt
|
|
||||||
// to allocate thread-local storage from the operating system. If it fails, it
|
|
||||||
// will abort the program. If this is undesirable, you may call allocate()
|
|
||||||
// up-front and handle the error case manually.
|
|
||||||
//
|
|
||||||
// The number of thread local slots available to processes is limited (on
|
|
||||||
// Linux, it is generally 1024). It is best to use ThreadLocal sparingly to
|
|
||||||
// play nicely with other libraries.
|
|
||||||
//
|
|
||||||
// ThreadLocal will free the underlying thread-local storage slot in its
|
|
||||||
// destructor, but it is not an AutoPtr. It does not delete pointers. Since
|
|
||||||
// one thread's value is only observable from that thread, make sure to free
|
|
||||||
// the contained resource (if necessary) before the thread exits.
|
|
||||||
template <typename T>
|
|
||||||
class ThreadLocal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void operator =(const T &other) {
|
|
||||||
set(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
T operator *() const {
|
|
||||||
return get();
|
|
||||||
}
|
|
||||||
T operator ->() const {
|
|
||||||
return get();
|
|
||||||
}
|
|
||||||
bool operator !() const {
|
|
||||||
return !get();
|
|
||||||
}
|
|
||||||
bool operator ==(const T &other) const {
|
|
||||||
return get() == other;
|
|
||||||
}
|
|
||||||
bool operator !=(const T &other) const {
|
|
||||||
return get() != other;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadLocal(const ThreadLocal &other) KE_DELETE;
|
|
||||||
ThreadLocal &operator =(const ThreadLocal &other) KE_DELETE;
|
|
||||||
|
|
||||||
#if !defined(KE_SINGLE_THREADED)
|
|
||||||
private:
|
|
||||||
volatile int allocated_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadLocal() {
|
|
||||||
allocated_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
T get() const {
|
|
||||||
if (!allocated_)
|
|
||||||
return T();
|
|
||||||
return internalGet();
|
|
||||||
}
|
|
||||||
void set(const T &t) {
|
|
||||||
if (!allocated_ && !allocate()) {
|
|
||||||
fprintf(stderr, "could not allocate thread-local storage\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
internalSet(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
~ThreadLocal() {
|
|
||||||
if (allocated_)
|
|
||||||
TlsFree(key_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T internalGet() const {
|
|
||||||
return reinterpret_cast<T>(TlsGetValue(key_));
|
|
||||||
}
|
|
||||||
void internalSet(const T &t) {
|
|
||||||
TlsSetValue(key_, reinterpret_cast<LPVOID>(t));
|
|
||||||
}
|
|
||||||
bool allocate() {
|
|
||||||
if (InterlockedCompareExchange((volatile LONG *)&allocated_, 1, 0) == 1)
|
|
||||||
return true;
|
|
||||||
key_ = TlsAlloc();
|
|
||||||
return key_ != TLS_OUT_OF_INDEXES;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD key_;
|
|
||||||
|
|
||||||
# else
|
|
||||||
public:
|
|
||||||
~ThreadLocal() {
|
|
||||||
if (allocated_)
|
|
||||||
pthread_key_delete(key_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allocate() {
|
|
||||||
if (!__sync_bool_compare_and_swap(&allocated_, 0, 1))
|
|
||||||
return true;
|
|
||||||
return pthread_key_create(&key_, nullptr) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T internalGet() const {
|
|
||||||
return (T)reinterpret_cast<uintptr_t>(pthread_getspecific(key_));
|
|
||||||
}
|
|
||||||
void internalSet(const T &t) {
|
|
||||||
pthread_setspecific(key_, reinterpret_cast<void *>(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_key_t key_;
|
|
||||||
# endif // !_MSC_VER
|
|
||||||
|
|
||||||
#else // KE_SINGLE_THREADED
|
|
||||||
public:
|
|
||||||
ThreadLocal() {
|
|
||||||
t_ = T();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allocate() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
T get() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
void set(const T &t) {
|
|
||||||
t_ = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T t_;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_thread_local_h_
|
|
|
@ -1,64 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_type_traits_h_
|
|
||||||
#define _include_amtl_type_traits_h_
|
|
||||||
|
|
||||||
#include <am-cxx.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
// Remove references from types.
|
|
||||||
template <typename T>
|
|
||||||
struct remove_reference {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct remove_reference<T &> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
template <typename T>
|
|
||||||
struct remove_reference<T &&> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, T Value>
|
|
||||||
struct integral_constant {
|
|
||||||
static const T value = Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef integral_constant<bool, true> true_type;
|
|
||||||
typedef integral_constant<bool, false> false_type;
|
|
||||||
|
|
||||||
template<class T> struct is_lvalue_reference : false_type{};
|
|
||||||
template<class T> struct is_lvalue_reference<T&> : true_type {};
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_type_traits_h_
|
|
|
@ -1,421 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013-2014, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _include_amtl_utility_h_
|
|
||||||
#define _include_amtl_utility_h_
|
|
||||||
|
|
||||||
#define __STDC_FORMAT_MACROS
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# include <intrin.h>
|
|
||||||
#else
|
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
#include <am-moveable.h>
|
|
||||||
#include <am-cxx.h>
|
|
||||||
#include <am-algorithm.h>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
// Mac file format warning.
|
|
||||||
# pragma warning(disable:4355)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
static const size_t kMallocAlignment = sizeof(void *) * 2;
|
|
||||||
|
|
||||||
static const size_t kKB = 1024;
|
|
||||||
static const size_t kMB = 1024 * kKB;
|
|
||||||
static const size_t kGB = 1024 * kMB;
|
|
||||||
|
|
||||||
template <typename T> T
|
|
||||||
ReturnAndVoid(T &t)
|
|
||||||
{
|
|
||||||
T saved = t;
|
|
||||||
t = T();
|
|
||||||
return saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper that automatically deletes its contents. The pointer can be taken
|
|
||||||
// to avoid destruction.
|
|
||||||
template <typename T>
|
|
||||||
class AutoPtr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoPtr()
|
|
||||||
: t_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
explicit AutoPtr(T *t)
|
|
||||||
: t_(t)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
AutoPtr(AutoPtr &&other)
|
|
||||||
{
|
|
||||||
t_ = other.t_;
|
|
||||||
other.t_ = nullptr;
|
|
||||||
}
|
|
||||||
~AutoPtr() {
|
|
||||||
delete t_;
|
|
||||||
}
|
|
||||||
T *get() {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
T *take() {
|
|
||||||
return ReturnAndVoid(t_);
|
|
||||||
}
|
|
||||||
T *forget() {
|
|
||||||
return ReturnAndVoid(t_);
|
|
||||||
}
|
|
||||||
T *operator *() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
T *operator ->() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
operator T *() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
T *operator =(T *t) {
|
|
||||||
delete t_;
|
|
||||||
t_ = t;
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
T **address() {
|
|
||||||
return &t_;
|
|
||||||
}
|
|
||||||
T *operator =(AutoPtr &&other) {
|
|
||||||
delete t_;
|
|
||||||
t_ = other.t_;
|
|
||||||
other.t_ = nullptr;
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
bool operator !() const {
|
|
||||||
return !t_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoPtr(const AutoPtr &other) KE_DELETE;
|
|
||||||
AutoPtr &operator =(const AutoPtr &other) KE_DELETE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
T *t_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wrapper that automatically deletes its contents. The pointer can be taken
|
|
||||||
// to avoid destruction.
|
|
||||||
template <typename T>
|
|
||||||
class AutoArray
|
|
||||||
{
|
|
||||||
T *t_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AutoArray()
|
|
||||||
: t_(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
explicit AutoArray(T *t)
|
|
||||||
: t_(t)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~AutoArray() {
|
|
||||||
delete [] t_;
|
|
||||||
}
|
|
||||||
T *take() {
|
|
||||||
return ReturnAndVoid(t_);
|
|
||||||
}
|
|
||||||
T *forget() {
|
|
||||||
return ReturnAndVoid(t_);
|
|
||||||
}
|
|
||||||
T **address() {
|
|
||||||
return &t_;
|
|
||||||
}
|
|
||||||
T &operator *() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
operator T *() const {
|
|
||||||
return t_;
|
|
||||||
}
|
|
||||||
void operator =(T *t) {
|
|
||||||
delete [] t_;
|
|
||||||
t_ = t;
|
|
||||||
}
|
|
||||||
bool operator !() const {
|
|
||||||
return !t_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline size_t
|
|
||||||
Log2(size_t number)
|
|
||||||
{
|
|
||||||
assert(number != 0);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
unsigned long rval;
|
|
||||||
# ifdef _M_IX86
|
|
||||||
_BitScanReverse(&rval, number);
|
|
||||||
# elif _M_X64
|
|
||||||
_BitScanReverse64(&rval, number);
|
|
||||||
# endif
|
|
||||||
return rval;
|
|
||||||
#else
|
|
||||||
size_t bit;
|
|
||||||
asm("bsr %1, %0\n"
|
|
||||||
: "=r" (bit)
|
|
||||||
: "rm" (number));
|
|
||||||
return bit;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t
|
|
||||||
FindRightmostBit(size_t number)
|
|
||||||
{
|
|
||||||
assert(number != 0);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
unsigned long rval;
|
|
||||||
# ifdef _M_IX86
|
|
||||||
_BitScanForward(&rval, number);
|
|
||||||
# elif _M_X64
|
|
||||||
_BitScanForward64(&rval, number);
|
|
||||||
# endif
|
|
||||||
return rval;
|
|
||||||
#else
|
|
||||||
size_t bit;
|
|
||||||
asm("bsf %1, %0\n"
|
|
||||||
: "=r" (bit)
|
|
||||||
: "rm" (number));
|
|
||||||
return bit;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
IsPowerOfTwo(size_t value)
|
|
||||||
{
|
|
||||||
if (value == 0)
|
|
||||||
return false;
|
|
||||||
return !(value & (value - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t
|
|
||||||
Align(size_t count, size_t alignment)
|
|
||||||
{
|
|
||||||
assert(IsPowerOfTwo(alignment));
|
|
||||||
return count + (alignment - (count % alignment)) % alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
IsUint32AddSafe(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
if (!a || !b)
|
|
||||||
return true;
|
|
||||||
size_t log2_a = Log2(a);
|
|
||||||
size_t log2_b = Log2(b);
|
|
||||||
return (log2_a < sizeof(unsigned) * 8) &&
|
|
||||||
(log2_b < sizeof(unsigned) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
IsUintPtrAddSafe(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
if (!a || !b)
|
|
||||||
return true;
|
|
||||||
size_t log2_a = Log2(a);
|
|
||||||
size_t log2_b = Log2(b);
|
|
||||||
return (log2_a < sizeof(size_t) * 8) &&
|
|
||||||
(log2_b < sizeof(size_t) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
IsUint32MultiplySafe(unsigned a, unsigned b)
|
|
||||||
{
|
|
||||||
if (a <= 1 || b <= 1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
size_t log2_a = Log2(a);
|
|
||||||
size_t log2_b = Log2(b);
|
|
||||||
return log2_a + log2_b <= sizeof(unsigned) * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
IsUintPtrMultiplySafe(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
if (a <= 1 || b <= 1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
size_t log2_a = Log2(a);
|
|
||||||
size_t log2_b = Log2(b);
|
|
||||||
return log2_a + log2_b <= sizeof(size_t) * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
|
|
||||||
#define IS_ALIGNED(addr, alignment) (!(uintptr_t(addr) & ((alignment) - 1)))
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline bool
|
|
||||||
IsAligned(T addr, size_t alignment)
|
|
||||||
{
|
|
||||||
assert(IsPowerOfTwo(alignment));
|
|
||||||
return !(uintptr_t(addr) & (alignment - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
AlignedBase(void *addr, size_t alignment)
|
|
||||||
{
|
|
||||||
assert(IsPowerOfTwo(alignment));
|
|
||||||
return reinterpret_cast<void *>(uintptr_t(addr) & ~(alignment - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class StorageBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
T *address() {
|
|
||||||
return reinterpret_cast<T *>(buffer_);
|
|
||||||
}
|
|
||||||
const T *address() const {
|
|
||||||
return reinterpret_cast<const T *>(buffer_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
union {
|
|
||||||
char buffer_[sizeof(T)];
|
|
||||||
uint64_t aligned_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class SaveAndSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SaveAndSet(T *location, const T &value)
|
|
||||||
: location_(location),
|
|
||||||
old_(*location)
|
|
||||||
{
|
|
||||||
*location_ = value;
|
|
||||||
}
|
|
||||||
~SaveAndSet() {
|
|
||||||
*location_ = old_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T *location_;
|
|
||||||
T old_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Maybe
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Maybe()
|
|
||||||
: initialized_(false)
|
|
||||||
{}
|
|
||||||
~Maybe() {
|
|
||||||
if (initialized_)
|
|
||||||
t_.address()->~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
new (t_.address()) T();
|
|
||||||
initialized_ = true;
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
void init(U &&u) {
|
|
||||||
new (t_.address()) T(Forward<U>(u));
|
|
||||||
initialized_ = true;
|
|
||||||
}
|
|
||||||
bool initialized() const {
|
|
||||||
return initialized_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool initialized_;
|
|
||||||
StorageBuffer<T> t_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class StackLinked
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
StackLinked<T>(T **prevp)
|
|
||||||
: prevp_(prevp),
|
|
||||||
prev_(*prevp)
|
|
||||||
{
|
|
||||||
*prevp_ = static_cast<T *>(this);
|
|
||||||
}
|
|
||||||
virtual ~StackLinked() {
|
|
||||||
assert(*prevp_ == this);
|
|
||||||
*prevp_ = prev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
T **prevp_;
|
|
||||||
T *prev_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# define KE_FMT_SIZET "Iu"
|
|
||||||
# define KE_FMT_I64 "I64d"
|
|
||||||
# define KE_FMT_U64 "I64u"
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define KE_FMT_SIZET "zu"
|
|
||||||
# define KE_FMT_I64 PRId64
|
|
||||||
# define KE_FMT_U64 PRIu64
|
|
||||||
#else
|
|
||||||
# error "Implement format specifier string"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define KE_CRITICAL_LIKELY(x) __builtin_expect(!!(x), 1)
|
|
||||||
#else
|
|
||||||
# define KE_CRITICAL_LIKELY(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
# define KE_IMPORT __declspec(dllimport)
|
|
||||||
# define KE_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
# define KE_IMPORT
|
|
||||||
# define KE_EXPORT __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KE_EXPORTING)
|
|
||||||
# define KE_LINK KE_EXPORT
|
|
||||||
#elif defined(KE_IMPORTING)
|
|
||||||
# define KE_LINK KE_IMPORT
|
|
||||||
#else
|
|
||||||
# define KE_LINK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace ke
|
|
||||||
|
|
||||||
#endif // _include_amtl_utility_h_
|
|
|
@ -1,262 +0,0 @@
|
||||||
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
|
|
||||||
#define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <am-allocator-policies.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-moveable.h>
|
|
||||||
|
|
||||||
namespace ke {
|
|
||||||
|
|
||||||
template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
|
|
||||||
class Vector : public AllocPolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Vector(AllocPolicy = AllocPolicy())
|
|
||||||
: data_(nullptr),
|
|
||||||
nitems_(0),
|
|
||||||
maxsize_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector(Vector &&other) {
|
|
||||||
data_ = other.data_;
|
|
||||||
nitems_ = other.nitems_;
|
|
||||||
maxsize_ = other.maxsize_;
|
|
||||||
other.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Vector() {
|
|
||||||
zap();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool append(U &&item) {
|
|
||||||
if (!growIfNeeded(1))
|
|
||||||
return false;
|
|
||||||
new (&data_[nitems_]) T(ke::Forward<U>(item));
|
|
||||||
nitems_++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
void infallibleAppend(U &&item) {
|
|
||||||
assert(growIfNeeded(1));
|
|
||||||
new (&data_[nitems_]) T(ke::Forward<U>(item));
|
|
||||||
nitems_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shift all elements including |at| up by one, and insert |item| at the
|
|
||||||
// given position. If |at| is one greater than the last usable index,
|
|
||||||
// i.e. |at == length()|, then this is the same as append(). No other
|
|
||||||
// invalid indexes are allowed.
|
|
||||||
//
|
|
||||||
// This is a linear-time operation.
|
|
||||||
template <typename U>
|
|
||||||
bool insert(size_t at, U &&item) {
|
|
||||||
if (at == length())
|
|
||||||
return append(ke::Forward<U>(item));
|
|
||||||
if (!moveUp(at))
|
|
||||||
return false;
|
|
||||||
new (&data_[at]) T(ke::Forward<U>(item));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shift all elements at the given position down, removing the given
|
|
||||||
// element. This is a linear-time operation.
|
|
||||||
void remove(size_t at) {
|
|
||||||
for (size_t i = at; i < length() - 1; i++)
|
|
||||||
data_[i] = ke::Move(data_[i + 1]);
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
T popCopy() {
|
|
||||||
T t = at(length() - 1);
|
|
||||||
pop();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
void pop() {
|
|
||||||
assert(nitems_);
|
|
||||||
data_[nitems_ - 1].~T();
|
|
||||||
nitems_--;
|
|
||||||
}
|
|
||||||
bool empty() const {
|
|
||||||
return length() == 0;
|
|
||||||
}
|
|
||||||
size_t length() const {
|
|
||||||
return nitems_;
|
|
||||||
}
|
|
||||||
T& at(size_t i) {
|
|
||||||
assert(i < length());
|
|
||||||
return data_[i];
|
|
||||||
}
|
|
||||||
const T& at(size_t i) const {
|
|
||||||
assert(i < length());
|
|
||||||
return data_[i];
|
|
||||||
}
|
|
||||||
T& operator [](size_t i) {
|
|
||||||
return at(i);
|
|
||||||
}
|
|
||||||
const T& operator [](size_t i) const {
|
|
||||||
return at(i);
|
|
||||||
}
|
|
||||||
void clear() {
|
|
||||||
nitems_ = 0;
|
|
||||||
}
|
|
||||||
const T &back() const {
|
|
||||||
return at(length() - 1);
|
|
||||||
}
|
|
||||||
T &back() {
|
|
||||||
return at(length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
T *buffer() {
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
const T *buffer() const {
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool resize(size_t newLength) {
|
|
||||||
if (newLength < length()) {
|
|
||||||
while (newLength < length())
|
|
||||||
pop();
|
|
||||||
} else if (newLength > length()) {
|
|
||||||
if (!ensure(newLength))
|
|
||||||
return false;
|
|
||||||
size_t count = newLength - length();
|
|
||||||
for (size_t i = 0; i < count; i++)
|
|
||||||
infallibleAppend(T());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool ensure(size_t desired) {
|
|
||||||
if (desired <= length())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return growIfNeeded(desired - length());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
bool extend(U &&other) {
|
|
||||||
if (length() == 0) {
|
|
||||||
*this = Move(other);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < other.length(); i++) {
|
|
||||||
if (!append(Move(other[i])))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector &operator =(Vector &&other) {
|
|
||||||
zap();
|
|
||||||
data_ = other.data_;
|
|
||||||
nitems_ = other.nitems_;
|
|
||||||
maxsize_ = other.maxsize_;
|
|
||||||
other.reset();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// These are disallowed because they basically violate the failure handling
|
|
||||||
// model for AllocPolicies and are also likely to have abysmal performance.
|
|
||||||
Vector(const Vector<T> &other) KE_DELETE;
|
|
||||||
Vector &operator =(const Vector<T> &other) KE_DELETE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void zap() {
|
|
||||||
for (size_t i = 0; i < nitems_; i++)
|
|
||||||
data_[i].~T();
|
|
||||||
this->free(data_);
|
|
||||||
}
|
|
||||||
void reset() {
|
|
||||||
data_ = nullptr;
|
|
||||||
nitems_ = 0;
|
|
||||||
maxsize_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool moveUp(size_t at) {
|
|
||||||
// Note: we don't use append() here. Passing an element as a Moveable into
|
|
||||||
// insert() or append() can break, since the underlying storage could be
|
|
||||||
// reallocated, invalidating the Moveable reference. Instead, we inline
|
|
||||||
// the logic to append() to ensure growIfNeeded occurs before any
|
|
||||||
// references are taken.
|
|
||||||
if (!growIfNeeded(1))
|
|
||||||
return false;
|
|
||||||
new (&data_[nitems_]) T(ke::Move(data_[nitems_ - 1]));
|
|
||||||
nitems_++;
|
|
||||||
for (size_t i = nitems_ - 2; i > at; i--)
|
|
||||||
data_[i] = ke::Move(data_[i - 1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool growIfNeeded(size_t needed)
|
|
||||||
{
|
|
||||||
if (!IsUintPtrAddSafe(nitems_, needed)) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (nitems_ + needed < maxsize_)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
size_t new_maxsize = maxsize_ ? maxsize_ : 8;
|
|
||||||
while (nitems_ + needed > new_maxsize) {
|
|
||||||
if (!IsUintPtrMultiplySafe(new_maxsize, 2)) {
|
|
||||||
this->reportAllocationOverflow();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
new_maxsize *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* newdata = (T*)this->malloc(sizeof(T) * new_maxsize);
|
|
||||||
if (newdata == nullptr)
|
|
||||||
return false;
|
|
||||||
MoveRange<T>(newdata, data_, nitems_);
|
|
||||||
this->free(data_);
|
|
||||||
|
|
||||||
data_ = newdata;
|
|
||||||
maxsize_ = new_maxsize;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* data_;
|
|
||||||
size_t nitems_;
|
|
||||||
size_t maxsize_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <am-moveable.h>
|
||||||
|
|
||||||
#ifndef _include_sourcemod_namehashset_h_
|
#ifndef _include_sourcemod_namehashset_h_
|
||||||
#define _include_sourcemod_namehashset_h_
|
#define _include_sourcemod_namehashset_h_
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@
|
||||||
#include <am-allocator-policies.h>
|
#include <am-allocator-policies.h>
|
||||||
#include <am-hashmap.h>
|
#include <am-hashmap.h>
|
||||||
#include <am-string.h>
|
#include <am-string.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include "sm_stringhashmap.h"
|
||||||
|
|
||||||
//namespace SourceMod
|
//namespace SourceMod
|
||||||
//{
|
//{
|
||||||
|
@ -117,14 +119,10 @@ public:
|
||||||
return table_.findForAdd(aKey);
|
return table_.findForAdd(aKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(Insert &i, const T &value)
|
template <typename U>
|
||||||
|
void add(Insert &i, U &&value)
|
||||||
{
|
{
|
||||||
return table_.add(i, value);
|
return table_.add(i, ke::Forward<U>(value));
|
||||||
}
|
|
||||||
|
|
||||||
void add(Insert &i, T &&value)
|
|
||||||
{
|
|
||||||
return table_.add(i, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool retrieve(const char *aKey, T *value)
|
bool retrieve(const char *aKey, T *value)
|
||||||
|
@ -137,22 +135,14 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert(const char *aKey, const T &value)
|
template <typename U>
|
||||||
|
bool insert(const char *aKey, U &&value)
|
||||||
{
|
{
|
||||||
CharsAndLength key(aKey);
|
CharsAndLength key(aKey);
|
||||||
Insert i = table_.findForAdd(key);
|
Insert i = table_.findForAdd(key);
|
||||||
if (i.found())
|
if (i.found())
|
||||||
return false;
|
return false;
|
||||||
return table_.add(i, value);
|
return table_.add(i, ke::Forward<U>(value));
|
||||||
}
|
|
||||||
|
|
||||||
bool insert(const char *aKey, T &&value)
|
|
||||||
{
|
|
||||||
CharsAndLength key(aKey);
|
|
||||||
Insert i = table_.findForAdd(key);
|
|
||||||
if (i.found())
|
|
||||||
return false;
|
|
||||||
return table_.add(i, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains(const char *aKey)
|
bool contains(const char *aKey)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user