mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Squashed 'Subtrees/leveldb/' changes from ab82e57..ae6c262
ae6c262 Merge branch 'leveldb' into ripple-fork 28fa222 Looks like a bit more delay is needed to smooth the latency. a18f3e6 Tidy up JobQueue, add ripple_core module 18b245c Added GNU/kFreeBSD kernel name (TARGET_OS) git-subtree-dir: Subtrees/leveldb git-subtree-split: ae6c2620b2ef3d5c69e63dc0eda865d6a39fa061
This commit is contained in:
@@ -1,10 +0,0 @@
|
|||||||
;; Emacs - Code style and formatting settings
|
|
||||||
|
|
||||||
;; C++
|
|
||||||
((c++-mode
|
|
||||||
(indent-tabs-mode . t)
|
|
||||||
(tab-width . 4)
|
|
||||||
(c-basic-offset . 4)))
|
|
||||||
|
|
||||||
;; Headers should open in C++ mode
|
|
||||||
((c-mode . ((mode . c++))))
|
|
||||||
13
.gitattributes
vendored
13
.gitattributes
vendored
@@ -1,13 +0,0 @@
|
|||||||
# Set default behaviour, in case users don't have core.autocrlf set.
|
|
||||||
* text=auto
|
|
||||||
|
|
||||||
# These annoying files
|
|
||||||
rippled.1 binary
|
|
||||||
LICENSE binary
|
|
||||||
|
|
||||||
# Visual Studio
|
|
||||||
*.sln text eol=crlf
|
|
||||||
*.vcproj text eol=crlf
|
|
||||||
*.vcxproj text eol=crlf
|
|
||||||
*.props text eol=crlf
|
|
||||||
*.filters text eol=crlf
|
|
||||||
53
.gitignore
vendored
53
.gitignore
vendored
@@ -1,43 +1,12 @@
|
|||||||
# .gitignore
|
build_config.mk
|
||||||
|
*.a
|
||||||
# Ignore vim swap files.
|
|
||||||
*.swp
|
|
||||||
|
|
||||||
# Ignore SCons support files.
|
|
||||||
.sconsign.dblite
|
|
||||||
|
|
||||||
# Ignore python compiled files.
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
# Ignore Macintosh Desktop Services Store files.
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Ignore backup/temps
|
|
||||||
*~
|
|
||||||
|
|
||||||
# Ignore object files.
|
|
||||||
*.o
|
*.o
|
||||||
build
|
*.dylib*
|
||||||
tags
|
*.so
|
||||||
bin/rippled
|
*.so.*
|
||||||
Debug/*.*
|
*_test
|
||||||
Release/*.*
|
db_bench
|
||||||
|
Release
|
||||||
# Ignore locally installed node_modules
|
Debug
|
||||||
node_modules
|
Benchmark
|
||||||
|
vs2010.*
|
||||||
# Ignore tmp directory.
|
|
||||||
tmp
|
|
||||||
|
|
||||||
# Ignore database directory.
|
|
||||||
db
|
|
||||||
db/*.db
|
|
||||||
db/*.db-*
|
|
||||||
|
|
||||||
# Ignore customized configs
|
|
||||||
rippled.cfg
|
|
||||||
validators.txt
|
|
||||||
test/config.js
|
|
||||||
|
|
||||||
# Doxygen generated documentation output
|
|
||||||
HtmlDocumentation
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
#ifndef BEAST_BEASTCONFIG_HEADER
|
|
||||||
#define BEAST_BEASTCONFIG_HEADER
|
|
||||||
|
|
||||||
// beast_core flags:
|
|
||||||
|
|
||||||
#ifndef BEAST_FORCE_DEBUG
|
|
||||||
//#define BEAST_FORCE_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_LOG_ASSERTIONS
|
|
||||||
//#define BEAST_LOG_ASSERTIONS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
//#define BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
|
||||||
//#define BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros">
|
|
||||||
<RepoDir>..\..</RepoDir>
|
|
||||||
<SrcDir>$(RepoDir)\src\cpp\ripple</SrcDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutDir>$(RepoDir)\build\VisualStudio2010\$(Configuration).$(Platform)\</OutDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<IntDir>$(RepoDir)\build\obj\VisualStudio2010\$(Configuration).$(Platform)\</IntDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(RepoDir);$(RepoDir)\src\cpp\leveldb;$(RepoDir)\src\cpp\leveldb\include;$(RepoDir)\src\cpp\protobuf\src;$(RepoDir)\src\cpp\protobuf\vsprojects;$(RepoDir)\build\proto;$(RepoDir)\Subtrees\beast;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<PreprocessorDefinitions>USE_LEVELDB;BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<BuildMacro Include="RepoDir">
|
|
||||||
<Value>$(RepoDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
<BuildMacro Include="SrcDir">
|
|
||||||
<Value>$(SrcDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
|
||||||
# Visual Studio 2010
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{EE95954F-3D34-4FB1-ADBD-FE8395233026}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{EE95954F-3D34-4FB1-ADBD-FE8395233026}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{EE95954F-3D34-4FB1-ADBD-FE8395233026}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{EE95954F-3D34-4FB1-ADBD-FE8395233026}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{EE95954F-3D34-4FB1-ADBD-FE8395233026}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{EE95954F-3D34-4FB1-ADBD-FE8395233026}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>RippleD</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
<Import Project="RippleD.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt1.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt2.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt3.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt4.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_basics\ripple_basics.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_data\ripple_data.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\cpp\database\sqlite3.c" />
|
|
||||||
<ClCompile Include="..\..\src\cpp\leveldb_core.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\cpp\protobuf_core.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\cpp\websocket_core.cpp" />
|
|
||||||
<ClCompile Include="..\..\Subtrees\beast\modules\beast_basics\beast_basics.cpp" />
|
|
||||||
<ClCompile Include="..\..\Subtrees\beast\modules\beast_core\beast_core.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt1.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt2.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt3.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt4.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_basics\ripple_basics.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\ripple_data\ripple_data.cpp" />
|
|
||||||
<ClCompile Include="..\..\Subtrees\beast\modules\beast_basics\beast_basics.cpp">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\Subtrees\beast\modules\beast_core\beast_core.cpp">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\cpp\leveldb_core.cpp">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\cpp\protobuf_core.cpp">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\cpp\websocket_core.cpp">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\cpp\database\sqlite3.c">
|
|
||||||
<Filter>Subtrees</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Ripple">
|
|
||||||
<UniqueIdentifier>{63db902e-0e7a-42d1-b5f5-663e4b48786c}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Subtrees">
|
|
||||||
<UniqueIdentifier>{469e8a0a-64bf-4fa1-8b6f-81207db68577}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Express 2012 for Windows Desktop
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{19465545-42EE-42FA-9CC8-F8975F8F1CC7}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "beast", "..\..\Subtrees\beast\Builds\VisualStudio2012\beast.vcxproj", "{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|x64.Build.0 = Release|x64
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Debug|x64.ActiveCfg = Debug|Win32
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}.Release|x64.ActiveCfg = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros">
|
|
||||||
<RepoDir>..\..</RepoDir>
|
|
||||||
<SrcDir>$(RepoDir)\src\cpp\ripple</SrcDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutDir>$(RepoDir)\build\VisualStudio2012\$(Configuration).$(Platform)\</OutDir>
|
|
||||||
<IntDir>$(RepoDir)\build\obj\VisualStudio2012\$(Configuration).$(Platform)\</IntDir>
|
|
||||||
<TargetName>rippled</TargetName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<AdditionalIncludeDirectories>$(RepoDir);$(RepoDir)\src\cpp\protobuf\src;$(RepoDir)\src\cpp\protobuf\vsprojects;$(RepoDir)\build\proto;$(RepoDir)\Subtrees;$(RepoDir)\Subtrees\leveldb;$(RepoDir)\Subtrees\leveldb\include;$(RepoDir)\Subtrees\beast;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<ExceptionHandling>Async</ExceptionHandling>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<BuildMacro Include="RepoDir">
|
|
||||||
<Value>$(RepoDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
<BuildMacro Include="SrcDir">
|
|
||||||
<Value>$(SrcDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
Place XCode project file here!
|
|
||||||
17
CHANGELOG
17
CHANGELOG
@@ -1,17 +0,0 @@
|
|||||||
Critical protocol changes
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Mon Apr 8 16:13:12 PDT 2013
|
|
||||||
* The JSON field "inLedger" changing to "ledger_index"
|
|
||||||
|
|
||||||
Previous
|
|
||||||
* The JSON field "metaData" changing to "meta".
|
|
||||||
* RPC ledger will no longer take "ledger", use "ledger_hash" or "ledger_index".
|
|
||||||
* "ledgerClose" events:
|
|
||||||
** "hash" DEPRECATED: use "ledger_hash"
|
|
||||||
** "seqNum" DEPRECATED: use "ledger_index"
|
|
||||||
** "closeTime" DEPRECATED: use "close" or "close_human"
|
|
||||||
* stream "rt_accounts" --> "accounts_proposed"
|
|
||||||
* stream "rt_transactions" --> "transactions_proposed"
|
|
||||||
* subscribe "username" --> "url_username"
|
|
||||||
* subscribe "password" --> "url_password"
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Form
|
|
||||||
|
|
||||||
- One class per header file.
|
|
||||||
- Place each data member on its own line.
|
|
||||||
- Place each ctor-initializer on its own line.
|
|
||||||
- Create typedefs for primitive types to describe them.
|
|
||||||
- Return descriptive local variables instead of constants.
|
|
||||||
- Use long descriptive names instead of abbreviations.
|
|
||||||
- Use "explicit" for single-argument ctors
|
|
||||||
- Avoid globals especially objects with static storage duration
|
|
||||||
- Order class declarations as types, public, protected, private, then data.
|
|
||||||
- Prefer 'private' over 'protected'
|
|
||||||
|
|
||||||
# Function
|
|
||||||
|
|
||||||
- Minimize external dependencies
|
|
||||||
* Pass options in the ctor instead of using theConfig
|
|
||||||
* Use as few other classes as possible
|
|
||||||
217
CodingStyle.md
217
CodingStyle.md
@@ -1,217 +0,0 @@
|
|||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Coding Standards
|
|
||||||
|
|
||||||
Coding standards used here are extreme strict and consistent. The style
|
|
||||||
evolved gradually over the years, incorporating generally acknowledged
|
|
||||||
best-practice C++ advice, experience, and personal preference.
|
|
||||||
|
|
||||||
## Don't Repeat Yourself!
|
|
||||||
|
|
||||||
The [Don't Repeat Yourself][1] principle summarises the essence of what it
|
|
||||||
means to write good code, in all languages, at all levels.
|
|
||||||
|
|
||||||
## Formatting
|
|
||||||
|
|
||||||
The goal of source code formatting should always be to make things as easy to
|
|
||||||
read as possible. White space is used to guide the eye so that details are not
|
|
||||||
overlooked. Blank lines are used to separate code into "paragraphs."
|
|
||||||
|
|
||||||
* No tab characters please.
|
|
||||||
* Tab stops are set to 4 spaces.
|
|
||||||
* Braces are indented in the [Allman style][2].
|
|
||||||
* Always place a space before and after all binary operators,
|
|
||||||
especially assignments (`operator=`).
|
|
||||||
* The `!` operator should always be followed by a space.
|
|
||||||
* The `~` operator should be preceded by a space, but not followed by one.
|
|
||||||
* The `++` and `--` operators should have no spaces between the operator and
|
|
||||||
the operand.
|
|
||||||
* A space never appears before a comma, and always appears after a comma.
|
|
||||||
* Always place a space before an opening parenthesis. One exception is if
|
|
||||||
the parentheses are empty.
|
|
||||||
* Don't put spaces after a parenthesis. A typical member function call might
|
|
||||||
look like this: `foobar (1, 2, 3);`
|
|
||||||
* In general, leave a blank line before an `if` statement.
|
|
||||||
* In general, leave a blank line after a closing brace `}`.
|
|
||||||
* Do not place code or comments on the same line as any opening or
|
|
||||||
closing brace.
|
|
||||||
* Do not write `if` statements all-on-one-line. The exception to this is when
|
|
||||||
you've got a sequence of similar `if` statements, and are aligning them all
|
|
||||||
vertically to highlight their similarities.
|
|
||||||
* In an `if-else` statement, if you surround one half of the statement with
|
|
||||||
braces, you also need to put braces around the other half, to match.
|
|
||||||
* When writing a pointer type, use this spacing: `SomeObject* myObject`.
|
|
||||||
Technically, a more correct spacing would be `SomeObject *myObject`, but
|
|
||||||
it makes more sense for the asterisk to be grouped with the type name,
|
|
||||||
since being a pointer is part of the type, not the variable name. The only
|
|
||||||
time that this can lead to any problems is when you're declaring multiple
|
|
||||||
pointers of the same type in the same statement - which leads on to the next
|
|
||||||
rule:
|
|
||||||
* When declaring multiple pointers, never do so in a single statement, e.g.
|
|
||||||
`SomeObject* p1, *p2;` - instead, always split them out onto separate lines
|
|
||||||
and write the type name again, to make it quite clear what's going on, and
|
|
||||||
avoid the danger of missing out any vital asterisks.
|
|
||||||
* The previous point also applies to references, so always put the `&` next to
|
|
||||||
the type rather than the variable, e.g. `void foo (Thing const& thing)`. And
|
|
||||||
don't put a space on both sides of the `*` or `&` - always put a space after
|
|
||||||
it, but never before it.
|
|
||||||
* The word `const` should be placed to the right of the thing that it modifies,
|
|
||||||
for consistency. For example `int const` refers to an int which is const.
|
|
||||||
`int const*` is a pointer to an int which is const. `int *const` is a const
|
|
||||||
pointer to an int.
|
|
||||||
* Always place a space in between the template angle brackets and the type
|
|
||||||
name. Template code is already hard enough to read!
|
|
||||||
|
|
||||||
## Naming conventions
|
|
||||||
|
|
||||||
* Member variables and method names are written with camel-case, and never
|
|
||||||
begin with a capital letter.
|
|
||||||
* Class names are also written in camel-case, but always begin with a capital
|
|
||||||
letter.
|
|
||||||
* For global variables... well, you shouldn't have any, so it doesn't matter.
|
|
||||||
* Class data members begin with `m_`, static data members begin with `s_`.
|
|
||||||
Global variables begin with `g_`. This is so the scope of the corresponding
|
|
||||||
declaration can be easily determined.
|
|
||||||
* Avoid underscores in your names, especially leading or trailing underscores.
|
|
||||||
In particular, leading underscores should be avoided, as these are often used
|
|
||||||
in standard library code, so to use them in your own code looks quite jarring.
|
|
||||||
* If you really have to write a macro for some reason, then make it all caps,
|
|
||||||
with underscores to separate the words. And obviously make sure that its name
|
|
||||||
is unlikely to clash with symbols used in other libraries or 3rd party code.
|
|
||||||
|
|
||||||
## Types, const-correctness
|
|
||||||
|
|
||||||
* If a method can (and should!) be const, make it const!
|
|
||||||
* If a method definitely doesn't throw an exception (be careful!), mark it as
|
|
||||||
`noexcept`
|
|
||||||
* When returning a temporary object, e.g. a String, the returned object should
|
|
||||||
be non-const, so that if the class has a C++11 move operator, it can be used.
|
|
||||||
* If a local variable can be const, then make it const!
|
|
||||||
* Remember that pointers can be const as well as primitives; For example, if
|
|
||||||
you have a `char*` whose contents are going to be altered, you may still be
|
|
||||||
able to make the pointer itself const, e.g. `char* const foobar = getFoobar();`.
|
|
||||||
* Do not declare all your local variables at the top of a function or method
|
|
||||||
(i.e. in the old-fashioned C-style). Declare them at the last possible moment,
|
|
||||||
and give them as small a scope as possible.
|
|
||||||
* Object parameters should be passed as `const&` wherever possible. Only
|
|
||||||
pass a parameter as a copy-by-value object if you really need to mutate
|
|
||||||
a local copy inside the method, and if making a local copy inside the method
|
|
||||||
would be difficult.
|
|
||||||
* Use portable `for()` loop variable scoping (i.e. do not have multiple for
|
|
||||||
loops in the same scope that each re-declare the same variable name, as
|
|
||||||
this fails on older compilers)
|
|
||||||
* When you're testing a pointer to see if it's null, never write
|
|
||||||
`if (myPointer)`. Always avoid that implicit cast-to-bool by writing it more
|
|
||||||
fully: `if (myPointer != nullptr)`. And likewise, never ever write
|
|
||||||
`if (! myPointer)`, instead always write `if (myPointer == nullptr)`.
|
|
||||||
It is more readable that way.
|
|
||||||
* Avoid C-style casts except when converting between primitive numeric types.
|
|
||||||
Some people would say "avoid C-style casts altogether", but `static_cast` is
|
|
||||||
a bit unreadable when you just want to cast an `int` to a `float`. But
|
|
||||||
whenever a pointer is involved, or a non-primitive object, always use
|
|
||||||
`static_cast`. And when you're reinterpreting data, always use
|
|
||||||
`reinterpret_cast`.
|
|
||||||
* Until C++ gets a universal 64-bit primitive type (part of the C++11
|
|
||||||
standard), it's best to stick to the `int64` and `uint64` typedefs.
|
|
||||||
|
|
||||||
## Object lifetime and ownership
|
|
||||||
|
|
||||||
* Absolutely do NOT use `delete`, `deleteAndZero`, etc. There are very very few
|
|
||||||
situations where you can't use a `ScopedPointer` or some other automatic
|
|
||||||
lifetime management class.
|
|
||||||
* Do not use `new` unless there's no alternative. Whenever you type `new`, always
|
|
||||||
treat it as a failure to find a better solution. If a local variable can be
|
|
||||||
allocated on the stack rather than the heap, then always do so.
|
|
||||||
* Do not ever use `new` or `malloc` to allocate a C++ array. Always use a
|
|
||||||
`HeapBlock` instead.
|
|
||||||
* And just to make it doubly clear: Never use `malloc` or `calloc`.
|
|
||||||
* If a parent object needs to create and own some kind of child object, always
|
|
||||||
use composition as your first choice. If that's not possible (e.g. if the
|
|
||||||
child needs a pointer to the parent for its constructor), then use a
|
|
||||||
`ScopedPointer`.
|
|
||||||
* If possible, pass an object as a reference rather than a pointer. If possible,
|
|
||||||
make it a `const` reference.
|
|
||||||
* Obviously avoid static and global values. Sometimes there's no alternative,
|
|
||||||
but if there is an alternative, then use it, no matter how much effort it
|
|
||||||
involves.
|
|
||||||
* If allocating a local POD structure (e.g. an operating-system structure in
|
|
||||||
native code), and you need to initialise it with zeros, use the `= { 0 };`
|
|
||||||
syntax as your first choice for doing this. If for some reason that's not
|
|
||||||
appropriate, use the `zerostruct()` function, or in case that isn't suitable,
|
|
||||||
use `zeromem()`. Don't use `memset()`.
|
|
||||||
|
|
||||||
## Classes
|
|
||||||
|
|
||||||
* Declare a class's public section first, and put its constructors and
|
|
||||||
destructor first. Any protected items come next, and then private ones.
|
|
||||||
* Use the most restrictive access-specifier possible for each member. Prefer
|
|
||||||
`private` over `protected`, and `protected` over `public`. Don't expose
|
|
||||||
things unnecessarily.
|
|
||||||
* Preferred positioning for any inherited classes is to put them to the right
|
|
||||||
of the class name, vertically aligned, e.g.:
|
|
||||||
class Thing : public Foo,
|
|
||||||
private Bar
|
|
||||||
{
|
|
||||||
}
|
|
||||||
* Put a class's member variables (which should almost always be private, of course),
|
|
||||||
after all the public and protected method declarations.
|
|
||||||
* Any private methods can go towards the end of the class, after the member
|
|
||||||
variables.
|
|
||||||
* If your class does not have copy-by-value semantics, derive the class from
|
|
||||||
`Uncopyable`.
|
|
||||||
* If your class is likely to be leaked, then derive your class from
|
|
||||||
`LeakChecked<>`.
|
|
||||||
* Constructors that take a single parameter should be default be marked
|
|
||||||
`explicit`. Obviously there are cases where you do want implicit conversion,
|
|
||||||
but always think about it carefully before writing a non-explicit constructor.
|
|
||||||
* Do not use `NULL`, `null`, or 0 for a null-pointer. And especially never use
|
|
||||||
'0L', which is particulary burdensome. Use `nullptr` instead - this is the
|
|
||||||
C++2011 standard, so get used to it. There's a fallback definition for `nullptr`
|
|
||||||
in Beast, so it's always possible to use it even if your compiler isn't yet
|
|
||||||
C++2011 compliant.
|
|
||||||
* All the C++ 'guru' books and articles are full of excellent and detailed advice
|
|
||||||
on when it's best to use inheritance vs composition. If you're not already
|
|
||||||
familiar with the received wisdom in these matters, then do some reading!
|
|
||||||
|
|
||||||
## Miscellaneous
|
|
||||||
|
|
||||||
* `goto` statements should not be used at all, even if the alternative is
|
|
||||||
more verbose code. The only exception is when implementing an algorithm in
|
|
||||||
a function as a state machine.
|
|
||||||
* Don't use macros! OK, obviously there are many situations where they're the
|
|
||||||
right tool for the job, but treat them as a last resort. Certainly don't ever
|
|
||||||
use a macro just to hold a constant value or to perform any kind of function
|
|
||||||
that could have been done as a real inline function. And it goes without saying
|
|
||||||
that you should give them names which aren't going to clash with other code.
|
|
||||||
And `#undef` them after you've used them, if possible.
|
|
||||||
* When using the `++` or `--` operators, never use post-increment if
|
|
||||||
pre-increment could be used instead. Although it doesn't matter for
|
|
||||||
primitive types, it's good practice to pre-increment since this can be
|
|
||||||
much more efficient for more complex objects. In particular, if you're
|
|
||||||
writing a for loop, always use pre-increment,
|
|
||||||
e.g. `for (int = 0; i < 10; ++i)`
|
|
||||||
* Never put an "else" statement after a "return"! This is well-explained in the
|
|
||||||
LLVM coding standards...and a couple of other very good pieces of advice from
|
|
||||||
the LLVM standards are in there as well.
|
|
||||||
* When getting a possibly-null pointer and using it only if it's non-null, limit
|
|
||||||
the scope of the pointer as much as possible - e.g. Do NOT do this:
|
|
||||||
|
|
||||||
Foo* f = getFoo ();
|
|
||||||
if (f != nullptr)
|
|
||||||
f->doSomething ();
|
|
||||||
// other code
|
|
||||||
f->doSomething (); // oops! f may be null!
|
|
||||||
|
|
||||||
..instead, prefer to write it like this, which reduces the scope of the
|
|
||||||
pointer, making it impossible to write code that accidentally uses a null
|
|
||||||
pointer:
|
|
||||||
|
|
||||||
if (Foo* f = getFoo ())
|
|
||||||
f->doSomethingElse ();
|
|
||||||
|
|
||||||
// f is out-of-scope here, so impossible to use it if it's null
|
|
||||||
|
|
||||||
(This also results in smaller, cleaner code)
|
|
||||||
|
|
||||||
[1]: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
|
||||||
[2]: http://en.wikipedia.org/wiki/Indent_style#Allman_style
|
|
||||||
14
LEVELDB.txt
14
LEVELDB.txt
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
To use LevelDB, follow these steps:
|
|
||||||
|
|
||||||
1) Add the following to your rippled.cfg file:
|
|
||||||
[node_db]
|
|
||||||
LevelDB
|
|
||||||
|
|
||||||
2) If you have no databases, you can just start rippled. If you have
|
|
||||||
databases you don't care about, just remove them. Otherwise, start rippled
|
|
||||||
with '--import' to import your existing hashnode database into LevelDB.
|
|
||||||
After you import the hashnode database, either delete (or move) the
|
|
||||||
'hashnode.db', 'hashnode.db-shm' and 'hashnode.db-wal' files from your
|
|
||||||
database directory. Do not touch the LevelDB files in the 'hashnode'
|
|
||||||
directory.
|
|
||||||
16
README.md
16
README.md
@@ -1,16 +0,0 @@
|
|||||||
Ripple - P2P Payment Network
|
|
||||||
============================
|
|
||||||
|
|
||||||
Some portions of this source code are currently closed source.
|
|
||||||
|
|
||||||
This is the repository for Ripple's `rippled`, reference P2P network server.
|
|
||||||
|
|
||||||
Build instructions:
|
|
||||||
* https://ripple.com/wiki/Rippled_build_instructions
|
|
||||||
|
|
||||||
Setup instructions:
|
|
||||||
* https://ripple.com/wiki/Rippled_setup_instructions
|
|
||||||
|
|
||||||
For more information:
|
|
||||||
* https://ripple.com
|
|
||||||
* https://ripple.com/wiki
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros">
|
|
||||||
<RepoDir>.</RepoDir>
|
|
||||||
<SrcDir>$(RepoDir)\src\cpp\ripple</SrcDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutDir>$(SolutionDir)build\VisualStudio2012\$(Configuration).$(Platform)\</OutDir>
|
|
||||||
<IntDir>$(SolutionDir)build\obj\VisualStudio2012\$(Configuration).$(Platform)\</IntDir>
|
|
||||||
<TargetName>rippled</TargetName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>USE_LEVELDB;BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_WIN32_WINNT=0x0600;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<AdditionalIncludeDirectories>$(RepoDir);$(RepoDir)\src\cpp\leveldb;$(RepoDir)\src\cpp\leveldb\include;$(RepoDir)\src\cpp\protobuf\src;$(RepoDir)\src\cpp\protobuf\vsprojects;$(RepoDir)\build\proto;$(RepoDir)\Subtrees\beast;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<ExceptionHandling>Async</ExceptionHandling>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<BuildMacro Include="RepoDir">
|
|
||||||
<Value>$(RepoDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
<BuildMacro Include="SrcDir">
|
|
||||||
<Value>$(SrcDir)</Value>
|
|
||||||
</BuildMacro>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
197
SConstruct
197
SConstruct
@@ -1,197 +0,0 @@
|
|||||||
#
|
|
||||||
# Ripple - SConstruct
|
|
||||||
#
|
|
||||||
|
|
||||||
import commands
|
|
||||||
import copy
|
|
||||||
import glob
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import re
|
|
||||||
|
|
||||||
LevelDB = bool(1)
|
|
||||||
|
|
||||||
OSX = bool(platform.mac_ver()[0])
|
|
||||||
FreeBSD = bool('FreeBSD' == platform.system())
|
|
||||||
Linux = bool('Linux' == platform.system())
|
|
||||||
Ubuntu = bool(Linux and 'Ubuntu' == platform.linux_distribution()[0])
|
|
||||||
|
|
||||||
if OSX or Ubuntu:
|
|
||||||
CTAGS = '/usr/bin/ctags'
|
|
||||||
else:
|
|
||||||
CTAGS = '/usr/bin/exuberant-ctags'
|
|
||||||
|
|
||||||
#
|
|
||||||
# scons tools
|
|
||||||
#
|
|
||||||
|
|
||||||
env = Environment(
|
|
||||||
tools = ['default', 'protoc']
|
|
||||||
)
|
|
||||||
|
|
||||||
GCC_VERSION = re.split('\.', commands.getoutput(env['CXX'] + ' -dumpversion'))
|
|
||||||
|
|
||||||
# Use clang
|
|
||||||
#env.Replace(CC = 'clang')
|
|
||||||
#env.Replace(CXX = 'clang++')
|
|
||||||
|
|
||||||
#
|
|
||||||
# Builder for CTags
|
|
||||||
#
|
|
||||||
ctags = Builder(action = '$CTAGS $CTAGSOPTIONS -f $TARGET $SOURCES')
|
|
||||||
env.Append(BUILDERS = { 'CTags' : ctags })
|
|
||||||
if OSX:
|
|
||||||
env.Replace(CTAGS = CTAGS)
|
|
||||||
else:
|
|
||||||
env.Replace(CTAGS = CTAGS, CTAGSOPTIONS = '--tag-relative')
|
|
||||||
|
|
||||||
# Use openssl
|
|
||||||
env.ParseConfig('pkg-config --cflags --libs openssl')
|
|
||||||
|
|
||||||
# The required version of boost is documented in the README file.
|
|
||||||
#
|
|
||||||
# We whitelist platforms where the non -mt version is linked with pthreads.
|
|
||||||
# This can be verified with: ldd libboost_filesystem.*
|
|
||||||
# If a threading library is included the platform can be whitelisted.
|
|
||||||
#
|
|
||||||
# FreeBSD and Ubuntu non-mt libs do link with pthreads.
|
|
||||||
if FreeBSD or Ubuntu:
|
|
||||||
env.Append(
|
|
||||||
LIBS = [
|
|
||||||
'boost_date_time',
|
|
||||||
'boost_filesystem',
|
|
||||||
'boost_program_options',
|
|
||||||
'boost_regex',
|
|
||||||
'boost_system',
|
|
||||||
'boost_thread',
|
|
||||||
'boost_random',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
env.Append(
|
|
||||||
LIBS = [
|
|
||||||
'boost_date_time-mt',
|
|
||||||
'boost_filesystem-mt',
|
|
||||||
'boost_program_options-mt',
|
|
||||||
'boost_regex-mt',
|
|
||||||
'boost_system-mt',
|
|
||||||
'boost_thread-mt',
|
|
||||||
'boost_random-mt',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# VFALCO This is my oasis of sanity. Nothing having to do with directories,
|
|
||||||
# source files, or include paths should reside outside the boundaries.
|
|
||||||
#
|
|
||||||
|
|
||||||
# List of includes passed to the C++ compiler.
|
|
||||||
# These are all relative to the repo dir.
|
|
||||||
#
|
|
||||||
INCLUDE_PATHS = [
|
|
||||||
'.',
|
|
||||||
'build/proto',
|
|
||||||
'Subtrees',
|
|
||||||
'Subtrees/leveldb',
|
|
||||||
'Subtrees/leveldb/port',
|
|
||||||
'Subtrees/leveldb/include',
|
|
||||||
'Subtrees/beast',
|
|
||||||
'src/cpp/ripple'
|
|
||||||
]
|
|
||||||
|
|
||||||
COMPILED_FILES = [
|
|
||||||
'Subtrees/beast/modules/beast_core/beast_core.cpp',
|
|
||||||
'Subtrees/beast/modules/beast_basics/beast_basics.cpp',
|
|
||||||
'modules/ripple_basics/ripple_basics.cpp',
|
|
||||||
'modules/ripple_data/ripple_data.cpp',
|
|
||||||
'modules/ripple_json/ripple_json.cpp',
|
|
||||||
'modules/ripple_leveldb/ripple_leveldb.cpp',
|
|
||||||
'modules/ripple_websocket/ripple_websocket.cpp',
|
|
||||||
'modules/ripple_sqlite/ripple_sqlite.c',
|
|
||||||
'modules/ripple_app/ripple_app_pt1.cpp',
|
|
||||||
'modules/ripple_app/ripple_app_pt2.cpp',
|
|
||||||
'modules/ripple_app/ripple_app_pt3.cpp',
|
|
||||||
'modules/ripple_app/ripple_app_pt4.cpp'
|
|
||||||
]
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Map top level source directories to their location in the outputs
|
|
||||||
#
|
|
||||||
|
|
||||||
VariantDir('build/obj/src', 'src', duplicate=0)
|
|
||||||
VariantDir('build/obj/modules', 'modules', duplicate=0)
|
|
||||||
VariantDir('build/obj/Subtrees', 'Subtrees', duplicate=0)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Add the list of includes to compiler include paths.
|
|
||||||
#
|
|
||||||
for path in INCLUDE_PATHS:
|
|
||||||
env.Append (CPPPATH = [ path ])
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Apparently, only linux uses -ldl
|
|
||||||
if not FreeBSD:
|
|
||||||
env.Append(
|
|
||||||
LIBS = [
|
|
||||||
'dl', # dynamic linking for linux
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Apparently, pkg-config --libs protobuf on bsd fails to provide this necessary include dir.
|
|
||||||
if FreeBSD:
|
|
||||||
env.Append(LINKFLAGS = ['-I/usr/local/include'])
|
|
||||||
env.Append(CXXFLAGS = ['-DOS_FREEBSD'])
|
|
||||||
|
|
||||||
env.Append(
|
|
||||||
LIBS = [
|
|
||||||
'rt', # for clock_nanosleep in beast
|
|
||||||
'protobuf',
|
|
||||||
'z'
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
DEBUGFLAGS = ['-g', '-DDEBUG']
|
|
||||||
BOOSTFLAGS = ['-DBOOST_TEST_DYN_LINK', '-DBOOST_FILESYSTEM_NO_DEPRECATED']
|
|
||||||
|
|
||||||
env.Append(LINKFLAGS = ['-rdynamic', '-pthread'])
|
|
||||||
env.Append(CCFLAGS = ['-pthread', '-Wall', '-Wno-sign-compare', '-Wno-char-subscripts'])
|
|
||||||
env.Append(CXXFLAGS = ['-O0', '-pthread', '-Wno-invalid-offsetof', '-Wformat']+BOOSTFLAGS+DEBUGFLAGS)
|
|
||||||
|
|
||||||
# RTTI is required for Beast and CountedObject.
|
|
||||||
#
|
|
||||||
env.Append(CXXFLAGS = ['-frtti'])
|
|
||||||
|
|
||||||
if (int(GCC_VERSION[0]) > 4 or (int(GCC_VERSION[0]) == 4 and int(GCC_VERSION[1]) >= 7)):
|
|
||||||
env.Append(CXXFLAGS = ['-std=c++11'])
|
|
||||||
|
|
||||||
if OSX:
|
|
||||||
env.Append(LINKFLAGS = ['-L/usr/local/opt/openssl/lib'])
|
|
||||||
env.Append(CXXFLAGS = ['-I/usr/local/opt/openssl/include'])
|
|
||||||
|
|
||||||
PROTO_SRCS = env.Protoc([], 'src/cpp/ripple/ripple.proto', PROTOCOUTDIR='build/proto', PROTOCPYTHONOUTDIR=None)
|
|
||||||
env.Clean(PROTO_SRCS, 'site_scons/site_tools/protoc.pyc')
|
|
||||||
|
|
||||||
# Only tag actual Ripple files.
|
|
||||||
TAG_SRCS = copy.copy(COMPILED_FILES)
|
|
||||||
|
|
||||||
# Derive the object files from the source files.
|
|
||||||
OBJECT_FILES = []
|
|
||||||
|
|
||||||
OBJECT_FILES += PROTO_SRCS
|
|
||||||
|
|
||||||
for file in COMPILED_FILES:
|
|
||||||
OBJECT_FILES.append('build/obj/' + file)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Targets
|
|
||||||
#
|
|
||||||
|
|
||||||
rippled = env.Program('build/rippled', OBJECT_FILES)
|
|
||||||
|
|
||||||
tags = env.CTags('tags', TAG_SRCS)
|
|
||||||
|
|
||||||
Default(rippled, tags)
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# Subtrees
|
|
||||||
|
|
||||||
These directories come from entire outside repositories
|
|
||||||
brought in using git-subtree.
|
|
||||||
|
|
||||||
About git-subtree:
|
|
||||||
|
|
||||||
https://github.com/apenwarr/git-subtree <br>
|
|
||||||
http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/ <br>
|
|
||||||
|
|
||||||
## LevelDB
|
|
||||||
|
|
||||||
Repository <br>
|
|
||||||
```
|
|
||||||
git@github.com:vinniefalco/LevelDB.git
|
|
||||||
```
|
|
||||||
Branch
|
|
||||||
```
|
|
||||||
ripple-fork
|
|
||||||
```
|
|
||||||
|
|
||||||
## websocket
|
|
||||||
|
|
||||||
Repository
|
|
||||||
```
|
|
||||||
git@github.com:vinniefalco/websocketpp.git
|
|
||||||
```
|
|
||||||
Branch
|
|
||||||
```
|
|
||||||
ripple-fork
|
|
||||||
```
|
|
||||||
|
|
||||||
## protobuf
|
|
||||||
|
|
||||||
Repository
|
|
||||||
```
|
|
||||||
git@github.com:vinniefalco/protobuf.git
|
|
||||||
```
|
|
||||||
Branch
|
|
||||||
```
|
|
||||||
master
|
|
||||||
```
|
|
||||||
|
|
||||||
**NOTE** Linux builds use the protobuf installed in /usr/lib. This will be
|
|
||||||
fixed in a future revision.
|
|
||||||
|
|
||||||
## SQLite
|
|
||||||
|
|
||||||
Not technically a subtree but included here because it is a direct
|
|
||||||
copy of the official SQLite distributions available here:
|
|
||||||
|
|
||||||
http://sqlite.org/download.html
|
|
||||||
12
Subtrees/beast/.gitattributes
vendored
12
Subtrees/beast/.gitattributes
vendored
@@ -1,12 +0,0 @@
|
|||||||
# Set default behaviour, in case users don't have core.autocrlf set.
|
|
||||||
* text=auto
|
|
||||||
|
|
||||||
# Github
|
|
||||||
.md text eol=lf
|
|
||||||
|
|
||||||
# Visual Studio
|
|
||||||
*.sln text eol=crlf
|
|
||||||
*.vcproj text eol=crlf
|
|
||||||
*.vcxproj text eol=crlf
|
|
||||||
*.props text eol=crlf
|
|
||||||
*.filters text eol=crlf
|
|
||||||
26
Subtrees/beast/.gitignore
vendored
26
Subtrees/beast/.gitignore
vendored
@@ -1,26 +0,0 @@
|
|||||||
Docs
|
|
||||||
._*
|
|
||||||
*.mode1v3
|
|
||||||
*.pbxuser
|
|
||||||
*.perspectivev3
|
|
||||||
*.user
|
|
||||||
*.ncb
|
|
||||||
*.suo
|
|
||||||
*.obj
|
|
||||||
*.ilk
|
|
||||||
*.pch
|
|
||||||
*.pdb
|
|
||||||
*.dep
|
|
||||||
*.idb
|
|
||||||
*.manifest
|
|
||||||
*.manifest.res
|
|
||||||
*.o
|
|
||||||
*.d
|
|
||||||
*.sdf
|
|
||||||
xcuserdata
|
|
||||||
contents.xcworkspacedata
|
|
||||||
.DS_Store
|
|
||||||
.svn
|
|
||||||
profile
|
|
||||||
Builds/VisualStudio2012/Debug
|
|
||||||
Builds/VisualStudio2012/Release
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_BEASTCONFIG_HEADER
|
|
||||||
#define BEAST_BEASTCONFIG_HEADER
|
|
||||||
|
|
||||||
// beast_core flags:
|
|
||||||
|
|
||||||
#ifndef BEAST_FORCE_DEBUG
|
|
||||||
//#define BEAST_FORCE_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_LOG_ASSERTIONS
|
|
||||||
//#define BEAST_LOG_ASSERTIONS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
//#define BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
|
||||||
//#define BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// beast_basics flags
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_BOOST
|
|
||||||
#define BEAST_USE_BOOST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_BZIP2
|
|
||||||
#define BEAST_USE_BZIP2 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_NATIVE_SQLITE
|
|
||||||
#define BEAST_USE_NATIVE_SQLITE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_LEAKCHECKED
|
|
||||||
#define BEAST_USE_LEAKCHECKED BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,716 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="..\..\.gitattributes" />
|
|
||||||
<None Include="..\..\.gitignore" />
|
|
||||||
<None Include="..\..\CodingStyle.md" />
|
|
||||||
<None Include="..\..\Doxyfile" />
|
|
||||||
<None Include="..\..\modules\beast_core\beast_core.mm" />
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Files.mm">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Network.mm">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Strings.mm">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_SystemStats.mm">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Threads.mm">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\java\BeastAppActivity.java">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\zip\zlib\README" />
|
|
||||||
<None Include="..\..\README.md" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\beast_basics.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_List.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_LockFreeQueue.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_LockFreeStack.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_SharedTable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_SortedLookupTable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_CatchAny.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Debug.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Error.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_FPUFlags.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_LeakChecked.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_SafeBool.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Throw.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_OncePerSecond.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_PerformedAtExit.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\functor\beast_Bind.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\functor\beast_Function.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_Interval.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_Math.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_MurmurHash.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AllocatedBy.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicCounter.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicFlag.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicPointer.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicState.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_CacheLine.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStore.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithoutTLS.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithTLS.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalFifoFreeStore.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_MemoryAlignment.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_RefCountedSingleton.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_StaticObject.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_Uncopyable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_CallQueue.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ConcurrentObject.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ConcurrentState.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_GlobalThreadGroup.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Listeners.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SerialFor.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SharedObject.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SpinDelay.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_AbstractFifo.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_Array.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ArrayAllocationBase.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_DynamicObject.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ElementComparator.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_HashMap.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_LinkedListPointer.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_NamedValueSet.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_OwnedArray.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_PropertySet.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ReferenceCountedArray.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ScopedValueSetter.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_SortedSet.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_SparseSet.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_Variant.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_DirectoryIterator.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_File.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileInputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileOutputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileSearchPath.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_MemoryMappedFile.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_TemporaryFile.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\json\beast_JSON.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\logging\beast_FileLogger.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\logging\beast_Logger.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_BigInteger.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Expression.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_MathsFunctions.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Random.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Range.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Atomic.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ByteOrder.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_HeapBlock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_LeakedObjectDetector.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Memory.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_MemoryBlock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_OptionalScopedPointer.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ReferenceCountedObject.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ScopedPointer.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Singleton.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_WeakReference.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_Result.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_Uuid.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_WindowsRegistry.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_android_JNIHelpers.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_BasicNativeHeaders.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_osx_ObjCHelpers.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_posix_SharedCode.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_win32_ComSmartPtr.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_IPAddress.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_MACAddress.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_NamedPipe.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_Socket.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_URL.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_BufferedInputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_FileInputSource.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_InputSource.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_InputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_MemoryInputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_MemoryOutputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_OutputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_SubregionStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_PlatformDefs.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_StandardHeader.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_SystemStats.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_TargetPlatform.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharacterFunctions.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_ASCII.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF16.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF32.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF8.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_Identifier.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_LocalisedStrings.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_NewLine.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_String.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringArray.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringPairArray.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringPool.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_TextDiff.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ChildProcess.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_CriticalSection.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_DynamicLibrary.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_HighResolutionTimer.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_InterProcessLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_Process.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedReadLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedWriteLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_SpinLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_Thread.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadLocalValue.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadPool.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_WaitableEvent.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformanceCounter.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_RelativeTime.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_Time.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\unit_tests\beast_UnitTest.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\xml\beast_XmlDocument.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\xml\beast_XmlElement.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_GZIPCompressorOutputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_GZIPDecompressorInputStream.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_ZipFile.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\crc32.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\deflate.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inffast.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inffixed.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inflate.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inftrees.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\trees.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zconf.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zconf.in.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zlib.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zutil.h" />
|
|
||||||
<ClInclude Include="BeastConfig.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\beast_basics.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_CatchAny.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_Debug.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_Error.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_FPUFlags.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_LeakChecked.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\events\beast_OncePerSecond.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\events\beast_PerformedAtExit.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\math\beast_MurmurHash.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithoutTLS.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithTLS.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_posix_FPUFlags.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_posix_Threads.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_win32_FPUFlags.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_win32_Threads.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_CallQueue.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ConcurrentObject.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Listeners.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ParallelFor.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_SharedObject.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp" />
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_DynamicObject.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_NamedValueSet.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_PropertySet.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_Variant.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_DirectoryIterator.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_File.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileInputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileOutputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileSearchPath.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_TemporaryFile.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\json\beast_JSON.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\logging\beast_FileLogger.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\logging\beast_Logger.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_BigInteger.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_Expression.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_Random.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\memory\beast_MemoryBlock.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\misc\beast_Result.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\misc\beast_Uuid.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Files.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Misc.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Network.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_SystemStats.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Threads.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Files.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Network.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_SystemStats.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Threads.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_posix_NamedPipe.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Files.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Network.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Registry.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_SystemStats.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Threads.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_IPAddress.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_MACAddress.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_NamedPipe.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_Socket.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_URL.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_BufferedInputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_FileInputSource.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_InputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_MemoryInputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_MemoryOutputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_OutputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_SubregionStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\system\beast_SystemStats.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_CharacterFunctions.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_Identifier.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_LocalisedStrings.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_String.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringArray.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringPairArray.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringPool.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_TextDiff.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ChildProcess.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_HighResolutionTimer.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_Thread.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ThreadPool.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_PerformanceCounter.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_RelativeTime.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_Time.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\unit_tests\beast_UnitTest.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\xml\beast_XmlDocument.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\xml\beast_XmlElement.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_GZIPCompressorOutputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_GZIPDecompressorInputStream.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_ZipFile.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\adler32.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\compress.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\crc32.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\deflate.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\infback.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inffast.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inflate.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inftrees.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\trees.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\uncompr.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\zutil.c">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{73C5A0F0-7629-4DE7-9194-BE7AC6C19535}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>beast</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup />
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(ProjectDir)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,956 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="..\..\README.md" />
|
|
||||||
<None Include="..\..\CodingStyle.md" />
|
|
||||||
<None Include="..\..\modules\beast_core\beast_core.mm">
|
|
||||||
<Filter>beast_core</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Files.mm">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Network.mm">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Strings.mm">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_SystemStats.mm">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\beast_mac_Threads.mm">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\zip\zlib\README">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\modules\beast_core\native\java\BeastAppActivity.java">
|
|
||||||
<Filter>beast_core\native\java</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="..\..\Doxyfile" />
|
|
||||||
<None Include="..\..\.gitattributes" />
|
|
||||||
<None Include="..\..\.gitignore" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="beast_core">
|
|
||||||
<UniqueIdentifier>{6dafd8d5-2901-4b41-85b7-52f6e86baacc}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\containers">
|
|
||||||
<UniqueIdentifier>{7cc041c8-fdf4-4e98-a56a-df516c2a9aa2}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\files">
|
|
||||||
<UniqueIdentifier>{3b7d8d7e-eabc-423c-a631-2ff37bf9b9eb}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\json">
|
|
||||||
<UniqueIdentifier>{abe24d69-c1d1-49e2-98a1-1e7bf760b97a}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\logging">
|
|
||||||
<UniqueIdentifier>{0fa6b76b-305f-473c-9b94-c1028a3af3fc}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\maths">
|
|
||||||
<UniqueIdentifier>{e2339099-bb8e-4437-ae8b-d4f64ef1e3f3}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\memory">
|
|
||||||
<UniqueIdentifier>{a89aa17e-4e01-4c2d-ba7e-196e9e0b67bb}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\misc">
|
|
||||||
<UniqueIdentifier>{64a314e1-0361-428a-a294-0615d8140f58}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\native">
|
|
||||||
<UniqueIdentifier>{1d018a70-71b3-4d70-9280-02efd4f348de}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\network">
|
|
||||||
<UniqueIdentifier>{ad675f57-9303-4712-9ff2-c7f59f959e7b}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\streams">
|
|
||||||
<UniqueIdentifier>{016d839c-4860-4bc3-8f6c-e965f50c2bfa}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\system">
|
|
||||||
<UniqueIdentifier>{7fb77af6-ce16-4f53-823e-906963b42985}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\text">
|
|
||||||
<UniqueIdentifier>{4603580c-5668-4e70-bed8-77f00f03f0ff}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\threads">
|
|
||||||
<UniqueIdentifier>{3409dc7a-92b5-43aa-b678-fde9f82ced55}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\time">
|
|
||||||
<UniqueIdentifier>{d3ea4af5-ae48-4144-a2ef-a212342d72ee}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\unit_tests">
|
|
||||||
<UniqueIdentifier>{0a8a6870-87a4-4f19-bbd3-b277f94bb83e}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\xml">
|
|
||||||
<UniqueIdentifier>{a1a38659-7779-41d6-8a3c-068433c4deaf}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\zip">
|
|
||||||
<UniqueIdentifier>{df5f5a69-5919-4a24-bbce-b3f87e4903cf}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\native\java">
|
|
||||||
<UniqueIdentifier>{b0d206d9-c002-4be1-b503-4ad16aca838a}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_core\zip\zlib">
|
|
||||||
<UniqueIdentifier>{31038502-9139-4c19-bd67-8f90f08a70ca}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics">
|
|
||||||
<UniqueIdentifier>{e3a8f3eb-7f0f-4b81-b978-0dd0823f583b}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\containers">
|
|
||||||
<UniqueIdentifier>{3e9389c0-c8f0-4657-ab11-cbbea889d3be}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\diagnostic">
|
|
||||||
<UniqueIdentifier>{ba11b980-76dd-49a4-b2c7-878e9f08f8ce}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\events">
|
|
||||||
<UniqueIdentifier>{b8caa85d-f224-4e3a-966f-a19b65023869}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\functor">
|
|
||||||
<UniqueIdentifier>{bb0bef46-51a6-4c26-8354-4df753c3bace}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\math">
|
|
||||||
<UniqueIdentifier>{1d53386e-0732-4213-b45d-026ff3d14042}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\memory">
|
|
||||||
<UniqueIdentifier>{9e850052-6ab7-4a65-911d-adfde81ceb5f}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\native">
|
|
||||||
<UniqueIdentifier>{811c5374-8959-4df9-aba9-a7e27b85046e}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="beast_basics\threads">
|
|
||||||
<UniqueIdentifier>{f58dddf7-fe43-49a2-8e57-91feba586119}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
|
||||||
<Filter>beast_core</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_AbstractFifo.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_Array.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ArrayAllocationBase.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_DynamicObject.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ElementComparator.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_HashMap.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_LinkedListPointer.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_NamedValueSet.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_OwnedArray.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_PropertySet.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ReferenceCountedArray.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_ScopedValueSetter.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_SortedSet.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_SparseSet.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\beast_Variant.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_DirectoryIterator.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_File.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileInputStream.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileOutputStream.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_FileSearchPath.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_MemoryMappedFile.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\files\beast_TemporaryFile.h">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\json\beast_JSON.h">
|
|
||||||
<Filter>beast_core\json</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\logging\beast_FileLogger.h">
|
|
||||||
<Filter>beast_core\logging</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\logging\beast_Logger.h">
|
|
||||||
<Filter>beast_core\logging</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_BigInteger.h">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Expression.h">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_MathsFunctions.h">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Random.h">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\maths\beast_Range.h">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Atomic.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ByteOrder.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_HeapBlock.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_LeakedObjectDetector.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Memory.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_MemoryBlock.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_OptionalScopedPointer.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ReferenceCountedObject.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ScopedPointer.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_Singleton.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_WeakReference.h">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_Result.h">
|
|
||||||
<Filter>beast_core\misc</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_Uuid.h">
|
|
||||||
<Filter>beast_core\misc</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\misc\beast_WindowsRegistry.h">
|
|
||||||
<Filter>beast_core\misc</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_android_JNIHelpers.h">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_BasicNativeHeaders.h">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_osx_ObjCHelpers.h">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_posix_SharedCode.h">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\beast_win32_ComSmartPtr.h">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_IPAddress.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_MACAddress.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_NamedPipe.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_Socket.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\beast_URL.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_BufferedInputStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_FileInputSource.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_InputSource.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_InputStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_MemoryInputStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_MemoryOutputStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_OutputStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\beast_SubregionStream.h">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_PlatformDefs.h">
|
|
||||||
<Filter>beast_core\system</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_StandardHeader.h">
|
|
||||||
<Filter>beast_core\system</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_SystemStats.h">
|
|
||||||
<Filter>beast_core\system</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\system\beast_TargetPlatform.h">
|
|
||||||
<Filter>beast_core\system</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharacterFunctions.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_ASCII.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF8.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF16.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_CharPointer_UTF32.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_Identifier.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_LocalisedStrings.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_NewLine.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_String.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringArray.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringPairArray.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_StringPool.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\text\beast_TextDiff.h">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ChildProcess.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_CriticalSection.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_DynamicLibrary.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_HighResolutionTimer.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_InterProcessLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_Process.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedReadLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ScopedWriteLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_SpinLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_Thread.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadLocalValue.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_ThreadPool.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\beast_WaitableEvent.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_PerformanceCounter.h">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_RelativeTime.h">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\beast_Time.h">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\unit_tests\beast_UnitTest.h">
|
|
||||||
<Filter>beast_core\unit_tests</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\xml\beast_XmlDocument.h">
|
|
||||||
<Filter>beast_core\xml</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\xml\beast_XmlElement.h">
|
|
||||||
<Filter>beast_core\xml</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_GZIPCompressorOutputStream.h">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_GZIPDecompressorInputStream.h">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\beast_ZipFile.h">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\crc32.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\deflate.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inffast.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inffixed.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inflate.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\inftrees.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\trees.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zconf.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zconf.in.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zlib.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\zip\zlib\zutil.h">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="BeastConfig.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\beast_basics.h">
|
|
||||||
<Filter>beast_basics</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_List.h">
|
|
||||||
<Filter>beast_basics\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_LockFreeQueue.h">
|
|
||||||
<Filter>beast_basics\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_LockFreeStack.h">
|
|
||||||
<Filter>beast_basics\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_SharedTable.h">
|
|
||||||
<Filter>beast_basics\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\containers\beast_SortedLookupTable.h">
|
|
||||||
<Filter>beast_basics\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_CatchAny.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Debug.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Error.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_FPUFlags.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_LeakChecked.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_SafeBool.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\diagnostic\beast_Throw.h">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_OncePerSecond.h">
|
|
||||||
<Filter>beast_basics\events</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_PerformedAtExit.h">
|
|
||||||
<Filter>beast_basics\events</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\functor\beast_Bind.h">
|
|
||||||
<Filter>beast_basics\functor</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\functor\beast_Function.h">
|
|
||||||
<Filter>beast_basics\functor</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_Interval.h">
|
|
||||||
<Filter>beast_basics\math</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_Math.h">
|
|
||||||
<Filter>beast_basics\math</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\math\beast_MurmurHash.h">
|
|
||||||
<Filter>beast_basics\math</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AllocatedBy.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicCounter.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicFlag.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicPointer.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_AtomicState.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_CacheLine.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStore.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithoutTLS.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithTLS.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalFifoFreeStore.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_MemoryAlignment.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_RefCountedSingleton.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_StaticObject.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\memory\beast_Uncopyable.h">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_CallQueue.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ConcurrentObject.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ConcurrentState.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_GlobalThreadGroup.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Listeners.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ParallelFor.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_Semaphore.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SerialFor.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SharedObject.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_SpinDelay.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.h">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
|
||||||
<Filter>beast_core</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_AbstractFifo.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_DynamicObject.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_NamedValueSet.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_PropertySet.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\beast_Variant.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_DirectoryIterator.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_File.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileInputStream.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileOutputStream.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_FileSearchPath.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\files\beast_TemporaryFile.cpp">
|
|
||||||
<Filter>beast_core\files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\json\beast_JSON.cpp">
|
|
||||||
<Filter>beast_core\json</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\logging\beast_FileLogger.cpp">
|
|
||||||
<Filter>beast_core\logging</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\logging\beast_Logger.cpp">
|
|
||||||
<Filter>beast_core\logging</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_BigInteger.cpp">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_Expression.cpp">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\maths\beast_Random.cpp">
|
|
||||||
<Filter>beast_core\maths</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\memory\beast_MemoryBlock.cpp">
|
|
||||||
<Filter>beast_core\memory</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\misc\beast_Result.cpp">
|
|
||||||
<Filter>beast_core\misc</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\misc\beast_Uuid.cpp">
|
|
||||||
<Filter>beast_core\misc</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Files.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Misc.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Network.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_SystemStats.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_android_Threads.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Files.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Network.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_SystemStats.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_linux_Threads.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_posix_NamedPipe.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Files.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Network.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Registry.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_SystemStats.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\beast_win32_Threads.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_IPAddress.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_MACAddress.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_NamedPipe.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_Socket.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\beast_URL.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_BufferedInputStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_FileInputSource.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_InputStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_MemoryInputStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_MemoryOutputStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_OutputStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\streams\beast_SubregionStream.cpp">
|
|
||||||
<Filter>beast_core\streams</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\system\beast_SystemStats.cpp">
|
|
||||||
<Filter>beast_core\system</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_CharacterFunctions.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_Identifier.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_LocalisedStrings.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_String.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringArray.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringPairArray.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_StringPool.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\text\beast_TextDiff.cpp">
|
|
||||||
<Filter>beast_core\text</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ChildProcess.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_HighResolutionTimer.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ReadWriteLock.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_Thread.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_ThreadPool.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\beast_TimeSliceThread.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_PerformanceCounter.cpp">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_RelativeTime.cpp">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\beast_Time.cpp">
|
|
||||||
<Filter>beast_core\time</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\unit_tests\beast_UnitTest.cpp">
|
|
||||||
<Filter>beast_core\unit_tests</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\xml\beast_XmlDocument.cpp">
|
|
||||||
<Filter>beast_core\xml</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\xml\beast_XmlElement.cpp">
|
|
||||||
<Filter>beast_core\xml</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_GZIPCompressorOutputStream.cpp">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_GZIPDecompressorInputStream.cpp">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\beast_ZipFile.cpp">
|
|
||||||
<Filter>beast_core\zip</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\adler32.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\compress.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\crc32.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\deflate.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\infback.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inffast.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inflate.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\inftrees.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\trees.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\uncompr.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\zip\zlib\zutil.c">
|
|
||||||
<Filter>beast_core\zip\zlib</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\beast_basics.cpp">
|
|
||||||
<Filter>beast_basics</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_CatchAny.cpp">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_Debug.cpp">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_Error.cpp">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_FPUFlags.cpp">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\diagnostic\beast_LeakChecked.cpp">
|
|
||||||
<Filter>beast_basics\diagnostic</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\events\beast_OncePerSecond.cpp">
|
|
||||||
<Filter>beast_basics\events</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\events\beast_PerformedAtExit.cpp">
|
|
||||||
<Filter>beast_basics\events</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\math\beast_MurmurHash.cpp">
|
|
||||||
<Filter>beast_basics\math</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithoutTLS.cpp">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_FifoFreeStoreWithTLS.cpp">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_GlobalPagedFreeStore.cpp">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\memory\beast_PagedFreeStore.cpp">
|
|
||||||
<Filter>beast_basics\memory</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_posix_FPUFlags.cpp">
|
|
||||||
<Filter>beast_basics\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_posix_Threads.cpp">
|
|
||||||
<Filter>beast_basics\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_win32_FPUFlags.cpp">
|
|
||||||
<Filter>beast_basics\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\native\beast_win32_Threads.cpp">
|
|
||||||
<Filter>beast_basics\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_CallQueue.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ConcurrentObject.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_InterruptibleThread.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Listeners.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ParallelFor.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ReadWriteMutex.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_Semaphore.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_SharedObject.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ThreadGroup.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_basics\threads\beast_ThreadWithCallQueue.cpp">
|
|
||||||
<Filter>beast_basics\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Coding Standards
|
|
||||||
|
|
||||||
Coding standards used here are extreme strict and consistent. The style
|
|
||||||
evolved gradually over the years, incorporating generally acknowledged
|
|
||||||
best-practice C++ advice, experience, and personal preference.
|
|
||||||
|
|
||||||
## Don't Repeat Yourself!
|
|
||||||
|
|
||||||
The [Don't Repeat Yourself][1] principle summarises the essence of what it
|
|
||||||
means to write good code, in all languages, at all levels.
|
|
||||||
|
|
||||||
## Formatting
|
|
||||||
|
|
||||||
The goal of source code formatting should always be to make things as easy to
|
|
||||||
read as possible. White space is used to guide the eye so that details are not
|
|
||||||
overlooked. Blank lines are used to separate code into "paragraphs."
|
|
||||||
|
|
||||||
* No tab characters please.
|
|
||||||
* Tab stops are set to 4 spaces.
|
|
||||||
* Braces are indented in the [Allman style][2].
|
|
||||||
* Always place a space before and after all binary operators,
|
|
||||||
especially assignments (`operator=`).
|
|
||||||
* The `!` operator should always be followed by a space.
|
|
||||||
* The `~` operator should be preceded by a space, but not followed by one.
|
|
||||||
* The `++` and `--` operators should have no spaces between the operator and
|
|
||||||
the operand.
|
|
||||||
* A space never appears before a comma, and always appears after a comma.
|
|
||||||
* Always place a space before an opening parenthesis. One exception is if
|
|
||||||
the parentheses are empty.
|
|
||||||
* Don't put spaces after a parenthesis. A typical member function call might
|
|
||||||
look like this: `foobar (1, 2, 3);`
|
|
||||||
* In general, leave a blank line before an `if` statement.
|
|
||||||
* In general, leave a blank line after a closing brace `}`.
|
|
||||||
* Do not place code or comments on the same line as any opening or
|
|
||||||
closing brace.
|
|
||||||
* Do not write `if` statements all-on-one-line. The exception to this is when
|
|
||||||
you've got a sequence of similar `if` statements, and are aligning them all
|
|
||||||
vertically to highlight their similarities.
|
|
||||||
* In an `if-else` statement, if you surround one half of the statement with
|
|
||||||
braces, you also need to put braces around the other half, to match.
|
|
||||||
* When writing a pointer type, use this spacing: `SomeObject* myObject`.
|
|
||||||
Technically, a more correct spacing would be `SomeObject *myObject`, but
|
|
||||||
it makes more sense for the asterisk to be grouped with the type name,
|
|
||||||
since being a pointer is part of the type, not the variable name. The only
|
|
||||||
time that this can lead to any problems is when you're declaring multiple
|
|
||||||
pointers of the same type in the same statement - which leads on to the next
|
|
||||||
rule:
|
|
||||||
* When declaring multiple pointers, never do so in a single statement, e.g.
|
|
||||||
`SomeObject* p1, *p2;` - instead, always split them out onto separate lines
|
|
||||||
and write the type name again, to make it quite clear what's going on, and
|
|
||||||
avoid the danger of missing out any vital asterisks.
|
|
||||||
* The previous point also applies to references, so always put the `&` next to
|
|
||||||
the type rather than the variable, e.g. `void foo (Thing const& thing)`. And
|
|
||||||
don't put a space on both sides of the `*` or `&` - always put a space after
|
|
||||||
it, but never before it.
|
|
||||||
* The word `const` should be placed to the right of the thing that it modifies,
|
|
||||||
for consistency. For example `int const` refers to an int which is const.
|
|
||||||
`int const*` is a pointer to an int which is const. `int *const` is a const
|
|
||||||
pointer to an int.
|
|
||||||
* Always place a space in between the template angle brackets and the type
|
|
||||||
name. Template code is already hard enough to read!
|
|
||||||
|
|
||||||
## Naming conventions
|
|
||||||
|
|
||||||
* Member variables and method names are written with camel-case, and never
|
|
||||||
begin with a capital letter.
|
|
||||||
* Class names are also written in camel-case, but always begin with a capital
|
|
||||||
letter.
|
|
||||||
* For global variables... well, you shouldn't have any, so it doesn't matter.
|
|
||||||
* Class data members begin with `m_`, static data members begin with `s_`.
|
|
||||||
Global variables begin with `g_`. This is so the scope of the corresponding
|
|
||||||
declaration can be easily determined.
|
|
||||||
* Avoid underscores in your names, especially leading or trailing underscores.
|
|
||||||
In particular, leading underscores should be avoided, as these are often used
|
|
||||||
in standard library code, so to use them in your own code looks quite jarring.
|
|
||||||
* If you really have to write a macro for some reason, then make it all caps,
|
|
||||||
with underscores to separate the words. And obviously make sure that its name
|
|
||||||
is unlikely to clash with symbols used in other libraries or 3rd party code.
|
|
||||||
|
|
||||||
## Types, const-correctness
|
|
||||||
|
|
||||||
* If a method can (and should!) be const, make it const!
|
|
||||||
* If a method definitely doesn't throw an exception (be careful!), mark it as
|
|
||||||
`noexcept`
|
|
||||||
* When returning a temporary object, e.g. a String, the returned object should
|
|
||||||
be non-const, so that if the class has a C++11 move operator, it can be used.
|
|
||||||
* If a local variable can be const, then make it const!
|
|
||||||
* Remember that pointers can be const as well as primitives; For example, if
|
|
||||||
you have a `char*` whose contents are going to be altered, you may still be
|
|
||||||
able to make the pointer itself const, e.g. `char* const foobar = getFoobar();`.
|
|
||||||
* Do not declare all your local variables at the top of a function or method
|
|
||||||
(i.e. in the old-fashioned C-style). Declare them at the last possible moment,
|
|
||||||
and give them as small a scope as possible.
|
|
||||||
* Object parameters should be passed as `const&` wherever possible. Only
|
|
||||||
pass a parameter as a copy-by-value object if you really need to mutate
|
|
||||||
a local copy inside the method, and if making a local copy inside the method
|
|
||||||
would be difficult.
|
|
||||||
* Use portable `for()` loop variable scoping (i.e. do not have multiple for
|
|
||||||
loops in the same scope that each re-declare the same variable name, as
|
|
||||||
this fails on older compilers)
|
|
||||||
* When you're testing a pointer to see if it's null, never write
|
|
||||||
`if (myPointer)`. Always avoid that implicit cast-to-bool by writing it more
|
|
||||||
fully: `if (myPointer != nullptr)`. And likewise, never ever write
|
|
||||||
`if (! myPointer)`, instead always write `if (myPointer == nullptr)`.
|
|
||||||
It is more readable that way.
|
|
||||||
* Avoid C-style casts except when converting between primitive numeric types.
|
|
||||||
Some people would say "avoid C-style casts altogether", but `static_cast` is
|
|
||||||
a bit unreadable when you just want to cast an `int` to a `float`. But
|
|
||||||
whenever a pointer is involved, or a non-primitive object, always use
|
|
||||||
`static_cast`. And when you're reinterpreting data, always use
|
|
||||||
`reinterpret_cast`.
|
|
||||||
* Until C++ gets a universal 64-bit primitive type (part of the C++11
|
|
||||||
standard), it's best to stick to the `int64` and `uint64` typedefs.
|
|
||||||
|
|
||||||
## Object lifetime and ownership
|
|
||||||
|
|
||||||
* Absolutely do NOT use `delete`, `deleteAndZero`, etc. There are very very few
|
|
||||||
situations where you can't use a `ScopedPointer` or some other automatic
|
|
||||||
lifetime management class.
|
|
||||||
* Do not use `new` unless there's no alternative. Whenever you type `new`, always
|
|
||||||
treat it as a failure to find a better solution. If a local variable can be
|
|
||||||
allocated on the stack rather than the heap, then always do so.
|
|
||||||
* Do not ever use `new` or `malloc` to allocate a C++ array. Always use a
|
|
||||||
`HeapBlock` instead.
|
|
||||||
* And just to make it doubly clear: Never use `malloc` or `calloc`.
|
|
||||||
* If a parent object needs to create and own some kind of child object, always
|
|
||||||
use composition as your first choice. If that's not possible (e.g. if the
|
|
||||||
child needs a pointer to the parent for its constructor), then use a
|
|
||||||
`ScopedPointer`.
|
|
||||||
* If possible, pass an object as a reference rather than a pointer. If possible,
|
|
||||||
make it a `const` reference.
|
|
||||||
* Obviously avoid static and global values. Sometimes there's no alternative,
|
|
||||||
but if there is an alternative, then use it, no matter how much effort it
|
|
||||||
involves.
|
|
||||||
* If allocating a local POD structure (e.g. an operating-system structure in
|
|
||||||
native code), and you need to initialise it with zeros, use the `= { 0 };`
|
|
||||||
syntax as your first choice for doing this. If for some reason that's not
|
|
||||||
appropriate, use the `zerostruct()` function, or in case that isn't suitable,
|
|
||||||
use `zeromem()`. Don't use `memset()`.
|
|
||||||
|
|
||||||
## Classes
|
|
||||||
|
|
||||||
* Declare a class's public section first, and put its constructors and
|
|
||||||
destructor first. Any protected items come next, and then private ones.
|
|
||||||
* Use the most restrictive access-specifier possible for each member. Prefer
|
|
||||||
`private` over `protected`, and `protected` over `public`. Don't expose
|
|
||||||
things unnecessarily.
|
|
||||||
* Preferred positioning for any inherited classes is to put them to the right
|
|
||||||
of the class name, vertically aligned, e.g.:
|
|
||||||
class Thing : public Foo,
|
|
||||||
private Bar
|
|
||||||
{
|
|
||||||
}
|
|
||||||
* Put a class's member variables (which should almost always be private, of course),
|
|
||||||
after all the public and protected method declarations.
|
|
||||||
* Any private methods can go towards the end of the class, after the member
|
|
||||||
variables.
|
|
||||||
* If your class does not have copy-by-value semantics, derive the class from
|
|
||||||
`Uncopyable`.
|
|
||||||
* If your class is likely to be leaked, then derive your class from
|
|
||||||
`LeakChecked<>`.
|
|
||||||
* Constructors that take a single parameter should be default be marked
|
|
||||||
`explicit`. Obviously there are cases where you do want implicit conversion,
|
|
||||||
but always think about it carefully before writing a non-explicit constructor.
|
|
||||||
* Do not use `NULL`, `null`, or 0 for a null-pointer. And especially never use
|
|
||||||
'0L', which is particulary burdensome. Use `nullptr` instead - this is the
|
|
||||||
C++2011 standard, so get used to it. There's a fallback definition for `nullptr`
|
|
||||||
in Beast, so it's always possible to use it even if your compiler isn't yet
|
|
||||||
C++2011 compliant.
|
|
||||||
* All the C++ 'guru' books and articles are full of excellent and detailed advice
|
|
||||||
on when it's best to use inheritance vs composition. If you're not already
|
|
||||||
familiar with the received wisdom in these matters, then do some reading!
|
|
||||||
|
|
||||||
## Miscellaneous
|
|
||||||
|
|
||||||
* `goto` statements should not be used at all, even if the alternative is
|
|
||||||
more verbose code. The only exception is when implementing an algorithm in
|
|
||||||
a function as a state machine.
|
|
||||||
* Don't use macros! OK, obviously there are many situations where they're the
|
|
||||||
right tool for the job, but treat them as a last resort. Certainly don't ever
|
|
||||||
use a macro just to hold a constant value or to perform any kind of function
|
|
||||||
that could have been done as a real inline function. And it goes without saying
|
|
||||||
that you should give them names which aren't going to clash with other code.
|
|
||||||
And `#undef` them after you've used them, if possible.
|
|
||||||
* When using the `++` or `--` operators, never use post-increment if
|
|
||||||
pre-increment could be used instead. Although it doesn't matter for
|
|
||||||
primitive types, it's good practice to pre-increment since this can be
|
|
||||||
much more efficient for more complex objects. In particular, if you're
|
|
||||||
writing a for loop, always use pre-increment,
|
|
||||||
e.g. `for (int = 0; i < 10; ++i)`
|
|
||||||
* Never put an "else" statement after a "return"! This is well-explained in the
|
|
||||||
LLVM coding standards...and a couple of other very good pieces of advice from
|
|
||||||
the LLVM standards are in there as well.
|
|
||||||
* When getting a possibly-null pointer and using it only if it's non-null, limit
|
|
||||||
the scope of the pointer as much as possible - e.g. Do NOT do this:
|
|
||||||
|
|
||||||
Foo* f = getFoo ();
|
|
||||||
if (f != nullptr)
|
|
||||||
f->doSomething ();
|
|
||||||
// other code
|
|
||||||
f->doSomething (); // oops! f may be null!
|
|
||||||
|
|
||||||
..instead, prefer to write it like this, which reduces the scope of the
|
|
||||||
pointer, making it impossible to write code that accidentally uses a null
|
|
||||||
pointer:
|
|
||||||
|
|
||||||
if (Foo* f = getFoo ())
|
|
||||||
f->doSomethingElse ();
|
|
||||||
|
|
||||||
// f is out-of-scope here, so impossible to use it if it's null
|
|
||||||
|
|
||||||
(This also results in smaller, cleaner code)
|
|
||||||
|
|
||||||
[1]: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
|
||||||
[2]: http://en.wikipedia.org/wiki/Indent_style#Allman_style
|
|
||||||
@@ -1,303 +0,0 @@
|
|||||||
# Doxyfile 1.8.3.1
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Project related configuration options
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
DOXYFILE_ENCODING = UTF-8
|
|
||||||
PROJECT_NAME = "Beast"
|
|
||||||
PROJECT_NUMBER =
|
|
||||||
PROJECT_BRIEF =
|
|
||||||
PROJECT_LOGO =
|
|
||||||
OUTPUT_DIRECTORY = Docs
|
|
||||||
CREATE_SUBDIRS = NO
|
|
||||||
OUTPUT_LANGUAGE = English
|
|
||||||
BRIEF_MEMBER_DESC = YES
|
|
||||||
REPEAT_BRIEF = YES
|
|
||||||
ABBREVIATE_BRIEF =
|
|
||||||
ALWAYS_DETAILED_SEC = NO
|
|
||||||
INLINE_INHERITED_MEMB = NO
|
|
||||||
FULL_PATH_NAMES = YES
|
|
||||||
STRIP_FROM_PATH =
|
|
||||||
STRIP_FROM_INC_PATH =
|
|
||||||
SHORT_NAMES = NO
|
|
||||||
JAVADOC_AUTOBRIEF = NO
|
|
||||||
QT_AUTOBRIEF = NO
|
|
||||||
MULTILINE_CPP_IS_BRIEF = NO
|
|
||||||
INHERIT_DOCS = YES
|
|
||||||
SEPARATE_MEMBER_PAGES = NO
|
|
||||||
TAB_SIZE = 4
|
|
||||||
ALIASES =
|
|
||||||
TCL_SUBST =
|
|
||||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
|
||||||
OPTIMIZE_OUTPUT_JAVA = NO
|
|
||||||
OPTIMIZE_FOR_FORTRAN = NO
|
|
||||||
OPTIMIZE_OUTPUT_VHDL = NO
|
|
||||||
EXTENSION_MAPPING =
|
|
||||||
MARKDOWN_SUPPORT = YES
|
|
||||||
AUTOLINK_SUPPORT = YES
|
|
||||||
BUILTIN_STL_SUPPORT = NO
|
|
||||||
CPP_CLI_SUPPORT = NO
|
|
||||||
SIP_SUPPORT = NO
|
|
||||||
IDL_PROPERTY_SUPPORT = YES
|
|
||||||
DISTRIBUTE_GROUP_DOC = NO
|
|
||||||
SUBGROUPING = YES
|
|
||||||
INLINE_GROUPED_CLASSES = NO
|
|
||||||
INLINE_SIMPLE_STRUCTS = NO
|
|
||||||
TYPEDEF_HIDES_STRUCT = NO
|
|
||||||
SYMBOL_CACHE_SIZE = 0
|
|
||||||
LOOKUP_CACHE_SIZE = 0
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Build related configuration options
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
EXTRACT_ALL = NO
|
|
||||||
EXTRACT_PRIVATE = NO
|
|
||||||
EXTRACT_PACKAGE = NO
|
|
||||||
EXTRACT_STATIC = NO
|
|
||||||
EXTRACT_LOCAL_CLASSES = YES
|
|
||||||
EXTRACT_LOCAL_METHODS = NO
|
|
||||||
EXTRACT_ANON_NSPACES = NO
|
|
||||||
HIDE_UNDOC_MEMBERS = NO
|
|
||||||
HIDE_UNDOC_CLASSES = NO
|
|
||||||
HIDE_FRIEND_COMPOUNDS = NO
|
|
||||||
HIDE_IN_BODY_DOCS = NO
|
|
||||||
INTERNAL_DOCS = NO
|
|
||||||
CASE_SENSE_NAMES = NO
|
|
||||||
HIDE_SCOPE_NAMES = NO
|
|
||||||
SHOW_INCLUDE_FILES = YES
|
|
||||||
FORCE_LOCAL_INCLUDES = NO
|
|
||||||
INLINE_INFO = YES
|
|
||||||
SORT_MEMBER_DOCS = YES
|
|
||||||
SORT_BRIEF_DOCS = NO
|
|
||||||
SORT_MEMBERS_CTORS_1ST = NO
|
|
||||||
SORT_GROUP_NAMES = NO
|
|
||||||
SORT_BY_SCOPE_NAME = NO
|
|
||||||
STRICT_PROTO_MATCHING = NO
|
|
||||||
GENERATE_TODOLIST = YES
|
|
||||||
GENERATE_TESTLIST = YES
|
|
||||||
GENERATE_BUGLIST = YES
|
|
||||||
GENERATE_DEPRECATEDLIST= YES
|
|
||||||
ENABLED_SECTIONS =
|
|
||||||
MAX_INITIALIZER_LINES = 30
|
|
||||||
SHOW_USED_FILES = YES
|
|
||||||
SHOW_FILES = YES
|
|
||||||
SHOW_NAMESPACES = YES
|
|
||||||
FILE_VERSION_FILTER =
|
|
||||||
LAYOUT_FILE =
|
|
||||||
CITE_BIB_FILES =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to warning and progress messages
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
QUIET = NO
|
|
||||||
WARNINGS = YES
|
|
||||||
WARN_IF_UNDOCUMENTED = YES
|
|
||||||
WARN_IF_DOC_ERROR = YES
|
|
||||||
WARN_NO_PARAMDOC = NO
|
|
||||||
WARN_FORMAT = "$file:$line: $text"
|
|
||||||
WARN_LOGFILE =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the input files
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
INPUT = modules
|
|
||||||
INPUT_ENCODING = UTF-8
|
|
||||||
FILE_PATTERNS =
|
|
||||||
RECURSIVE = YES
|
|
||||||
EXCLUDE = modules/beast_core/beast_core.h \
|
|
||||||
modules/beast_core/beast_core.cpp \
|
|
||||||
modules/beast_basics/beast_basics.h \
|
|
||||||
modules/beast_basics/beast_basics.cpp \
|
|
||||||
modules/beast_basics/native \
|
|
||||||
modules/beast_basics/zip/zlib
|
|
||||||
EXCLUDE_SYMLINKS = NO
|
|
||||||
EXCLUDE_PATTERNS =
|
|
||||||
EXCLUDE_SYMBOLS =
|
|
||||||
EXAMPLE_PATH =
|
|
||||||
EXAMPLE_PATTERNS =
|
|
||||||
EXAMPLE_RECURSIVE = NO
|
|
||||||
IMAGE_PATH =
|
|
||||||
INPUT_FILTER =
|
|
||||||
FILTER_PATTERNS =
|
|
||||||
FILTER_SOURCE_FILES = NO
|
|
||||||
FILTER_SOURCE_PATTERNS =
|
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to source browsing
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
SOURCE_BROWSER = NO
|
|
||||||
INLINE_SOURCES = NO
|
|
||||||
STRIP_CODE_COMMENTS = YES
|
|
||||||
REFERENCED_BY_RELATION = NO
|
|
||||||
REFERENCES_RELATION = NO
|
|
||||||
REFERENCES_LINK_SOURCE = YES
|
|
||||||
USE_HTAGS = NO
|
|
||||||
VERBATIM_HEADERS = YES
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the alphabetical class index
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
ALPHABETICAL_INDEX = YES
|
|
||||||
COLS_IN_ALPHA_INDEX = 5
|
|
||||||
IGNORE_PREFIX =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the HTML output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_HTML = YES
|
|
||||||
HTML_OUTPUT = .
|
|
||||||
HTML_FILE_EXTENSION = .html
|
|
||||||
HTML_HEADER =
|
|
||||||
HTML_FOOTER =
|
|
||||||
HTML_STYLESHEET =
|
|
||||||
HTML_EXTRA_STYLESHEET =
|
|
||||||
HTML_EXTRA_FILES =
|
|
||||||
HTML_COLORSTYLE_HUE = 220
|
|
||||||
HTML_COLORSTYLE_SAT = 100
|
|
||||||
HTML_COLORSTYLE_GAMMA = 80
|
|
||||||
HTML_TIMESTAMP = YES
|
|
||||||
HTML_DYNAMIC_SECTIONS = NO
|
|
||||||
HTML_INDEX_NUM_ENTRIES = 100
|
|
||||||
GENERATE_DOCSET = NO
|
|
||||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
|
||||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
|
||||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
|
||||||
DOCSET_PUBLISHER_NAME = Publisher
|
|
||||||
GENERATE_HTMLHELP = NO
|
|
||||||
CHM_FILE =
|
|
||||||
HHC_LOCATION =
|
|
||||||
GENERATE_CHI = NO
|
|
||||||
CHM_INDEX_ENCODING =
|
|
||||||
BINARY_TOC = NO
|
|
||||||
TOC_EXPAND = NO
|
|
||||||
GENERATE_QHP = NO
|
|
||||||
QCH_FILE =
|
|
||||||
QHP_NAMESPACE = org.doxygen.Project
|
|
||||||
QHP_VIRTUAL_FOLDER = doc
|
|
||||||
QHP_CUST_FILTER_NAME =
|
|
||||||
QHP_CUST_FILTER_ATTRS =
|
|
||||||
QHP_SECT_FILTER_ATTRS =
|
|
||||||
QHG_LOCATION =
|
|
||||||
GENERATE_ECLIPSEHELP = NO
|
|
||||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
|
||||||
DISABLE_INDEX = NO
|
|
||||||
GENERATE_TREEVIEW = NO
|
|
||||||
ENUM_VALUES_PER_LINE = 4
|
|
||||||
TREEVIEW_WIDTH = 250
|
|
||||||
EXT_LINKS_IN_WINDOW = NO
|
|
||||||
FORMULA_FONTSIZE = 10
|
|
||||||
FORMULA_TRANSPARENT = YES
|
|
||||||
USE_MATHJAX = NO
|
|
||||||
MATHJAX_FORMAT = HTML-CSS
|
|
||||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
|
||||||
MATHJAX_EXTENSIONS =
|
|
||||||
SEARCHENGINE = YES
|
|
||||||
SERVER_BASED_SEARCH = NO
|
|
||||||
EXTERNAL_SEARCH = NO
|
|
||||||
SEARCHENGINE_URL =
|
|
||||||
SEARCHDATA_FILE = searchdata.xml
|
|
||||||
EXTERNAL_SEARCH_ID =
|
|
||||||
EXTRA_SEARCH_MAPPINGS =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the LaTeX output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_LATEX = NO
|
|
||||||
LATEX_OUTPUT = latex
|
|
||||||
LATEX_CMD_NAME = latex
|
|
||||||
MAKEINDEX_CMD_NAME = makeindex
|
|
||||||
COMPACT_LATEX = NO
|
|
||||||
PAPER_TYPE = a4
|
|
||||||
EXTRA_PACKAGES =
|
|
||||||
LATEX_HEADER =
|
|
||||||
LATEX_FOOTER =
|
|
||||||
PDF_HYPERLINKS = YES
|
|
||||||
USE_PDFLATEX = YES
|
|
||||||
LATEX_BATCHMODE = NO
|
|
||||||
LATEX_HIDE_INDICES = NO
|
|
||||||
LATEX_SOURCE_CODE = NO
|
|
||||||
LATEX_BIB_STYLE = plain
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the RTF output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_RTF = NO
|
|
||||||
RTF_OUTPUT = rtf
|
|
||||||
COMPACT_RTF = NO
|
|
||||||
RTF_HYPERLINKS = NO
|
|
||||||
RTF_STYLESHEET_FILE =
|
|
||||||
RTF_EXTENSIONS_FILE =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the man page output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_MAN = NO
|
|
||||||
MAN_OUTPUT = man
|
|
||||||
MAN_EXTENSION = .3
|
|
||||||
MAN_LINKS = NO
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the XML output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_XML = NO
|
|
||||||
XML_OUTPUT = xml
|
|
||||||
XML_SCHEMA =
|
|
||||||
XML_DTD =
|
|
||||||
XML_PROGRAMLISTING = YES
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options for the AutoGen Definitions output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_AUTOGEN_DEF = NO
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# configuration options related to the Perl module output
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
GENERATE_PERLMOD = NO
|
|
||||||
PERLMOD_LATEX = NO
|
|
||||||
PERLMOD_PRETTY = YES
|
|
||||||
PERLMOD_MAKEVAR_PREFIX =
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration options related to the preprocessor
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
ENABLE_PREPROCESSING = YES
|
|
||||||
MACRO_EXPANSION = NO
|
|
||||||
EXPAND_ONLY_PREDEF = NO
|
|
||||||
SEARCH_INCLUDES = YES
|
|
||||||
INCLUDE_PATH =
|
|
||||||
INCLUDE_FILE_PATTERNS =
|
|
||||||
PREDEFINED =
|
|
||||||
EXPAND_AS_DEFINED =
|
|
||||||
SKIP_FUNCTION_MACROS = YES
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration::additions related to external references
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
TAGFILES =
|
|
||||||
GENERATE_TAGFILE =
|
|
||||||
ALLEXTERNALS = NO
|
|
||||||
EXTERNAL_GROUPS = YES
|
|
||||||
PERL_PATH = /usr/bin/perl
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# Configuration options related to the dot tool
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
CLASS_DIAGRAMS = YES
|
|
||||||
MSCGEN_PATH =
|
|
||||||
HIDE_UNDOC_RELATIONS = YES
|
|
||||||
HAVE_DOT = YES
|
|
||||||
DOT_NUM_THREADS = 0
|
|
||||||
DOT_FONTNAME = Helvetica
|
|
||||||
DOT_FONTSIZE = 10
|
|
||||||
DOT_FONTPATH =
|
|
||||||
CLASS_GRAPH = YES
|
|
||||||
COLLABORATION_GRAPH = YES
|
|
||||||
GROUP_GRAPHS = YES
|
|
||||||
UML_LOOK = NO
|
|
||||||
UML_LIMIT_NUM_FIELDS = 10
|
|
||||||
TEMPLATE_RELATIONS = NO
|
|
||||||
INCLUDE_GRAPH = YES
|
|
||||||
INCLUDED_BY_GRAPH = YES
|
|
||||||
CALL_GRAPH = NO
|
|
||||||
CALLER_GRAPH = NO
|
|
||||||
GRAPHICAL_HIERARCHY = YES
|
|
||||||
DIRECTORY_GRAPH = YES
|
|
||||||
DOT_IMAGE_FORMAT = png
|
|
||||||
INTERACTIVE_SVG = NO
|
|
||||||
DOT_PATH =
|
|
||||||
DOTFILE_DIRS =
|
|
||||||
MSCFILE_DIRS =
|
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
|
||||||
MAX_DOT_GRAPH_DEPTH = 0
|
|
||||||
DOT_TRANSPARENT = NO
|
|
||||||
DOT_MULTI_TARGETS = NO
|
|
||||||
GENERATE_LEGEND = YES
|
|
||||||
DOT_CLEANUP = YES
|
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# Beast: An amazing cross platform library
|
|
||||||
|
|
||||||
Contains cross platform objects to do a variety of useful things.
|
|
||||||
No external dependencies, no complicated build steps.
|
|
||||||
|
|
||||||
Things people need for building peer to peer, concurrent, cryptographic systems.
|
|
||||||
|
|
||||||
The hope is that this will replace the use of boost and other cumbersome jalopies.
|
|
||||||
|
|
||||||
## JUCE
|
|
||||||
|
|
||||||
Beast is based on the beast_core module which is provided under the ISC
|
|
||||||
license. More information about JUCE is available at
|
|
||||||
http://www.juce.com
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
/** Add this to get the @ref beast_basics module.
|
|
||||||
|
|
||||||
@file beast_basics.cpp
|
|
||||||
@ingroup beast_basics
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "BeastConfig.h"
|
|
||||||
|
|
||||||
#include "beast_basics.h"
|
|
||||||
|
|
||||||
#if BEAST_MSVC && _DEBUG
|
|
||||||
#include <crtdbg.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_MSVC
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable: 4100) // unreferenced formal parmaeter
|
|
||||||
#pragma warning (disable: 4355) // 'this' used in base member
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace beast
|
|
||||||
{
|
|
||||||
|
|
||||||
#include "diagnostic/beast_CatchAny.cpp"
|
|
||||||
#include "diagnostic/beast_Debug.cpp"
|
|
||||||
#include "diagnostic/beast_Error.cpp"
|
|
||||||
#include "diagnostic/beast_FPUFlags.cpp"
|
|
||||||
#include "diagnostic/beast_LeakChecked.cpp"
|
|
||||||
|
|
||||||
#include "events/beast_OncePerSecond.cpp"
|
|
||||||
#include "events/beast_PerformedAtExit.cpp"
|
|
||||||
|
|
||||||
#include "math/beast_MurmurHash.cpp"
|
|
||||||
|
|
||||||
#include "threads/beast_InterruptibleThread.cpp"
|
|
||||||
#include "threads/beast_Semaphore.cpp"
|
|
||||||
|
|
||||||
#if BEAST_WINDOWS
|
|
||||||
#include "native/beast_win32_FPUFlags.cpp"
|
|
||||||
#include "native/beast_win32_Threads.cpp"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include "native/beast_posix_FPUFlags.cpp"
|
|
||||||
#include "native/beast_posix_Threads.cpp"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
#include "memory/beast_FifoFreeStoreWithTLS.cpp"
|
|
||||||
#else
|
|
||||||
#include "memory/beast_FifoFreeStoreWithoutTLS.cpp"
|
|
||||||
#endif
|
|
||||||
#include "memory/beast_GlobalPagedFreeStore.cpp"
|
|
||||||
#include "memory/beast_PagedFreeStore.cpp"
|
|
||||||
|
|
||||||
#include "threads/beast_CallQueue.cpp"
|
|
||||||
#include "threads/beast_ConcurrentObject.cpp"
|
|
||||||
#include "threads/beast_Listeners.cpp"
|
|
||||||
#include "threads/beast_ManualCallQueue.cpp"
|
|
||||||
#include "threads/beast_ParallelFor.cpp"
|
|
||||||
#include "threads/beast_ReadWriteMutex.cpp"
|
|
||||||
#include "threads/beast_SharedObject.cpp"
|
|
||||||
#include "threads/beast_ThreadGroup.cpp"
|
|
||||||
#include "threads/beast_ThreadWithCallQueue.cpp"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BEAST_MSVC
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
@@ -1,470 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
/** Include this to get the @ref beast_basics module.
|
|
||||||
|
|
||||||
@file beast_basics.h
|
|
||||||
@ingroup beast_basics
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BEAST_BASICS_BEASTHEADER
|
|
||||||
#define BEAST_BASICS_BEASTHEADER
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
@mainpage Beast: A multipurpose library using parts of JUCE.
|
|
||||||
|
|
||||||
### Version 1.1
|
|
||||||
|
|
||||||
Copyright (C) 2008 by Vinnie Falco \<vinnie.falco@gmail.com\> ([e-mail][0])
|
|
||||||
|
|
||||||
Beast is a source code collection of individual modules containing
|
|
||||||
functionality for a variety of applications, with an emphasis on building
|
|
||||||
concurrent systems. Beast requires [JUCE][3] (Jules' Utility Class
|
|
||||||
Extensions), available from [Raw Material Software][4]. JUCE is available
|
|
||||||
under both the [GNU General Public License][5] and a [commercial license][6].
|
|
||||||
Other than JUCE, Beast has no external dependencies.
|
|
||||||
|
|
||||||
Beast is hosted on Github at [https://github.com/vinniefalco/Beast][1]
|
|
||||||
|
|
||||||
The online documentation is at [http://vinniefalco.github.com/Beast][2]
|
|
||||||
|
|
||||||
## Platforms
|
|
||||||
|
|
||||||
All platforms supported by JUCE are also supported by Beast. Currently these
|
|
||||||
platforms include:
|
|
||||||
|
|
||||||
- **Windows**: Applications and VST/RTAS/NPAPI/ActiveX plugins can be built
|
|
||||||
using MS Visual Studio. The results are all fully compatible with Windows
|
|
||||||
XP, Vista or Windows 7.
|
|
||||||
|
|
||||||
- **Mac OS X**: Applications and VST/AudioUnit/RTAS/NPAPI plugins with Xcode.
|
|
||||||
|
|
||||||
- **GNU/Linux**: Applications and plugins can be built for any kernel 2.6 or
|
|
||||||
later.
|
|
||||||
|
|
||||||
- **iOS**: Native iPhone and iPad apps.
|
|
||||||
|
|
||||||
- **Android**: Supported.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
This documentation assumes that the reader has a working knowledge of JUCE.
|
|
||||||
Some modules built on external libraries assume that the reader understands
|
|
||||||
the operation of those external libraries. Certain modules assume that the
|
|
||||||
reader understands additional domain-specific information. Modules with
|
|
||||||
additional prerequisites are marked in the documentation.
|
|
||||||
|
|
||||||
## External Modules
|
|
||||||
|
|
||||||
Some modules bring in functionality provided by external libraries. For
|
|
||||||
example, the @ref beast_bzip2 module provides the compression and decompression
|
|
||||||
algorithms in [bZip2][7]. Usage of these external library modules is optional.
|
|
||||||
They come with complete source code, as well as options for using either
|
|
||||||
system or user provided variants of the external libraries: it is not
|
|
||||||
necessary to download additional source code packages to use these modules.
|
|
||||||
|
|
||||||
External code incorporated into Beast is covered by separate licenses. See
|
|
||||||
the licensing information and notes in the corresponding source files for
|
|
||||||
copyright information and terms of use.
|
|
||||||
|
|
||||||
## Integration
|
|
||||||
|
|
||||||
Beast requires recent versions of JUCE. It won't work with versions 1.53 or
|
|
||||||
earlier. To use the library it is necessary to first download JUCE to a
|
|
||||||
location where your development environment can find it. Or, you can use your
|
|
||||||
existing installation of JUCE.
|
|
||||||
|
|
||||||
This library uses the same modularized organizational structure as JUCE. To
|
|
||||||
use a module, first add a path to the list of includes searched by your
|
|
||||||
development environment or project, which points to the Beast directory. Then,
|
|
||||||
add the single corresponding .c or .cpp file to your existing project which
|
|
||||||
already uses JUCE. For example, to use the @ref beast_core module, add the file
|
|
||||||
beast_core.cpp to your project. Some modules depend on other modules.
|
|
||||||
|
|
||||||
To use a module, include the appropriate header from within your source code.
|
|
||||||
For example, to access classes in the @ref beast_concurrent module, use this:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
#include "modules/beast_concurrent/beast_concurrent.h"
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Then add the corresponding file beast_concurrent.cpp to your build.
|
|
||||||
|
|
||||||
## AppConfig
|
|
||||||
|
|
||||||
Some Beast features can be controlled at compilation time through
|
|
||||||
preprocessor directives. The available choices of compilation options are
|
|
||||||
described in AppConfig.h, located in the AppConfigTemplate directory. Copy
|
|
||||||
the provided settings into your existing AppConfig.h (a file used by JUCE
|
|
||||||
convention).
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This library contains portions of other open source products covered by
|
|
||||||
separate licenses. Please see the corresponding source files for specific
|
|
||||||
terms.
|
|
||||||
|
|
||||||
Beast is provided under the terms of The MIT License (MIT):
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Some files contain portions of these external projects, licensed separately:
|
|
||||||
|
|
||||||
- [bZip2][7] is Copyright (C) 1996-2010 Julian R Seward. All rights
|
|
||||||
reserved. See the corresponding file LICENSE for licensing terms.
|
|
||||||
|
|
||||||
- Portions of the software are Copyright (C) 1996-2001, 2006 by [The FreeType
|
|
||||||
Project][8]. All rights reserved. [FreeType][8] is distributed
|
|
||||||
under both the [GNU General Public License][5], or the
|
|
||||||
[FreeType License][9].
|
|
||||||
|
|
||||||
- Portions of this software are Copyright (C) 1994-2012 [Lua.org][10], PUC-Rio.
|
|
||||||
Lua is distributed under the terms of the [MIT License][11].
|
|
||||||
|
|
||||||
- [Luabridge][12] is Copyright (C) 2012 by Vinnie Falco and Copyrighted (C)
|
|
||||||
2007 by Nathan Reed. [Luabridge][12] is distributed under the terms of the
|
|
||||||
[MIT License][11].
|
|
||||||
|
|
||||||
- [Soci][13] is Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton, and
|
|
||||||
various others noted in the corresponding source files. Soci is distributed
|
|
||||||
under the [Boost Software License, Version 1.0][14].
|
|
||||||
|
|
||||||
- [SQLite][15], placed in the public domain.
|
|
||||||
|
|
||||||
- [TagLib][16] is distributed under both the [GNU Lesser General Public License,
|
|
||||||
Version 2.1][17] and the [Mozilla Public License][18].
|
|
||||||
|
|
||||||
[0]: mailto:vinnie.falco@gmail.com "Vinnie Falco (Email)"
|
|
||||||
[1]: https://github.com/vinniefalco/Beast "Beast Project"
|
|
||||||
[2]: http://vinniefalco.github.com/Beast/ "Beast Documentation"
|
|
||||||
[3]: http://rawmaterialsoftware.com/juce.php "JUCE"
|
|
||||||
[4]: http://rawmaterialsoftware.com/ "Raw Material Software"
|
|
||||||
[5]: http://www.gnu.org/licenses/gpl-2.0.html "GNU General Public License, version 2"
|
|
||||||
[6]: http://rawmaterialsoftware.com/jucelicense.php "JUCE Licenses"
|
|
||||||
[7]: http://www.bzip.org/ "bZip2: Home"
|
|
||||||
[8]: http://freetype.org/ "The FreeType Project"
|
|
||||||
[9]: http://www.freetype.org/FTL.TXT "The FreeType Project License"
|
|
||||||
[10]: http://www.lua.org/ "The Programming Language Lua"
|
|
||||||
[11]: http://www.opensource.org/licenses/mit-license.html "The MIT License"
|
|
||||||
[12]: https://github.com/vinniefalco/LuaBridge
|
|
||||||
[13]: http://soci.sourceforge.net/ "SOCI"
|
|
||||||
[14]: http://www.boost.org/LICENSE_1_0.txt "Boost Software License, Version 1.0"
|
|
||||||
[15]: http://sqlite.org/ "SQLite Home Page"
|
|
||||||
[16]: http://developer.kde.org/~wheeler/taglib.html "TagLib"
|
|
||||||
[17]: http://www.gnu.org/licenses/lgpl-2.1.html "Gnu Lesser General Public License, version 2.1"
|
|
||||||
[18]: http://www.mozilla.org/MPL/1.1/ "Mozilla Public License"
|
|
||||||
|
|
||||||
@copyright Copyright (C) 2008 by Vinnie Falco \<vinnie.falco@gmail.com\> ([e-mail][0])
|
|
||||||
@copyright Provided under the [MIT License][11]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
@internal
|
|
||||||
|
|
||||||
Implementation classes.
|
|
||||||
|
|
||||||
Thase classes are used internally.
|
|
||||||
|
|
||||||
@defgroup internal internal
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
External modules.
|
|
||||||
|
|
||||||
These modules bring in functionality from third party or system libraries.
|
|
||||||
|
|
||||||
@defgroup external external
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Core classes.
|
|
||||||
|
|
||||||
This module provides core required functionality, and classes useful for
|
|
||||||
general development. All other modules require this module.
|
|
||||||
|
|
||||||
@todo Discuss the treatment of exceptions versus Error objects in the library.
|
|
||||||
|
|
||||||
@todo Discuss the additions to AppConfig.h
|
|
||||||
|
|
||||||
@defgroup beast_core beast_core
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* See the Juce notes regarding AppConfig.h
|
|
||||||
|
|
||||||
This file must always be included before any Juce headers.
|
|
||||||
|
|
||||||
There are some Beast specific build options that may be placed
|
|
||||||
into this file. See the AppConfig.h provided with Beast.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* BeastConfig.h must be included before this file */
|
|
||||||
|
|
||||||
/* Use sensible default configurations if they forgot
|
|
||||||
to append the necessary macros into their AppConfig.h.
|
|
||||||
*/
|
|
||||||
#ifndef BEAST_USE_BOOST
|
|
||||||
#define BEAST_USE_BOOST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_BZIP2
|
|
||||||
#define BEAST_USE_BZIP2 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_NATIVE_SQLITE
|
|
||||||
#define BEAST_USE_NATIVE_SQLITE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BEAST_USE_LEAKCHECKED
|
|
||||||
#define BEAST_USE_LEAKCHECKED BEAST_CHECK_MEMORY_LEAKS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get this early so we can use it. */
|
|
||||||
#include "../beast_core/system/beast_TargetPlatform.h"
|
|
||||||
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
#include <boost/thread/tss.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_MSVC
|
|
||||||
# include <crtdbg.h>
|
|
||||||
# include <functional>
|
|
||||||
|
|
||||||
#elif BEAST_IOS
|
|
||||||
# if BEAST_USE_BOOST
|
|
||||||
# include <boost/bind.hpp>
|
|
||||||
# include <boost/function.hpp>
|
|
||||||
# else
|
|
||||||
# include <ciso646> // detect std::lib
|
|
||||||
# if _LIBCPP_VERSION // libc++
|
|
||||||
# include <functional>
|
|
||||||
# else // libstdc++ (GNU)
|
|
||||||
# include <tr1/functional>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif BEAST_MAC
|
|
||||||
# include <ciso646> // detect std::lib
|
|
||||||
# if _LIBCPP_VERSION // libc++
|
|
||||||
# include <functional>
|
|
||||||
# else // libstdc++ (GNU)
|
|
||||||
# include <tr1/functional>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif BEAST_LINUX
|
|
||||||
# include <tr1/functional>
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error Unnkown platform!
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cfloat>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <exception>
|
|
||||||
#include <istream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <limits>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <new>
|
|
||||||
#include <numeric>
|
|
||||||
#include <ostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <float.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef _CRTDBG_MAP_ALLOC
|
|
||||||
#error "MSVC C Runtime Debug Macros not supported"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If the MSVC debug heap headers were included, disable
|
|
||||||
// the macros during the juce include since they conflict.
|
|
||||||
#ifdef _CRTDBG_MAP_ALLOC
|
|
||||||
#include <crtdbg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#pragma push_macro("calloc")
|
|
||||||
#pragma push_macro("free")
|
|
||||||
#pragma push_macro("malloc")
|
|
||||||
#pragma push_macro("realloc")
|
|
||||||
#pragma push_macro("_recalloc")
|
|
||||||
#pragma push_macro("_aligned_free")
|
|
||||||
#pragma push_macro("_aligned_malloc")
|
|
||||||
#pragma push_macro("_aligned_offset_malloc")
|
|
||||||
#pragma push_macro("_aligned_realloc")
|
|
||||||
#pragma push_macro("_aligned_recalloc")
|
|
||||||
#pragma push_macro("_aligned_offset_realloc")
|
|
||||||
#pragma push_macro("_aligned_offset_recalloc")
|
|
||||||
#pragma push_macro("_aligned_msize")
|
|
||||||
|
|
||||||
#undef calloc
|
|
||||||
#undef free
|
|
||||||
#undef malloc
|
|
||||||
#undef realloc
|
|
||||||
#undef _recalloc
|
|
||||||
#undef _aligned_free
|
|
||||||
#undef _aligned_malloc
|
|
||||||
#undef _aligned_offset_malloc
|
|
||||||
#undef _aligned_realloc
|
|
||||||
#undef _aligned_recalloc
|
|
||||||
#undef _aligned_offset_realloc
|
|
||||||
#undef _aligned_offset_recalloc
|
|
||||||
#undef _aligned_msize
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../beast_core/beast_core.h"
|
|
||||||
|
|
||||||
#ifdef _CRTDBG_MAP_ALLOC
|
|
||||||
#pragma pop_macro("_aligned_msize")
|
|
||||||
#pragma pop_macro("_aligned_offset_recalloc")
|
|
||||||
#pragma pop_macro("_aligned_offset_realloc")
|
|
||||||
#pragma pop_macro("_aligned_recalloc")
|
|
||||||
#pragma pop_macro("_aligned_realloc")
|
|
||||||
#pragma pop_macro("_aligned_offset_malloc")
|
|
||||||
#pragma pop_macro("_aligned_malloc")
|
|
||||||
#pragma pop_macro("_aligned_free")
|
|
||||||
#pragma pop_macro("_recalloc")
|
|
||||||
#pragma pop_macro("realloc")
|
|
||||||
#pragma pop_macro("malloc")
|
|
||||||
#pragma pop_macro("free")
|
|
||||||
#pragma pop_macro("calloc")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** The Beast namespace.
|
|
||||||
|
|
||||||
This namespace contains all Beast symbols.
|
|
||||||
*/
|
|
||||||
namespace beast
|
|
||||||
{
|
|
||||||
|
|
||||||
// This group must come first since other files need it
|
|
||||||
#include "memory/beast_Uncopyable.h"
|
|
||||||
#include "diagnostic/beast_CatchAny.h"
|
|
||||||
#include "diagnostic/beast_Debug.h"
|
|
||||||
#include "diagnostic/beast_Error.h"
|
|
||||||
#include "diagnostic/beast_FPUFlags.h"
|
|
||||||
#include "diagnostic/beast_LeakChecked.h"
|
|
||||||
#include "diagnostic/beast_SafeBool.h"
|
|
||||||
#include "diagnostic/beast_Throw.h"
|
|
||||||
|
|
||||||
#include "containers/beast_List.h"
|
|
||||||
#include "containers/beast_LockFreeStack.h"
|
|
||||||
#include "containers/beast_LockFreeQueue.h"
|
|
||||||
#include "containers/beast_SharedTable.h"
|
|
||||||
#include "containers/beast_SortedLookupTable.h"
|
|
||||||
|
|
||||||
#include "events/beast_OncePerSecond.h"
|
|
||||||
#include "events/beast_PerformedAtExit.h"
|
|
||||||
|
|
||||||
#include "functor/beast_Bind.h"
|
|
||||||
#include "functor/beast_Function.h"
|
|
||||||
|
|
||||||
#include "math/beast_Interval.h"
|
|
||||||
#include "math/beast_Math.h"
|
|
||||||
#include "math/beast_MurmurHash.h"
|
|
||||||
|
|
||||||
#include "memory/beast_MemoryAlignment.h"
|
|
||||||
#include "memory/beast_StaticObject.h"
|
|
||||||
#include "memory/beast_AtomicCounter.h"
|
|
||||||
#include "memory/beast_AtomicFlag.h"
|
|
||||||
#include "memory/beast_AtomicPointer.h"
|
|
||||||
#include "memory/beast_AtomicState.h"
|
|
||||||
#include "memory/beast_AllocatedBy.h"
|
|
||||||
#include "memory/beast_RefCountedSingleton.h"
|
|
||||||
#include "memory/beast_FifoFreeStore.h"
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
#include "memory/beast_FifoFreeStoreWithTLS.h"
|
|
||||||
#else
|
|
||||||
#include "memory/beast_FifoFreeStoreWithoutTLS.h"
|
|
||||||
#endif
|
|
||||||
#include "memory/beast_GlobalFifoFreeStore.h"
|
|
||||||
#include "memory/beast_GlobalPagedFreeStore.h"
|
|
||||||
#include "memory/beast_PagedFreeStore.h"
|
|
||||||
|
|
||||||
#if BEAST_MSVC
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning (disable: 4100) // unreferenced formal parmaeter
|
|
||||||
#pragma warning (disable: 4355) // 'this' used in base member
|
|
||||||
#endif
|
|
||||||
#include "memory/beast_CacheLine.h"
|
|
||||||
#if BEAST_MSVC
|
|
||||||
#pragma warning (pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "threads/beast_Semaphore.h"
|
|
||||||
#include "threads/beast_SerialFor.h"
|
|
||||||
#include "threads/beast_SpinDelay.h"
|
|
||||||
#include "threads/beast_InterruptibleThread.h"
|
|
||||||
#include "threads/beast_ReadWriteMutex.h"
|
|
||||||
#include "threads/beast_ThreadGroup.h"
|
|
||||||
#include "threads/beast_CallQueue.h"
|
|
||||||
#include "threads/beast_ConcurrentObject.h"
|
|
||||||
#include "threads/beast_ConcurrentState.h"
|
|
||||||
#include "threads/beast_GlobalThreadGroup.h"
|
|
||||||
#include "threads/beast_Listeners.h"
|
|
||||||
#include "threads/beast_ManualCallQueue.h"
|
|
||||||
#include "threads/beast_ParallelFor.h"
|
|
||||||
#include "threads/beast_ThreadWithCallQueue.h"
|
|
||||||
#include "threads/beast_SharedObject.h"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,796 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_LIST_BEASTHEADER
|
|
||||||
#define BEAST_LIST_BEASTHEADER
|
|
||||||
|
|
||||||
struct ListDefaultTag;
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Intrusive Containers
|
|
||||||
|
|
||||||
# Introduction
|
|
||||||
|
|
||||||
Intrusive containers are special containers that offer better performance
|
|
||||||
and exception safety guarantees than non-intrusive containers (like the
|
|
||||||
STL containers). They are useful building blocks for high performance
|
|
||||||
concurrent systems or other purposes where allocations are restricted
|
|
||||||
(such as the AudioIODeviceCallback object), because intrusive list
|
|
||||||
operations do not allocate or free memory.
|
|
||||||
|
|
||||||
While intrusive containers were and are widely used in C, they became more
|
|
||||||
and more forgotten in C++ due to the presence of the standard containers
|
|
||||||
which don't support intrusive techniques. VFLib not only reintroduces this
|
|
||||||
technique to C++ for lists, it also encapsulates the implementation in a
|
|
||||||
mostly compliant STL interface. Hence anyone familiar with standard
|
|
||||||
containers can easily use them.
|
|
||||||
|
|
||||||
# Interface
|
|
||||||
|
|
||||||
The interface for intrusive elements in this library is unified for all
|
|
||||||
containers. Unlike STL containers, objects placed into intrusive containers
|
|
||||||
are not copied. Instead, a pointer to the object is stored. All
|
|
||||||
responsibility for object lifetime is the responsibility of the caller;
|
|
||||||
the intrusive container just keeps track of what is in it.
|
|
||||||
|
|
||||||
Summary of intrusive container differences:
|
|
||||||
|
|
||||||
- Holds pointers to existing objects instead of copies.
|
|
||||||
|
|
||||||
- Does not allocate or free any objects.
|
|
||||||
|
|
||||||
- Requires a element's class declaration to be modified.
|
|
||||||
|
|
||||||
- Methods never throw exceptions when called with valid arguments.
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
Like STL containers, intrusive containers are all template based, where the
|
|
||||||
template argument specifies the type of object that the container will hold.
|
|
||||||
These declarations specify a doubly linked list where each element points
|
|
||||||
to a user defined class:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
class Object; // Forward declaration
|
|
||||||
|
|
||||||
List <Object> list; // Doubly-linked list of Object
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Because intrusive containers allocate no memory, allowing objects to be
|
|
||||||
placed inside requires a modification to their class declaration. Each
|
|
||||||
intrusive container declares a nested class `Node` which elements must be
|
|
||||||
derived from, using the Curiously Recurring Template Pattern (CRTP). We
|
|
||||||
will continue to fully declare the Object type from the previous example
|
|
||||||
to support emplacement into an intrusive container:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
class Object : public List <Object>::Node // Required for List
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void performAction ();
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Usage of a typedef eliminates redundant specification of the template
|
|
||||||
arguments but requires a forward declaration. The following code is
|
|
||||||
equivalent.
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
class Object; // Forward declaration
|
|
||||||
|
|
||||||
// Specify template parameters just once
|
|
||||||
typedef List <Object> ListType;
|
|
||||||
|
|
||||||
class Object : public ListType::Node
|
|
||||||
{
|
|
||||||
void performAction ();
|
|
||||||
};
|
|
||||||
|
|
||||||
ListType::Node list;
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
With these declarations we may proceed to create our objects, add them to
|
|
||||||
the list, and perform operations:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
// Create a few objects and put them in the list
|
|
||||||
for (i = 0; i < 5; ++i)
|
|
||||||
list.push_back (*new Object);
|
|
||||||
|
|
||||||
// Call a method on each list
|
|
||||||
for (ListType::iterator iter = list.begin(); iter != list.end (); ++iter)
|
|
||||||
iter->performAction ();
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Unlike regular STL containers, an object derived from an intrusive container
|
|
||||||
node cannot exist in more than one instance of that list at a time. This is
|
|
||||||
because the bookkeeping information for maintaining the list is kept in
|
|
||||||
the object rather than the list.
|
|
||||||
|
|
||||||
To support objects existing in multiple containers, templates variations
|
|
||||||
are instantiated by distinguishing them with an empty structure, called a
|
|
||||||
tag. The object is derived from multiple instances of Node, where each
|
|
||||||
instance specifies a unique tag. The tag is passed as the second template
|
|
||||||
argument. When the second argument is unspecified, the default tag is used.
|
|
||||||
|
|
||||||
This declaration example shows the usage of tags to allow an object to exist
|
|
||||||
simultaneously in two separate lists:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct GlobalListTag { }; // list of all objects
|
|
||||||
struct ActiveListTag { }; // subset of all objects that are active
|
|
||||||
|
|
||||||
class Object : public List <Object, GlobalListTag>
|
|
||||||
, public List <Object, ActiveListTag>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Object () : m_isActive (false)
|
|
||||||
{
|
|
||||||
// Add ourselves to the global list
|
|
||||||
s_globalList.push_front (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Object ()
|
|
||||||
{
|
|
||||||
deactivate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void becomeActive ()
|
|
||||||
{
|
|
||||||
// Add ourselves to the active list
|
|
||||||
if (!m_isActive)
|
|
||||||
{
|
|
||||||
s_activeList.push_front (*this);
|
|
||||||
m_isActive = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void deactivate ()
|
|
||||||
{
|
|
||||||
if (m_isActive)
|
|
||||||
{
|
|
||||||
// Doesn't delete the object
|
|
||||||
s_activeList.erase (s_activeList.iterator_to (this));
|
|
||||||
|
|
||||||
m_isActive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_isActive;
|
|
||||||
|
|
||||||
static List <Object, GlobalListTag> s_globalList;
|
|
||||||
static List <Object, ActiveListTag> s_activeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@defgroup intrusive intrusive
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Intrusive doubly linked list.
|
|
||||||
|
|
||||||
This intrusive List is a container similar in operation to std::list in the
|
|
||||||
Standard Template Library (STL). Like all @ref intrusive containers, List
|
|
||||||
requires you to first derive your class from List<>::Node:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct Object : List <Object>::Node
|
|
||||||
{
|
|
||||||
Object (int value) : m_value (value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Now we define the list, and add a couple of items.
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
List <Object> list;
|
|
||||||
|
|
||||||
list.push_back (* (new Object (1)));
|
|
||||||
list.push_back (* (new Object (2)));
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
For compatibility with the standard containers, push_back() expects a
|
|
||||||
reference to the object. Unlike the standard container, however, push_back()
|
|
||||||
places the actual object in the list and not a copy-constructed duplicate.
|
|
||||||
|
|
||||||
Iterating over the list follows the same idiom as the STL:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
for (List <Object>::iterator iter = list.begin(); iter != list.end; ++iter)
|
|
||||||
std::cout << iter->m_value;
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
You can even use BOOST_FOREACH, or range based for loops:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
BOOST_FOREACH (Object& object, list) // boost only
|
|
||||||
std::cout << object.m_value;
|
|
||||||
|
|
||||||
for (Object& object : list) // C++11 only
|
|
||||||
std::cout << object.m_value;
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Because List is mostly STL compliant, it can be passed into STL algorithms:
|
|
||||||
e.g. `std::for_each()` or `std::find_first_of()`.
|
|
||||||
|
|
||||||
In general, objects placed into a List should be dynamically allocated
|
|
||||||
although this cannot be enforced at compile time. Since the caller provides
|
|
||||||
the storage for the object, the caller is also responsible for deleting the
|
|
||||||
object. An object still exists after being removed from a List, until the
|
|
||||||
caller deletes it. This means an element can be moved from one List to
|
|
||||||
another with practically no overhead.
|
|
||||||
|
|
||||||
Unlike the standard containers, an object may only exist in one list at a
|
|
||||||
time, unless special preparations are made. The Tag template parameter is
|
|
||||||
used to distinguish between different list types for the same object,
|
|
||||||
allowing the object to exist in more than one list simultaneously.
|
|
||||||
|
|
||||||
For example, consider an actor system where a global list of actors is
|
|
||||||
maintained, so that they can each be periodically receive processing
|
|
||||||
time. We wish to also maintain a list of the subset of actors that require
|
|
||||||
a domain-dependent update. To achieve this, we declare two tags, the
|
|
||||||
associated list types, and the list element thusly:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct Actor; // Forward declaration required
|
|
||||||
|
|
||||||
struct ProcessTag { };
|
|
||||||
struct UpdateTag { };
|
|
||||||
|
|
||||||
typedef List <Actor, ProcessTag> ProcessList;
|
|
||||||
typedef List <Actor, UpdateTag> UpdateList;
|
|
||||||
|
|
||||||
// Derive from both node types so we can be in each list at once.
|
|
||||||
//
|
|
||||||
struct Actor : ProcessList::Node, UpdateList::Node
|
|
||||||
{
|
|
||||||
bool process (); // returns true if we need an update
|
|
||||||
void update ();
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@tparam Element The base type of element which the list will store
|
|
||||||
pointers to.
|
|
||||||
|
|
||||||
@tparam Tag An optional unique type name used to distinguish lists and nodes,
|
|
||||||
when the object can exist in multiple lists simultaneously.
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
template <class Element, class Tag = ListDefaultTag>
|
|
||||||
class List : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef int size_type;
|
|
||||||
|
|
||||||
typedef Element value_type;
|
|
||||||
typedef Element& reference;
|
|
||||||
typedef Element const& const_reference;
|
|
||||||
typedef Element* pointer;
|
|
||||||
typedef Element const* const_pointer;
|
|
||||||
|
|
||||||
class Node : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Node () { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class List;
|
|
||||||
Node* m_next;
|
|
||||||
Node* m_prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class ElemType, class NodeType>
|
|
||||||
class iterator_base : public std::iterator <
|
|
||||||
std::bidirectional_iterator_tag, int >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ElemType value_type;
|
|
||||||
typedef ElemType* pointer;
|
|
||||||
typedef ElemType& reference;
|
|
||||||
|
|
||||||
iterator_base (NodeType* node = nullptr) : m_node (node)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OtherElemType, class OtherNodeType>
|
|
||||||
iterator_base (iterator_base <OtherElemType, OtherNodeType> const& other)
|
|
||||||
: m_node (other.m_node)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OtherElemType, class OtherNodeType>
|
|
||||||
iterator_base& operator= (iterator_base <OtherElemType, OtherNodeType> const& other)
|
|
||||||
{
|
|
||||||
m_node = other.m_node;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OtherElemType, class OtherNodeType>
|
|
||||||
bool operator == (iterator_base <OtherElemType, OtherNodeType> const& other) const
|
|
||||||
{
|
|
||||||
return m_node == other.m_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OtherElemType, class OtherNodeType>
|
|
||||||
bool operator != (iterator_base <OtherElemType, OtherNodeType> const& other) const
|
|
||||||
{
|
|
||||||
return ! this->operator== (other);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator* () const
|
|
||||||
{
|
|
||||||
return dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator-> () const
|
|
||||||
{
|
|
||||||
return &dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_base& operator++ ()
|
|
||||||
{
|
|
||||||
increment ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_base operator++ (int)
|
|
||||||
{
|
|
||||||
iterator_base result (*this);
|
|
||||||
increment ();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_base& operator-- ()
|
|
||||||
{
|
|
||||||
decrement ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_base operator-- (int)
|
|
||||||
{
|
|
||||||
iterator_base result (*this);
|
|
||||||
decrement ();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class List;
|
|
||||||
|
|
||||||
NodeType* get_node ()
|
|
||||||
{
|
|
||||||
return m_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeType const* get_node () const
|
|
||||||
{
|
|
||||||
return m_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference dereference () const
|
|
||||||
{
|
|
||||||
return *static_cast <ElemType*> (m_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equal (NodeType* const* node) const
|
|
||||||
{
|
|
||||||
return m_node == node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment ()
|
|
||||||
{
|
|
||||||
bassert (m_node->m_next);
|
|
||||||
m_node = m_node->m_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement ()
|
|
||||||
{
|
|
||||||
bassert (m_node->m_prev && m_node->m_prev->m_prev != 0);
|
|
||||||
m_node = m_node->m_prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
NodeType* m_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** A read/write List iterator. */
|
|
||||||
typedef iterator_base <Element, Node> iterator;
|
|
||||||
|
|
||||||
/** A read-only List iterator. */
|
|
||||||
typedef iterator_base <Element const, Node const> const_iterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Create an empty list. */
|
|
||||||
List () : m_size (0)
|
|
||||||
{
|
|
||||||
m_head.m_prev = nullptr; // identifies the head
|
|
||||||
m_tail.m_next = nullptr; // identifies the tail
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of elements in the list
|
|
||||||
|
|
||||||
@return The number of elements in the list.
|
|
||||||
*/
|
|
||||||
size_type size () const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a reference to the first element.
|
|
||||||
|
|
||||||
@invariant The list may not be empty.
|
|
||||||
|
|
||||||
@return A reference to the first element.
|
|
||||||
*/
|
|
||||||
reference front ()
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
return element_from (m_head.m_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const reference to the first element.
|
|
||||||
|
|
||||||
@invariant The list may not be empty.
|
|
||||||
|
|
||||||
@return A const reference to the first element.
|
|
||||||
*/
|
|
||||||
const_reference front () const
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
return element_from (m_head.m_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a reference to the last element.
|
|
||||||
|
|
||||||
@invariant The list may not be empty.
|
|
||||||
|
|
||||||
@return A reference to the last element.
|
|
||||||
*/
|
|
||||||
reference back ()
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
return element_from (m_tail.m_prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const reference to the last element.
|
|
||||||
|
|
||||||
@invariant The list may not be empty.
|
|
||||||
|
|
||||||
@return A const reference to the last element.
|
|
||||||
*/
|
|
||||||
const_reference back () const
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
return element_from (m_tail.m_prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain an iterator to the beginning of the list.
|
|
||||||
|
|
||||||
@return An iterator pointing to the beginning of the list.
|
|
||||||
*/
|
|
||||||
iterator begin ()
|
|
||||||
{
|
|
||||||
return iterator (m_head.m_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const iterator to the beginning of the list.
|
|
||||||
|
|
||||||
@return A const iterator pointing to the beginning of the list.
|
|
||||||
*/
|
|
||||||
const_iterator begin () const
|
|
||||||
{
|
|
||||||
return const_iterator (m_head.m_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const iterator to the beginning of the list.
|
|
||||||
|
|
||||||
@return A const iterator pointing to the beginning of the list.
|
|
||||||
*/
|
|
||||||
const_iterator cbegin () const
|
|
||||||
{
|
|
||||||
return const_iterator (m_head.m_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a iterator to the end of the list.
|
|
||||||
|
|
||||||
@return An iterator pointing to the end of the list.
|
|
||||||
*/
|
|
||||||
iterator end ()
|
|
||||||
{
|
|
||||||
return iterator (&m_tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const iterator to the end of the list.
|
|
||||||
|
|
||||||
@return A constiterator pointing to the end of the list.
|
|
||||||
*/
|
|
||||||
const_iterator end () const
|
|
||||||
{
|
|
||||||
return const_iterator (&m_tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const iterator to the end of the list.
|
|
||||||
|
|
||||||
@return A constiterator pointing to the end of the list.
|
|
||||||
*/
|
|
||||||
const_iterator cend () const
|
|
||||||
{
|
|
||||||
return const_iterator (&m_tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the list is empty.
|
|
||||||
|
|
||||||
@return `true` if the list is empty.
|
|
||||||
*/
|
|
||||||
bool empty () const
|
|
||||||
{
|
|
||||||
return m_head.m_next == &m_tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clear the list.
|
|
||||||
|
|
||||||
@note This does not free the elements.
|
|
||||||
*/
|
|
||||||
void clear ()
|
|
||||||
{
|
|
||||||
m_head.m_next = &m_tail;
|
|
||||||
m_tail.m_prev = &m_head;
|
|
||||||
m_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert an element.
|
|
||||||
|
|
||||||
@invariant The element must not already be in the list.
|
|
||||||
|
|
||||||
@param pos The location to insert after.
|
|
||||||
|
|
||||||
@param elem The element to insert.
|
|
||||||
|
|
||||||
@return An iterator pointing to the newly inserted element.
|
|
||||||
*/
|
|
||||||
iterator insert (iterator pos, Element& elem)
|
|
||||||
{
|
|
||||||
Node* node = node_from (elem);
|
|
||||||
node->m_next = pos.get_node ();
|
|
||||||
node->m_prev = node->m_next->m_prev;
|
|
||||||
node->m_next->m_prev = node;
|
|
||||||
node->m_prev->m_next = node;
|
|
||||||
++m_size;
|
|
||||||
return iterator (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert another list into this one.
|
|
||||||
|
|
||||||
The other list is cleared.
|
|
||||||
|
|
||||||
@param pos The location to insert after.
|
|
||||||
|
|
||||||
@param other The list to insert.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void insert (iterator pos, List& other)
|
|
||||||
{
|
|
||||||
if (!other.empty ())
|
|
||||||
{
|
|
||||||
Node* before = pos.get_node ();
|
|
||||||
other.m_head.m_next->m_prev = before->m_prev;
|
|
||||||
before->m_prev->m_next = other.m_head.m_next;
|
|
||||||
other.m_tail.m_prev->m_next = before;
|
|
||||||
before->m_prev = other.m_tail.m_prev;
|
|
||||||
m_size += other.m_size;
|
|
||||||
other.clear ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Remove an element.
|
|
||||||
|
|
||||||
@invariant The element must exist in the list.
|
|
||||||
|
|
||||||
@param pos An iterator pointing to the element to remove.
|
|
||||||
|
|
||||||
@return An iterator pointing to the next element after the one removed.
|
|
||||||
*/
|
|
||||||
iterator erase (iterator pos)
|
|
||||||
{
|
|
||||||
Node* node = pos.get_node ();
|
|
||||||
++pos;
|
|
||||||
node->m_next->m_prev = node->m_prev;
|
|
||||||
node->m_prev->m_next = node->m_next;
|
|
||||||
--m_size;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert an element at the beginning of the list.
|
|
||||||
|
|
||||||
@invariant The element must not exist in the list.
|
|
||||||
|
|
||||||
@param elem The element to insert.
|
|
||||||
*/
|
|
||||||
void push_front (Element& elem)
|
|
||||||
{
|
|
||||||
insert (begin (), elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Remove the element at the beginning of the list.
|
|
||||||
|
|
||||||
@invariant The list must not be empty.
|
|
||||||
*/
|
|
||||||
void pop_front ()
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
erase (begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Append an element at the end of the list.
|
|
||||||
|
|
||||||
@invariant The element must not exist in the list.
|
|
||||||
|
|
||||||
@param elem The element to append.
|
|
||||||
*/
|
|
||||||
void push_back (Element& elem)
|
|
||||||
{
|
|
||||||
insert (end (), elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Remove the element at the end of the list.
|
|
||||||
|
|
||||||
@invariant The list must not be empty.
|
|
||||||
*/
|
|
||||||
void pop_back ()
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, Error::noMoreData));
|
|
||||||
|
|
||||||
erase (--end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Swap contents with another list.
|
|
||||||
*/
|
|
||||||
void swap (List& other)
|
|
||||||
{
|
|
||||||
List temp;
|
|
||||||
temp.append (other);
|
|
||||||
other.append (*this);
|
|
||||||
append (temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert another list at the beginning of this list.
|
|
||||||
|
|
||||||
The other list is cleared.
|
|
||||||
|
|
||||||
@param list The other list to insert.
|
|
||||||
*/
|
|
||||||
void prepend (List& list)
|
|
||||||
{
|
|
||||||
insert (begin (), list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Append another list at the end of this list.
|
|
||||||
|
|
||||||
The other list is cleared.
|
|
||||||
|
|
||||||
@param list the other list to append.
|
|
||||||
*/
|
|
||||||
void append (List& list)
|
|
||||||
{
|
|
||||||
insert (end (), list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain an iterator from an element.
|
|
||||||
|
|
||||||
@invariant The element must exist in the list.
|
|
||||||
|
|
||||||
@param elem The element to obtain an iterator for.
|
|
||||||
|
|
||||||
@return An iterator to the element.
|
|
||||||
*/
|
|
||||||
iterator iterator_to (Element& elem) const
|
|
||||||
{
|
|
||||||
return iterator (static_cast <Node*> (&elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a const iterator from an element.
|
|
||||||
|
|
||||||
@invariant The element must exist in the list.
|
|
||||||
|
|
||||||
@param elem The element to obtain an iterator for.
|
|
||||||
|
|
||||||
@return A const iterator to the element.
|
|
||||||
*/
|
|
||||||
const_iterator const_iterator_to (Element const& elem) const
|
|
||||||
{
|
|
||||||
return const_iterator (static_cast <Node const*> (&elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline reference element_from (Node* node)
|
|
||||||
{
|
|
||||||
return * (static_cast <pointer> (node));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const_reference element_from (Node const* node) const
|
|
||||||
{
|
|
||||||
return * (static_cast <const_pointer> (node));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Node* node_from (Element& elem)
|
|
||||||
{
|
|
||||||
return static_cast <Node*> (&elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Node const* node_from (Element const& elem) const
|
|
||||||
{
|
|
||||||
return static_cast <Node const*> (&elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_type m_size;
|
|
||||||
Node m_head;
|
|
||||||
Node m_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Default tag for List.
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
struct ListDefaultTag { };
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_LOCKFREEQUEUE_BEASTHEADER
|
|
||||||
#define BEAST_LOCKFREEQUEUE_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../memory/beast_CacheLine.h"
|
|
||||||
#include "../memory/beast_AtomicPointer.h"
|
|
||||||
#include "../threads/beast_SpinDelay.h"
|
|
||||||
|
|
||||||
struct LockFreeQueueDefaultTag;
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Multiple Producer, Single Consumer (MPSC) intrusive FIFO.
|
|
||||||
|
|
||||||
This container uses the same intrusive interface as List. It is wait-free
|
|
||||||
for producers and lock-free for consumers. The caller is responsible for
|
|
||||||
preventing the ABA problem (http://en.wikipedia.org/wiki/ABA_problem)
|
|
||||||
|
|
||||||
Invariants:
|
|
||||||
|
|
||||||
- Any thread may call push_back() at any time (Multiple Producer).
|
|
||||||
|
|
||||||
- Only one thread may call try_pop_front() at a time (Single Consumer)
|
|
||||||
|
|
||||||
- The queue is signaled if there are one or more elements.
|
|
||||||
|
|
||||||
@param Tag A type name used to distinguish lists and nodes, for
|
|
||||||
putting objects in multiple lists. If this parameter is
|
|
||||||
omitted, the default tag is used.
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
template <class Element, class Tag = LockFreeQueueDefaultTag>
|
|
||||||
class LockFreeQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class Node : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Node () { }
|
|
||||||
explicit Node (Node* next) : m_next (next) { }
|
|
||||||
|
|
||||||
AtomicPointer <Node> m_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Create an empty list.
|
|
||||||
*/
|
|
||||||
LockFreeQueue ()
|
|
||||||
: m_head (&m_null)
|
|
||||||
, m_tail (&m_null)
|
|
||||||
, m_null (nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the list is empty.
|
|
||||||
|
|
||||||
This is not thread safe, the caller must synchronize.
|
|
||||||
|
|
||||||
@return true if the list is empty.
|
|
||||||
*/
|
|
||||||
bool empty () const
|
|
||||||
{
|
|
||||||
return (m_head.get () == m_tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put an element into the list.
|
|
||||||
|
|
||||||
This operation is wait-free.
|
|
||||||
|
|
||||||
@param node The element to enqueue.
|
|
||||||
|
|
||||||
@return true if the list was previously empty.
|
|
||||||
*/
|
|
||||||
bool push_back (Node* node)
|
|
||||||
{
|
|
||||||
node->m_next.set (0);
|
|
||||||
|
|
||||||
Node* prev = m_head.exchange (node);
|
|
||||||
|
|
||||||
// (*) If a try_pop_front() happens at this point, it might not see the
|
|
||||||
// element we are pushing. This only happens when the list is empty,
|
|
||||||
// and furthermore it is detectable.
|
|
||||||
|
|
||||||
prev->m_next.set (node);
|
|
||||||
|
|
||||||
return prev == &m_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve an element from the list.
|
|
||||||
|
|
||||||
This operation is lock-free.
|
|
||||||
|
|
||||||
@return The element, or nullptr if the list was empty.
|
|
||||||
*/
|
|
||||||
Element* pop_front ()
|
|
||||||
{
|
|
||||||
Element* elem;
|
|
||||||
|
|
||||||
// Avoid the SpinDelay ctor if possible
|
|
||||||
if (!try_pop_front (&elem))
|
|
||||||
{
|
|
||||||
SpinDelay delay;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
delay.pause ();
|
|
||||||
}
|
|
||||||
while (!try_pop_front (&elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Attempt to retrieve an element.
|
|
||||||
|
|
||||||
This attempts to pop an element from the front of the list. The return
|
|
||||||
value indicates if the operation was successful. An operation is
|
|
||||||
successful if there is no contention for the list. On a successful
|
|
||||||
operation, an element is returned if the list was non empty, else nullptr
|
|
||||||
is returned. On failure, the returned element is undefined.
|
|
||||||
|
|
||||||
This operation is wait-free.
|
|
||||||
|
|
||||||
@param[out] pElem The element that was retrieved, or nullptr if the
|
|
||||||
list was empty.
|
|
||||||
|
|
||||||
@return true if the list was uncontended.
|
|
||||||
*/
|
|
||||||
bool try_pop_front (Element** pElem)
|
|
||||||
{
|
|
||||||
Node* tail = m_tail;
|
|
||||||
Node* next = tail->m_next.get ();
|
|
||||||
|
|
||||||
if (tail == &m_null)
|
|
||||||
{
|
|
||||||
if (next == 0)
|
|
||||||
{
|
|
||||||
// (*) If a push_back() happens at this point,
|
|
||||||
// we might not see the element.
|
|
||||||
|
|
||||||
if (m_head.get () == tail)
|
|
||||||
{
|
|
||||||
*pElem = nullptr;
|
|
||||||
return true; // success, but queue empty
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false; // failure: a push_back() caused contention
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tail = next;
|
|
||||||
tail = next;
|
|
||||||
next = next->m_next.get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
m_tail = next;
|
|
||||||
*pElem = static_cast <Element*> (tail);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* head = m_head.get ();
|
|
||||||
|
|
||||||
if (tail == head)
|
|
||||||
{
|
|
||||||
push_back (&m_null);
|
|
||||||
next = tail->m_next.get ();
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
m_tail = next;
|
|
||||||
*pElem = static_cast <Element*> (tail);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// (*) If a push_back() happens at this point,
|
|
||||||
// we might not see the element.
|
|
||||||
|
|
||||||
if (head == m_tail)
|
|
||||||
{
|
|
||||||
*pElem = nullptr;
|
|
||||||
return true; // success, but queue empty
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false; // failure: a push_back() caused contention
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Elements are pushed on to the head and popped from the tail.
|
|
||||||
AtomicPointer <Node> m_head;
|
|
||||||
Node* m_tail;
|
|
||||||
Node m_null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/** Default tag for LockFreeQueue
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
struct LockFreeQueueDefaultTag { };
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_LOCKFREESTACK_BEASTHEADER
|
|
||||||
#define BEAST_LOCKFREESTACK_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../memory/beast_AtomicPointer.h"
|
|
||||||
|
|
||||||
struct LockFreeStackDefaultTag;
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Multiple Producer, Multiple Consumer (MPMC) intrusive stack.
|
|
||||||
|
|
||||||
This stack is implemented using the same intrusive interface as List. All
|
|
||||||
operations are lock-free.
|
|
||||||
|
|
||||||
The caller is responsible for preventing the "ABA" problem
|
|
||||||
(http://en.wikipedia.org/wiki/ABA_problem)
|
|
||||||
|
|
||||||
@param Tag A type name used to distinguish lists and nodes, for
|
|
||||||
putting objects in multiple lists. If this parameter is
|
|
||||||
omitted, the default tag is used.
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
template <class Element, class Tag = LockFreeStackDefaultTag>
|
|
||||||
class LockFreeStack : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class Node : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Node ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Node (Node* next) : m_next (next)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class LockFreeStack;
|
|
||||||
|
|
||||||
AtomicPointer <Node> m_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
LockFreeStack () : m_head (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a LockFreeStack from another stack.
|
|
||||||
|
|
||||||
The contents of the other stack are atomically acquired.
|
|
||||||
The other stack is cleared.
|
|
||||||
|
|
||||||
@param other The other stack to acquire.
|
|
||||||
*/
|
|
||||||
explicit LockFreeStack (LockFreeStack& other)
|
|
||||||
{
|
|
||||||
Node* head;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
head = other.m_head.get ();
|
|
||||||
}
|
|
||||||
while (!other.m_head.compareAndSet (0, head));
|
|
||||||
|
|
||||||
m_head = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Push a node onto the stack.
|
|
||||||
|
|
||||||
The caller is responsible for preventing the ABA problem. This operation
|
|
||||||
is lock-free.
|
|
||||||
|
|
||||||
@param node The node to push.
|
|
||||||
|
|
||||||
@return True if the stack was previously empty. If multiple threads
|
|
||||||
are attempting to push, only one will receive true.
|
|
||||||
*/
|
|
||||||
bool push_front (Node* node)
|
|
||||||
{
|
|
||||||
bool first;
|
|
||||||
Node* head;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
head = m_head.get ();
|
|
||||||
first = head == 0;
|
|
||||||
node->m_next = head;
|
|
||||||
}
|
|
||||||
while (!m_head.compareAndSet (node, head));
|
|
||||||
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Pop an element off the stack.
|
|
||||||
|
|
||||||
The caller is responsible for preventing the ABA problem. This operation
|
|
||||||
is lock-free.
|
|
||||||
|
|
||||||
@return The element that was popped, or nullptr if the stack was empty.
|
|
||||||
*/
|
|
||||||
Element* pop_front ()
|
|
||||||
{
|
|
||||||
Node* node;
|
|
||||||
Node* head;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
node = m_head.get ();
|
|
||||||
|
|
||||||
if (node == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
head = node->m_next.get ();
|
|
||||||
}
|
|
||||||
while (!m_head.compareAndSet (head, node));
|
|
||||||
|
|
||||||
return node ? static_cast <Element*> (node) : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Swap the contents of this stack with another stack.
|
|
||||||
|
|
||||||
This call is not thread safe or atomic. The caller is responsible for
|
|
||||||
synchronizing access.
|
|
||||||
|
|
||||||
@param other The other stack to swap contents with.
|
|
||||||
*/
|
|
||||||
void swap (LockFreeStack& other)
|
|
||||||
{
|
|
||||||
Node* temp = other.m_head.get ();
|
|
||||||
other.m_head.set (m_head.get ());
|
|
||||||
m_head.set (temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicPointer <Node> m_head;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/** Default tag for LockFreeStack
|
|
||||||
|
|
||||||
@ingroup beast_core intrusive
|
|
||||||
*/
|
|
||||||
struct LockFreeStackDefaultTag { };
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SHAREDTABLE_BEASTHEADER
|
|
||||||
#define BEAST_SHAREDTABLE_BEASTHEADER
|
|
||||||
|
|
||||||
/** Handle to a reference counted fixed size table.
|
|
||||||
|
|
||||||
@note Currently, ElementType must be an aggregate of POD.
|
|
||||||
|
|
||||||
@tparam ElementType The type of element.
|
|
||||||
|
|
||||||
@ingroup beast_gui
|
|
||||||
*/
|
|
||||||
template <class ElementType>
|
|
||||||
class SharedTable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ElementType Entry;
|
|
||||||
|
|
||||||
static SharedTable <ElementType> const null;
|
|
||||||
|
|
||||||
/** Creates a null table.
|
|
||||||
*/
|
|
||||||
SharedTable ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a table with the specified number of entries.
|
|
||||||
|
|
||||||
The entries are uninitialized.
|
|
||||||
|
|
||||||
@param numEntries The number of entries in the table.
|
|
||||||
|
|
||||||
@todo Initialize the data if ElementType is not POD.
|
|
||||||
*/
|
|
||||||
explicit SharedTable (int numEntries)
|
|
||||||
: m_data (new Data (numEntries))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a shared reference to another table.
|
|
||||||
*/
|
|
||||||
SharedTable (SharedTable const& other)
|
|
||||||
: m_data (other.m_data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes this table refer to another table.
|
|
||||||
*/
|
|
||||||
SharedTable& operator= (SharedTable const& other)
|
|
||||||
{
|
|
||||||
m_data = other.m_data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
|
||||||
SharedTable (SharedTable&& other) noexcept
|
|
||||||
:
|
|
||||||
m_data (static_cast < typename Data::Ptr&& > (other.m_data))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedTable& operator= (SharedTable && other) noexcept
|
|
||||||
{
|
|
||||||
m_data = static_cast < typename Data::Ptr && > (other.m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Destructor.
|
|
||||||
*/
|
|
||||||
~SharedTable ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the two tables share the same set of entries.
|
|
||||||
*/
|
|
||||||
bool operator== (SharedTable const& other) const noexcept
|
|
||||||
{
|
|
||||||
return m_data == other.m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the two tables do not share the same set of entries.
|
|
||||||
*/
|
|
||||||
bool operator!= (SharedTable const& other) const noexcept
|
|
||||||
{
|
|
||||||
return m_data != other.m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the table is not null.
|
|
||||||
*/
|
|
||||||
inline bool isValid () const noexcept
|
|
||||||
{
|
|
||||||
return m_data != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the table is null.
|
|
||||||
*/
|
|
||||||
inline bool isNull () const noexcept
|
|
||||||
{
|
|
||||||
return m_data == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of tables referring to the same shared entries.
|
|
||||||
*/
|
|
||||||
int getReferenceCount () const noexcept
|
|
||||||
{
|
|
||||||
return m_data == nullptr ? 0 : m_data->getReferenceCount ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a physical duplicate of the table.
|
|
||||||
*/
|
|
||||||
SharedTable createCopy () const
|
|
||||||
{
|
|
||||||
return SharedTable (m_data != nullptr ? m_data->clone () : nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes sure no other tables share the same entries as this table.
|
|
||||||
*/
|
|
||||||
void duplicateIfShared ()
|
|
||||||
{
|
|
||||||
if (m_data != nullptr && m_data->getReferenceCount () > 1)
|
|
||||||
m_data = m_data->clone ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the number of entries in this table.
|
|
||||||
*/
|
|
||||||
inline int getNumEntries () const noexcept
|
|
||||||
{
|
|
||||||
return m_data->getNumEntries ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve a table entry.
|
|
||||||
|
|
||||||
@param index The index of the entry, from 0 to getNumEntries ().
|
|
||||||
*/
|
|
||||||
inline ElementType& operator [] (int index) const noexcept
|
|
||||||
{
|
|
||||||
return m_data->getReference (index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Data : public ReferenceCountedObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ReferenceCountedObjectPtr <Data> Ptr;
|
|
||||||
|
|
||||||
explicit Data (int numEntries)
|
|
||||||
: m_numEntries (numEntries)
|
|
||||||
, m_table (numEntries)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Data* clone () const
|
|
||||||
{
|
|
||||||
Data* data = new Data (m_numEntries);
|
|
||||||
|
|
||||||
memcpy (
|
|
||||||
data->m_table.getData (),
|
|
||||||
m_table.getData (),
|
|
||||||
m_numEntries * sizeof (ElementType));
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int getNumEntries () const
|
|
||||||
{
|
|
||||||
return m_numEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ElementType& getReference (int index) const
|
|
||||||
{
|
|
||||||
bassert (index >= 0 && index < m_numEntries);
|
|
||||||
return m_table [index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int const m_numEntries;
|
|
||||||
HeapBlock <ElementType> const m_table;
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit SharedTable (Data* data)
|
|
||||||
: m_data (data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceCountedObjectPtr <Data> m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ElementType>
|
|
||||||
SharedTable <ElementType> const SharedTable <ElementType>::null;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SORTEDLOOKUPTABLE_BEASTHEADER
|
|
||||||
#define BEAST_SORTEDLOOKUPTABLE_BEASTHEADER
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
Sorted map for fast lookups.
|
|
||||||
|
|
||||||
This container is optimized for a data set with fixed elements.
|
|
||||||
|
|
||||||
SchemaType obeys this concept:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SchemaType
|
|
||||||
{
|
|
||||||
typename KeyType;
|
|
||||||
typename ValueType;
|
|
||||||
|
|
||||||
// Retrieve the key for a specified value.
|
|
||||||
KeyType getKey (Value const& value);
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
To use the table, reserve space with reserveSpaceForValues() if the number
|
|
||||||
of elements is known ahead of time. Then, call insert() for all the your
|
|
||||||
elements. Call prepareForLookups() once then call lookupValueByKey ()
|
|
||||||
*/
|
|
||||||
template <class SchemaType>
|
|
||||||
class SortedLookupTable
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename SchemaType::KeyType KeyType;
|
|
||||||
typedef typename SchemaType::ValueType ValueType;
|
|
||||||
|
|
||||||
typedef std::vector <ValueType> values_t;
|
|
||||||
|
|
||||||
values_t m_values;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct SortCompare
|
|
||||||
{
|
|
||||||
bool operator () (ValueType const& lhs, ValueType const& rhs) const
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FindCompare
|
|
||||||
{
|
|
||||||
bool operator () (ValueType const& lhs, ValueType const& rhs)
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator () (KeyType const& key, ValueType const& rhs)
|
|
||||||
{
|
|
||||||
return key < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator () (ValueType const& lhs, KeyType const& key)
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < key;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename values_t::size_type size_type;
|
|
||||||
|
|
||||||
/** Reserve space for values.
|
|
||||||
|
|
||||||
Although not necessary, this can help with memory usage if the
|
|
||||||
number of values is known ahead of time.
|
|
||||||
|
|
||||||
@param numberOfValues The amount of space to reserve.
|
|
||||||
*/
|
|
||||||
void reserveSpaceForValues (size_type numberOfValues)
|
|
||||||
{
|
|
||||||
m_values.reserve (numberOfValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert a value into the index.
|
|
||||||
|
|
||||||
@invariant The value must not already exist in the index.
|
|
||||||
|
|
||||||
@param valueToInsert The value to insert.
|
|
||||||
*/
|
|
||||||
void insert (ValueType const& valueToInsert)
|
|
||||||
{
|
|
||||||
m_values.push_back (valueToInsert);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Prepare the index for lookups.
|
|
||||||
|
|
||||||
This must be called at least once after calling insert()
|
|
||||||
and before calling find().
|
|
||||||
*/
|
|
||||||
void prepareForLookups ()
|
|
||||||
{
|
|
||||||
std::sort (m_values.begin (), m_values.end (), SortCompare ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find the value for a key.
|
|
||||||
|
|
||||||
Quickly locates a value matching the key, or returns false
|
|
||||||
indicating no value was found.
|
|
||||||
|
|
||||||
@invariant You must call prepareForLookups() once, after all
|
|
||||||
insertions, before calling this function.
|
|
||||||
|
|
||||||
@param key The key to locate.
|
|
||||||
@param pFoundValue Pointer to store the value if a matching
|
|
||||||
key was found.
|
|
||||||
@return `true` if the value was found.
|
|
||||||
*/
|
|
||||||
bool lookupValueByKey (KeyType const& key, ValueType* pFoundValue)
|
|
||||||
{
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
std::pair <typename values_t::iterator, typename values_t::iterator> result =
|
|
||||||
std::equal_range (m_values.begin (), m_values.end (), key, FindCompare ());
|
|
||||||
|
|
||||||
if (result.first != result.second)
|
|
||||||
{
|
|
||||||
*pFoundValue = *result.first;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Windows structured exception handling
|
|
||||||
//
|
|
||||||
#if BEAST_MSVC
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
namespace vf
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// While this object is in scope, any Windows SEH
|
|
||||||
// exceptions will be caught and re-thrown as an Error object.
|
|
||||||
//
|
|
||||||
class ScopedPlatformExceptionCatcher : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScopedPlatformExceptionCatcher ()
|
|
||||||
{
|
|
||||||
//s_mutex.enter ();
|
|
||||||
|
|
||||||
if (++s_count == 1)
|
|
||||||
s_sehPrev = ::SetUnhandledExceptionFilter (sehFilter);
|
|
||||||
|
|
||||||
//s_mutex.exit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedPlatformExceptionCatcher ()
|
|
||||||
{
|
|
||||||
//s_mutex.enter ();
|
|
||||||
|
|
||||||
if (--s_count == 0)
|
|
||||||
SetUnhandledExceptionFilter (s_sehPrev);
|
|
||||||
|
|
||||||
//s_mutex.exit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static LONG WINAPI sehFilter (_EXCEPTION_POINTERS* ei)
|
|
||||||
{
|
|
||||||
EXCEPTION_RECORD* er = ei->ExceptionRecord;
|
|
||||||
|
|
||||||
if (er->ExceptionCode == EXCEPTION_BREAKPOINT ||
|
|
||||||
er->ExceptionCode == EXCEPTION_SINGLE_STEP)
|
|
||||||
{
|
|
||||||
// pass through
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String s;
|
|
||||||
|
|
||||||
switch (er->ExceptionCode)
|
|
||||||
{
|
|
||||||
case EXCEPTION_ACCESS_VIOLATION:
|
|
||||||
s = TRANS ("an access violation occurred");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
|
||||||
s = TRANS ("array bounds were exceeded");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
|
||||||
s = TRANS ("memory access was unaligned");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
|
||||||
s = TRANS ("a floating point operation produced a denormal");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
|
||||||
s = TRANS ("a floating point divide by zero was attempted");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
|
||||||
s = TRANS ("the floating point operation was unrepresentable");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
|
||||||
s = TRANS ("the floating point operation was invalid");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_OVERFLOW:
|
|
||||||
s = TRANS ("the floating point operation overflowed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_STACK_CHECK:
|
|
||||||
s = TRANS ("a stack check resulted from a floating point operation");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_FLT_UNDERFLOW:
|
|
||||||
s = TRANS ("the floating point operation underflowed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
|
||||||
s = TRANS ("an invalid instruction was received");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_IN_PAGE_ERROR:
|
|
||||||
s = TRANS ("a virtual paging error occurred");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
|
||||||
s = TRANS ("an integer divide by zero was attempted");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_INT_OVERFLOW:
|
|
||||||
s = TRANS ("an integer operation overflowed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_INVALID_DISPOSITION:
|
|
||||||
s = TRANS ("the exception handler returned an invalid disposition");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
|
||||||
s = TRANS ("a non-continuable exception occurred");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_PRIV_INSTRUCTION:
|
|
||||||
s = TRANS ("a privileged instruction was attempted");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXCEPTION_STACK_OVERFLOW:
|
|
||||||
s = TRANS ("the stack overflowed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
s = TRANS ("an unknown system exception of code ");
|
|
||||||
s << String ((unsigned int)er->ExceptionCode);
|
|
||||||
s << " " << TRANS ("occurred");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, s, Error::platform));
|
|
||||||
}
|
|
||||||
|
|
||||||
return s_sehPrev (ei);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static int s_count;
|
|
||||||
static CriticalSection s_mutex;
|
|
||||||
static LPTOP_LEVEL_EXCEPTION_FILTER s_sehPrev;
|
|
||||||
};
|
|
||||||
|
|
||||||
CriticalSection ScopedPlatformExceptionCatcher::s_mutex;
|
|
||||||
int ScopedPlatformExceptionCatcher::s_count = 0;
|
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER ScopedPlatformExceptionCatcher::s_sehPrev = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// TODO: POSIX SIGNAL HANDLER
|
|
||||||
|
|
||||||
#pragma message(BEAST_FILEANDLINE_ "Missing class ScopedPlatformExceptionCatcher")
|
|
||||||
|
|
||||||
namespace vf
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
class ScopedPlatformExceptionCatcher
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Missing
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
END_BEAST_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool CatchAny (Function <void (void)> f, bool returnFromException)
|
|
||||||
{
|
|
||||||
bool caughtException = true; // assume the worst
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//ScopedPlatformExceptionCatcher platformExceptionCatcher;
|
|
||||||
|
|
||||||
f ();
|
|
||||||
|
|
||||||
caughtException = false;
|
|
||||||
}
|
|
||||||
catch (Error& e)
|
|
||||||
{
|
|
||||||
if (!returnFromException)
|
|
||||||
{
|
|
||||||
JUCEApplication* app = JUCEApplication::getInstance ();
|
|
||||||
|
|
||||||
if (app)
|
|
||||||
{
|
|
||||||
app->unhandledException (
|
|
||||||
&e,
|
|
||||||
e.getSourceFilename (),
|
|
||||||
e.getLineNumber ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << e.what ();
|
|
||||||
std::unexpected ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
if (!returnFromException)
|
|
||||||
{
|
|
||||||
JUCEApplication* app = JUCEApplication::getInstance ();
|
|
||||||
|
|
||||||
if (app)
|
|
||||||
{
|
|
||||||
app->unhandledException (&e, __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << e.what ();
|
|
||||||
std::unexpected ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
if (!returnFromException)
|
|
||||||
{
|
|
||||||
JUCEApplication* app = JUCEApplication::getInstance ();
|
|
||||||
|
|
||||||
if (app)
|
|
||||||
{
|
|
||||||
app->unhandledException (0, __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::unexpected ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return caughtException;
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_CATCHANY_BEASTHEADER
|
|
||||||
#define BEAST_CATCHANY_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../functor/beast_Function.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Exception catcher.
|
|
||||||
|
|
||||||
Executes the function and catches any exception.
|
|
||||||
In addition to C++ exceptions, this will also catch
|
|
||||||
any platform-specific exceptions. For example, SEH
|
|
||||||
(Structured Exception Handling) on Windows, or POSIX
|
|
||||||
signals if they are available.
|
|
||||||
|
|
||||||
If returnFromException is false then a framework
|
|
||||||
specific unhandled exception handler will be called.
|
|
||||||
Otherwise, this function will return true if it
|
|
||||||
catches something or else false.
|
|
||||||
|
|
||||||
The return value approach is useful for detecting
|
|
||||||
when outside code fails (for example, a VST plugin),
|
|
||||||
and disabling its future use for example.
|
|
||||||
|
|
||||||
@todo Remove dependence on the JUCEApplication object and remove beast_gui_basics.h from beast_core.cpp
|
|
||||||
|
|
||||||
@param f The function to call.
|
|
||||||
|
|
||||||
@param returnFromException `false` if exceptions should terminate the app.
|
|
||||||
|
|
||||||
@return `true` if an exception was caught.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
extern bool CatchAny (Function <void (void)> f,
|
|
||||||
bool returnFromException = false);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
namespace Debug
|
|
||||||
{
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool isDebuggerAttached ()
|
|
||||||
{
|
|
||||||
return beast_isRunningUnderDebugger ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if BEAST_DEBUG && defined (beast_breakDebugger)
|
|
||||||
void breakPoint ()
|
|
||||||
{
|
|
||||||
if (isDebuggerAttached ())
|
|
||||||
beast_breakDebugger;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void breakPoint ()
|
|
||||||
{
|
|
||||||
bassertfalse
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if BEAST_MSVC && defined (_DEBUG)
|
|
||||||
|
|
||||||
void setHeapAlwaysCheck (bool bAlwaysCheck)
|
|
||||||
{
|
|
||||||
int flags = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
|
|
||||||
|
|
||||||
if (bAlwaysCheck) flags |= _CRTDBG_CHECK_ALWAYS_DF; // on
|
|
||||||
else flags &= ~_CRTDBG_CHECK_ALWAYS_DF; // off
|
|
||||||
|
|
||||||
_CrtSetDbgFlag (flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHeapDelayedFree (bool bDelayedFree)
|
|
||||||
{
|
|
||||||
int flags = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
|
|
||||||
|
|
||||||
if (bDelayedFree) flags |= _CRTDBG_DELAY_FREE_MEM_DF; // on
|
|
||||||
else flags &= ~_CRTDBG_DELAY_FREE_MEM_DF; // off
|
|
||||||
|
|
||||||
_CrtSetDbgFlag (flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHeapReportLeaks (bool bReportLeaks)
|
|
||||||
{
|
|
||||||
int flags = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
|
|
||||||
|
|
||||||
if (bReportLeaks) flags |= _CRTDBG_LEAK_CHECK_DF; // on
|
|
||||||
else flags &= ~_CRTDBG_LEAK_CHECK_DF; // off
|
|
||||||
|
|
||||||
_CrtSetDbgFlag (flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkHeap ()
|
|
||||||
{
|
|
||||||
_CrtCheckMemory ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void setHeapAlwaysCheck (bool)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHeapDelayedFree (bool)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHeapReportLeaks (bool)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkHeap ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const String getFileNameFromPath (const char* sourceFileName)
|
|
||||||
{
|
|
||||||
return File::createFileWithoutCheckingPath (sourceFileName).getFileName ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a String with double quotes escaped
|
|
||||||
static const String withEscapedQuotes (String const& string)
|
|
||||||
{
|
|
||||||
String escaped;
|
|
||||||
|
|
||||||
int i0 = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
i = string.indexOfChar (i0, '"');
|
|
||||||
|
|
||||||
if (i == -1)
|
|
||||||
{
|
|
||||||
escaped << string.substring (i0, string.length ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
escaped << string.substring (i0, i) << "\\\"";
|
|
||||||
i0 = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (i != -1);
|
|
||||||
|
|
||||||
return escaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts escaped quotes back into regular quotes
|
|
||||||
static const String withUnescapedQuotes (String const& string)
|
|
||||||
{
|
|
||||||
String unescaped;
|
|
||||||
|
|
||||||
int i0 = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
i = string.indexOfChar (i0, '\\');
|
|
||||||
|
|
||||||
if (i == -1)
|
|
||||||
{
|
|
||||||
unescaped << string.substring (i0, string.length ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// peek
|
|
||||||
if (string.length () > i && string[i + 1] == '\"')
|
|
||||||
{
|
|
||||||
unescaped << string.substring (i0, i) << '"';
|
|
||||||
i0 = i + 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unescaped << string.substring (i0, i + 1);
|
|
||||||
i0 = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (i != -1);
|
|
||||||
|
|
||||||
return unescaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a String that may contain newlines, into a
|
|
||||||
// command line where each line is delimited with quotes.
|
|
||||||
// Any quotes in the actual string will be escaped via \".
|
|
||||||
String stringToCommandLine (String const& string)
|
|
||||||
{
|
|
||||||
String commandLine;
|
|
||||||
|
|
||||||
int i0 = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < string.length (); i++)
|
|
||||||
{
|
|
||||||
beast_wchar c = string[i];
|
|
||||||
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
if (i0 != 0)
|
|
||||||
commandLine << ' ';
|
|
||||||
|
|
||||||
commandLine << '"' << withEscapedQuotes (string.substring (i0, i)) << '"';
|
|
||||||
i0 = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i0 < i)
|
|
||||||
{
|
|
||||||
if (i0 != 0)
|
|
||||||
commandLine << ' ';
|
|
||||||
|
|
||||||
commandLine << '"' << withEscapedQuotes (string.substring (i0, i)) << '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
return commandLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a command line consisting of multiple quoted strings
|
|
||||||
// back into a single string with newlines delimiting each quoted
|
|
||||||
// string. Escaped quotes \" are turned into real quotes.
|
|
||||||
String commandLineToString (const String& commandLine)
|
|
||||||
{
|
|
||||||
String string;
|
|
||||||
|
|
||||||
bool quoting = false;
|
|
||||||
int i0 = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < commandLine.length (); i++)
|
|
||||||
{
|
|
||||||
beast_wchar c = commandLine[i];
|
|
||||||
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
// peek
|
|
||||||
if (commandLine.length () > i && commandLine[i + 1] == '\"')
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c == '"')
|
|
||||||
{
|
|
||||||
if (!quoting)
|
|
||||||
{
|
|
||||||
i0 = i + 1;
|
|
||||||
quoting = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!string.isEmpty ())
|
|
||||||
string << '\n';
|
|
||||||
|
|
||||||
string << withUnescapedQuotes (commandLine.substring (i0, i));
|
|
||||||
quoting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_DEBUG_BEASTHEADER
|
|
||||||
#define BEAST_DEBUG_BEASTHEADER
|
|
||||||
|
|
||||||
// Auxiliary outines for debugging
|
|
||||||
|
|
||||||
namespace Debug
|
|
||||||
{
|
|
||||||
|
|
||||||
// Returns true if a debugger is attached, for any build.
|
|
||||||
extern bool isDebuggerAttached ();
|
|
||||||
|
|
||||||
// Breaks to the debugger if a debugger is attached.
|
|
||||||
extern void breakPoint ();
|
|
||||||
|
|
||||||
// VF: IS THIS REALLY THE RIGHT PLACE FOR THESE??
|
|
||||||
|
|
||||||
// Return only the filename portion of sourceFileName
|
|
||||||
// This hides the programmer's directory structure from end-users.
|
|
||||||
const String getFileNameFromPath (const char* sourceFileName);
|
|
||||||
|
|
||||||
// Convert a String that may contain double quotes and newlines
|
|
||||||
// into a String with double quotes escaped as \" and each
|
|
||||||
// line as a separate quoted command line argument.
|
|
||||||
String stringToCommandLine (const String& s);
|
|
||||||
|
|
||||||
// Convert a quoted and escaped command line back into a String
|
|
||||||
// that can contain newlines and double quotes.
|
|
||||||
String commandLineToString (const String& commandLine);
|
|
||||||
|
|
||||||
extern void setHeapAlwaysCheck (bool bAlwaysCheck);
|
|
||||||
extern void setHeapDelayedFree (bool bDelayedFree);
|
|
||||||
extern void setHeapReportLeaks (bool bReportLeaks);
|
|
||||||
extern void checkHeap ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
Error::Error ()
|
|
||||||
: m_code (success)
|
|
||||||
, m_lineNumber (0)
|
|
||||||
, m_needsToBeChecked (true)
|
|
||||||
, m_szWhat (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Error::Error (const Error& other)
|
|
||||||
: m_code (other.m_code)
|
|
||||||
, m_reasonText (other.m_reasonText)
|
|
||||||
, m_sourceFileName (other.m_sourceFileName)
|
|
||||||
, m_lineNumber (other.m_lineNumber)
|
|
||||||
, m_needsToBeChecked (true)
|
|
||||||
, m_szWhat (0)
|
|
||||||
{
|
|
||||||
other.m_needsToBeChecked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error::~Error () noexcept
|
|
||||||
{
|
|
||||||
/* If this goes off it means an error object was created but never tested */
|
|
||||||
bassert (!m_needsToBeChecked);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error& Error::operator= (const Error& other)
|
|
||||||
{
|
|
||||||
m_code = other.m_code;
|
|
||||||
m_reasonText = other.m_reasonText;
|
|
||||||
m_sourceFileName = other.m_sourceFileName;
|
|
||||||
m_lineNumber = other.m_lineNumber;
|
|
||||||
m_needsToBeChecked = true;
|
|
||||||
m_what = String::empty;
|
|
||||||
m_szWhat = 0;
|
|
||||||
|
|
||||||
other.m_needsToBeChecked = false;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error::Code Error::code () const
|
|
||||||
{
|
|
||||||
m_needsToBeChecked = false;
|
|
||||||
return m_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Error::failed () const
|
|
||||||
{
|
|
||||||
return code () != success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Error::asBoolean () const
|
|
||||||
{
|
|
||||||
return code () != success;
|
|
||||||
}
|
|
||||||
|
|
||||||
const String Error::getReasonText () const
|
|
||||||
{
|
|
||||||
return m_reasonText;
|
|
||||||
}
|
|
||||||
|
|
||||||
const String Error::getSourceFilename () const
|
|
||||||
{
|
|
||||||
return m_sourceFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Error::getLineNumber () const
|
|
||||||
{
|
|
||||||
return m_lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error& Error::fail (const char* sourceFileName,
|
|
||||||
int lineNumber,
|
|
||||||
const String reasonText,
|
|
||||||
Code errorCode)
|
|
||||||
{
|
|
||||||
bassert (m_code == success);
|
|
||||||
bassert (errorCode != success);
|
|
||||||
|
|
||||||
m_code = errorCode;
|
|
||||||
m_reasonText = reasonText;
|
|
||||||
m_sourceFileName = Debug::getFileNameFromPath (sourceFileName);
|
|
||||||
m_lineNumber = lineNumber;
|
|
||||||
m_needsToBeChecked = true;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error& Error::fail (const char* sourceFileName,
|
|
||||||
int lineNumber,
|
|
||||||
Code errorCode)
|
|
||||||
{
|
|
||||||
return fail (sourceFileName,
|
|
||||||
lineNumber,
|
|
||||||
getReasonTextForCode (errorCode),
|
|
||||||
errorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Error::reset ()
|
|
||||||
{
|
|
||||||
m_code = success;
|
|
||||||
m_reasonText = String::empty;
|
|
||||||
m_sourceFileName = String::empty;
|
|
||||||
m_lineNumber = 0;
|
|
||||||
m_needsToBeChecked = true;
|
|
||||||
m_what = String::empty;
|
|
||||||
m_szWhat = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Error::willBeReported () const
|
|
||||||
{
|
|
||||||
m_needsToBeChecked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Error::what () const noexcept
|
|
||||||
{
|
|
||||||
if (!m_szWhat)
|
|
||||||
{
|
|
||||||
// The application could not be initialized because sqlite was denied access permission
|
|
||||||
// The application unexpectedly quit because the exception 'sqlite was denied access permission at file ' was thrown
|
|
||||||
m_what <<
|
|
||||||
m_reasonText << " " <<
|
|
||||||
TRANS ("at file") << " '" <<
|
|
||||||
m_sourceFileName << "' " <<
|
|
||||||
TRANS ("line") << " " <<
|
|
||||||
String (m_lineNumber) << " " <<
|
|
||||||
TRANS ("with code") << " = " <<
|
|
||||||
String (m_code);
|
|
||||||
|
|
||||||
m_szWhat = (const char*)m_what.toUTF8 ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_szWhat;
|
|
||||||
}
|
|
||||||
|
|
||||||
const String Error::getReasonTextForCode (Code code)
|
|
||||||
{
|
|
||||||
String s;
|
|
||||||
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case success:
|
|
||||||
s = TRANS ("the operation was successful");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case general:
|
|
||||||
s = TRANS ("a general error occurred");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case canceled:
|
|
||||||
s = TRANS ("the operation was canceled");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case exception:
|
|
||||||
s = TRANS ("an exception was thrown");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case unexpected:
|
|
||||||
s = TRANS ("an unexpected result was encountered");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case platform:
|
|
||||||
s = TRANS ("a system exception was signaled");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case noMemory:
|
|
||||||
s = TRANS ("there was not enough memory");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case noMoreData:
|
|
||||||
s = TRANS ("the end of data was reached");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case invalidData:
|
|
||||||
s = TRANS ("the data is corrupt or invalid");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case bufferSpace:
|
|
||||||
s = TRANS ("the buffer is too small");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case badParameter:
|
|
||||||
s = TRANS ("one or more parameters were invalid");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case assertFailed:
|
|
||||||
s = TRANS ("an assertion failed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileInUse:
|
|
||||||
s = TRANS ("the file is in use");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileExists:
|
|
||||||
s = TRANS ("the file exists");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileNoPerm:
|
|
||||||
s = TRANS ("permission was denied");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileIOError:
|
|
||||||
s = TRANS ("an I/O or device error occurred");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileNoSpace:
|
|
||||||
s = TRANS ("there is no space left on the device");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileNotFound:
|
|
||||||
s = TRANS ("the file was not found");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case fileNameInvalid:
|
|
||||||
s = TRANS ("the file name was illegal or malformed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
s = TRANS ("an unknown error code was received");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ERROR_BEASTHEADER
|
|
||||||
#define BEAST_ERROR_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_SafeBool.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
A concise error report.
|
|
||||||
|
|
||||||
This lightweight but flexible class records lets you record the file and
|
|
||||||
line where a recoverable error occurred, along with some optional human
|
|
||||||
readable text.
|
|
||||||
|
|
||||||
A recoverable error can be passed along and turned into a non recoverable
|
|
||||||
error by throwing the object: it's derivation from std::exception is
|
|
||||||
fully compliant with the C++ exception interface.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class Error
|
|
||||||
: public std::exception
|
|
||||||
, public SafeBool <Error>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Numeric code.
|
|
||||||
|
|
||||||
This enumeration is useful when the caller needs to take different
|
|
||||||
actions depending on the failure. For example, trying again later if
|
|
||||||
a file is locked.
|
|
||||||
*/
|
|
||||||
enum Code
|
|
||||||
{
|
|
||||||
success, //!< "the operation was successful"
|
|
||||||
|
|
||||||
general, //!< "a general error occurred"
|
|
||||||
|
|
||||||
canceled, //!< "the operation was canceled"
|
|
||||||
exception, //!< "an exception was thrown"
|
|
||||||
unexpected, //!< "an unexpected result was encountered"
|
|
||||||
platform, //!< "a system exception was signaled"
|
|
||||||
|
|
||||||
noMemory, //!< "there was not enough memory"
|
|
||||||
noMoreData, //!< "the end of data was reached"
|
|
||||||
invalidData, //!< "the data is corrupt or invalid"
|
|
||||||
bufferSpace, //!< "the buffer is too small"
|
|
||||||
badParameter, //!< "one or more parameters were invalid"
|
|
||||||
assertFailed, //!< "an assertion failed"
|
|
||||||
|
|
||||||
fileInUse, //!< "the file is in use"
|
|
||||||
fileExists, //!< "the file exists"
|
|
||||||
fileNoPerm, //!< "permission was denied" (file attributes conflict)
|
|
||||||
fileIOError, //!< "an I/O or device error occurred"
|
|
||||||
fileNoSpace, //!< "there is no space left on the device"
|
|
||||||
fileNotFound, //!< "the file was not found"
|
|
||||||
fileNameInvalid //!< "the file name was illegal or malformed"
|
|
||||||
};
|
|
||||||
|
|
||||||
Error ();
|
|
||||||
Error (const Error& other);
|
|
||||||
Error& operator= (const Error& other);
|
|
||||||
|
|
||||||
virtual ~Error () noexcept;
|
|
||||||
|
|
||||||
Code code () const;
|
|
||||||
bool failed () const;
|
|
||||||
|
|
||||||
bool asBoolean () const;
|
|
||||||
|
|
||||||
const String getReasonText () const;
|
|
||||||
const String getSourceFilename () const;
|
|
||||||
int getLineNumber () const;
|
|
||||||
|
|
||||||
Error& fail (const char* sourceFileName,
|
|
||||||
int lineNumber,
|
|
||||||
const String reasonText,
|
|
||||||
Code errorCode = general);
|
|
||||||
|
|
||||||
Error& fail (const char* sourceFileName,
|
|
||||||
int lineNumber,
|
|
||||||
Code errorCode = general);
|
|
||||||
|
|
||||||
// A function that is capable of recovering from an error (for
|
|
||||||
// example, by performing a different action) can reset the
|
|
||||||
// object so it can be passed up.
|
|
||||||
void reset ();
|
|
||||||
|
|
||||||
// Call this when reporting the error to clear the "checked" flag
|
|
||||||
void willBeReported () const;
|
|
||||||
|
|
||||||
// for std::exception. This lets you throw an Error that should
|
|
||||||
// terminate the application. The what() message will be less
|
|
||||||
// descriptive so ideally you should catch the Error object instead.
|
|
||||||
const char* what () const noexcept;
|
|
||||||
|
|
||||||
static const String getReasonTextForCode (Code code);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Code m_code;
|
|
||||||
String m_reasonText;
|
|
||||||
String m_sourceFileName;
|
|
||||||
int m_lineNumber;
|
|
||||||
mutable bool m_needsToBeChecked;
|
|
||||||
|
|
||||||
mutable String m_what; // created on demand
|
|
||||||
mutable const char* m_szWhat;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
void FPUFlags::clearUnsetFlagsFrom (const FPUFlags& flags)
|
|
||||||
{
|
|
||||||
if (!flags.getMaskNaNs ().is_set ()) m_maskNaNs.clear ();
|
|
||||||
|
|
||||||
if (!flags.getMaskDenormals ().is_set ()) m_maskDenormals.clear ();
|
|
||||||
|
|
||||||
if (!flags.getMaskZeroDivides ().is_set ()) m_maskZeroDivides.clear ();
|
|
||||||
|
|
||||||
if (!flags.getMaskOverflows ().is_set ()) m_maskOverflows.clear ();
|
|
||||||
|
|
||||||
if (!flags.getMaskUnderflows ().is_set ()) m_maskUnderflows.clear ();
|
|
||||||
|
|
||||||
//if (!flags.getMaskInexacts().is_set ()) m_maskInexacts.clear ();
|
|
||||||
if (!flags.getFlushDenormals ().is_set ()) m_flushDenormals.clear ();
|
|
||||||
|
|
||||||
if (!flags.getInfinitySigned ().is_set ()) m_infinitySigned.clear ();
|
|
||||||
|
|
||||||
if (!flags.getRounding ().is_set ()) m_rounding.clear ();
|
|
||||||
|
|
||||||
if (!flags.getPrecision ().is_set ()) m_precision.clear ();
|
|
||||||
}
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_FPUFLAGS_BEASTHEADER
|
|
||||||
#define BEAST_FPUFLAGS_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A set of IEEE FPU flags.
|
|
||||||
|
|
||||||
Description.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class FPUFlags
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** An individual FPU flag */
|
|
||||||
struct Flag
|
|
||||||
{
|
|
||||||
Flag () : m_set (false) { }
|
|
||||||
Flag (Flag const& flag) : m_set (flag.m_set), m_value (flag.m_value) { }
|
|
||||||
Flag& operator= (Flag const& flag)
|
|
||||||
{
|
|
||||||
m_set = flag.m_set;
|
|
||||||
m_value = flag.m_value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
bool is_set () const
|
|
||||||
{
|
|
||||||
return m_set;
|
|
||||||
}
|
|
||||||
bool value () const
|
|
||||||
{
|
|
||||||
assert (m_set);
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
void set_value (bool value)
|
|
||||||
{
|
|
||||||
m_set = true;
|
|
||||||
m_value = value;
|
|
||||||
}
|
|
||||||
void clear ()
|
|
||||||
{
|
|
||||||
m_set = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_set : 1;
|
|
||||||
bool m_value : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A multi-valued FPU setting */
|
|
||||||
template <typename Constants>
|
|
||||||
struct Enum
|
|
||||||
{
|
|
||||||
Enum () : m_set (false) { }
|
|
||||||
Enum (Enum const& value) : m_set (value.m_set), m_value (value.m_value) { }
|
|
||||||
Enum& operator= (Enum const& value)
|
|
||||||
{
|
|
||||||
m_set = value.m_set;
|
|
||||||
m_value = value.m_value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
bool is_set () const
|
|
||||||
{
|
|
||||||
return m_set;
|
|
||||||
}
|
|
||||||
Constants value () const
|
|
||||||
{
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
void set_value (Constants value)
|
|
||||||
{
|
|
||||||
m_set = true;
|
|
||||||
m_value = value;
|
|
||||||
}
|
|
||||||
void clear ()
|
|
||||||
{
|
|
||||||
m_set = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_set : 1;
|
|
||||||
Constants m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
//
|
|
||||||
// Exception masks
|
|
||||||
//
|
|
||||||
|
|
||||||
void setMaskNaNs (bool mask = true)
|
|
||||||
{
|
|
||||||
m_maskNaNs.set_value (mask);
|
|
||||||
}
|
|
||||||
void setMaskDenormals (bool mask = true)
|
|
||||||
{
|
|
||||||
m_maskDenormals.set_value (mask);
|
|
||||||
}
|
|
||||||
void setMaskZeroDivides (bool mask = true)
|
|
||||||
{
|
|
||||||
m_maskZeroDivides.set_value (mask);
|
|
||||||
}
|
|
||||||
void setMaskOverflows (bool mask = true)
|
|
||||||
{
|
|
||||||
m_maskOverflows.set_value (mask);
|
|
||||||
}
|
|
||||||
void setMaskUnderflows (bool mask = true)
|
|
||||||
{
|
|
||||||
m_maskUnderflows.set_value (mask);
|
|
||||||
}
|
|
||||||
//void setMaskInexacts (bool mask = true) { m_maskInexacts.set_value (mask); }
|
|
||||||
|
|
||||||
void setUnmaskAllExceptions (bool unmask = true)
|
|
||||||
{
|
|
||||||
setMaskNaNs (!unmask);
|
|
||||||
setMaskDenormals (!unmask);
|
|
||||||
setMaskZeroDivides (!unmask);
|
|
||||||
setMaskOverflows (!unmask);
|
|
||||||
setMaskUnderflows (!unmask);
|
|
||||||
//setMaskInexacts (!unmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Denormal control
|
|
||||||
//
|
|
||||||
|
|
||||||
void setFlushDenormals (bool flush = true)
|
|
||||||
{
|
|
||||||
m_flushDenormals.set_value (flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Infinity control
|
|
||||||
//
|
|
||||||
|
|
||||||
void setInfinitySigned (bool is_signed = true)
|
|
||||||
{
|
|
||||||
m_infinitySigned.set_value (is_signed);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Rounding control
|
|
||||||
//
|
|
||||||
|
|
||||||
enum Rounding
|
|
||||||
{
|
|
||||||
roundChop,
|
|
||||||
roundUp,
|
|
||||||
roundDown,
|
|
||||||
roundNear
|
|
||||||
};
|
|
||||||
|
|
||||||
void setRounding (Rounding rounding)
|
|
||||||
{
|
|
||||||
m_rounding.set_value (rounding);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Precision control
|
|
||||||
//
|
|
||||||
|
|
||||||
enum Precision
|
|
||||||
{
|
|
||||||
bits24,
|
|
||||||
bits53,
|
|
||||||
bits64
|
|
||||||
};
|
|
||||||
|
|
||||||
void setPrecision (Precision precision)
|
|
||||||
{
|
|
||||||
m_precision.set_value (precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Retrieval
|
|
||||||
//
|
|
||||||
|
|
||||||
const Flag getMaskNaNs () const
|
|
||||||
{
|
|
||||||
return m_maskNaNs;
|
|
||||||
}
|
|
||||||
const Flag getMaskDenormals () const
|
|
||||||
{
|
|
||||||
return m_maskDenormals;
|
|
||||||
}
|
|
||||||
const Flag getMaskZeroDivides () const
|
|
||||||
{
|
|
||||||
return m_maskZeroDivides;
|
|
||||||
}
|
|
||||||
const Flag getMaskOverflows () const
|
|
||||||
{
|
|
||||||
return m_maskOverflows;
|
|
||||||
}
|
|
||||||
const Flag getMaskUnderflows () const
|
|
||||||
{
|
|
||||||
return m_maskUnderflows;
|
|
||||||
}
|
|
||||||
//const Flag getMaskInexacts () const { return m_maskInexacts; }
|
|
||||||
const Flag getFlushDenormals () const
|
|
||||||
{
|
|
||||||
return m_flushDenormals;
|
|
||||||
}
|
|
||||||
const Flag getInfinitySigned () const
|
|
||||||
{
|
|
||||||
return m_infinitySigned;
|
|
||||||
}
|
|
||||||
const Enum <Rounding> getRounding () const
|
|
||||||
{
|
|
||||||
return m_rounding;
|
|
||||||
}
|
|
||||||
const Enum <Precision> getPrecision () const
|
|
||||||
{
|
|
||||||
return m_precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flag& getMaskNaNs ()
|
|
||||||
{
|
|
||||||
return m_maskNaNs;
|
|
||||||
}
|
|
||||||
Flag& getMaskDenormals ()
|
|
||||||
{
|
|
||||||
return m_maskDenormals;
|
|
||||||
}
|
|
||||||
Flag& getMaskZeroDivides ()
|
|
||||||
{
|
|
||||||
return m_maskZeroDivides;
|
|
||||||
}
|
|
||||||
Flag& getMaskOverflows ()
|
|
||||||
{
|
|
||||||
return m_maskOverflows;
|
|
||||||
}
|
|
||||||
Flag& getMaskUnderflows ()
|
|
||||||
{
|
|
||||||
return m_maskUnderflows;
|
|
||||||
}
|
|
||||||
//Flag& getMaskInexacts () { return m_maskInexacts; }
|
|
||||||
Flag& getFlushDenormals ()
|
|
||||||
{
|
|
||||||
return m_flushDenormals;
|
|
||||||
}
|
|
||||||
Flag& getInfinitySigned ()
|
|
||||||
{
|
|
||||||
return m_infinitySigned;
|
|
||||||
}
|
|
||||||
Enum <Rounding>& getRounding ()
|
|
||||||
{
|
|
||||||
return m_rounding;
|
|
||||||
}
|
|
||||||
Enum <Precision>& getPrecision ()
|
|
||||||
{
|
|
||||||
return m_precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clears our flags if they are not set in another object
|
|
||||||
void clearUnsetFlagsFrom (FPUFlags const& flags);
|
|
||||||
|
|
||||||
// Retrieve the current flags fron the FPU
|
|
||||||
static FPUFlags getCurrent ();
|
|
||||||
|
|
||||||
// Change the current FPU flags based on what is set in flags
|
|
||||||
static void setCurrent (FPUFlags const& flags);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Flag m_maskNaNs;
|
|
||||||
Flag m_maskDenormals;
|
|
||||||
Flag m_maskZeroDivides;
|
|
||||||
Flag m_maskOverflows;
|
|
||||||
Flag m_maskUnderflows;
|
|
||||||
//Flag m_maskInexacts;
|
|
||||||
Flag m_flushDenormals;
|
|
||||||
Flag m_infinitySigned;
|
|
||||||
Enum <Rounding> m_rounding;
|
|
||||||
Enum <Precision> m_precision;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
IEEE FPU flag modifications with scoped lifetime.
|
|
||||||
|
|
||||||
An instance of the class saves the FPU flags and updates
|
|
||||||
|
|
||||||
FPUFlags flags;
|
|
||||||
flags.setUnmaskAllExceptions ();
|
|
||||||
|
|
||||||
{
|
|
||||||
ScopedFPUFlags fpu (flags);
|
|
||||||
|
|
||||||
// Perform floating point calculations
|
|
||||||
}
|
|
||||||
|
|
||||||
// FPU flags are back to what they were now
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class ScopedFPUFlags
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScopedFPUFlags (FPUFlags const& flagsToSet)
|
|
||||||
{
|
|
||||||
m_savedFlags = FPUFlags::getCurrent ();
|
|
||||||
m_savedFlags.clearUnsetFlagsFrom (flagsToSet);
|
|
||||||
FPUFlags::setCurrent (flagsToSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedFPUFlags ()
|
|
||||||
{
|
|
||||||
FPUFlags::setCurrent (m_savedFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FPUFlags m_savedFlags;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#if BEAST_USE_LEAKCHECKED
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
// Type-independent portion of Counter
|
|
||||||
class LeakCheckedBase::CounterBase::Singleton
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void push_back (CounterBase* counter)
|
|
||||||
{
|
|
||||||
m_list.push_front (counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void detectAllLeaks ()
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
CounterBase* counter = m_list.pop_front ();
|
|
||||||
|
|
||||||
if (!counter)
|
|
||||||
break;
|
|
||||||
|
|
||||||
counter->detectLeaks ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Singleton& getInstance ()
|
|
||||||
{
|
|
||||||
static Singleton instance;
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
LockFreeStack <CounterBase> m_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LeakCheckedBase::CounterBase::CounterBase ()
|
|
||||||
{
|
|
||||||
Singleton::getInstance ().push_back (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeakCheckedBase::CounterBase::detectAllLeaks ()
|
|
||||||
{
|
|
||||||
Singleton::getInstance ().detectAllLeaks ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeakCheckedBase::CounterBase::detectLeaks ()
|
|
||||||
{
|
|
||||||
// If there's a runtime error from this line, it means there's
|
|
||||||
// an order of destruction problem between different translation units!
|
|
||||||
//
|
|
||||||
this->checkPureVirtual ();
|
|
||||||
|
|
||||||
int const count = m_count.get ();
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
bassertfalse;
|
|
||||||
DBG ("[LEAK] " << count << " of " << getClassName ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void LeakCheckedBase::detectAllLeaks ()
|
|
||||||
{
|
|
||||||
CounterBase::detectAllLeaks ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_LEAKCHECKED_BEASTHEADER
|
|
||||||
#define BEAST_LEAKCHECKED_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_Error.h"
|
|
||||||
#include "beast_Throw.h"
|
|
||||||
#include "../memory/beast_StaticObject.h"
|
|
||||||
#include "../containers/beast_LockFreeStack.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Derived classes are automatically leak-checked on exit
|
|
||||||
//
|
|
||||||
|
|
||||||
#if BEAST_USE_LEAKCHECKED
|
|
||||||
|
|
||||||
class LeakCheckedBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void detectAllLeaks ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class CounterBase : public LockFreeStack <CounterBase>::Node
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CounterBase ();
|
|
||||||
|
|
||||||
virtual ~CounterBase () { }
|
|
||||||
|
|
||||||
inline int increment ()
|
|
||||||
{
|
|
||||||
return ++m_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int decrement ()
|
|
||||||
{
|
|
||||||
return --m_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual char const* getClassName () const = 0;
|
|
||||||
|
|
||||||
static void detectAllLeaks ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void detectLeaks ();
|
|
||||||
|
|
||||||
virtual void checkPureVirtual () const = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Singleton;
|
|
||||||
|
|
||||||
Atomic <int> m_count;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Detects leaks at program exit.
|
|
||||||
|
|
||||||
To use this, derive your class from this template using CRTP (curiously
|
|
||||||
recurring template pattern).
|
|
||||||
*/
|
|
||||||
template <class Object>
|
|
||||||
class LeakChecked : private LeakCheckedBase
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
LeakChecked () noexcept
|
|
||||||
{
|
|
||||||
if (getLeakCheckedCounter ().increment () == 0)
|
|
||||||
{
|
|
||||||
DBG ("[LOGIC] " << getLeakCheckedName ());
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LeakChecked (const LeakChecked&) noexcept
|
|
||||||
{
|
|
||||||
if (getLeakCheckedCounter ().increment () == 0)
|
|
||||||
{
|
|
||||||
DBG ("[LOGIC] " << getLeakCheckedName ());
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~LeakChecked ()
|
|
||||||
{
|
|
||||||
if (getLeakCheckedCounter ().decrement () < 0)
|
|
||||||
{
|
|
||||||
DBG ("[LOGIC] " << getLeakCheckedName ());
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Counter : public CounterBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Counter () noexcept
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* getClassName () const
|
|
||||||
{
|
|
||||||
return getLeakCheckedName ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkPureVirtual () const { }
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
/* Due to a bug in Visual Studio 10 and earlier, the string returned by
|
|
||||||
typeid().name() will appear to leak on exit. Therefore, we should
|
|
||||||
only call this function when there's an actual leak, or else there
|
|
||||||
will be spurious leak notices at exit.
|
|
||||||
*/
|
|
||||||
static const char* getLeakCheckedName ()
|
|
||||||
{
|
|
||||||
return typeid (Object).name ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Counter& getLeakCheckedCounter () noexcept
|
|
||||||
{
|
|
||||||
static Counter* volatile s_instance;
|
|
||||||
static Static::Initializer s_initializer;
|
|
||||||
|
|
||||||
if (s_initializer.begin ())
|
|
||||||
{
|
|
||||||
static char s_storage [sizeof (Counter)];
|
|
||||||
s_instance = new (s_storage) Counter;
|
|
||||||
s_initializer.end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *s_instance;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
class LeakCheckedBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
friend class PerformedAtExit;
|
|
||||||
|
|
||||||
static void detectAllLeaks () { }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Object>
|
|
||||||
struct LeakChecked : LeakCheckedBase
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SAFEBOOL_BEASTHEADER
|
|
||||||
#define BEAST_SAFEBOOL_BEASTHEADER
|
|
||||||
|
|
||||||
/**
|
|
||||||
Safe evaluation of class as `bool`.
|
|
||||||
|
|
||||||
This allows a class to be safely evaluated as a bool without the usual harmful
|
|
||||||
side effects of the straightforward operator conversion approach. To use it,
|
|
||||||
derive your class from SafeBool and implement `asBoolean()` as:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
bool asBoolean () const;
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Ideas from http://www.artima.com/cppsource/safebool.html
|
|
||||||
|
|
||||||
@class SafeBool
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
|
|
||||||
class SafeBoolBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void disallowed () const { }
|
|
||||||
|
|
||||||
public:
|
|
||||||
void allowed () const { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef void (SafeBoolBase::*boolean_t) () const;
|
|
||||||
|
|
||||||
SafeBoolBase () { }
|
|
||||||
SafeBoolBase (SafeBoolBase const&) { }
|
|
||||||
SafeBoolBase& operator= (SafeBoolBase const&)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~SafeBoolBase () { }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T = void>
|
|
||||||
class SafeBool : public SafeBoolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
operator boolean_t () const
|
|
||||||
{
|
|
||||||
return (static_cast <T const*> (this))->asBoolean ()
|
|
||||||
? &SafeBoolBase::allowed : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~SafeBool () { }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
void operator== (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
|
||||||
{
|
|
||||||
lhs.disallowed ();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
void operator!= (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
|
||||||
{
|
|
||||||
lhs.disallowed ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_THROW_BEASTHEADER
|
|
||||||
#define BEAST_THROW_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_Debug.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Throw an exception, with the opportunity to get a
|
|
||||||
// breakpoint with the call stack before the throw.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class Exception>
|
|
||||||
inline void Throw (Exception const& e)
|
|
||||||
{
|
|
||||||
Debug::breakPoint ();
|
|
||||||
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class OncePerSecond::TimerSingleton
|
|
||||||
: public RefCountedSingleton <OncePerSecond::TimerSingleton>
|
|
||||||
, private InterruptibleThread::EntryPoint
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
TimerSingleton ()
|
|
||||||
: RefCountedSingleton <OncePerSecond::TimerSingleton> (
|
|
||||||
SingletonLifetime::persistAfterCreation)
|
|
||||||
, m_thread ("Once Per Second")
|
|
||||||
{
|
|
||||||
m_thread.start (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~TimerSingleton ()
|
|
||||||
{
|
|
||||||
m_thread.join ();
|
|
||||||
|
|
||||||
bassert (m_list.empty ());
|
|
||||||
}
|
|
||||||
|
|
||||||
void threadRun ()
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const bool interrupted = m_thread.wait (1000);
|
|
||||||
|
|
||||||
if (interrupted)
|
|
||||||
break;
|
|
||||||
|
|
||||||
notify ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void notify ()
|
|
||||||
{
|
|
||||||
CriticalSection::ScopedLockType lock (m_mutex);
|
|
||||||
|
|
||||||
for (List <Elem>::iterator iter = m_list.begin (); iter != m_list.end ();)
|
|
||||||
{
|
|
||||||
OncePerSecond* object = iter->object;
|
|
||||||
++iter;
|
|
||||||
object->doOncePerSecond ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void insert (Elem* elem)
|
|
||||||
{
|
|
||||||
CriticalSection::ScopedLockType lock (m_mutex);
|
|
||||||
|
|
||||||
m_list.push_back (*elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove (Elem* elem)
|
|
||||||
{
|
|
||||||
CriticalSection::ScopedLockType lock (m_mutex);
|
|
||||||
|
|
||||||
m_list.erase (m_list.iterator_to (*elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
static TimerSingleton* createInstance ()
|
|
||||||
{
|
|
||||||
return new TimerSingleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
InterruptibleThread m_thread;
|
|
||||||
CriticalSection m_mutex;
|
|
||||||
List <Elem> m_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
OncePerSecond::OncePerSecond ()
|
|
||||||
{
|
|
||||||
m_elem.instance = TimerSingleton::getInstance ();
|
|
||||||
m_elem.object = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
OncePerSecond::~OncePerSecond ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OncePerSecond::startOncePerSecond ()
|
|
||||||
{
|
|
||||||
m_elem.instance->insert (&m_elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OncePerSecond::endOncePerSecond ()
|
|
||||||
{
|
|
||||||
m_elem.instance->remove (&m_elem);
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ONCEPERSECOND_BEASTHEADER
|
|
||||||
#define BEAST_ONCEPERSECOND_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../containers/beast_List.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Provides a once per second notification.
|
|
||||||
|
|
||||||
Derive your class from OncePerSecond and override doOncePerSecond(). Then,
|
|
||||||
call startOncePerSecond() to begin receiving the notifications. No clean-up
|
|
||||||
or other actions are required.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class OncePerSecond : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OncePerSecond ();
|
|
||||||
virtual ~OncePerSecond ();
|
|
||||||
|
|
||||||
/** Begin receiving notifications. */
|
|
||||||
void startOncePerSecond ();
|
|
||||||
|
|
||||||
/** Stop receiving notifications. */
|
|
||||||
void endOncePerSecond ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Called once per second. */
|
|
||||||
virtual void doOncePerSecond () = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class TimerSingleton;
|
|
||||||
typedef ReferenceCountedObjectPtr <TimerSingleton> TimerPtr;
|
|
||||||
|
|
||||||
struct Elem : List <Elem>::Node
|
|
||||||
{
|
|
||||||
TimerPtr instance;
|
|
||||||
OncePerSecond* object;
|
|
||||||
};
|
|
||||||
|
|
||||||
Elem m_elem;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class PerformedAtExit::Performer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Static::Storage <LockFreeStack <PerformedAtExit>, PerformedAtExit> StackType;
|
|
||||||
|
|
||||||
private:
|
|
||||||
~Performer ()
|
|
||||||
{
|
|
||||||
PerformedAtExit* object = s_list->pop_front ();
|
|
||||||
|
|
||||||
while (object != nullptr)
|
|
||||||
{
|
|
||||||
object->performAtExit ();
|
|
||||||
|
|
||||||
object = s_list->pop_front ();
|
|
||||||
}
|
|
||||||
|
|
||||||
LeakCheckedBase::detectAllLeaks ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void push_front (PerformedAtExit* object)
|
|
||||||
{
|
|
||||||
s_list->push_front (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class PerformedAtExit;
|
|
||||||
|
|
||||||
static StackType s_list;
|
|
||||||
|
|
||||||
static Performer s_performer;
|
|
||||||
};
|
|
||||||
|
|
||||||
PerformedAtExit::Performer PerformedAtExit::Performer::s_performer;
|
|
||||||
PerformedAtExit::Performer::StackType PerformedAtExit::Performer::s_list;
|
|
||||||
|
|
||||||
PerformedAtExit::PerformedAtExit ()
|
|
||||||
{
|
|
||||||
#if BEAST_IOS
|
|
||||||
// TODO: PerformedAtExit::Performer::push_front crashes on iOS if s_storage is not accessed before used
|
|
||||||
char* hack = PerformedAtExit::Performer::s_list.s_storage;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Performer::push_front (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_PERFORMEDATEXIT_BEASTHEADER
|
|
||||||
#define BEAST_PERFORMEDATEXIT_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../containers/beast_LockFreeStack.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Perform an action at program exit
|
|
||||||
|
|
||||||
To use, derive your class from PerformedAtExit, and override `performAtExit()`.
|
|
||||||
The call will be made during the destruction of objects with static storage
|
|
||||||
duration, before LeakChecked performs its diagnostics.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class PerformedAtExit : public LockFreeStack <PerformedAtExit>::Node
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
PerformedAtExit ();
|
|
||||||
virtual ~PerformedAtExit () { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Called at program exit.
|
|
||||||
*/
|
|
||||||
virtual void performAtExit () = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Performer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_BIND_BEASTHEADER
|
|
||||||
#define BEAST_BIND_BEASTHEADER
|
|
||||||
|
|
||||||
/* Brings functional support into our namespace, based on environment.
|
|
||||||
*/
|
|
||||||
#if BEAST_MSVC
|
|
||||||
// Visual Studio has these in std.
|
|
||||||
using std::ref;
|
|
||||||
using std::bind;
|
|
||||||
using std::function;
|
|
||||||
using std::placeholders::_1;
|
|
||||||
using std::placeholders::_2;
|
|
||||||
|
|
||||||
#elif BEAST_IOS
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
/* If boost is activated, use it. This works
|
|
||||||
around a bug with the iOS implementation of bind.
|
|
||||||
*/
|
|
||||||
using boost::ref
|
|
||||||
using boost::bind;
|
|
||||||
using boost::function;
|
|
||||||
using ::_1;
|
|
||||||
using ::_2;
|
|
||||||
#else
|
|
||||||
#if _LIBCPP_VERSION // libc++
|
|
||||||
using std::ref;
|
|
||||||
using std::bind;
|
|
||||||
using std::function;
|
|
||||||
using std::placeholders::_1;
|
|
||||||
using std::placeholders::_2;
|
|
||||||
#else // libstdc++ (GNU)
|
|
||||||
using std::tr1::ref;
|
|
||||||
using std::tr1::bind;
|
|
||||||
using std::tr1::function;
|
|
||||||
using std::tr1::placeholders::_1;
|
|
||||||
using std::tr1::placeholders::_2;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif BEAST_MAC
|
|
||||||
#if _LIBCPP_VERSION // libc++
|
|
||||||
using std::ref;
|
|
||||||
using std::bind;
|
|
||||||
using std::function;
|
|
||||||
using std::placeholders::_1;
|
|
||||||
using std::placeholders::_2;
|
|
||||||
#else // libstdc++ (GNU)
|
|
||||||
using std::tr1::ref;
|
|
||||||
using std::tr1::bind;
|
|
||||||
using std::tr1::function;
|
|
||||||
using std::tr1::placeholders::_1;
|
|
||||||
using std::tr1::placeholders::_2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif BEAST_LINUX
|
|
||||||
using std::tr1::bind;
|
|
||||||
using std::tr1::placeholders::_1;
|
|
||||||
using std::tr1::placeholders::_2;
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error Unknown platform in beast_Bind.h
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Max number of arguments to bind, total.
|
|
||||||
*/
|
|
||||||
#if BEAST_MSVC
|
|
||||||
# ifdef _VARIADIC_MAX
|
|
||||||
# define BEAST_VARIADIC_MAX _VARIADIC_MAX
|
|
||||||
# else
|
|
||||||
# define BEAST_VARIADIC_MAX 9
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define BEAST_VARIADIC_MAX 9
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_FUNCTION_BEASTHEADER
|
|
||||||
#define BEAST_FUNCTION_BEASTHEADER
|
|
||||||
|
|
||||||
//
|
|
||||||
// Strong replacement for boost::function:
|
|
||||||
//
|
|
||||||
// #1 Bounded memory requirement, avoids the free store.
|
|
||||||
//
|
|
||||||
// #2 Always refers to a functor (i.e. is never invalid)
|
|
||||||
//
|
|
||||||
// #3 Default value (None) is a function that
|
|
||||||
// returns a default object (the result type
|
|
||||||
// constructed with a default constructor).
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename Signature, int Bytes = 128>
|
|
||||||
class Function;
|
|
||||||
|
|
||||||
//
|
|
||||||
// nullary function
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename R, int Bytes>
|
|
||||||
class Function <R (void), Bytes>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef R result_type;
|
|
||||||
typedef Function self_type;
|
|
||||||
|
|
||||||
struct None
|
|
||||||
{
|
|
||||||
typedef R result_type;
|
|
||||||
result_type operator () () const
|
|
||||||
{
|
|
||||||
return result_type ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Function ()
|
|
||||||
{
|
|
||||||
constructCopyOf (None ());
|
|
||||||
}
|
|
||||||
|
|
||||||
Function (Function const& f)
|
|
||||||
{
|
|
||||||
f.getCall ().constructCopyInto (m_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
Function (Functor const& f)
|
|
||||||
{
|
|
||||||
constructCopyOf (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Function ()
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Function& operator= (Function const& f)
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
f.getCall ().constructCopyInto (m_storage);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
Function& operator= (Functor const& f)
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
constructCopyOf (f);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type operator () ()
|
|
||||||
{
|
|
||||||
return getCall ().operator () ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class Functor>
|
|
||||||
void constructCopyOf (Functor const& f)
|
|
||||||
{
|
|
||||||
// If this generates a compile error it means that
|
|
||||||
// the functor is too large for the static buffer.
|
|
||||||
// Increase the storage template parameter until
|
|
||||||
// the error message goes away. This might cause
|
|
||||||
// changes throughout the application with other
|
|
||||||
// template classes that depend on the size.
|
|
||||||
static_bassert (sizeof (StoredCall <Functor>) <= Bytes);
|
|
||||||
new (m_storage) StoredCall <Functor> (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Call
|
|
||||||
{
|
|
||||||
virtual ~Call () {}
|
|
||||||
virtual void constructCopyInto (void* p) const = 0;
|
|
||||||
virtual result_type operator () () = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
struct StoredCall : Call
|
|
||||||
{
|
|
||||||
explicit StoredCall (Functor const& f) : m_f (f) { }
|
|
||||||
StoredCall (const StoredCall& c) : m_f (c.m_f) { }
|
|
||||||
void constructCopyInto (void* p) const
|
|
||||||
{
|
|
||||||
new (p) StoredCall (m_f);
|
|
||||||
}
|
|
||||||
result_type operator () ()
|
|
||||||
{
|
|
||||||
return m_f ();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Functor m_f;
|
|
||||||
};
|
|
||||||
|
|
||||||
Call& getCall ()
|
|
||||||
{
|
|
||||||
return *reinterpret_cast <Call*> (&m_storage[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Call const& getCall () const
|
|
||||||
{
|
|
||||||
return *reinterpret_cast <Call const*> (&m_storage[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char m_storage [Bytes]; // should be enough
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//
|
|
||||||
// unary function
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename R, typename T1, int Bytes>
|
|
||||||
class Function <R (T1 t1), Bytes>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef R result_type;
|
|
||||||
typedef Function self_type;
|
|
||||||
|
|
||||||
struct None
|
|
||||||
{
|
|
||||||
typedef R result_type;
|
|
||||||
result_type operator () (T1) const
|
|
||||||
{
|
|
||||||
return result_type ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Function ()
|
|
||||||
{
|
|
||||||
constructCopyOf (None ());
|
|
||||||
}
|
|
||||||
|
|
||||||
Function (const Function& f)
|
|
||||||
{
|
|
||||||
f.getCall ().constructCopyInto (m_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
Function (Functor const& f)
|
|
||||||
{
|
|
||||||
constructCopyOf (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Function ()
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Function& operator= (const Function& f)
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
f.getCall ().constructCopyInto (m_storage);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
Function& operator= (Functor const& f)
|
|
||||||
{
|
|
||||||
getCall ().~Call ();
|
|
||||||
constructCopyOf (f);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type operator () (T1 t1)
|
|
||||||
{
|
|
||||||
return getCall ().operator () (t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class Functor>
|
|
||||||
void constructCopyOf (Functor const& f)
|
|
||||||
{
|
|
||||||
// If this generates a compile error it means that
|
|
||||||
// the functor is too large for the static buffer.
|
|
||||||
// Increase the storage template parameter until
|
|
||||||
// the error message goes away. This might cause
|
|
||||||
// changes throughout the application with other
|
|
||||||
// template classes that depend on the size.
|
|
||||||
static_bassert (sizeof (StoredCall <Functor>) <= Bytes);
|
|
||||||
new (m_storage) StoredCall <Functor> (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Call
|
|
||||||
{
|
|
||||||
virtual ~Call () {}
|
|
||||||
virtual void constructCopyInto (void* p) const = 0;
|
|
||||||
virtual result_type operator () (T1 t1) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
struct StoredCall : Call
|
|
||||||
{
|
|
||||||
explicit StoredCall (Functor const& f) : m_f (f) { }
|
|
||||||
StoredCall (const StoredCall& c) : m_f (c.m_f) { }
|
|
||||||
void constructCopyInto (void* p) const
|
|
||||||
{
|
|
||||||
new (p) StoredCall (m_f);
|
|
||||||
}
|
|
||||||
result_type operator () (T1 t1)
|
|
||||||
{
|
|
||||||
return m_f (t1);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Functor m_f;
|
|
||||||
};
|
|
||||||
|
|
||||||
Call& getCall ()
|
|
||||||
{
|
|
||||||
return *reinterpret_cast <Call*> (&m_storage[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Call const& getCall () const
|
|
||||||
{
|
|
||||||
return *reinterpret_cast <Call const*> (&m_storage[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char m_storage [Bytes]; // should be enough
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,387 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_INTERVAL_BEASTHEADER
|
|
||||||
#define BEAST_INTERVAL_BEASTHEADER
|
|
||||||
|
|
||||||
/** A half-open interval.
|
|
||||||
|
|
||||||
This represents the half-open interval [begin, end) over the scalar
|
|
||||||
type of template parameter `Ty`. It may also be considered as the
|
|
||||||
specification of a subset of a 1-dimensional Euclidean space.
|
|
||||||
|
|
||||||
@tparam Ty A scalar numerical type.
|
|
||||||
*/
|
|
||||||
template <class Ty>
|
|
||||||
class Interval
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Ty value_type;
|
|
||||||
|
|
||||||
/** The empty interval.
|
|
||||||
*/
|
|
||||||
static const Interval none;
|
|
||||||
|
|
||||||
/** Create an uninitialized interval.
|
|
||||||
*/
|
|
||||||
Interval ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an interval with the specified values.
|
|
||||||
*/
|
|
||||||
Interval (Ty begin, Ty end)
|
|
||||||
: m_begin (begin)
|
|
||||||
, m_end (end)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an interval from another interval.
|
|
||||||
*/
|
|
||||||
Interval (Interval const& other)
|
|
||||||
: m_begin (other.m_begin)
|
|
||||||
, m_end (other.m_end)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Assign from another interval.
|
|
||||||
|
|
||||||
@param other The interval to assign from.
|
|
||||||
|
|
||||||
@return A reference to this interval.
|
|
||||||
*/
|
|
||||||
Interval& operator= (const Interval& other)
|
|
||||||
{
|
|
||||||
m_begin = other.m_begin;
|
|
||||||
m_end = other.m_end;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compare an interval for equality.
|
|
||||||
|
|
||||||
Empty intervals are always equal to other empty intervals.
|
|
||||||
|
|
||||||
@param rhs The other interval to compare.
|
|
||||||
|
|
||||||
@return `true` if this interval is equal to the specified interval.
|
|
||||||
*/
|
|
||||||
bool operator== (Interval const& rhs) const
|
|
||||||
{
|
|
||||||
return (empty () && rhs.empty ()) ||
|
|
||||||
(m_begin == rhs.m_begin && m_end == rhs.m_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compare an interval for inequality.
|
|
||||||
|
|
||||||
@param rhs The other interval to compare.
|
|
||||||
|
|
||||||
@return `true` if this interval is not equal to the specified interval.
|
|
||||||
*/
|
|
||||||
bool operator!= (Interval const& rhs) const
|
|
||||||
{
|
|
||||||
return !this->operator== (rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the starting value of the interval.
|
|
||||||
|
|
||||||
@return The starting point of the interval.
|
|
||||||
*/
|
|
||||||
Ty begin () const
|
|
||||||
{
|
|
||||||
return m_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the ending value of the interval.
|
|
||||||
|
|
||||||
@return The ending point of the interval.
|
|
||||||
*/
|
|
||||||
Ty end () const
|
|
||||||
{
|
|
||||||
return m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the Lebesque measure.
|
|
||||||
|
|
||||||
@return The Lebesque measure.
|
|
||||||
*/
|
|
||||||
Ty length () const
|
|
||||||
{
|
|
||||||
return empty () ? Ty () : (end () - begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Ty count () const { return length (); } // sugar
|
|
||||||
//Ty distance () const { return length (); } // sugar
|
|
||||||
|
|
||||||
/** Determine if the interval is empty.
|
|
||||||
|
|
||||||
@return `true` if the interval is empty.
|
|
||||||
*/
|
|
||||||
bool empty () const
|
|
||||||
{
|
|
||||||
return m_begin >= m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the interval is non-empty.
|
|
||||||
|
|
||||||
@return `true` if the interval is not empty.
|
|
||||||
*/
|
|
||||||
bool notEmpty () const
|
|
||||||
{
|
|
||||||
return m_begin < m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the starting point of the interval.
|
|
||||||
|
|
||||||
@param v The starting point.
|
|
||||||
*/
|
|
||||||
void setBegin (Ty v)
|
|
||||||
{
|
|
||||||
m_begin = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the ending point of the interval.
|
|
||||||
|
|
||||||
@param v The ending point.
|
|
||||||
*/
|
|
||||||
void setEnd (Ty v)
|
|
||||||
{
|
|
||||||
m_end = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the ending point relative to the starting point.
|
|
||||||
|
|
||||||
@param v The length of the resulting interval.
|
|
||||||
*/
|
|
||||||
void setLength (Ty v)
|
|
||||||
{
|
|
||||||
m_end = m_begin + v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if a value is contained in the interval.
|
|
||||||
|
|
||||||
@param v The value to check.
|
|
||||||
|
|
||||||
@return `true` if this interval contains `v`.
|
|
||||||
*/
|
|
||||||
bool contains (Ty v) const
|
|
||||||
{
|
|
||||||
return notEmpty () && v >= m_begin && v < m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval intersects another interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if the intervals intersect.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool intersects (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return notEmpty () && other.notEmpty () &&
|
|
||||||
end () > other.begin () && begin () < other.end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval adjoins another interval.
|
|
||||||
|
|
||||||
An interval is adjoint to another interval if and only if the union of the
|
|
||||||
intervals is a single non-empty half-open subset.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if the intervals are adjoint.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool adjoins (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return (empty () != other.empty ()) ||
|
|
||||||
(notEmpty () && end () >= other.begin ()
|
|
||||||
&& begin () <= other.end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval is disjoint from another interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if the intervals are disjoint.
|
|
||||||
*/
|
|
||||||
bool disjoint (Interval const& other) const
|
|
||||||
{
|
|
||||||
return !intersects (other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval is a superset of another interval.
|
|
||||||
|
|
||||||
An interval A is a superset of interval B if B is empty or if A fully
|
|
||||||
contains B.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if this is a superset of `other`.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool superset_of (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return other.empty () ||
|
|
||||||
(notEmpty () && begin () <= other.begin ()
|
|
||||||
&& end () >= other.end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval is a proper superset of another interval.
|
|
||||||
|
|
||||||
An interval A is a proper superset of interval B if A is a superset of
|
|
||||||
B and A is not equal to B.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if this interval is a proper superset of `other`.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool proper_superset_of (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return this->superset_of (other) && this->operator != (other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval is a subset of another interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if this interval is a subset of `other`.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool subset_of (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return other.superset_of (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if this interval is a proper subset of another interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return `true` if this interval is a proper subset of `other`.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
bool proper_subset_of (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return other.proper_superset_of (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the intersection of this interval with another interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return The intersection of the intervals.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
Interval intersection (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return Interval (std::max (begin (), other.begin ()),
|
|
||||||
std::min (end (), other.end ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine the smallest interval that contains both intervals.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return The simple union of the intervals.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
Interval simple_union (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
return Interval (
|
|
||||||
std::min (other.normalized ().begin (), normalized ().begin ()),
|
|
||||||
std::max (other.normalized ().end (), normalized ().end ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Calculate the single-interval union.
|
|
||||||
|
|
||||||
The result is empty if the union cannot be represented as a
|
|
||||||
single half-open interval.
|
|
||||||
|
|
||||||
@param other The other interval.
|
|
||||||
|
|
||||||
@return The simple union of the intervals.
|
|
||||||
*/
|
|
||||||
template <class To>
|
|
||||||
Interval single_union (Interval <To> const& other) const
|
|
||||||
{
|
|
||||||
if (empty ())
|
|
||||||
return other;
|
|
||||||
|
|
||||||
else if (other.empty ())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
else if (end () < other.begin () || begin () > other.end ())
|
|
||||||
return none;
|
|
||||||
|
|
||||||
else
|
|
||||||
return Interval (std::min (begin (), other.begin ()),
|
|
||||||
std::max (end (), other.end ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the interval is correctly ordered.
|
|
||||||
|
|
||||||
@return `true` if the interval is correctly ordered.
|
|
||||||
*/
|
|
||||||
bool normal () const
|
|
||||||
{
|
|
||||||
return end () >= begin ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return a normalized interval.
|
|
||||||
|
|
||||||
@return The normalized interval.
|
|
||||||
*/
|
|
||||||
Interval normalized () const
|
|
||||||
{
|
|
||||||
if (normal ())
|
|
||||||
return *this;
|
|
||||||
else
|
|
||||||
return Interval (end (), begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clamp a value to the interval.
|
|
||||||
|
|
||||||
@param v The value to clamp.
|
|
||||||
|
|
||||||
@return The clamped result.
|
|
||||||
*/
|
|
||||||
template <typename Tv>
|
|
||||||
Ty clamp (Tv v) const
|
|
||||||
{
|
|
||||||
// These conditionals are carefully ordered so
|
|
||||||
// that if m_begin == m_end, value is assigned m_begin.
|
|
||||||
if (v > end ())
|
|
||||||
v = end () - (std::numeric_limits <Tv>::is_integer ? 1 :
|
|
||||||
std::numeric_limits <Tv>::epsilon ());
|
|
||||||
|
|
||||||
if (v < begin ())
|
|
||||||
v = begin ();
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ty m_begin;
|
|
||||||
Ty m_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Ty>
|
|
||||||
const Interval<Ty> Interval<Ty>::none = Interval<Ty> (Ty (), Ty ());
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_MATH_BEASTHEADER
|
|
||||||
#define BEAST_MATH_BEASTHEADER
|
|
||||||
|
|
||||||
//
|
|
||||||
// Miscellaneous mathematical calculations
|
|
||||||
//
|
|
||||||
|
|
||||||
// Calculate the bin for a value given the bin size.
|
|
||||||
// This correctly handles negative numbers. For example
|
|
||||||
// if value == -1 then calc_bin returns -1.
|
|
||||||
template <typename Ty>
|
|
||||||
inline Ty calc_bin (Ty value, int size)
|
|
||||||
{
|
|
||||||
if (value >= 0)
|
|
||||||
return value / size;
|
|
||||||
else
|
|
||||||
return (value - size + 1) / size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a number and a bin size, this returns the first
|
|
||||||
// corresponding value of the bin associated with the given number.
|
|
||||||
// It correctly handles negative numbers. For example,
|
|
||||||
// if value == -1 then calc_bin always returns -size
|
|
||||||
template <typename Ty>
|
|
||||||
inline Ty calc_bin_start (Ty value, int size)
|
|
||||||
{
|
|
||||||
return calc_bin (value, size) * size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T pi () noexcept
|
|
||||||
{
|
|
||||||
return 3.14159265358979;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T twoPi () noexcept
|
|
||||||
{
|
|
||||||
return 6.28318530717958;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T oneOverTwoPi () noexcept
|
|
||||||
{
|
|
||||||
return 0.1591549430918955;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
inline T degreesToRadians (U degrees)
|
|
||||||
{
|
|
||||||
return T (degrees * 0.0174532925199433);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
inline T radiansToDegrees (U radians)
|
|
||||||
{
|
|
||||||
T deg = T (radians * U (57.29577951308238));
|
|
||||||
|
|
||||||
if (deg < 0)
|
|
||||||
deg += 360;
|
|
||||||
|
|
||||||
return deg;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,487 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// http://code.google.com/p/smhasher/
|
|
||||||
|
|
||||||
namespace Murmur
|
|
||||||
{
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Platform-specific functions and macros
|
|
||||||
|
|
||||||
// Microsoft Visual Studio
|
|
||||||
|
|
||||||
#if BEAST_MSVC
|
|
||||||
|
|
||||||
#define ROTL32(x,y) _rotl(x,y)
|
|
||||||
#define ROTL64(x,y) _rotl64(x,y)
|
|
||||||
|
|
||||||
#define BIG_CONSTANT(x) (x)
|
|
||||||
|
|
||||||
// Other compilers
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline uint32_t rotl32 ( uint32_t x, int8_t r )
|
|
||||||
{
|
|
||||||
return (x << r) | (x >> (32 - r));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t rotl64 ( uint64_t x, int8_t r )
|
|
||||||
{
|
|
||||||
return (x << r) | (x >> (64 - r));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ROTL32(x,y) rotl32(x,y)
|
|
||||||
#define ROTL64(x,y) rotl64(x,y)
|
|
||||||
|
|
||||||
#define BIG_CONSTANT(x) (x##LLU)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Block read - if your platform needs to do endian-swapping or can only
|
|
||||||
// handle aligned reads, do the conversion here
|
|
||||||
|
|
||||||
static forcedinline uint32_t getblock ( const uint32_t* p, int i )
|
|
||||||
{
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
static forcedinline uint64_t getblock ( const uint64_t* p, int i )
|
|
||||||
{
|
|
||||||
return p[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Finalization mix - force all bits of a hash block to avalanche
|
|
||||||
|
|
||||||
static forcedinline uint32_t fmix ( uint32_t h )
|
|
||||||
{
|
|
||||||
h ^= h >> 16;
|
|
||||||
h *= 0x85ebca6b;
|
|
||||||
h ^= h >> 13;
|
|
||||||
h *= 0xc2b2ae35;
|
|
||||||
h ^= h >> 16;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------
|
|
||||||
|
|
||||||
static forcedinline uint64_t fmix ( uint64_t k )
|
|
||||||
{
|
|
||||||
k ^= k >> 33;
|
|
||||||
k *= BIG_CONSTANT (0xff51afd7ed558ccd);
|
|
||||||
k ^= k >> 33;
|
|
||||||
k *= BIG_CONSTANT (0xc4ceb9fe1a85ec53);
|
|
||||||
k ^= k >> 33;
|
|
||||||
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void MurmurHash3_x86_32 ( const void* key, int len,
|
|
||||||
uint32_t seed, void* out )
|
|
||||||
{
|
|
||||||
const uint8_t* data = (const uint8_t*)key;
|
|
||||||
const int nblocks = len / 4;
|
|
||||||
|
|
||||||
uint32_t h1 = seed;
|
|
||||||
|
|
||||||
uint32_t c1 = 0xcc9e2d51;
|
|
||||||
uint32_t c2 = 0x1b873593;
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// body
|
|
||||||
|
|
||||||
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 4);
|
|
||||||
|
|
||||||
for (int i = -nblocks; i; i++)
|
|
||||||
{
|
|
||||||
uint32_t k1 = getblock (blocks, i);
|
|
||||||
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL32 (k1, 15);
|
|
||||||
k1 *= c2;
|
|
||||||
|
|
||||||
h1 ^= k1;
|
|
||||||
h1 = ROTL32 (h1, 13);
|
|
||||||
h1 = h1 * 5 + 0xe6546b64;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// tail
|
|
||||||
|
|
||||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
|
|
||||||
|
|
||||||
uint32_t k1 = 0;
|
|
||||||
|
|
||||||
switch (len & 3)
|
|
||||||
{
|
|
||||||
case 3:
|
|
||||||
k1 ^= tail[2] << 16;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
k1 ^= tail[1] << 8;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
k1 ^= tail[0];
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL32 (k1, 15);
|
|
||||||
k1 *= c2;
|
|
||||||
h1 ^= k1;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// finalization
|
|
||||||
|
|
||||||
h1 ^= len;
|
|
||||||
|
|
||||||
h1 = fmix (h1);
|
|
||||||
|
|
||||||
* (uint32_t*)out = h1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void MurmurHash3_x86_128 ( const void* key, const int len,
|
|
||||||
uint32_t seed, void* out )
|
|
||||||
{
|
|
||||||
const uint8_t* data = (const uint8_t*)key;
|
|
||||||
const int nblocks = len / 16;
|
|
||||||
|
|
||||||
uint32_t h1 = seed;
|
|
||||||
uint32_t h2 = seed;
|
|
||||||
uint32_t h3 = seed;
|
|
||||||
uint32_t h4 = seed;
|
|
||||||
|
|
||||||
uint32_t c1 = 0x239b961b;
|
|
||||||
uint32_t c2 = 0xab0e9789;
|
|
||||||
uint32_t c3 = 0x38b34ae5;
|
|
||||||
uint32_t c4 = 0xa1e38b93;
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// body
|
|
||||||
|
|
||||||
const uint32_t* blocks = (const uint32_t*) (data + nblocks * 16);
|
|
||||||
|
|
||||||
for (int i = -nblocks; i; i++)
|
|
||||||
{
|
|
||||||
uint32_t k1 = getblock (blocks, i * 4 + 0);
|
|
||||||
uint32_t k2 = getblock (blocks, i * 4 + 1);
|
|
||||||
uint32_t k3 = getblock (blocks, i * 4 + 2);
|
|
||||||
uint32_t k4 = getblock (blocks, i * 4 + 3);
|
|
||||||
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL32 (k1, 15);
|
|
||||||
k1 *= c2;
|
|
||||||
h1 ^= k1;
|
|
||||||
|
|
||||||
h1 = ROTL32 (h1, 19);
|
|
||||||
h1 += h2;
|
|
||||||
h1 = h1 * 5 + 0x561ccd1b;
|
|
||||||
|
|
||||||
k2 *= c2;
|
|
||||||
k2 = ROTL32 (k2, 16);
|
|
||||||
k2 *= c3;
|
|
||||||
h2 ^= k2;
|
|
||||||
|
|
||||||
h2 = ROTL32 (h2, 17);
|
|
||||||
h2 += h3;
|
|
||||||
h2 = h2 * 5 + 0x0bcaa747;
|
|
||||||
|
|
||||||
k3 *= c3;
|
|
||||||
k3 = ROTL32 (k3, 17);
|
|
||||||
k3 *= c4;
|
|
||||||
h3 ^= k3;
|
|
||||||
|
|
||||||
h3 = ROTL32 (h3, 15);
|
|
||||||
h3 += h4;
|
|
||||||
h3 = h3 * 5 + 0x96cd1c35;
|
|
||||||
|
|
||||||
k4 *= c4;
|
|
||||||
k4 = ROTL32 (k4, 18);
|
|
||||||
k4 *= c1;
|
|
||||||
h4 ^= k4;
|
|
||||||
|
|
||||||
h4 = ROTL32 (h4, 13);
|
|
||||||
h4 += h1;
|
|
||||||
h4 = h4 * 5 + 0x32ac3b17;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// tail
|
|
||||||
|
|
||||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
|
|
||||||
|
|
||||||
uint32_t k1 = 0;
|
|
||||||
uint32_t k2 = 0;
|
|
||||||
uint32_t k3 = 0;
|
|
||||||
uint32_t k4 = 0;
|
|
||||||
|
|
||||||
switch (len & 15)
|
|
||||||
{
|
|
||||||
case 15:
|
|
||||||
k4 ^= tail[14] << 16;
|
|
||||||
|
|
||||||
case 14:
|
|
||||||
k4 ^= tail[13] << 8;
|
|
||||||
|
|
||||||
case 13:
|
|
||||||
k4 ^= tail[12] << 0;
|
|
||||||
k4 *= c4;
|
|
||||||
k4 = ROTL32 (k4, 18);
|
|
||||||
k4 *= c1;
|
|
||||||
h4 ^= k4;
|
|
||||||
|
|
||||||
case 12:
|
|
||||||
k3 ^= tail[11] << 24;
|
|
||||||
|
|
||||||
case 11:
|
|
||||||
k3 ^= tail[10] << 16;
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
k3 ^= tail[ 9] << 8;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
k3 ^= tail[ 8] << 0;
|
|
||||||
k3 *= c3;
|
|
||||||
k3 = ROTL32 (k3, 17);
|
|
||||||
k3 *= c4;
|
|
||||||
h3 ^= k3;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
k2 ^= tail[ 7] << 24;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
k2 ^= tail[ 6] << 16;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
k2 ^= tail[ 5] << 8;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
k2 ^= tail[ 4] << 0;
|
|
||||||
k2 *= c2;
|
|
||||||
k2 = ROTL32 (k2, 16);
|
|
||||||
k2 *= c3;
|
|
||||||
h2 ^= k2;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
k1 ^= tail[ 3] << 24;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
k1 ^= tail[ 2] << 16;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
k1 ^= tail[ 1] << 8;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
k1 ^= tail[ 0] << 0;
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL32 (k1, 15);
|
|
||||||
k1 *= c2;
|
|
||||||
h1 ^= k1;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// finalization
|
|
||||||
|
|
||||||
h1 ^= len;
|
|
||||||
|
|
||||||
h2 ^= len;
|
|
||||||
|
|
||||||
h3 ^= len;
|
|
||||||
|
|
||||||
h4 ^= len;
|
|
||||||
|
|
||||||
h1 += h2;
|
|
||||||
|
|
||||||
h1 += h3;
|
|
||||||
|
|
||||||
h1 += h4;
|
|
||||||
|
|
||||||
h2 += h1;
|
|
||||||
|
|
||||||
h3 += h1;
|
|
||||||
|
|
||||||
h4 += h1;
|
|
||||||
|
|
||||||
h1 = fmix (h1);
|
|
||||||
|
|
||||||
h2 = fmix (h2);
|
|
||||||
|
|
||||||
h3 = fmix (h3);
|
|
||||||
|
|
||||||
h4 = fmix (h4);
|
|
||||||
|
|
||||||
h1 += h2;
|
|
||||||
|
|
||||||
h1 += h3;
|
|
||||||
|
|
||||||
h1 += h4;
|
|
||||||
|
|
||||||
h2 += h1;
|
|
||||||
|
|
||||||
h3 += h1;
|
|
||||||
|
|
||||||
h4 += h1;
|
|
||||||
|
|
||||||
((uint32_t*)out)[0] = h1;
|
|
||||||
|
|
||||||
((uint32_t*)out)[1] = h2;
|
|
||||||
|
|
||||||
((uint32_t*)out)[2] = h3;
|
|
||||||
|
|
||||||
((uint32_t*)out)[3] = h4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void MurmurHash3_x64_128 ( const void* key, const int len,
|
|
||||||
const uint32_t seed, void* out )
|
|
||||||
{
|
|
||||||
const uint8_t* data = (const uint8_t*)key;
|
|
||||||
const int nblocks = len / 16;
|
|
||||||
|
|
||||||
uint64_t h1 = seed;
|
|
||||||
uint64_t h2 = seed;
|
|
||||||
|
|
||||||
uint64_t c1 = BIG_CONSTANT (0x87c37b91114253d5);
|
|
||||||
uint64_t c2 = BIG_CONSTANT (0x4cf5ad432745937f);
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// body
|
|
||||||
|
|
||||||
const uint64_t* blocks = (const uint64_t*) (data);
|
|
||||||
|
|
||||||
for (int i = 0; i < nblocks; i++)
|
|
||||||
{
|
|
||||||
uint64_t k1 = getblock (blocks, i * 2 + 0);
|
|
||||||
uint64_t k2 = getblock (blocks, i * 2 + 1);
|
|
||||||
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL64 (k1, 31);
|
|
||||||
k1 *= c2;
|
|
||||||
h1 ^= k1;
|
|
||||||
|
|
||||||
h1 = ROTL64 (h1, 27);
|
|
||||||
h1 += h2;
|
|
||||||
h1 = h1 * 5 + 0x52dce729;
|
|
||||||
|
|
||||||
k2 *= c2;
|
|
||||||
k2 = ROTL64 (k2, 33);
|
|
||||||
k2 *= c1;
|
|
||||||
h2 ^= k2;
|
|
||||||
|
|
||||||
h2 = ROTL64 (h2, 31);
|
|
||||||
h2 += h1;
|
|
||||||
h2 = h2 * 5 + 0x38495ab5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// tail
|
|
||||||
|
|
||||||
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
|
|
||||||
|
|
||||||
uint64_t k1 = 0;
|
|
||||||
uint64_t k2 = 0;
|
|
||||||
|
|
||||||
switch (len & 15)
|
|
||||||
{
|
|
||||||
case 15:
|
|
||||||
k2 ^= uint64_t (tail[14]) << 48;
|
|
||||||
|
|
||||||
case 14:
|
|
||||||
k2 ^= uint64_t (tail[13]) << 40;
|
|
||||||
|
|
||||||
case 13:
|
|
||||||
k2 ^= uint64_t (tail[12]) << 32;
|
|
||||||
|
|
||||||
case 12:
|
|
||||||
k2 ^= uint64_t (tail[11]) << 24;
|
|
||||||
|
|
||||||
case 11:
|
|
||||||
k2 ^= uint64_t (tail[10]) << 16;
|
|
||||||
|
|
||||||
case 10:
|
|
||||||
k2 ^= uint64_t (tail[ 9]) << 8;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
k2 ^= uint64_t (tail[ 8]) << 0;
|
|
||||||
k2 *= c2;
|
|
||||||
k2 = ROTL64 (k2, 33);
|
|
||||||
k2 *= c1;
|
|
||||||
h2 ^= k2;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
k1 ^= uint64_t (tail[ 7]) << 56;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
k1 ^= uint64_t (tail[ 6]) << 48;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
k1 ^= uint64_t (tail[ 5]) << 40;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
k1 ^= uint64_t (tail[ 4]) << 32;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
k1 ^= uint64_t (tail[ 3]) << 24;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
k1 ^= uint64_t (tail[ 2]) << 16;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
k1 ^= uint64_t (tail[ 1]) << 8;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
k1 ^= uint64_t (tail[ 0]) << 0;
|
|
||||||
k1 *= c1;
|
|
||||||
k1 = ROTL64 (k1, 31);
|
|
||||||
k1 *= c2;
|
|
||||||
h1 ^= k1;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------
|
|
||||||
// finalization
|
|
||||||
|
|
||||||
h1 ^= len;
|
|
||||||
|
|
||||||
h2 ^= len;
|
|
||||||
|
|
||||||
h1 += h2;
|
|
||||||
|
|
||||||
h2 += h1;
|
|
||||||
|
|
||||||
h1 = fmix (h1);
|
|
||||||
|
|
||||||
h2 = fmix (h2);
|
|
||||||
|
|
||||||
h1 += h2;
|
|
||||||
|
|
||||||
h2 += h1;
|
|
||||||
|
|
||||||
((uint64_t*)out)[0] = h1;
|
|
||||||
|
|
||||||
((uint64_t*)out)[1] = h2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_MURMURHASH_BEASTHEADER
|
|
||||||
#define BEAST_MURMURHASH_BEASTHEADER
|
|
||||||
|
|
||||||
// Original source code links in .cpp file
|
|
||||||
|
|
||||||
// This file depends on some Juce declarations and defines
|
|
||||||
|
|
||||||
namespace Murmur
|
|
||||||
{
|
|
||||||
|
|
||||||
extern void MurmurHash3_x86_32 (const void* key, int len, uint32 seed, void* out);
|
|
||||||
extern void MurmurHash3_x86_128 (const void* key, int len, uint32 seed, void* out);
|
|
||||||
extern void MurmurHash3_x64_128 (const void* key, int len, uint32 seed, void* out);
|
|
||||||
|
|
||||||
// Uses Juce to choose an appropriate routine
|
|
||||||
|
|
||||||
// This handy template deduces which size hash is desired
|
|
||||||
template <typename HashType>
|
|
||||||
inline void Hash (const void* key, int len, uint32 seed, HashType* out)
|
|
||||||
{
|
|
||||||
switch (8 * sizeof (HashType))
|
|
||||||
{
|
|
||||||
case 32:
|
|
||||||
MurmurHash3_x86_32 (key, len, seed, out);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if BEAST_64BIT
|
|
||||||
|
|
||||||
case 128:
|
|
||||||
MurmurHash3_x64_128 (key, len, seed, out);
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
|
|
||||||
case 128:
|
|
||||||
MurmurHash3_x86_128 (key, len, seed, out);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
Throw (std::runtime_error ("invalid key size in MurmurHash"));
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ALLOCATEDBY_BEASTHEADER
|
|
||||||
#define BEAST_ALLOCATEDBY_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Customized allocation for heap objects.
|
|
||||||
|
|
||||||
Derived classes will use the specified allocator for new and delete.
|
|
||||||
|
|
||||||
@param AllocatorType The type of allocator to use.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
template <class AllocatorType>
|
|
||||||
class AllocatedBy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static inline void* operator new (size_t bytes, AllocatorType& allocator) noexcept
|
|
||||||
{
|
|
||||||
return allocator.allocate (bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void* operator new (size_t bytes, AllocatorType* allocator) noexcept
|
|
||||||
{
|
|
||||||
return allocator->allocate (bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void operator delete (void* p, AllocatorType&) noexcept
|
|
||||||
{
|
|
||||||
AllocatorType::deallocate (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void operator delete (void* p, AllocatorType*) noexcept
|
|
||||||
{
|
|
||||||
AllocatorType::deallocate (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void operator delete (void* p) noexcept
|
|
||||||
{
|
|
||||||
AllocatorType::deallocate (p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ATOMICCOUNTER_BEASTHEADER
|
|
||||||
#define BEAST_ATOMICCOUNTER_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A thread safe usage counter.
|
|
||||||
|
|
||||||
This provides a simplified interface to an atomic integer suitable for
|
|
||||||
measuring reference or usage counts. The counter is signaled when the
|
|
||||||
count is non zero.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class AtomicCounter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a new counter.
|
|
||||||
|
|
||||||
@param initialValue An optional starting usage count (default is 0).
|
|
||||||
*/
|
|
||||||
AtomicCounter (int initialValue = 0) noexcept
|
|
||||||
:
|
|
||||||
m_value (initialValue)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Increment the usage count.
|
|
||||||
|
|
||||||
@return `true` if the counter became signaled.
|
|
||||||
*/
|
|
||||||
inline bool addref () noexcept
|
|
||||||
{
|
|
||||||
return (++m_value) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Decrements the usage count.
|
|
||||||
|
|
||||||
@return `true` if the counter became non-signaled.
|
|
||||||
*/
|
|
||||||
inline bool release () noexcept
|
|
||||||
{
|
|
||||||
// Unfortunately, AllocatorWithoutTLS breaks this assert
|
|
||||||
//bassert (isSignaled ());
|
|
||||||
|
|
||||||
return (--m_value) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determine if the counter is signaled.
|
|
||||||
|
|
||||||
Note that another thread can cause the counter to become reset after
|
|
||||||
this function returns true.
|
|
||||||
|
|
||||||
@return `true` if the counter was signaled.
|
|
||||||
*/
|
|
||||||
inline bool isSignaled () const noexcept
|
|
||||||
{
|
|
||||||
return m_value.get () > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Atomic <int> m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ATOMICFLAG_BEASTHEADER
|
|
||||||
#define BEAST_ATOMICFLAG_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A thread safe flag.
|
|
||||||
|
|
||||||
This provides a simplified interface to an atomic integer suitable for
|
|
||||||
representing a flag. The flag is signaled when on, else it is considered
|
|
||||||
reset.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class AtomicFlag
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create an AtomicFlag in the reset state. */
|
|
||||||
AtomicFlag () noexcept
|
|
||||||
:
|
|
||||||
m_value (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Signal the flag.
|
|
||||||
|
|
||||||
If two or more threads simultaneously attempt to signal the flag,
|
|
||||||
only one will receive a true return value.
|
|
||||||
|
|
||||||
@return true if the flag was previously reset.
|
|
||||||
*/
|
|
||||||
inline bool trySignal () noexcept
|
|
||||||
{
|
|
||||||
return m_value.compareAndSetBool (1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Signal the flag.
|
|
||||||
|
|
||||||
The flag must be in the reset state. Only one thread may
|
|
||||||
call this at a time.
|
|
||||||
*/
|
|
||||||
inline void signal () noexcept
|
|
||||||
{
|
|
||||||
#if BEAST_DEBUG
|
|
||||||
const bool success = m_value.compareAndSetBool (1, 0);
|
|
||||||
bassert (success);
|
|
||||||
#else
|
|
||||||
m_value.set (1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reset the flag.
|
|
||||||
|
|
||||||
The flag must be in the signaled state. Only one thread may
|
|
||||||
call this at a time. Usually it is the thread that was successful
|
|
||||||
in a previous call to trySignal().
|
|
||||||
*/
|
|
||||||
inline void reset () noexcept
|
|
||||||
{
|
|
||||||
#if BEAST_DEBUG
|
|
||||||
const bool success = m_value.compareAndSetBool (0, 1);
|
|
||||||
bassert (success);
|
|
||||||
#else
|
|
||||||
m_value.set (0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check if the AtomicFlag is signaled
|
|
||||||
|
|
||||||
The signaled status may change immediately after this call
|
|
||||||
returns. The caller must synchronize.
|
|
||||||
|
|
||||||
@return true if the flag was signaled.
|
|
||||||
*/
|
|
||||||
inline bool isSignaled () const noexcept
|
|
||||||
{
|
|
||||||
return m_value.get () == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Atomic <int> m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ATOMICPOINTER_BEASTHEADER
|
|
||||||
#define BEAST_ATOMICPOINTER_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A thread safe pointer.
|
|
||||||
|
|
||||||
This provides a simplified interface to an atomic pointer suitable
|
|
||||||
for building containers or composite classes. Operator overloads
|
|
||||||
allow access to the underlying pointer using natural C++ syntax.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
template <class P>
|
|
||||||
class AtomicPointer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a pointer.
|
|
||||||
|
|
||||||
@param initialValue An optional starting value (default is null).
|
|
||||||
*/
|
|
||||||
explicit AtomicPointer (P* const initialValue = nullptr) noexcept
|
|
||||||
:
|
|
||||||
m_value (initialValue)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve the pointer value */
|
|
||||||
inline P* get () const noexcept
|
|
||||||
{
|
|
||||||
return m_value.get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a pointer to P through type conversion.
|
|
||||||
|
|
||||||
The caller must synchronize access to P.
|
|
||||||
|
|
||||||
@return A pointer to P.
|
|
||||||
*/
|
|
||||||
inline operator P* () const noexcept
|
|
||||||
{
|
|
||||||
return get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dereference operator
|
|
||||||
|
|
||||||
The caller must synchronize access to P.
|
|
||||||
|
|
||||||
@return A reference to P.
|
|
||||||
*/
|
|
||||||
inline P& operator* () const noexcept
|
|
||||||
{
|
|
||||||
return &get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Member selection
|
|
||||||
|
|
||||||
The caller must synchronize access to P.
|
|
||||||
|
|
||||||
@return A pointer to P.
|
|
||||||
*/
|
|
||||||
inline P* operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set (P* p)
|
|
||||||
{
|
|
||||||
m_value.set (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Atomically assign a new pointer
|
|
||||||
|
|
||||||
@param newValue The new value to assign.
|
|
||||||
*/
|
|
||||||
inline void operator= (P* newValue) noexcept
|
|
||||||
{
|
|
||||||
set (newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Atomically assign a new pointer and return the old value.
|
|
||||||
|
|
||||||
@param newValue The new value to assign.
|
|
||||||
|
|
||||||
@return The previous value.
|
|
||||||
*/
|
|
||||||
inline P* exchange (P* newValue)
|
|
||||||
{
|
|
||||||
return m_value.exchange (newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Conditionally perform an atomic assignment.
|
|
||||||
|
|
||||||
The current value is compared with oldValue and atomically
|
|
||||||
set to newValue if the comparison is equal.
|
|
||||||
|
|
||||||
The caller is responsible for handling the ABA problem.
|
|
||||||
|
|
||||||
@param newValue The new value to assign.
|
|
||||||
|
|
||||||
@param oldValue The matching old value.
|
|
||||||
|
|
||||||
@return true if the assignment was performed.
|
|
||||||
*/
|
|
||||||
inline bool compareAndSet (P* newValue, P* oldValue)
|
|
||||||
{
|
|
||||||
return m_value.compareAndSetBool (newValue, oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Atomic <P*> m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_ATOMICSTATE_BEASTHEADER
|
|
||||||
#define BEAST_ATOMICSTATE_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A thread safe state variable.
|
|
||||||
|
|
||||||
This provides a simplified interface to an integer used to control atomic
|
|
||||||
state transitions. A state is distinguished by a single integer value.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class AtomicState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a new state with an optional starting value.
|
|
||||||
|
|
||||||
@param initialState The initial state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
explicit AtomicState (const int initialState = 0) noexcept
|
|
||||||
:
|
|
||||||
m_value (initialState)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve the current state.
|
|
||||||
|
|
||||||
This converts the object to an integer reflecting the current state.
|
|
||||||
|
|
||||||
Note that other threads may change the value immediately after this
|
|
||||||
function returns. The caller is responsible for synchronizing.
|
|
||||||
|
|
||||||
@return The state at the time of the call.
|
|
||||||
*/
|
|
||||||
inline operator int () const
|
|
||||||
{
|
|
||||||
return m_value.get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Attempt a state transition.
|
|
||||||
|
|
||||||
The current state is compared to `from`, and if the comparison is
|
|
||||||
successful the state becomes `to`. The entire operation is atomic.
|
|
||||||
|
|
||||||
@param from The current state, for comparison.
|
|
||||||
|
|
||||||
@param to The desired new state.
|
|
||||||
|
|
||||||
@return true if the state transition succeeded.
|
|
||||||
*/
|
|
||||||
inline bool tryChangeState (const int from, const int to) noexcept
|
|
||||||
{
|
|
||||||
return m_value.compareAndSetBool (to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Perform a state transition.
|
|
||||||
|
|
||||||
This attempts to change the state and generates a diagnostic on
|
|
||||||
failure. This routine can be used instead of tryChangeState()
|
|
||||||
when program logic requires that the state change must succeed.
|
|
||||||
|
|
||||||
@param from The required current state.
|
|
||||||
|
|
||||||
@param to The new state.
|
|
||||||
*/
|
|
||||||
inline void changeState (const int from, const int to) noexcept
|
|
||||||
{
|
|
||||||
#if BEAST_DEBUG
|
|
||||||
const bool success = tryChangeState (from, to);
|
|
||||||
bassert (success);
|
|
||||||
#else
|
|
||||||
tryChangeState (from, to);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Atomic <int> m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,478 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_CACHELINE_BEASTHEADER
|
|
||||||
#define BEAST_CACHELINE_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_MemoryAlignment.h"
|
|
||||||
|
|
||||||
// Allows turning off of all padding,
|
|
||||||
// e.g. for memory-constrained systems or testing.
|
|
||||||
//
|
|
||||||
#define GLOBAL_PADDING_ENABLED 0
|
|
||||||
|
|
||||||
namespace CacheLine
|
|
||||||
{
|
|
||||||
|
|
||||||
#if GLOBAL_PADDING_ENABLED
|
|
||||||
|
|
||||||
// Pads an object so that it starts on a cache line boundary.
|
|
||||||
//
|
|
||||||
template <typename T>
|
|
||||||
class Aligned
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~Aligned ()
|
|
||||||
{
|
|
||||||
ptr ()->~T ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Aligned ()
|
|
||||||
{
|
|
||||||
new (ptr ()) T;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit Aligned (const T1& t1)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
Aligned (const T1& t1, const T2& t2)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3, t4);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3, t4, t5);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5, const T6& t6)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3, t4, t5, t6);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7 >
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3, t4, t5, t6, t7);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7, class T8 >
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
|
||||||
{
|
|
||||||
new (ptr ()) T (t1, t2, t3, t4, t5, t6, t7, t8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator= (T const& other)
|
|
||||||
{
|
|
||||||
*ptr () = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T& operator* () noexcept { return *ptr (); }
|
|
||||||
inline T* operator-> () noexcept { return ptr (); }
|
|
||||||
inline operator T& () noexcept { return *ptr (); }
|
|
||||||
inline operator T* () noexcept { return ptr (); }
|
|
||||||
|
|
||||||
inline const T& operator* () const noexcept
|
|
||||||
{
|
|
||||||
return *ptr ();
|
|
||||||
}
|
|
||||||
inline const T* operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return ptr ();
|
|
||||||
}
|
|
||||||
inline operator const T& () const noexcept
|
|
||||||
{
|
|
||||||
return *ptr ();
|
|
||||||
}
|
|
||||||
inline operator const T* () const noexcept
|
|
||||||
{
|
|
||||||
return ptr ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline T* ptr () noexcept
|
|
||||||
{
|
|
||||||
return (T*) ((uintptr_t (m_storage) + Memory::cacheLineAlignMask)
|
|
||||||
& ~Memory::cacheLineAlignMask);
|
|
||||||
/*
|
|
||||||
return reinterpret_cast <T*> (Memory::pointerAdjustedForAlignment (
|
|
||||||
m_storage, Memory::cacheLineBytes));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
char m_storage [ (sizeof (T) + Memory::cacheLineAlignMask)
|
|
||||||
& ~Memory::cacheLineAlignMask];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Holds an object padded it to completely fill a CPU cache line.
|
|
||||||
// The caller must ensure that this object starts at the beginning
|
|
||||||
// of a cache line.
|
|
||||||
//
|
|
||||||
template <typename T>
|
|
||||||
class Padded
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Padded ()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit Padded (const T1& t1)
|
|
||||||
: m_t (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
Padded (const T1& t1, const T2& t2)
|
|
||||||
: m_t (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3)
|
|
||||||
: m_t (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
|
||||||
: m_t (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5)
|
|
||||||
: m_t (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5, const T6& t6)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7 >
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7, class T8 >
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
|
|
||||||
void operator= (const T& other)
|
|
||||||
{
|
|
||||||
m_t = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator* () noexcept { return m_t; }
|
|
||||||
T* operator-> () noexcept { return &m_t; }
|
|
||||||
operator T& () noexcept { return m_t; }
|
|
||||||
operator T* () noexcept { return &m_t; }
|
|
||||||
|
|
||||||
const T& operator* () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
const T* operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
operator const T& () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
operator const T* () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T m_t;
|
|
||||||
char pad [Memory::cacheLineAlignBytes - sizeof (T)];
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Aligned
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Aligned ()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit Aligned (const T1& t1)
|
|
||||||
: m_t (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
Aligned (const T1& t1, const T2& t2)
|
|
||||||
: m_t (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3)
|
|
||||||
: m_t (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
|
||||||
: m_t (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5)
|
|
||||||
: m_t (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5, const T6& t6)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7 >
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7, class T8 >
|
|
||||||
Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
|
|
||||||
void operator= (const T& other)
|
|
||||||
{
|
|
||||||
m_t = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator* () noexcept { return m_t; }
|
|
||||||
T* operator-> () noexcept { return &m_t; }
|
|
||||||
operator T& () noexcept { return m_t; }
|
|
||||||
operator T* () noexcept { return &m_t; }
|
|
||||||
|
|
||||||
const T& operator* () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
const T* operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
operator const T& () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
operator const T* () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T m_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Padded
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Padded ()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit Padded (const T1& t1)
|
|
||||||
: m_t (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
Padded (const T1& t1, const T2& t2)
|
|
||||||
: m_t (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3)
|
|
||||||
: m_t (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
|
||||||
: m_t (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5)
|
|
||||||
: m_t (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5, const T6& t6)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7 >
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7, class T8 >
|
|
||||||
Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
|
|
||||||
void operator= (const T& other)
|
|
||||||
{
|
|
||||||
m_t = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator* () noexcept { return m_t; }
|
|
||||||
T* operator-> () noexcept { return &m_t; }
|
|
||||||
operator T& () noexcept { return m_t; }
|
|
||||||
operator T* () noexcept { return &m_t; }
|
|
||||||
|
|
||||||
const T& operator* () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
const T* operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
operator const T& () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
operator const T* () const noexcept
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T m_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Used to remove padding without changing code
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Unpadded
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Unpadded ()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit Unpadded (const T1& t1)
|
|
||||||
: m_t (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
Unpadded (const T1& t1, const T2& t2)
|
|
||||||
: m_t (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3)
|
|
||||||
: m_t (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
|
||||||
: m_t (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5)
|
|
||||||
: m_t (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3,
|
|
||||||
const T4& t4, const T5& t5, const T6& t6)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7 >
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template < class T1, class T2, class T3, class T4,
|
|
||||||
class T5, class T6, class T7, class T8 >
|
|
||||||
Unpadded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
|
|
||||||
const T5& t5, const T6& t6, const T7& t7, const T8& t8)
|
|
||||||
: m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
|
|
||||||
void operator= (const T& other)
|
|
||||||
{
|
|
||||||
m_t = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator* ()
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
T* operator-> ()
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
operator T& ()
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
operator T* ()
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& operator* () const
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
const T* operator-> () const
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
operator const T& () const
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
operator const T* () const
|
|
||||||
{
|
|
||||||
return &m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T m_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_FIFOFREESTORE_BEASTHEADER
|
|
||||||
#define BEAST_FIFOFREESTORE_BEASTHEADER
|
|
||||||
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
#include "beast_FifoFreeStoreWithTLS.h"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include "beast_FifoFreeStoreWithoutTLS.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Selected free store based on compilation settings.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
#if BEAST_USE_BOOST
|
|
||||||
typedef FifoFreeStoreWithTLS FifoFreeStoreType;
|
|
||||||
#else
|
|
||||||
typedef FifoFreeStoreWithoutTLS FifoFreeStoreType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// Implementation notes
|
|
||||||
//
|
|
||||||
// - A Page is a large allocation from a global PageAllocator.
|
|
||||||
//
|
|
||||||
// - Each thread maintains an 'active' page from which it makes allocations.
|
|
||||||
//
|
|
||||||
// - When the active page is full, a new one takes it's place.
|
|
||||||
//
|
|
||||||
// - Page memory is deallocated when it is not active and no longer referenced.
|
|
||||||
//
|
|
||||||
// - Each instance of FifoFreeStoreWithTLS maintains its own set of per-thread active pages,
|
|
||||||
// but uses a global PageAllocator. This reduces memory consumption without
|
|
||||||
// affecting performance.
|
|
||||||
//
|
|
||||||
|
|
||||||
// This precedes every allocation
|
|
||||||
//
|
|
||||||
struct FifoFreeStoreWithTLS::Header
|
|
||||||
{
|
|
||||||
FifoFreeStoreWithTLS::Page* page;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class FifoFreeStoreWithTLS::Page : LeakChecked <Page>, Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Page (const size_t bytes) : m_refs (1)
|
|
||||||
{
|
|
||||||
m_end = reinterpret_cast <char*> (this) + bytes;
|
|
||||||
m_free = reinterpret_cast <char*> (
|
|
||||||
Memory::pointerAdjustedForAlignment (this + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
~Page ()
|
|
||||||
{
|
|
||||||
bassert (! m_refs.isSignaled ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool release ()
|
|
||||||
{
|
|
||||||
bassert (! m_refs.isSignaled ());
|
|
||||||
|
|
||||||
return m_refs.release ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* allocate (size_t bytes)
|
|
||||||
{
|
|
||||||
bassert (bytes > 0);
|
|
||||||
|
|
||||||
char* p = Memory::pointerAdjustedForAlignment (m_free);
|
|
||||||
char* free = p + bytes;
|
|
||||||
|
|
||||||
if (free <= m_end)
|
|
||||||
{
|
|
||||||
m_free = free;
|
|
||||||
|
|
||||||
m_refs.addref ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicCounter m_refs; // reference count
|
|
||||||
char* m_free; // next free byte
|
|
||||||
char* m_end; // last free byte + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class FifoFreeStoreWithTLS::PerThreadData : LeakChecked <PerThreadData>, Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit PerThreadData (FifoFreeStoreWithTLS* allocator)
|
|
||||||
: m_allocator (*allocator)
|
|
||||||
, m_active (m_allocator.newPage ())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~PerThreadData ()
|
|
||||||
{
|
|
||||||
if (m_active->release ())
|
|
||||||
m_allocator.deletePage (m_active);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* allocate (const size_t bytes)
|
|
||||||
{
|
|
||||||
const size_t headerBytes = Memory::sizeAdjustedForAlignment (sizeof (Header));
|
|
||||||
const size_t bytesNeeded = headerBytes + bytes;
|
|
||||||
|
|
||||||
if (bytesNeeded > m_allocator.m_pages->getPageBytes ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, TRANS ("the memory request was too large")));
|
|
||||||
|
|
||||||
Header* header;
|
|
||||||
|
|
||||||
header = reinterpret_cast <Header*> (m_active->allocate (bytesNeeded));
|
|
||||||
|
|
||||||
if (!header)
|
|
||||||
{
|
|
||||||
if (m_active->release ())
|
|
||||||
deletePage (m_active);
|
|
||||||
|
|
||||||
m_active = m_allocator.newPage ();
|
|
||||||
|
|
||||||
header = reinterpret_cast <Header*> (m_active->allocate (bytesNeeded));
|
|
||||||
}
|
|
||||||
|
|
||||||
header->page = m_active;
|
|
||||||
|
|
||||||
return reinterpret_cast <char*> (header) + headerBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FifoFreeStoreWithTLS& m_allocator;
|
|
||||||
Page* m_active;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline FifoFreeStoreWithTLS::Page* FifoFreeStoreWithTLS::newPage ()
|
|
||||||
{
|
|
||||||
return new (m_pages->allocate ()) Page (m_pages->getPageBytes ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void FifoFreeStoreWithTLS::deletePage (Page* page)
|
|
||||||
{
|
|
||||||
// Safe, because each thread maintains its own active page.
|
|
||||||
page->~Page ();
|
|
||||||
PagedFreeStoreType::deallocate (page);
|
|
||||||
}
|
|
||||||
|
|
||||||
FifoFreeStoreWithTLS::FifoFreeStoreWithTLS ()
|
|
||||||
: m_pages (PagedFreeStoreType::getInstance ())
|
|
||||||
{
|
|
||||||
//bassert (m_pages->getPageBytes () >= sizeof (Page) + Memory::allocAlignBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
FifoFreeStoreWithTLS::~FifoFreeStoreWithTLS ()
|
|
||||||
{
|
|
||||||
// Clean up this thread's data before we release
|
|
||||||
// the reference to the global page allocator.
|
|
||||||
m_tsp.reset (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void* FifoFreeStoreWithTLS::allocate (const size_t bytes)
|
|
||||||
{
|
|
||||||
PerThreadData* data = m_tsp.get ();
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
data = new PerThreadData (this);
|
|
||||||
m_tsp.reset (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data->allocate (bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void FifoFreeStoreWithTLS::deallocate (void* p)
|
|
||||||
{
|
|
||||||
const size_t headerBytes = Memory::sizeAdjustedForAlignment (sizeof (Header));
|
|
||||||
Header* const header = reinterpret_cast <Header*> (reinterpret_cast <char*> (p) - headerBytes);
|
|
||||||
Page* const page = header->page;
|
|
||||||
|
|
||||||
if (page->release ())
|
|
||||||
deletePage (page);
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_FIFOFREESTOREWITHTLS_BEASTHEADER
|
|
||||||
#define BEAST_FIFOFREESTOREWITHTLS_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_GlobalPagedFreeStore.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Lock-free and mostly wait-free FIFO memory allocator.
|
|
||||||
|
|
||||||
This allocator is suitable for use with CallQueue and Listeners. It is
|
|
||||||
expected that over time, deallocations will occur in roughly the same order
|
|
||||||
as allocations.
|
|
||||||
|
|
||||||
@note This implementation uses Thread Local Storage to further improve
|
|
||||||
performance. However, it requires boost style thread_specific_ptr.
|
|
||||||
|
|
||||||
@invariant allocate() and deallocate() are fully concurrent.
|
|
||||||
|
|
||||||
@invariant The ABA problem is handled automatically.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class FifoFreeStoreWithTLS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FifoFreeStoreWithTLS ();
|
|
||||||
~FifoFreeStoreWithTLS ();
|
|
||||||
|
|
||||||
void* allocate (const size_t bytes);
|
|
||||||
static void deallocate (void* const p);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef GlobalPagedFreeStore PagedFreeStoreType;
|
|
||||||
struct Header;
|
|
||||||
|
|
||||||
class Page;
|
|
||||||
|
|
||||||
inline Page* newPage ();
|
|
||||||
static inline void deletePage (Page* page);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class PerThreadData;
|
|
||||||
boost::thread_specific_ptr <PerThreadData> m_tsp;
|
|
||||||
|
|
||||||
PagedFreeStoreType::Ptr m_pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,241 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// This precedes every allocation
|
|
||||||
struct FifoFreeStoreWithoutTLS::Header
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
FifoFreeStoreWithoutTLS::Block* block; // backpointer to the page
|
|
||||||
|
|
||||||
char pad [Memory::allocAlignBytes];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class FifoFreeStoreWithoutTLS::Block : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Block (const size_t bytes) : m_refs (1)
|
|
||||||
{
|
|
||||||
m_end = reinterpret_cast <char*> (this) + bytes;
|
|
||||||
m_free = reinterpret_cast <char*> (
|
|
||||||
Memory::pointerAdjustedForAlignment (this + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
~Block ()
|
|
||||||
{
|
|
||||||
bassert (!m_refs.isSignaled ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addref ()
|
|
||||||
{
|
|
||||||
m_refs.addref ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool release ()
|
|
||||||
{
|
|
||||||
return m_refs.release ();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Result
|
|
||||||
{
|
|
||||||
success, // successful allocation
|
|
||||||
ignore, // disregard the block
|
|
||||||
consumed // block is consumed (1 thread sees this)
|
|
||||||
};
|
|
||||||
|
|
||||||
Result allocate (size_t bytes, void* pBlock)
|
|
||||||
{
|
|
||||||
bassert (bytes > 0);
|
|
||||||
|
|
||||||
Result result;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
char* base = m_free.get ();
|
|
||||||
|
|
||||||
if (base)
|
|
||||||
{
|
|
||||||
char* p = Memory::pointerAdjustedForAlignment (base);
|
|
||||||
char* free = p + bytes;
|
|
||||||
|
|
||||||
if (free <= m_end)
|
|
||||||
{
|
|
||||||
// Try to commit the allocation
|
|
||||||
if (m_free.compareAndSet (free, base))
|
|
||||||
{
|
|
||||||
* (reinterpret_cast <void**> (pBlock)) = p;
|
|
||||||
result = success;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Someone changed m_free, retry.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Mark the block consumed.
|
|
||||||
if (m_free.compareAndSet (0, base))
|
|
||||||
{
|
|
||||||
// Only one caller sees this, the rest get 'ignore'
|
|
||||||
result = consumed;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Happens with another concurrent allocate(), retry.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Block is consumed, ignore it.
|
|
||||||
result = ignore;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicCounter m_refs; // reference count
|
|
||||||
AtomicPointer <char> m_free; // next free byte or 0 if inactive.
|
|
||||||
char* m_end; // last free byte + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline FifoFreeStoreWithoutTLS::Block* FifoFreeStoreWithoutTLS::newBlock ()
|
|
||||||
{
|
|
||||||
return new (m_pages->allocate ()) Block (m_pages->getPageBytes ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void FifoFreeStoreWithoutTLS::deleteBlock (Block* b)
|
|
||||||
{
|
|
||||||
// It is critical that we do not call the destructor,
|
|
||||||
// because due to the lock-free implementation, a Block
|
|
||||||
// can be accessed for a short time after it is deleted.
|
|
||||||
/* b->~Block (); */ // DO NOT CALL!!!
|
|
||||||
|
|
||||||
PagedFreeStoreType::deallocate (b);
|
|
||||||
}
|
|
||||||
|
|
||||||
FifoFreeStoreWithoutTLS::FifoFreeStoreWithoutTLS ()
|
|
||||||
: m_pages (GlobalPagedFreeStore::getInstance ())
|
|
||||||
{
|
|
||||||
if (m_pages->getPageBytes () < sizeof (Block) + 256)
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, TRANS ("the block size is too small")));
|
|
||||||
|
|
||||||
m_active = newBlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
FifoFreeStoreWithoutTLS::~FifoFreeStoreWithoutTLS ()
|
|
||||||
{
|
|
||||||
deleteBlock (m_active);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void* FifoFreeStoreWithoutTLS::allocate (const size_t bytes)
|
|
||||||
{
|
|
||||||
const size_t actual = sizeof (Header) + bytes;
|
|
||||||
|
|
||||||
if (actual > m_pages->getPageBytes ())
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, TRANS ("the memory request was too large")));
|
|
||||||
|
|
||||||
Header* h;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
// Get an active block.
|
|
||||||
Block* b = m_active;
|
|
||||||
|
|
||||||
while (!b)
|
|
||||||
{
|
|
||||||
Thread::yield ();
|
|
||||||
b = m_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (*) It is possible for the block to get a final release here
|
|
||||||
// In this case it will have been put in the garbage, and
|
|
||||||
// m_active will not match.
|
|
||||||
|
|
||||||
// Acquire a reference.
|
|
||||||
b->addref ();
|
|
||||||
|
|
||||||
// Is it still active?
|
|
||||||
if (m_active == b)
|
|
||||||
{
|
|
||||||
// Yes so try to allocate from it.
|
|
||||||
const Block::Result result = b->allocate (actual, &h);
|
|
||||||
|
|
||||||
if (result == Block::success)
|
|
||||||
{
|
|
||||||
// Keep the reference and return the allocation.
|
|
||||||
h->block = b;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (result == Block::consumed)
|
|
||||||
{
|
|
||||||
// Remove block from active.
|
|
||||||
m_active = 0;
|
|
||||||
|
|
||||||
// Take away the reference we added
|
|
||||||
b->release ();
|
|
||||||
|
|
||||||
// Take away the original active reference.
|
|
||||||
if (b->release ())
|
|
||||||
deleteBlock (b);
|
|
||||||
|
|
||||||
// Install a fresh empty active block.
|
|
||||||
m_active = newBlock ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (b->release ())
|
|
||||||
deleteBlock (b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try again.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Block became inactive, so release our reference.
|
|
||||||
b->release ();
|
|
||||||
|
|
||||||
// (*) It is possible for this to be a duplicate final release.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return h + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void FifoFreeStoreWithoutTLS::deallocate (void* p)
|
|
||||||
{
|
|
||||||
Block* const b = (reinterpret_cast <Header*> (p) - 1)->block;
|
|
||||||
|
|
||||||
if (b->release ())
|
|
||||||
deleteBlock (b);
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_FIFOFREESTOREWITHOUTTLS_BEASTHEADER
|
|
||||||
#define BEAST_FIFOFREESTOREWITHOUTTLS_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_GlobalPagedFreeStore.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Lock-free FIFO memory allocator.
|
|
||||||
|
|
||||||
This allocator is suitable for use with CallQueue and Listeners. It is
|
|
||||||
expected that over time, deallocations will occur in roughly the same order
|
|
||||||
as allocations.
|
|
||||||
|
|
||||||
@note This version of the fifo free store uses less memory and doesn't require
|
|
||||||
thread specific storage. However, it runs slower. The performance
|
|
||||||
differences are negligible for desktop class applications.
|
|
||||||
|
|
||||||
@invariant allocate() and deallocate() are fully concurrent.
|
|
||||||
|
|
||||||
@invariant The ABA problem is handled automatically.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class FifoFreeStoreWithoutTLS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit FifoFreeStoreWithoutTLS ();
|
|
||||||
~FifoFreeStoreWithoutTLS ();
|
|
||||||
|
|
||||||
void* allocate (const size_t bytes);
|
|
||||||
static void deallocate (void* const p);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef GlobalPagedFreeStore PagedFreeStoreType;
|
|
||||||
|
|
||||||
struct Header;
|
|
||||||
|
|
||||||
class Block;
|
|
||||||
|
|
||||||
inline Block* newBlock ();
|
|
||||||
static inline void deleteBlock (Block* b);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Block* volatile m_active;
|
|
||||||
PagedFreeStoreType::Ptr m_pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_GLOBALFIFOFREESTORE_BEASTHEADER
|
|
||||||
#define BEAST_GLOBALFIFOFREESTORE_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_FifoFreeStore.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A @ref FifoFreeStoreType singleton.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
template <class Tag>
|
|
||||||
class GlobalFifoFreeStore : public RefCountedSingleton <GlobalFifoFreeStore <Tag> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline void* allocate (size_t bytes)
|
|
||||||
{
|
|
||||||
return m_allocator.allocate (bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void deallocate (void* const p)
|
|
||||||
{
|
|
||||||
FifoFreeStoreType::deallocate (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GlobalFifoFreeStore* createInstance ()
|
|
||||||
{
|
|
||||||
return new GlobalFifoFreeStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GlobalFifoFreeStore ()
|
|
||||||
: RefCountedSingleton <GlobalFifoFreeStore <Tag> >
|
|
||||||
(SingletonLifetime::persistAfterCreation)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~GlobalFifoFreeStore ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FifoFreeStoreType m_allocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// Size of a page
|
|
||||||
//
|
|
||||||
static const size_t globalPageBytes = 8 * 1024;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalPagedFreeStore::GlobalPagedFreeStore ()
|
|
||||||
: RefCountedSingleton <GlobalPagedFreeStore> (SingletonLifetime::persistAfterCreation)
|
|
||||||
, m_allocator (globalPageBytes)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalPagedFreeStore::~GlobalPagedFreeStore ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalPagedFreeStore* GlobalPagedFreeStore::createInstance ()
|
|
||||||
{
|
|
||||||
return new GlobalPagedFreeStore;
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_GLOBALPAGEDFREESTORE_BEASTHEADER
|
|
||||||
#define BEAST_GLOBALPAGEDFREESTORE_BEASTHEADER
|
|
||||||
|
|
||||||
#include "beast_PagedFreeStore.h"
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A PagedFreeStore singleton.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class GlobalPagedFreeStore
|
|
||||||
: public RefCountedSingleton <GlobalPagedFreeStore>
|
|
||||||
, LeakChecked <GlobalPagedFreeStore>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
GlobalPagedFreeStore ();
|
|
||||||
~GlobalPagedFreeStore ();
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline size_t getPageBytes ()
|
|
||||||
{
|
|
||||||
return m_allocator.getPageBytes ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* allocate ()
|
|
||||||
{
|
|
||||||
return m_allocator.allocate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void deallocate (void* const p)
|
|
||||||
{
|
|
||||||
PagedFreeStore::deallocate (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GlobalPagedFreeStore* createInstance ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
PagedFreeStore m_allocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_MEMORYALIGNMENT_BEASTHEADER
|
|
||||||
#define BEAST_MEMORYALIGNMENT_BEASTHEADER
|
|
||||||
|
|
||||||
namespace Memory
|
|
||||||
{
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
|
|
||||||
const int cacheLineAlignBits = 6; // 64 bytes
|
|
||||||
const int cacheLineAlignBytes = 1 << cacheLineAlignBits;
|
|
||||||
const int cacheLineAlignMask = cacheLineAlignBytes - 1;
|
|
||||||
|
|
||||||
const int allocAlignBits = 3; // 8 bytes
|
|
||||||
const int allocAlignBytes = 1 << allocAlignBits;
|
|
||||||
const int allocAlignMask = allocAlignBytes - 1;
|
|
||||||
|
|
||||||
// Returns the number of bytes needed to advance p to the correct alignment
|
|
||||||
template <typename P>
|
|
||||||
inline size_t bytesNeededForAlignment (P const* const p)
|
|
||||||
{
|
|
||||||
return (allocAlignBytes - (uintptr_t (p) & allocAlignMask))
|
|
||||||
& allocAlignMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the number of bytes to make "bytes" an aligned size
|
|
||||||
inline size_t sizeAdjustedForAlignment (const size_t bytes)
|
|
||||||
{
|
|
||||||
return (bytes + allocAlignMask) & ~allocAlignMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a pointer with alignment added.
|
|
||||||
template <typename P>
|
|
||||||
inline P* pointerAdjustedForAlignment (P* const p)
|
|
||||||
{
|
|
||||||
return reinterpret_cast <P*> (reinterpret_cast <char*> (p) +
|
|
||||||
bytesNeededForAlignment (p));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#define LOG_GC 0
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// This is the upper limit on the amount of physical memory an instance of the
|
|
||||||
// allocator will allow. Going over this limit means that consumers cannot keep
|
|
||||||
// up with producers, and application logic should be re-examined.
|
|
||||||
//
|
|
||||||
// TODO: ENFORCE THIS GLOBALLY? MEASURE IN KILOBYTES AND FORCE KILOBYTE PAGE SIZES
|
|
||||||
#define HARD_LIMIT 1
|
|
||||||
const size_t hardLimitMegaBytes = 256;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Implementation notes
|
|
||||||
|
|
||||||
- There are two pools, the 'hot' pool and the 'cold' pool.
|
|
||||||
|
|
||||||
- When a new page is needed we pop from the 'fresh' stack of the hot pool.
|
|
||||||
|
|
||||||
- When a page is deallocated it is pushed to the 'garbage' stack of the hot pool.
|
|
||||||
|
|
||||||
- Every so often, a garbage collection is performed on a separate thread.
|
|
||||||
During collection, fresh and garbage are swapped in the cold pool.
|
|
||||||
Then, the hot and cold pools are atomically swapped.
|
|
||||||
|
|
||||||
*/
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct PagedFreeStore::Page : Pages::Node, LeakChecked <Page>
|
|
||||||
{
|
|
||||||
explicit Page (PagedFreeStore* const allocator)
|
|
||||||
: m_allocator (*allocator)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PagedFreeStore& getAllocator () const
|
|
||||||
{
|
|
||||||
return m_allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PagedFreeStore& m_allocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void* PagedFreeStore::fromPage (Page* const p)
|
|
||||||
{
|
|
||||||
return reinterpret_cast <char*> (p) +
|
|
||||||
Memory::sizeAdjustedForAlignment (sizeof (Page));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline PagedFreeStore::Page* PagedFreeStore::toPage (void* const p)
|
|
||||||
{
|
|
||||||
return reinterpret_cast <Page*> (
|
|
||||||
(reinterpret_cast <char*> (p) -
|
|
||||||
Memory::sizeAdjustedForAlignment (sizeof (Page))));
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
PagedFreeStore::PagedFreeStore (const size_t pageBytes)
|
|
||||||
: m_pageBytes (pageBytes)
|
|
||||||
, m_pageBytesAvailable (pageBytes - Memory::sizeAdjustedForAlignment (sizeof (Page)))
|
|
||||||
, m_newPagesLeft (int ((hardLimitMegaBytes * 1024 * 1024) / m_pageBytes))
|
|
||||||
#if LOG_GC
|
|
||||||
, m_swaps (0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
m_hot = m_pool1;
|
|
||||||
m_cold = m_pool2;
|
|
||||||
|
|
||||||
startOncePerSecond ();
|
|
||||||
}
|
|
||||||
|
|
||||||
PagedFreeStore::~PagedFreeStore ()
|
|
||||||
{
|
|
||||||
endOncePerSecond ();
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
bassert (!m_used.isSignaled ());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dispose (m_pool1);
|
|
||||||
dispose (m_pool2);
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
bassert (!m_total.isSignaled ());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void* PagedFreeStore::allocate ()
|
|
||||||
{
|
|
||||||
Page* page = m_hot->fresh->pop_front ();
|
|
||||||
|
|
||||||
if (!page)
|
|
||||||
{
|
|
||||||
#if HARD_LIMIT
|
|
||||||
const bool exhausted = m_newPagesLeft.release ();
|
|
||||||
|
|
||||||
if (exhausted)
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__,
|
|
||||||
TRANS ("the limit of memory allocations was reached")));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void* storage = ::malloc (m_pageBytes);
|
|
||||||
|
|
||||||
if (!storage)
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__,
|
|
||||||
TRANS ("a memory allocation failed")));
|
|
||||||
|
|
||||||
page = new (storage) Page (this);
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
m_total.addref ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
m_used.addref ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return fromPage (page);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PagedFreeStore::deallocate (void* const p)
|
|
||||||
{
|
|
||||||
Page* const page = toPage (p);
|
|
||||||
PagedFreeStore& allocator = page->getAllocator ();
|
|
||||||
|
|
||||||
allocator.m_hot->garbage->push_front (page);
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
allocator.m_used.release ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform garbage collection.
|
|
||||||
//
|
|
||||||
void PagedFreeStore::doOncePerSecond ()
|
|
||||||
{
|
|
||||||
// Physically free one page.
|
|
||||||
// This will reduce the working set over time after a spike.
|
|
||||||
{
|
|
||||||
Page* page = m_cold->garbage->pop_front ();
|
|
||||||
|
|
||||||
if (page)
|
|
||||||
{
|
|
||||||
page->~Page ();
|
|
||||||
::free (page);
|
|
||||||
m_newPagesLeft.addref ();
|
|
||||||
#ifdef LOG_GC
|
|
||||||
m_total.release ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cold->fresh->swap (m_cold->garbage);
|
|
||||||
|
|
||||||
// Swap atomically with respect to m_hot
|
|
||||||
Pool* temp = m_hot;
|
|
||||||
m_hot = m_cold; // atomic
|
|
||||||
m_cold = temp;
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
String s;
|
|
||||||
s << "swap " << String (++m_swaps);
|
|
||||||
s << " (" << String (m_used.get ()) << "/"
|
|
||||||
<< String (m_total.get ()) << " of "
|
|
||||||
<< String (m_newPagesLeft.get ()) << ")";
|
|
||||||
Logger::outputDebugString (s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void PagedFreeStore::dispose (Pages& pages)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
Page* const page = pages.pop_front ();
|
|
||||||
|
|
||||||
if (page)
|
|
||||||
{
|
|
||||||
page->~Page ();
|
|
||||||
::free (page);
|
|
||||||
|
|
||||||
#if LOG_GC
|
|
||||||
m_total.release ();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PagedFreeStore::dispose (Pool& pool)
|
|
||||||
{
|
|
||||||
dispose (pool.fresh);
|
|
||||||
dispose (pool.garbage);
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_PAGEDFREESTORE_BEASTHEADER
|
|
||||||
#define BEAST_PAGEDFREESTORE_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Lock-free memory allocator for fixed size pages.
|
|
||||||
|
|
||||||
The ABA problem (http://en.wikipedia.org/wiki/ABA_problem) is avoided by
|
|
||||||
treating freed pages as garbage, and performing a collection every second.
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class PagedFreeStore : private OncePerSecond
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit PagedFreeStore (const size_t pageBytes);
|
|
||||||
~PagedFreeStore ();
|
|
||||||
|
|
||||||
// The available bytes per page is a little bit less
|
|
||||||
// than requested in the constructor, due to overhead.
|
|
||||||
//
|
|
||||||
inline size_t getPageBytes () const
|
|
||||||
{
|
|
||||||
return m_pageBytesAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* allocate (const size_t bytes)
|
|
||||||
{
|
|
||||||
if (bytes > m_pageBytes)
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, "the size is too large"));
|
|
||||||
|
|
||||||
return allocate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* allocate ();
|
|
||||||
static void deallocate (void* const p);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* newPage ();
|
|
||||||
void doOncePerSecond ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Page;
|
|
||||||
typedef LockFreeStack <Page> Pages;
|
|
||||||
|
|
||||||
struct Pool
|
|
||||||
{
|
|
||||||
CacheLine::Padded <Pages> fresh;
|
|
||||||
CacheLine::Padded <Pages> garbage;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void* fromPage (Page* const p);
|
|
||||||
static inline Page* toPage (void* const p);
|
|
||||||
|
|
||||||
void dispose (Pages& pages);
|
|
||||||
void dispose (Pool& pool);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const size_t m_pageBytes;
|
|
||||||
const size_t m_pageBytesAvailable;
|
|
||||||
CacheLine::Aligned <Pool> m_pool1; // pair of pools
|
|
||||||
CacheLine::Aligned <Pool> m_pool2;
|
|
||||||
Pool* volatile m_cold; // pool which is cooling down
|
|
||||||
Pool* volatile m_hot; // pool we are currently using
|
|
||||||
AtomicCounter m_newPagesLeft; // limit of system allocations
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
int m_swaps;
|
|
||||||
AtomicCounter m_total;
|
|
||||||
AtomicCounter m_used;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_REFERENCECOUNTEDSINGLETON_BEASTHEADER
|
|
||||||
#define BEAST_REFERENCECOUNTEDSINGLETON_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../events/beast_PerformedAtExit.h"
|
|
||||||
#include "../memory/beast_StaticObject.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
Thread-safe singleton which comes into existence on first use. Use this
|
|
||||||
instead of creating objects with static storage duration. These singletons
|
|
||||||
are automatically reference counted, so if you hold a pointer to it in every
|
|
||||||
object that depends on it, the order of destruction of objects is assured
|
|
||||||
to be correct.
|
|
||||||
|
|
||||||
class Object must provide the function `Object* Object::createInstance()`
|
|
||||||
|
|
||||||
@class RefCountedSingleton
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
class SingletonLifetime
|
|
||||||
{
|
|
||||||
// "base classes dependent on a template parameter
|
|
||||||
// aren't part of lookup." - ville
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
Construction options for RefCountedSingleton
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
enum Lifetime
|
|
||||||
{
|
|
||||||
/** Singleton is created on first use and destroyed when
|
|
||||||
the last reference is removed.
|
|
||||||
*/
|
|
||||||
createOnDemand,
|
|
||||||
|
|
||||||
/** Like createOnDemand, but after the Singleton is destroyed an
|
|
||||||
exception will be thrown if an attempt is made to create it again.
|
|
||||||
*/
|
|
||||||
createOnDemandOnce,
|
|
||||||
|
|
||||||
/** The singleton is created on first use and persists until program exit.
|
|
||||||
*/
|
|
||||||
persistAfterCreation
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Object>
|
|
||||||
class RefCountedSingleton
|
|
||||||
: public SingletonLifetime
|
|
||||||
, private PerformedAtExit
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef SpinLock LockType;
|
|
||||||
|
|
||||||
/** Create the singleton.
|
|
||||||
|
|
||||||
@param lifetime The lifetime management option.
|
|
||||||
*/
|
|
||||||
explicit RefCountedSingleton (Lifetime const lifetime)
|
|
||||||
: m_lifetime (lifetime)
|
|
||||||
{
|
|
||||||
bassert (s_instance == nullptr);
|
|
||||||
|
|
||||||
if (m_lifetime == persistAfterCreation)
|
|
||||||
{
|
|
||||||
incReferenceCount ();
|
|
||||||
}
|
|
||||||
else if (m_lifetime == createOnDemandOnce && *s_created)
|
|
||||||
{
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
|
|
||||||
*s_created = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~RefCountedSingleton ()
|
|
||||||
{
|
|
||||||
bassert (s_instance == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef ReferenceCountedObjectPtr <Object> Ptr;
|
|
||||||
|
|
||||||
/** Retrieve a reference to the singleton.
|
|
||||||
*/
|
|
||||||
static Ptr getInstance ()
|
|
||||||
{
|
|
||||||
Ptr instance;
|
|
||||||
|
|
||||||
instance = s_instance;
|
|
||||||
|
|
||||||
if (instance == nullptr)
|
|
||||||
{
|
|
||||||
LockType::ScopedLockType lock (*s_mutex);
|
|
||||||
|
|
||||||
instance = s_instance;
|
|
||||||
|
|
||||||
if (instance == nullptr)
|
|
||||||
{
|
|
||||||
s_instance = Object::createInstance ();
|
|
||||||
|
|
||||||
instance = s_instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void incReferenceCount () noexcept
|
|
||||||
{
|
|
||||||
m_refs.addref ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void decReferenceCount () noexcept
|
|
||||||
{
|
|
||||||
if (m_refs.release ())
|
|
||||||
destroySingleton ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller must synchronize.
|
|
||||||
inline bool isBeingReferenced () const
|
|
||||||
{
|
|
||||||
return m_refs.isSignaled ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void performAtExit ()
|
|
||||||
{
|
|
||||||
if (m_lifetime == SingletonLifetime::persistAfterCreation)
|
|
||||||
decReferenceCount ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroySingleton ()
|
|
||||||
{
|
|
||||||
bool destroy;
|
|
||||||
|
|
||||||
{
|
|
||||||
LockType::ScopedLockType lock (*s_mutex);
|
|
||||||
|
|
||||||
if (isBeingReferenced ())
|
|
||||||
{
|
|
||||||
destroy = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
destroy = true;
|
|
||||||
s_instance = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (destroy)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Lifetime const m_lifetime;
|
|
||||||
AtomicCounter m_refs;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Object* s_instance;
|
|
||||||
static Static::Storage <LockType, RefCountedSingleton <Object> > s_mutex;
|
|
||||||
static Static::Storage <bool, RefCountedSingleton <Object> > s_created;
|
|
||||||
};
|
|
||||||
/** @{ */
|
|
||||||
|
|
||||||
template <class Object>
|
|
||||||
Object* RefCountedSingleton <Object>::s_instance;
|
|
||||||
|
|
||||||
template <class Object>
|
|
||||||
Static::Storage <typename RefCountedSingleton <Object>::LockType, RefCountedSingleton <Object> >
|
|
||||||
RefCountedSingleton <Object>::s_mutex;
|
|
||||||
|
|
||||||
template <class Object>
|
|
||||||
Static::Storage <bool, RefCountedSingleton <Object> >
|
|
||||||
RefCountedSingleton <Object>::s_created;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_STATICOBJECT_BEASTHEADER
|
|
||||||
#define BEAST_STATICOBJECT_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../threads/beast_SpinDelay.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// A full suite of thread-safe objects designed for static storage duration.
|
|
||||||
//
|
|
||||||
// Wraps an object with a thread-safe initialization preamble so that it can
|
|
||||||
// properly exist with static storage duration.
|
|
||||||
//
|
|
||||||
// Implementation notes:
|
|
||||||
//
|
|
||||||
// This is accomplished by omitting the constructor and relying on the C++
|
|
||||||
// specification that plain data types with static storage duration are filled
|
|
||||||
// with zeroes before any other initialization code executes.
|
|
||||||
//
|
|
||||||
// Spec: N2914=09-0104
|
|
||||||
//
|
|
||||||
// [3.6.2] Initialization of non-local objects
|
|
||||||
//
|
|
||||||
// Objects with static storage duration (3.7.1) or thread storage
|
|
||||||
// duration (3.7.2) shall be zero-initialized (8.5) before any
|
|
||||||
// other initialization takes place.
|
|
||||||
//
|
|
||||||
// Requirements:
|
|
||||||
//
|
|
||||||
// Object must be constructible without parameters.
|
|
||||||
// The StaticObject must be declared with static storage duration or
|
|
||||||
// the behavior is undefined.
|
|
||||||
//
|
|
||||||
// Usage example:
|
|
||||||
//
|
|
||||||
// Object* getInstance ()
|
|
||||||
// {
|
|
||||||
// static StaticObject <Object> instance;
|
|
||||||
// return instance->getObject ();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace Static
|
|
||||||
{
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Holds an object with static storage duration.
|
|
||||||
// The owner determines if and when the object is constructed and destroyed.
|
|
||||||
// Caller is responsible for synchronization.
|
|
||||||
//
|
|
||||||
template <class ObjectType, class Tag>
|
|
||||||
class Storage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static inline void construct ()
|
|
||||||
{
|
|
||||||
new (getObjectPtr ()) ObjectType;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void destroy ()
|
|
||||||
{
|
|
||||||
getObjectPtr ()->~ObjectType ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ObjectType* getObjectPtr ()
|
|
||||||
{
|
|
||||||
return reinterpret_cast <ObjectType*> (s_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ObjectType& getObject ()
|
|
||||||
{
|
|
||||||
return *getObjectPtr ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ObjectType* operator-> () const
|
|
||||||
{
|
|
||||||
return getObjectPtr ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ObjectType& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator ObjectType* () const
|
|
||||||
{
|
|
||||||
return getObjectPtr ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Crashes on iOS if not accessed before usage
|
|
||||||
static char s_storage [sizeof (ObjectType)];
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ObjectType, class Tag>
|
|
||||||
char Storage <ObjectType, Tag>::s_storage [sizeof (ObjectType)];
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Provides a thread safe flag for indicating if and when
|
|
||||||
// initialization is required for an object with static storage duration.
|
|
||||||
//
|
|
||||||
class Initializer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
bool inited () const
|
|
||||||
{
|
|
||||||
return m_state.get () == stateInitialized;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If the condition is not initialized, the first caller will
|
|
||||||
// receive true, while concurrent callers get blocked until
|
|
||||||
// initialization completes.
|
|
||||||
//
|
|
||||||
bool begin ()
|
|
||||||
{
|
|
||||||
bool shouldInitialize;
|
|
||||||
|
|
||||||
if (m_state.get () == stateUninitialized)
|
|
||||||
{
|
|
||||||
if (m_state.compareAndSetBool (stateInitializing, stateUninitialized))
|
|
||||||
{
|
|
||||||
shouldInitialize = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SpinDelay delay;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
delay.pause ();
|
|
||||||
}
|
|
||||||
while (m_state.get () != stateInitialized);
|
|
||||||
|
|
||||||
shouldInitialize = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shouldInitialize = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shouldInitialize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called to signal that the initialization is complete
|
|
||||||
//
|
|
||||||
void end ()
|
|
||||||
{
|
|
||||||
m_state.set (stateInitialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
stateUninitialized = 0, // must be zero
|
|
||||||
stateInitializing,
|
|
||||||
stateInitialized
|
|
||||||
};
|
|
||||||
|
|
||||||
Atomic <int> m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_UNCOPYABLE_BEASTHEADER
|
|
||||||
#define BEAST_UNCOPYABLE_BEASTHEADER
|
|
||||||
|
|
||||||
// Prevents warnings about missing copy
|
|
||||||
// constructors and assignment operators.
|
|
||||||
|
|
||||||
// Ideas based on boost
|
|
||||||
class Uncopyable
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
inline Uncopyable () { }
|
|
||||||
inline ~Uncopyable () { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Uncopyable (Uncopyable const&);
|
|
||||||
Uncopyable const& operator= (Uncopyable const&);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
//#pragma message(BEAST_FILEANDLINE_ "Missing platform-specific implementation")
|
|
||||||
|
|
||||||
FPUFlags FPUFlags::getCurrent ()
|
|
||||||
{
|
|
||||||
return FPUFlags ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FPUFlags::setCurrent (const FPUFlags& flags)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
FPUFlags FPUFlags::getCurrent ()
|
|
||||||
{
|
|
||||||
unsigned int currentControl;
|
|
||||||
const unsigned int newControl = 0;
|
|
||||||
const unsigned int mask = 0;
|
|
||||||
|
|
||||||
errno_t result = _controlfp_s (¤tControl, newControl, mask);
|
|
||||||
|
|
||||||
if (result != 0)
|
|
||||||
Throw (std::runtime_error ("error in _controlfp_s"));
|
|
||||||
|
|
||||||
FPUFlags flags;
|
|
||||||
|
|
||||||
flags.setMaskNaNs ((currentControl & _EM_INVALID) == _EM_INVALID);
|
|
||||||
flags.setMaskDenormals ((currentControl & _EM_DENORMAL) == _EM_DENORMAL);
|
|
||||||
flags.setMaskZeroDivides ((currentControl & _EM_ZERODIVIDE) == _EM_ZERODIVIDE);
|
|
||||||
flags.setMaskOverflows ((currentControl & _EM_OVERFLOW) == _EM_OVERFLOW);
|
|
||||||
flags.setMaskUnderflows ((currentControl & _EM_UNDERFLOW) == _EM_UNDERFLOW);
|
|
||||||
//flags.setMaskInexacts ((currentControl & _EM_INEXACT) == _EM_INEXACT);
|
|
||||||
flags.setFlushDenormals ((currentControl & _DN_FLUSH) == _DN_FLUSH);
|
|
||||||
flags.setInfinitySigned ((currentControl & _IC_AFFINE) == _IC_AFFINE);
|
|
||||||
|
|
||||||
Rounding rounding = roundDown;
|
|
||||||
|
|
||||||
switch (currentControl & _MCW_RC)
|
|
||||||
{
|
|
||||||
case _RC_CHOP:
|
|
||||||
rounding = roundChop;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _RC_UP:
|
|
||||||
rounding = roundUp;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _RC_DOWN:
|
|
||||||
rounding = roundDown;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _RC_NEAR:
|
|
||||||
rounding = roundNear;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Throw (std::runtime_error ("unknown rounding in _controlfp_s"));
|
|
||||||
};
|
|
||||||
|
|
||||||
flags.setRounding (rounding);
|
|
||||||
|
|
||||||
Precision precision = bits64;
|
|
||||||
|
|
||||||
switch (currentControl & _MCW_PC )
|
|
||||||
{
|
|
||||||
case _PC_64:
|
|
||||||
precision = bits64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _PC_53:
|
|
||||||
precision = bits53;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _PC_24:
|
|
||||||
precision = bits24;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Throw (std::runtime_error ("unknown precision in _controlfp_s"));
|
|
||||||
};
|
|
||||||
|
|
||||||
flags.setPrecision (precision);
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setControl (const FPUFlags::Flag& flag,
|
|
||||||
unsigned int& newControl,
|
|
||||||
unsigned int& mask,
|
|
||||||
unsigned int constant)
|
|
||||||
{
|
|
||||||
if (flag.is_set ())
|
|
||||||
{
|
|
||||||
mask |= constant;
|
|
||||||
|
|
||||||
if (flag.value ())
|
|
||||||
newControl |= constant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FPUFlags::setCurrent (const FPUFlags& flags)
|
|
||||||
{
|
|
||||||
unsigned int newControl = 0;
|
|
||||||
unsigned int mask = 0;
|
|
||||||
|
|
||||||
setControl (flags.getMaskNaNs (), newControl, mask, _EM_INVALID);
|
|
||||||
setControl (flags.getMaskDenormals (), newControl, mask, _EM_DENORMAL);
|
|
||||||
setControl (flags.getMaskZeroDivides (), newControl, mask, _EM_ZERODIVIDE);
|
|
||||||
setControl (flags.getMaskOverflows (), newControl, mask, _EM_OVERFLOW);
|
|
||||||
setControl (flags.getMaskUnderflows (), newControl, mask, _EM_UNDERFLOW);
|
|
||||||
//setControl (flags.getMaskInexacts(), newControl, mask, _EM_INEXACT);
|
|
||||||
setControl (flags.getFlushDenormals (), newControl, mask, _DN_FLUSH);
|
|
||||||
setControl (flags.getInfinitySigned (), newControl, mask, _IC_AFFINE);
|
|
||||||
|
|
||||||
if (flags.getRounding ().is_set ())
|
|
||||||
{
|
|
||||||
Rounding rounding = flags.getRounding ().value ();
|
|
||||||
|
|
||||||
switch (rounding)
|
|
||||||
{
|
|
||||||
case roundChop:
|
|
||||||
mask |= _MCW_RC;
|
|
||||||
newControl |= _RC_CHOP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case roundUp:
|
|
||||||
mask |= _MCW_RC;
|
|
||||||
newControl |= _RC_UP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case roundDown:
|
|
||||||
mask |= _MCW_RC;
|
|
||||||
newControl |= _RC_DOWN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case roundNear:
|
|
||||||
mask |= _MCW_RC;
|
|
||||||
newControl |= _RC_NEAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags.getPrecision ().is_set ())
|
|
||||||
{
|
|
||||||
switch (flags.getPrecision ().value ())
|
|
||||||
{
|
|
||||||
case bits64:
|
|
||||||
mask |= _MCW_PC;
|
|
||||||
newControl |= _PC_64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case bits53:
|
|
||||||
mask |= _MCW_PC;
|
|
||||||
newControl |= _PC_53;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case bits24:
|
|
||||||
mask |= _MCW_PC;
|
|
||||||
newControl |= _PC_24;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int currentControl;
|
|
||||||
|
|
||||||
errno_t result = _controlfp_s (¤tControl, newControl, mask);
|
|
||||||
|
|
||||||
if (result != 0)
|
|
||||||
Throw (std::runtime_error ("error in _controlfp_s"));
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
CallQueue::CallQueue (String name)
|
|
||||||
: m_name (name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CallQueue::~CallQueue ()
|
|
||||||
{
|
|
||||||
// Someone forget to close the queue.
|
|
||||||
bassert (m_closed.isSignaled ());
|
|
||||||
|
|
||||||
// Can't destroy queue with unprocessed calls.
|
|
||||||
bassert (m_queue.empty ());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CallQueue::isAssociatedWithCurrentThread () const
|
|
||||||
{
|
|
||||||
return Thread::getCurrentThreadId () == m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a call to the queue of execution.
|
|
||||||
void CallQueue::queuep (Work* c)
|
|
||||||
{
|
|
||||||
// If this goes off it means calls are being made after the
|
|
||||||
// queue is closed, and probably there is no one around to
|
|
||||||
// process it.
|
|
||||||
bassert (!m_closed.isSignaled ());
|
|
||||||
|
|
||||||
if (m_queue.push_back (c))
|
|
||||||
signal ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the Work to the queue. If this call is made from the same
|
|
||||||
// thread as the last thread that called synchronize(), then the call
|
|
||||||
// will execute synchronously.
|
|
||||||
//
|
|
||||||
void CallQueue::callp (Work* c)
|
|
||||||
{
|
|
||||||
queuep (c);
|
|
||||||
|
|
||||||
// If we are called on the process thread and we are not
|
|
||||||
// recursed into doSynchronize, then process the queue. This
|
|
||||||
// makes calls from the process thread synchronous.
|
|
||||||
//
|
|
||||||
// NOTE: The value of isBeingSynchronized is invalid/volatile unless
|
|
||||||
// this thread is the last process thread.
|
|
||||||
//
|
|
||||||
// NOTE: There is a small window of opportunity where we
|
|
||||||
// might get an undesired synchronization if new thread
|
|
||||||
// calls synchronize() concurrently.
|
|
||||||
//
|
|
||||||
if (isAssociatedWithCurrentThread () &&
|
|
||||||
m_isBeingSynchronized.trySignal ())
|
|
||||||
{
|
|
||||||
doSynchronize ();
|
|
||||||
|
|
||||||
m_isBeingSynchronized.reset ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CallQueue::synchronize ()
|
|
||||||
{
|
|
||||||
bool did_something;
|
|
||||||
|
|
||||||
// Detect recursion into doSynchronize(), and
|
|
||||||
// break ties for concurrent calls atomically.
|
|
||||||
//
|
|
||||||
if (m_isBeingSynchronized.trySignal ())
|
|
||||||
{
|
|
||||||
// Remember this thread.
|
|
||||||
m_id = Thread::getCurrentThreadId ();
|
|
||||||
|
|
||||||
did_something = doSynchronize ();
|
|
||||||
|
|
||||||
m_isBeingSynchronized.reset ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
did_something = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return did_something;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can still have pending calls, just can't put new ones in.
|
|
||||||
void CallQueue::close ()
|
|
||||||
{
|
|
||||||
m_closed.signal ();
|
|
||||||
|
|
||||||
synchronize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process everything in the queue. The list of pending calls is
|
|
||||||
// acquired atomically. New calls may enter the queue while we are
|
|
||||||
// processing.
|
|
||||||
//
|
|
||||||
// Returns true if any functors were called.
|
|
||||||
//
|
|
||||||
bool CallQueue::doSynchronize ()
|
|
||||||
{
|
|
||||||
bool did_something;
|
|
||||||
|
|
||||||
// Reset since we are emptying the queue. Since we loop
|
|
||||||
// until the queue is empty, it is possible for us to exit
|
|
||||||
// this function with an empty queue and signaled state.
|
|
||||||
//
|
|
||||||
reset ();
|
|
||||||
|
|
||||||
Work* call = m_queue.pop_front ();
|
|
||||||
|
|
||||||
if (call)
|
|
||||||
{
|
|
||||||
did_something = true;
|
|
||||||
|
|
||||||
// This method of processing one at a time has the desired
|
|
||||||
// side effect of synchronizing nested calls to us from a functor.
|
|
||||||
//
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
call->operator () ();
|
|
||||||
delete call;
|
|
||||||
|
|
||||||
call = m_queue.pop_front ();
|
|
||||||
|
|
||||||
if (call == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
did_something = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return did_something;
|
|
||||||
}
|
|
||||||
@@ -1,542 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_CALLQUEUE_BEASTHEADER
|
|
||||||
#define BEAST_CALLQUEUE_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A FIFO for calling functors asynchronously.
|
|
||||||
|
|
||||||
This object is an alternative to traditional locking techniques used to
|
|
||||||
implement concurrent systems. Instead of acquiring a mutex to change shared
|
|
||||||
data, a functor is queued for later execution (usually on another thread). The
|
|
||||||
execution of the functor applies the transformation to the shared state that
|
|
||||||
was formerly performed within a lock (i.e. CriticalSection).
|
|
||||||
|
|
||||||
For read operations on shared data, instead of acquiring a mutex and
|
|
||||||
accessing the data directly, copies are made (one for each thread), and the
|
|
||||||
thread accesses its copy without acquiring a lock. One thread owns the master
|
|
||||||
copy of the shared state. Requests for changing shared state are made by other
|
|
||||||
threads by posting functors to the master thread's CallQueue. The master
|
|
||||||
thread notifies other threads of changes by posting functors to their
|
|
||||||
respective associated CallQueue, using the Listeners interface.
|
|
||||||
|
|
||||||
The purpose of the functor is to encapsulate one mutation of shared state to
|
|
||||||
guarantee progress towards a consensus of the concurrent data among
|
|
||||||
participating threads. Functors should execute quickly, ideally in constant
|
|
||||||
time. Dynamically allocated objects of class type passed as functor parameters
|
|
||||||
should, in general, be reference counted. The ConcurrentObject class is ideal
|
|
||||||
for meeting this requirement, and has the additional benefit that the workload
|
|
||||||
of deletion is performed on a separate, provided thread. This queue is not a
|
|
||||||
replacement for a thread pool or job queue type system.
|
|
||||||
|
|
||||||
A CallQueue is considered signaled when one or more functors are present.
|
|
||||||
Functors are executed during a call to synchronize(). The operation of
|
|
||||||
executing functors via the call to synchronize() is called synchronizing
|
|
||||||
the queue. It can more generally be thought of as synchronizing multiple
|
|
||||||
copies of shared data between threads.
|
|
||||||
|
|
||||||
Although there is some extra work required to set up and maintain this
|
|
||||||
system, the benefits are significant. Since shared data is only synchronized
|
|
||||||
at well defined times, the programmer can reason and make strong statements
|
|
||||||
about the correctness of the concurrent system. For example, if an
|
|
||||||
AudioIODeviceCallback synchronizes the CallQueue only at the beginning of its
|
|
||||||
execution, it is guaranteed that shared data will remain the same throughout
|
|
||||||
the remainder of the function.
|
|
||||||
|
|
||||||
Because shared data is accessed for reading without a lock, upper bounds
|
|
||||||
on the run time performance can easily be calculated and assured. Compare
|
|
||||||
this with the use of a mutex - the run time performance experiences a
|
|
||||||
combinatorial explosion of possibilities depending on the complex interaction
|
|
||||||
of multiple threads.
|
|
||||||
|
|
||||||
Since a CallQueue is almost always used to invoke parameterized member
|
|
||||||
functions of objects, the call() function comes in a variety of convenient
|
|
||||||
forms to make usage easy:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
void func1 (int);
|
|
||||||
|
|
||||||
struct Object
|
|
||||||
{
|
|
||||||
void func2 (void);
|
|
||||||
void func3 (String name);
|
|
||||||
|
|
||||||
static void func4 ();
|
|
||||||
};
|
|
||||||
|
|
||||||
CallQueue fifo ("Example");
|
|
||||||
|
|
||||||
void example ()
|
|
||||||
{
|
|
||||||
fifo.call (func1, 42); // same as: func1 (42)
|
|
||||||
|
|
||||||
Object* object = new Object;
|
|
||||||
|
|
||||||
fifo.call (&Object::func2, object); // same as: object->func2 ()
|
|
||||||
|
|
||||||
fifo.call (&Object::func3, // same as: object->funcf ("Label")
|
|
||||||
object,
|
|
||||||
"Label");
|
|
||||||
|
|
||||||
fifo.call (&Object::func4); // even static members can be called.
|
|
||||||
|
|
||||||
fifo.callf (bind (&Object::func2, // same as: object->func2 ()
|
|
||||||
object));
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@invariant Functors can be added from any thread at any time, to any queue
|
|
||||||
which is not closed.
|
|
||||||
|
|
||||||
@invariant When synchronize() is called, functors are called and deleted.
|
|
||||||
|
|
||||||
@invariant The thread from which synchronize() is called is considered the
|
|
||||||
thread associated with the CallQueue.
|
|
||||||
|
|
||||||
@invariant Functors queued by the same thread always execute in the same
|
|
||||||
order they were queued.
|
|
||||||
|
|
||||||
@invariant Functors are guaranteed to execute. It is an error if the
|
|
||||||
CallQueue is deleted while there are functors in it.
|
|
||||||
|
|
||||||
Normally, you will not use CallQueue directly, but one of its subclasses
|
|
||||||
instead. The CallQueue is one of a handful of objects that work together to
|
|
||||||
implement this system of concurrent data access.
|
|
||||||
|
|
||||||
For performance considerations, this implementation is wait-free for
|
|
||||||
producers and mostly wait-free for consumers. It also uses a lock-free
|
|
||||||
and wait-free (in the fast path) custom memory allocator.
|
|
||||||
|
|
||||||
@see GuiCallQueue, ManualCallQueue, MessageThread, ThreadWithCallQueue
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class CallQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
/** Type of allocator to use.
|
|
||||||
|
|
||||||
@internal
|
|
||||||
*/
|
|
||||||
typedef FifoFreeStoreType AllocatorType;
|
|
||||||
|
|
||||||
/** Abstract nullary functor in a @ref CallQueue.
|
|
||||||
|
|
||||||
Custom implementations may derive from this object for efficiency instead
|
|
||||||
of using the automatic binding functions.
|
|
||||||
*/
|
|
||||||
class Work : public LockFreeQueue <Work>::Node,
|
|
||||||
public AllocatedBy <AllocatorType>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~Work () { }
|
|
||||||
|
|
||||||
/** Calls the functor.
|
|
||||||
|
|
||||||
This executes during the queue's call to synchronize().
|
|
||||||
*/
|
|
||||||
virtual void operator () () = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
/** Create the CallQueue.
|
|
||||||
|
|
||||||
The queue starts out open and empty.
|
|
||||||
|
|
||||||
@param name A string to identify the queue during debugging.
|
|
||||||
*/
|
|
||||||
explicit CallQueue (String name);
|
|
||||||
|
|
||||||
/** Destroy the CallQueue.
|
|
||||||
|
|
||||||
@invariant Destroying a queue that contains functors results in undefined
|
|
||||||
behavior.
|
|
||||||
|
|
||||||
@note It is customary to call close() on the CallQueue early in the
|
|
||||||
shutdown process to catch functors going into the queue late.
|
|
||||||
*/
|
|
||||||
virtual ~CallQueue ();
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
/** Add a functor and possibly synchronize.
|
|
||||||
|
|
||||||
Use this when you want to perform the bind yourself.
|
|
||||||
|
|
||||||
@param f The functor to add, typically the return value of a call
|
|
||||||
to bind().
|
|
||||||
|
|
||||||
@see call
|
|
||||||
*/
|
|
||||||
template <class Functor>
|
|
||||||
void callf (Functor f)
|
|
||||||
{
|
|
||||||
callp (new (m_allocator) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add a function call and possibly synchronize.
|
|
||||||
|
|
||||||
Parameters are evaluated immediately and added to the queue as a packaged
|
|
||||||
functor. If the current thread of execution is the same as the thread
|
|
||||||
associated with the CallQueue, synchronize() is called automatically. This
|
|
||||||
behavior can be avoided by using queue() instead.
|
|
||||||
|
|
||||||
@param f The function to call followed by up to eight parameters,
|
|
||||||
evaluated immediately. The parameter list must match the function
|
|
||||||
signature. For class member functions, the first argument must be a
|
|
||||||
pointer to the class object.
|
|
||||||
|
|
||||||
@see queue
|
|
||||||
|
|
||||||
@todo Provide an example of when synchronize() is needed in call().
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Fn>
|
|
||||||
void call (Fn f)
|
|
||||||
{
|
|
||||||
callf (bind (f));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Fn, class T1>
|
|
||||||
void call (Fn f, T1 t1)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Fn, class T1, class T2>
|
|
||||||
void call (Fn f, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Fn, class T1, class T2, class T3>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void call (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
callf (bind (f, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Add a functor without synchronizing.
|
|
||||||
|
|
||||||
Use this when you want to perform the bind yourself.
|
|
||||||
|
|
||||||
@param f The functor to add, typically the return value of a call
|
|
||||||
to bind().
|
|
||||||
|
|
||||||
@see queue
|
|
||||||
*/
|
|
||||||
template <class Functor>
|
|
||||||
void queuef (Functor f)
|
|
||||||
{
|
|
||||||
queuep (new (m_allocator) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add a function call without synchronizing.
|
|
||||||
|
|
||||||
Parameters are evaluated immediately, then the resulting functor is added
|
|
||||||
to the queue. This is used to postpone the call to synchronize() when
|
|
||||||
there would be adverse side effects to executing the function immediately.
|
|
||||||
In this example, we use queue() instead of call() to avoid a deadlock:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SharedState; // contains data shared between threads
|
|
||||||
|
|
||||||
ConcurrentState <SharedState> sharedState;
|
|
||||||
|
|
||||||
void stateChanged ()
|
|
||||||
{
|
|
||||||
ConcurrentState <SharedState>::ReadAccess state (sharedState);
|
|
||||||
|
|
||||||
// (read state)
|
|
||||||
}
|
|
||||||
|
|
||||||
CallQueue fifo;
|
|
||||||
|
|
||||||
void changeState ()
|
|
||||||
{
|
|
||||||
ConcurrentState <State>::WriteAccess state (sharedState);
|
|
||||||
|
|
||||||
// (read and write state)
|
|
||||||
|
|
||||||
fifo.call (&stateChanged); // BUG: DEADLOCK because of the implicit synchronize().
|
|
||||||
|
|
||||||
fifo.queue (&stateChanged); // Okay, synchronize() will be called later,
|
|
||||||
// after the write lock is released.
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@param f The function to call followed by up to eight parameters,
|
|
||||||
evaluated immediately. The parameter list must match the
|
|
||||||
function signature. For non-static class member functions,
|
|
||||||
the first argument must be a pointer an instance of the class.
|
|
||||||
|
|
||||||
@see call
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Fn>
|
|
||||||
void queue (Fn f)
|
|
||||||
{
|
|
||||||
queuef (bind (f));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Fn, class T1>
|
|
||||||
void queue (Fn f, T1 t1)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Fn, class T1, class T2>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Fn, class T1, class T2, class T3>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Fn, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void queue (Fn f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
queuef (bind (f, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//============================================================================
|
|
||||||
/** Synchronize the queue.
|
|
||||||
|
|
||||||
A synchronize operation calls all functors in the queue. If a functor
|
|
||||||
causes additional functors to be added, they are eventually executed
|
|
||||||
before synchronize() returns. Derived class call this when the queue is
|
|
||||||
signaled, and optionally at any other time. Calling this function from
|
|
||||||
more than one thread simultaneously is undefined.
|
|
||||||
|
|
||||||
@return true if any functors were executed.
|
|
||||||
*/
|
|
||||||
bool synchronize ();
|
|
||||||
|
|
||||||
/** Close the queue.
|
|
||||||
|
|
||||||
Functors may not be added after this routine is called. This is used for
|
|
||||||
diagnostics, to track down spurious calls during application shutdown
|
|
||||||
or exit. Derived classes may call this if the appropriate time is known.
|
|
||||||
|
|
||||||
The queue is synchronized after it is closed.
|
|
||||||
*/
|
|
||||||
void close ();
|
|
||||||
|
|
||||||
/** Called when the queue becomes signaled.
|
|
||||||
|
|
||||||
A queue is signaled on the transition from empty to non-empty. Derived
|
|
||||||
classes implement this function to perform a notification so that
|
|
||||||
synchronize() will be called. For example, by triggering a WaitableEvent.
|
|
||||||
|
|
||||||
@note Due to the implementation the queue can remain signaled for one
|
|
||||||
extra cycle. This does not happen under load and is not an issue
|
|
||||||
in practice.
|
|
||||||
*/
|
|
||||||
virtual void signal () = 0;
|
|
||||||
|
|
||||||
/** Called when the queue is reset.
|
|
||||||
|
|
||||||
A queue is reset when it was previously signaled and then becomes empty
|
|
||||||
as a result of a call to synchronize.
|
|
||||||
*/
|
|
||||||
virtual void reset () = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
/** Add a raw call.
|
|
||||||
|
|
||||||
@internal
|
|
||||||
|
|
||||||
Custom implementations use this to control the allocation.
|
|
||||||
|
|
||||||
@param c The call to add. The memory must come from the allocator.
|
|
||||||
*/
|
|
||||||
void callp (Work* c);
|
|
||||||
|
|
||||||
/** Queue a raw call.
|
|
||||||
|
|
||||||
Custom implementations use this to control the allocation.
|
|
||||||
|
|
||||||
@param c The call to add. The memory must come from the allocator.
|
|
||||||
*/
|
|
||||||
void queuep (Work* c);
|
|
||||||
|
|
||||||
/** Retrieve the allocator.
|
|
||||||
|
|
||||||
@return The allocator to use when allocating a raw Work object.
|
|
||||||
*/
|
|
||||||
inline AllocatorType& getAllocator ()
|
|
||||||
{
|
|
||||||
return m_allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See if the caller is on the association thread.
|
|
||||||
|
|
||||||
@return `true` if the calling thread of execution is associated with the
|
|
||||||
queue.
|
|
||||||
*/
|
|
||||||
bool isAssociatedWithCurrentThread () const;
|
|
||||||
|
|
||||||
/** See if the queue is being synchronized.
|
|
||||||
|
|
||||||
This is used for diagnostics.
|
|
||||||
|
|
||||||
@note This must be called from the associated thread or else the return
|
|
||||||
value is undefined.
|
|
||||||
|
|
||||||
@return `true` if the call stack contains synchronize() for this queue.
|
|
||||||
*/
|
|
||||||
bool isBeingSynchronized () const
|
|
||||||
{
|
|
||||||
return m_isBeingSynchronized.isSignaled ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <class Functor>
|
|
||||||
class CallType : public Work
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CallType (Functor f) : m_f (f) { }
|
|
||||||
void operator () ()
|
|
||||||
{
|
|
||||||
m_f ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Functor m_f;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool doSynchronize ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
String const m_name;
|
|
||||||
Thread::ThreadID m_id;
|
|
||||||
LockFreeQueue <Work> m_queue;
|
|
||||||
AtomicFlag m_closed;
|
|
||||||
AtomicFlag m_isBeingSynchronized;
|
|
||||||
AllocatorType m_allocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class ConcurrentObject::Deleter : private ThreadWithCallQueue::EntryPoints
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Deleter () : m_thread ("AsyncDeleter")
|
|
||||||
{
|
|
||||||
m_thread.start (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Deleter ()
|
|
||||||
{
|
|
||||||
m_thread.stop (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void performAtExit ()
|
|
||||||
{
|
|
||||||
//delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void doDelete (ConcurrentObject* sharedObject)
|
|
||||||
{
|
|
||||||
delete sharedObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void destroy (ConcurrentObject* sharedObject)
|
|
||||||
{
|
|
||||||
if (m_thread.isAssociatedWithCurrentThread ())
|
|
||||||
delete sharedObject;
|
|
||||||
else
|
|
||||||
m_thread.call (&Deleter::doDelete, sharedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Deleter& getInstance ()
|
|
||||||
{
|
|
||||||
static Deleter instance;
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadWithCallQueue m_thread;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ConcurrentObject::ConcurrentObject ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ConcurrentObject::~ConcurrentObject ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentObject::destroyConcurrentObject ()
|
|
||||||
{
|
|
||||||
Deleter::getInstance ().destroy (this);
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_CONCURRENTOBJECT_BEASTHEADER
|
|
||||||
#define BEAST_CONCURRENTOBJECT_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A reference counted object with overridable destroy behavior.
|
|
||||||
|
|
||||||
This is a reference counted object compatible with
|
|
||||||
ReferenceCountedObjectPtr. When the last reference is removed, the
|
|
||||||
object is queued for deletion on a separate, provided thread. On
|
|
||||||
program exit the thread will clean itself up - no other action is
|
|
||||||
required.
|
|
||||||
|
|
||||||
This class is useful for offloading the deletion work of "deep" objects
|
|
||||||
shared by multiple threads: objects containing complex members, or a
|
|
||||||
hierarchy of allocated structures. For example, a ValueTree. The problem
|
|
||||||
of performing heavyweight memory or cleanup operations from either an
|
|
||||||
AudioIODeviceCallback or the message thread is avoided.
|
|
||||||
|
|
||||||
The deletion behavior can be overriden by providing a replacement
|
|
||||||
for destroyConcurrentObject().
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class ConcurrentObject : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline void incReferenceCount () noexcept
|
|
||||||
{
|
|
||||||
m_refs.addref ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void decReferenceCount () noexcept
|
|
||||||
{
|
|
||||||
if (m_refs.release ())
|
|
||||||
destroyConcurrentObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ConcurrentObject ();
|
|
||||||
|
|
||||||
virtual ~ConcurrentObject ();
|
|
||||||
|
|
||||||
/** Delete the object.
|
|
||||||
|
|
||||||
This function is called when the reference count drops to zero. The
|
|
||||||
default implementation performs the delete on a separate, provided thread
|
|
||||||
that cleans up after itself on exit.
|
|
||||||
*/
|
|
||||||
virtual void destroyConcurrentObject ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Deleter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
AtomicCounter m_refs;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_CONCURRENTSTATE_BEASTHEADER
|
|
||||||
#define BEAST_CONCURRENTSTATE_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
Structured access to a shared state.
|
|
||||||
|
|
||||||
This template wraps an object containing members representing state
|
|
||||||
information shared between multiple threads of execution, where any thread
|
|
||||||
may need to read or write as needed. Synchronized access to the concurrent
|
|
||||||
state is enforced at compile time through strongly typed accessor classes.
|
|
||||||
This interface design facilitates source code pattern matching to find all
|
|
||||||
areas where a concurrent state is accessed.
|
|
||||||
|
|
||||||
There are three types of access:
|
|
||||||
|
|
||||||
- ReadAccess
|
|
||||||
|
|
||||||
Allows read access to the underlying object as `const`. ReadAccess may be
|
|
||||||
granted to one or more threads simultaneously. If one or more threads have
|
|
||||||
ReadAccess, requests to obtain WriteAccess are blocked.
|
|
||||||
|
|
||||||
- WriteAccess
|
|
||||||
|
|
||||||
Allows exclusive read/write access the underlying object. A WriteAccess
|
|
||||||
request blocks until all existing ReadAccess and WriteAccess requests are
|
|
||||||
released. While a WriteAccess exists, requests for ReadAccess will block.
|
|
||||||
|
|
||||||
- UnlockedAccess
|
|
||||||
|
|
||||||
Allows read access to the underlying object without using the lock. This
|
|
||||||
can be helpful when designing concurrent structures through composition.
|
|
||||||
It also makes it easier to search for places in code which use unlocked
|
|
||||||
access.
|
|
||||||
|
|
||||||
This code example demonstrates various forms of access to a ConcurrentState:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SharedData
|
|
||||||
{
|
|
||||||
int value1;
|
|
||||||
String value2;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef ConcurrentState <SharedData> SharedState;
|
|
||||||
|
|
||||||
SharedState sharedState;
|
|
||||||
|
|
||||||
void readExample ()
|
|
||||||
{
|
|
||||||
SharedState::ReadAccess state (sharedState);
|
|
||||||
|
|
||||||
print (state->value1); // read access
|
|
||||||
print (state->value2); // read access
|
|
||||||
|
|
||||||
state->value1 = 42; // write disallowed: compile error
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeExample ()
|
|
||||||
{
|
|
||||||
SharedState::WriteAccess state (sharedState);
|
|
||||||
|
|
||||||
state->value2 = "Label"; // write access
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Forwarding constructors with up to eight parameters are provided. This lets
|
|
||||||
you write constructors into the underlying data object. For example:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SharedData
|
|
||||||
{
|
|
||||||
explicit SharedData (int numSlots)
|
|
||||||
{
|
|
||||||
m_array.reserve (numSlots);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector <AudioSampleBuffer*> m_array;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct SharedData with one parameter
|
|
||||||
ConcurrentState <SharedData> sharedState (16);
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@param Object The type of object to encapsulate.
|
|
||||||
|
|
||||||
@warning Recursive calls are not supported. It is generally not possible for
|
|
||||||
a thread of execution to acquire write access while it already has
|
|
||||||
read access. Such an attempt will result in undefined behavior. Calling into
|
|
||||||
unknown code while holding a lock can cause deadlock. See
|
|
||||||
@ref CallQueue::queue().
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
template <class Object>
|
|
||||||
class ConcurrentState : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class ReadAccess;
|
|
||||||
class WriteAccess;
|
|
||||||
class UnlockedAccess;
|
|
||||||
|
|
||||||
/** Create a concurrent state.
|
|
||||||
|
|
||||||
Up to 8 parameters can be specified in the constructor. These parameters
|
|
||||||
are forwarded to the corresponding constructor in Object. If no
|
|
||||||
constructor in Object matches the parameter list, a compile error is
|
|
||||||
generated.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
ConcurrentState () { }
|
|
||||||
|
|
||||||
template <class T1>
|
|
||||||
explicit ConcurrentState (T1 t1)
|
|
||||||
: m_obj (t1) { }
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
ConcurrentState (T1 t1, T2 t2)
|
|
||||||
: m_obj (t1, t2) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3)
|
|
||||||
: m_obj (t1, t2, t3) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
: m_obj (t1, t2, t3, t4) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5, t6) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : m_obj (t1, t2, t3, t4, t5, t6, t7) { }
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
ConcurrentState (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
: m_obj (t1, t2, t3, t4, t5, t6, t7, t8) { }
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef ReadWriteMutex ReadWriteMutexType;
|
|
||||||
|
|
||||||
Object m_obj;
|
|
||||||
ReadWriteMutexType m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Unlocked access to a ConcurrentState.
|
|
||||||
|
|
||||||
Use sparingly.
|
|
||||||
*/
|
|
||||||
template <class Object>
|
|
||||||
class ConcurrentState <Object>::UnlockedAccess : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit UnlockedAccess (ConcurrentState const& state)
|
|
||||||
: m_state (state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Object const& getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ConcurrentState const& m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Read only access to a ConcurrentState */
|
|
||||||
template <class Object>
|
|
||||||
class ConcurrentState <Object>::ReadAccess : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a ReadAccess from the specified ConcurrentState */
|
|
||||||
explicit ReadAccess (ConcurrentState const volatile& state)
|
|
||||||
: m_state (const_cast <ConcurrentState const&> (state))
|
|
||||||
, m_lock (m_state.m_mutex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only smart pointer to Object */
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ConcurrentState const& m_state;
|
|
||||||
ReadWriteMutexType::ScopedReadLockType m_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Read/write access to a ConcurrentState */
|
|
||||||
template <class Object>
|
|
||||||
class ConcurrentState <Object>::WriteAccess : Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit WriteAccess (ConcurrentState& state)
|
|
||||||
: m_state (state)
|
|
||||||
, m_lock (m_state.m_mutex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const* getObject () const
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only reference to Object */
|
|
||||||
Object const& operator* () const
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read only smart pointer to Object */
|
|
||||||
Object const* operator-> () const
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write pointer to Object */
|
|
||||||
Object& getObject ()
|
|
||||||
{
|
|
||||||
return m_state.m_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write reference to Object */
|
|
||||||
Object& operator* ()
|
|
||||||
{
|
|
||||||
return getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Obtain a read/write smart pointer to Object */
|
|
||||||
Object* operator-> ()
|
|
||||||
{
|
|
||||||
return &getObject ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ConcurrentState& m_state;
|
|
||||||
ReadWriteMutexType::ScopedWriteLockType m_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_GLOBALTHREADGROUP_BEASTHEADER
|
|
||||||
#define BEAST_GLOBALTHREADGROUP_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A ThreadGroup singleton.
|
|
||||||
|
|
||||||
@see ThreadGroup
|
|
||||||
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class GlobalThreadGroup : public ThreadGroup,
|
|
||||||
public RefCountedSingleton <GlobalThreadGroup>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
friend class RefCountedSingleton <GlobalThreadGroup>;
|
|
||||||
|
|
||||||
GlobalThreadGroup ()
|
|
||||||
: RefCountedSingleton <GlobalThreadGroup> (
|
|
||||||
SingletonLifetime::persistAfterCreation)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static GlobalThreadGroup* createInstance ()
|
|
||||||
{
|
|
||||||
return new GlobalThreadGroup;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,225 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
InterruptibleThread::ThreadHelper::ThreadHelper (String name,
|
|
||||||
InterruptibleThread* owner)
|
|
||||||
: Thread (name)
|
|
||||||
, m_owner (owner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InterruptibleThread* InterruptibleThread::ThreadHelper::getOwner () const
|
|
||||||
{
|
|
||||||
return m_owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::ThreadHelper::run ()
|
|
||||||
{
|
|
||||||
m_owner->run ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
InterruptibleThread::InterruptibleThread (String name)
|
|
||||||
: m_thread (name, this)
|
|
||||||
, m_entryPoint (nullptr)
|
|
||||||
, m_state (stateRun)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InterruptibleThread::~InterruptibleThread ()
|
|
||||||
{
|
|
||||||
m_runEvent.signal ();
|
|
||||||
|
|
||||||
join ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::start (EntryPoint* const entryPoint)
|
|
||||||
{
|
|
||||||
m_entryPoint = entryPoint;
|
|
||||||
|
|
||||||
m_thread.startThread ();
|
|
||||||
|
|
||||||
// Prevent data race with member variables
|
|
||||||
//
|
|
||||||
m_runEvent.signal ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::join ()
|
|
||||||
{
|
|
||||||
m_thread.stopThread (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InterruptibleThread::wait (int milliSeconds)
|
|
||||||
{
|
|
||||||
// Can only be called from the corresponding thread of execution.
|
|
||||||
//
|
|
||||||
bassert (isTheCurrentThread ());
|
|
||||||
|
|
||||||
bool interrupted = false;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
bassert (m_state != stateWait);
|
|
||||||
|
|
||||||
// See if we are interrupted
|
|
||||||
//
|
|
||||||
if (m_state.tryChangeState (stateInterrupt, stateRun))
|
|
||||||
{
|
|
||||||
// We were interrupted, state is changed to Run. Caller must run now.
|
|
||||||
//
|
|
||||||
interrupted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (m_state.tryChangeState (stateRun, stateWait) ||
|
|
||||||
m_state.tryChangeState (stateReturn, stateWait))
|
|
||||||
{
|
|
||||||
// Transitioned to wait. Caller must wait now.
|
|
||||||
//
|
|
||||||
interrupted = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!interrupted)
|
|
||||||
{
|
|
||||||
interrupted = m_thread.wait (milliSeconds);
|
|
||||||
|
|
||||||
if (!interrupted)
|
|
||||||
{
|
|
||||||
if (m_state.tryChangeState (stateWait, stateRun))
|
|
||||||
{
|
|
||||||
interrupted = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bassert (m_state == stateInterrupt);
|
|
||||||
|
|
||||||
interrupted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return interrupted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::interrupt ()
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
int const state = m_state;
|
|
||||||
|
|
||||||
if (state == stateInterrupt ||
|
|
||||||
state == stateReturn ||
|
|
||||||
m_state.tryChangeState (stateRun, stateInterrupt))
|
|
||||||
{
|
|
||||||
// Thread will see this at next interruption point.
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (m_state.tryChangeState (stateWait, stateRun))
|
|
||||||
{
|
|
||||||
m_thread.notify ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InterruptibleThread::interruptionPoint ()
|
|
||||||
{
|
|
||||||
// Can only be called from the thread of execution.
|
|
||||||
//
|
|
||||||
bassert (isTheCurrentThread ());
|
|
||||||
|
|
||||||
if (m_state == stateWait)
|
|
||||||
{
|
|
||||||
// It is impossible for this function to be called while in the wait state.
|
|
||||||
//
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
else if (m_state == stateReturn)
|
|
||||||
{
|
|
||||||
// If this goes off it means the thread called the
|
|
||||||
// interruption a second time after already getting interrupted.
|
|
||||||
//
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool const interrupted = m_state.tryChangeState (stateInterrupt, stateRun);
|
|
||||||
|
|
||||||
return interrupted;
|
|
||||||
}
|
|
||||||
|
|
||||||
InterruptibleThread::id InterruptibleThread::getId () const
|
|
||||||
{
|
|
||||||
return m_threadId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InterruptibleThread::isTheCurrentThread () const
|
|
||||||
{
|
|
||||||
return m_thread.getCurrentThreadId () == m_threadId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::setPriority (int priority)
|
|
||||||
{
|
|
||||||
m_thread.setPriority (priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
InterruptibleThread* InterruptibleThread::getCurrentThread ()
|
|
||||||
{
|
|
||||||
InterruptibleThread* result = nullptr;
|
|
||||||
|
|
||||||
Thread* const thread = Thread::getCurrentThread ();
|
|
||||||
|
|
||||||
if (thread != nullptr)
|
|
||||||
{
|
|
||||||
ThreadHelper* const helper = dynamic_cast <ThreadHelper*> (thread);
|
|
||||||
|
|
||||||
bassert (helper != nullptr);
|
|
||||||
|
|
||||||
result = helper->getOwner ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptibleThread::run ()
|
|
||||||
{
|
|
||||||
m_threadId = m_thread.getThreadId ();
|
|
||||||
|
|
||||||
m_runEvent.wait ();
|
|
||||||
|
|
||||||
//CatchAny (m_function);
|
|
||||||
m_entryPoint->threadRun ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool CurrentInterruptibleThread::interruptionPoint ()
|
|
||||||
{
|
|
||||||
bool interrupted = false;
|
|
||||||
|
|
||||||
InterruptibleThread* const interruptibleThread (InterruptibleThread::getCurrentThread ());
|
|
||||||
|
|
||||||
bassert (interruptibleThread != nullptr);
|
|
||||||
|
|
||||||
interrupted = interruptibleThread->interruptionPoint ();
|
|
||||||
|
|
||||||
return interrupted;
|
|
||||||
}
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_INTERRUPTIBLETHREAD_BEASTHEADER
|
|
||||||
#define BEAST_INTERRUPTIBLETHREAD_BEASTHEADER
|
|
||||||
|
|
||||||
#include "../diagnostic/beast_SafeBool.h"
|
|
||||||
#include "../functor/beast_Function.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
A thread with soft interruption support.
|
|
||||||
|
|
||||||
The thread must periodically call interruptionPoint(), which returns `true`
|
|
||||||
the first time an interruption has occurred since the last call to
|
|
||||||
interruptionPoint().
|
|
||||||
|
|
||||||
To create a thread, derive your class from InterruptibleThread::EntryPoint
|
|
||||||
and implement the threadRun() function. Then, call run() with your object.
|
|
||||||
|
|
||||||
@ingroup beast_core
|
|
||||||
*/
|
|
||||||
class InterruptibleThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** InterruptibleThread entry point.
|
|
||||||
*/
|
|
||||||
class EntryPoint
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~EntryPoint () { }
|
|
||||||
|
|
||||||
virtual void threadRun () = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Thread::ThreadID id;
|
|
||||||
|
|
||||||
/** Construct an interruptible thread.
|
|
||||||
|
|
||||||
The name is used for debugger diagnostics.
|
|
||||||
|
|
||||||
@param name The name of the thread.
|
|
||||||
*/
|
|
||||||
explicit InterruptibleThread (String name);
|
|
||||||
|
|
||||||
/** Destroy the interruptible thread.
|
|
||||||
|
|
||||||
This will signal an interrupt and wait until the thread exits.
|
|
||||||
*/
|
|
||||||
~InterruptibleThread ();
|
|
||||||
|
|
||||||
/** Start the thread.
|
|
||||||
*/
|
|
||||||
void start (EntryPoint* const entryPoint);
|
|
||||||
|
|
||||||
/** Wait for the thread to exit.
|
|
||||||
*/
|
|
||||||
void join ();
|
|
||||||
|
|
||||||
/** Wait for interrupt or timeout.
|
|
||||||
|
|
||||||
This call blocks until the thread is interrupted, or until the timeout
|
|
||||||
expires if milliSeconds is non-negative.
|
|
||||||
|
|
||||||
May only be called by the thread of execution.
|
|
||||||
|
|
||||||
@param milliSeconds The amount of time to wait. Negative values mean
|
|
||||||
no timeout.
|
|
||||||
|
|
||||||
@return `true` if the interrupt occurred, or `false` if the
|
|
||||||
timeout expired.
|
|
||||||
*/
|
|
||||||
bool wait (int milliSeconds = -1);
|
|
||||||
|
|
||||||
/** Interrupt the thread of execution.
|
|
||||||
|
|
||||||
This can be called from any thread.
|
|
||||||
*/
|
|
||||||
void interrupt ();
|
|
||||||
|
|
||||||
/** Determine if an interruption is requested.
|
|
||||||
|
|
||||||
After the function returns `true`, the interrupt status is cleared.
|
|
||||||
Subsequent calls will return `false` until another interrupt is requested.
|
|
||||||
|
|
||||||
May only be called by the thread of execution.
|
|
||||||
|
|
||||||
@see CurrentInterruptibleThread::interruptionPoint
|
|
||||||
|
|
||||||
@return `true` if an interrupt was requested.
|
|
||||||
*/
|
|
||||||
bool interruptionPoint ();
|
|
||||||
|
|
||||||
/** Get the ID of the associated thread.
|
|
||||||
|
|
||||||
@return The ID of the thread.
|
|
||||||
*/
|
|
||||||
id getId () const;
|
|
||||||
|
|
||||||
/** Determine if this is the thread of execution.
|
|
||||||
|
|
||||||
@note The return value is undefined if the thread is not running.
|
|
||||||
|
|
||||||
@return `true` if the caller is this thread of execution.
|
|
||||||
*/
|
|
||||||
bool isTheCurrentThread () const;
|
|
||||||
|
|
||||||
/** Adjust the thread priority.
|
|
||||||
|
|
||||||
@note This only affects some platforms.
|
|
||||||
|
|
||||||
@param priority A number from 0..10
|
|
||||||
*/
|
|
||||||
void setPriority (int priority);
|
|
||||||
|
|
||||||
/** Get the InterruptibleThread for the thread of execution.
|
|
||||||
|
|
||||||
This will return `nullptr` when called from the message thread, or from
|
|
||||||
a thread of execution that is not an InterruptibleThread.
|
|
||||||
*/
|
|
||||||
static InterruptibleThread* getCurrentThread ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
class ThreadHelper : public Thread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThreadHelper (String name, InterruptibleThread* owner);
|
|
||||||
|
|
||||||
InterruptibleThread* getOwner () const;
|
|
||||||
|
|
||||||
void run ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
InterruptibleThread* const m_owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
void run ();
|
|
||||||
|
|
||||||
ThreadHelper m_thread;
|
|
||||||
EntryPoint* m_entryPoint;
|
|
||||||
Function <void (void)> m_function;
|
|
||||||
WaitableEvent m_runEvent;
|
|
||||||
id m_threadId;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
stateRun,
|
|
||||||
stateInterrupt,
|
|
||||||
stateReturn,
|
|
||||||
stateWait
|
|
||||||
};
|
|
||||||
|
|
||||||
AtomicState m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Global operations on the current InterruptibleThread.
|
|
||||||
|
|
||||||
Calling members of the class from a thread of execution which is not an
|
|
||||||
InterruptibleThread results in undefined behavior.
|
|
||||||
*/
|
|
||||||
class CurrentInterruptibleThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Call the current thread's interrupt point function.
|
|
||||||
*/
|
|
||||||
static bool interruptionPoint ();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,765 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
// CallQueue item to process a Call for a particular listener.
|
|
||||||
// This is used to avoid bind overhead.
|
|
||||||
//
|
|
||||||
class ListenersBase::CallWork : public CallQueue::Work
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline CallWork (ListenersBase::Call* const c, void* const listener)
|
|
||||||
: m_call (c), m_listener (listener)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator () ()
|
|
||||||
{
|
|
||||||
m_call->operator () (m_listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ListenersBase::Call::Ptr m_call;
|
|
||||||
void* const m_listener;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// CallQueue item to process a Call for a group.
|
|
||||||
// This is used to avoid bind overhead.
|
|
||||||
//
|
|
||||||
class ListenersBase::GroupWork : public CallQueue::Work
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline GroupWork (Group* group,
|
|
||||||
ListenersBase::Call* c,
|
|
||||||
const timestamp_t timestamp)
|
|
||||||
: m_group (group)
|
|
||||||
, m_call (c)
|
|
||||||
, m_timestamp (timestamp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator () ()
|
|
||||||
{
|
|
||||||
m_group->do_call (m_call, m_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Group::Ptr m_group;
|
|
||||||
ListenersBase::Call::Ptr m_call;
|
|
||||||
const timestamp_t m_timestamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// CallQueue item to process a call for a particular listener.
|
|
||||||
// This is used to avoid bind overhead.
|
|
||||||
//
|
|
||||||
class ListenersBase::GroupWork1 : public CallQueue::Work
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline GroupWork1 (Group* group,
|
|
||||||
ListenersBase::Call* c,
|
|
||||||
const timestamp_t timestamp,
|
|
||||||
void* const listener)
|
|
||||||
: m_group (group)
|
|
||||||
, m_call (c)
|
|
||||||
, m_timestamp (timestamp)
|
|
||||||
, m_listener (listener)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator () ()
|
|
||||||
{
|
|
||||||
m_group->do_call1 (m_call, m_timestamp, m_listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Group::Ptr m_group;
|
|
||||||
ListenersBase::Call::Ptr m_call;
|
|
||||||
const timestamp_t m_timestamp;
|
|
||||||
void* const m_listener;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// A Proxy maintains a list of Entry.
|
|
||||||
// Each Entry holds a group and the current Call (which can be updated).
|
|
||||||
//
|
|
||||||
struct ListenersBase::Proxy::Entry : Entries::Node,
|
|
||||||
ReferenceCountedObject,
|
|
||||||
AllocatedBy <AllocatorType>
|
|
||||||
{
|
|
||||||
typedef ReferenceCountedObjectPtr <Entry> Ptr;
|
|
||||||
|
|
||||||
explicit Entry (Group* g)
|
|
||||||
: group (g)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Entry ()
|
|
||||||
{
|
|
||||||
bassert (call.get () == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Group::Ptr group;
|
|
||||||
AtomicPointer <Call> call;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// A Group maintains a list of Entry.
|
|
||||||
//
|
|
||||||
struct ListenersBase::Group::Entry : List <Entry>::Node,
|
|
||||||
AllocatedBy <AllocatorType>
|
|
||||||
{
|
|
||||||
Entry (void* const l, const timestamp_t t)
|
|
||||||
: listener (l)
|
|
||||||
, timestamp (t)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void* const listener;
|
|
||||||
const timestamp_t timestamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Group
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// - A list of listeners associated with the same CallQueue.
|
|
||||||
//
|
|
||||||
// - The list is only iterated on the CallQueue's thread.
|
|
||||||
//
|
|
||||||
// - It is safe to add or remove listeners from the group
|
|
||||||
// at any time.
|
|
||||||
//
|
|
||||||
|
|
||||||
ListenersBase::Group::Group (CallQueue& callQueue)
|
|
||||||
: m_fifo (callQueue)
|
|
||||||
, m_listener (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ListenersBase::Group::~Group ()
|
|
||||||
{
|
|
||||||
// If this goes off it means a Listener forgot to remove itself.
|
|
||||||
bassert (m_list.empty ());
|
|
||||||
|
|
||||||
// shouldn't be deleting group during a call
|
|
||||||
bassert (m_listener == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the listener with the given timestamp.
|
|
||||||
// The listener will only get calls with higher timestamps.
|
|
||||||
// The caller must prevent duplicates.
|
|
||||||
//
|
|
||||||
void ListenersBase::Group::add (void* listener,
|
|
||||||
const timestamp_t timestamp,
|
|
||||||
AllocatorType& allocator)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_mutex);
|
|
||||||
|
|
||||||
bassert (!contains (listener));
|
|
||||||
|
|
||||||
// Should never be able to get here while in call()
|
|
||||||
bassert (m_listener == 0);
|
|
||||||
|
|
||||||
// Add the listener and remember the time stamp so we don't
|
|
||||||
// send it calls that were queued earlier than the add().
|
|
||||||
m_list.push_back (*new (allocator) Entry (listener, timestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the listener from the group if it exists.
|
|
||||||
// Returns true if the listener was removed.
|
|
||||||
//
|
|
||||||
bool ListenersBase::Group::remove (void* listener)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_mutex);
|
|
||||||
|
|
||||||
// Should never be able to get here while in call()
|
|
||||||
bassert (m_listener == 0);
|
|
||||||
|
|
||||||
for (List <Entry>::iterator iter = m_list.begin (); iter != m_list.end (); ++iter)
|
|
||||||
{
|
|
||||||
Entry* entry = & (*iter);
|
|
||||||
|
|
||||||
if (entry->listener == listener)
|
|
||||||
{
|
|
||||||
m_list.erase (m_list.iterator_to (*entry));
|
|
||||||
delete entry;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used for assertions.
|
|
||||||
// The caller must synchronize.
|
|
||||||
//
|
|
||||||
bool ListenersBase::Group::contains (void* const listener) /*const*/
|
|
||||||
{
|
|
||||||
for (List <Entry>::iterator iter = m_list.begin (); iter != m_list.end (); iter++)
|
|
||||||
if (iter->listener == listener)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::Group::call (Call* const c, const timestamp_t timestamp)
|
|
||||||
{
|
|
||||||
bassert (!empty ());
|
|
||||||
m_fifo.callp (new (m_fifo.getAllocator ()) GroupWork (this, c, timestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::Group::queue (Call* const c, const timestamp_t timestamp)
|
|
||||||
{
|
|
||||||
bassert (!empty ());
|
|
||||||
m_fifo.queuep (new (m_fifo.getAllocator ()) GroupWork (this, c, timestamp));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::Group::call1 (Call* const c,
|
|
||||||
const timestamp_t timestamp,
|
|
||||||
void* const listener)
|
|
||||||
{
|
|
||||||
m_fifo.callp (new (m_fifo.getAllocator ()) GroupWork1 (
|
|
||||||
this, c, timestamp, listener));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::Group::queue1 (Call* const c,
|
|
||||||
const timestamp_t timestamp,
|
|
||||||
void* const listener)
|
|
||||||
{
|
|
||||||
m_fifo.queuep (new (m_fifo.getAllocator ()) GroupWork1 (
|
|
||||||
this, c, timestamp, listener));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queues a reference to the Call on the thread queue of each listener
|
|
||||||
// that is currently in our list. The thread queue must be in the
|
|
||||||
// stack's call chain, either directly from CallQueue::synchronize(),
|
|
||||||
// or from Proxy::do_call() called from CallQueue::synchronize().
|
|
||||||
//
|
|
||||||
void ListenersBase::Group::do_call (Call* const c, const timestamp_t timestamp)
|
|
||||||
{
|
|
||||||
if (!empty ())
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_mutex);
|
|
||||||
|
|
||||||
// Recursion not allowed.
|
|
||||||
bassert (m_listener == 0);
|
|
||||||
|
|
||||||
// The body of the loop MUST NOT cause listeners to get called.
|
|
||||||
// Therefore, we don't have to worry about listeners removing
|
|
||||||
// themselves while iterating the list.
|
|
||||||
//
|
|
||||||
for (List <Entry>::iterator iter = m_list.begin (); iter != m_list.end ();)
|
|
||||||
{
|
|
||||||
Entry* entry = & (*iter++);
|
|
||||||
|
|
||||||
// Since it is possible for a listener to be added after a
|
|
||||||
// Call gets queued but before it executes, this prevents listeners
|
|
||||||
// from seeing Calls created before they were added.
|
|
||||||
//
|
|
||||||
if (timestamp > entry->timestamp)
|
|
||||||
{
|
|
||||||
m_listener = entry->listener;
|
|
||||||
|
|
||||||
// The thread queue's synchronize() function MUST be in our call
|
|
||||||
// stack to guarantee that these calls will not execute immediately.
|
|
||||||
// They will be handled by the tail recusion unrolling in the
|
|
||||||
// thread queue.
|
|
||||||
bassert (m_fifo.isBeingSynchronized ());
|
|
||||||
|
|
||||||
m_fifo.callp (new (m_fifo.getAllocator ()) CallWork (c, m_listener));
|
|
||||||
|
|
||||||
m_listener = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// last listener was removed before we got here,
|
|
||||||
// and the parent listener list may have been deleted.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::Group::do_call1 (Call* const c, const timestamp_t timestamp,
|
|
||||||
void* const listener)
|
|
||||||
{
|
|
||||||
if (!empty ())
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_mutex);
|
|
||||||
|
|
||||||
// Recursion not allowed.
|
|
||||||
bassert (m_listener == 0);
|
|
||||||
|
|
||||||
for (List <Entry>::iterator iter = m_list.begin (); iter != m_list.end ();)
|
|
||||||
{
|
|
||||||
Entry* entry = & (*iter++);
|
|
||||||
|
|
||||||
if (entry->listener == listener)
|
|
||||||
{
|
|
||||||
if (timestamp > entry->timestamp)
|
|
||||||
{
|
|
||||||
m_listener = entry->listener;
|
|
||||||
|
|
||||||
bassert (m_fifo.isBeingSynchronized ());
|
|
||||||
|
|
||||||
m_fifo.callp (new (m_fifo.getAllocator ()) CallWork (c, m_listener));
|
|
||||||
|
|
||||||
m_listener = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Listener was removed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Proxy
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// CallQueue item for processing a an Entry for a Proxy.
|
|
||||||
// This is used to avoid bind overhead.
|
|
||||||
//
|
|
||||||
class ListenersBase::Proxy::Work : public CallQueue::Work
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline Work (Proxy* proxy,
|
|
||||||
Entry* const entry,
|
|
||||||
const timestamp_t timestamp)
|
|
||||||
: m_proxy (proxy)
|
|
||||||
, m_entry (entry)
|
|
||||||
, m_timestamp (timestamp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator () ()
|
|
||||||
{
|
|
||||||
ListenersBase::Call* c = m_entry->call.exchange (0);
|
|
||||||
|
|
||||||
Group* group = m_entry->group;
|
|
||||||
|
|
||||||
if (!group->empty ())
|
|
||||||
group->do_call (c, m_timestamp);
|
|
||||||
|
|
||||||
c->decReferenceCount ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Proxy* const m_proxy;
|
|
||||||
Entry::Ptr m_entry;
|
|
||||||
const timestamp_t m_timestamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Holds a Call, and gets put in the CallQueue in place of the Call.
|
|
||||||
// The Call may be replaced if it hasn't been processed yet.
|
|
||||||
// A Proxy exists for the lifetime of the Listeners.
|
|
||||||
//
|
|
||||||
ListenersBase::Proxy::Proxy (void const* const member, const size_t bytes)
|
|
||||||
: m_bytes (bytes)
|
|
||||||
{
|
|
||||||
if (bytes > maxMemberBytes)
|
|
||||||
Throw (Error ().fail (__FILE__, __LINE__, "the Proxy member is too large"));
|
|
||||||
|
|
||||||
memcpy (m_member, member, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListenersBase::Proxy::~Proxy ()
|
|
||||||
{
|
|
||||||
// If the proxy is getting destroyed it means:
|
|
||||||
// - the listeners object is getting destroyed
|
|
||||||
// - all listeners must have removed themselves
|
|
||||||
// - all thread queues have been fully processed
|
|
||||||
// Therefore, our entries should be gone.
|
|
||||||
|
|
||||||
// NO it is possible for an empty Group, for which
|
|
||||||
// the parent listeners object has been destroyed,
|
|
||||||
// to still exist in a thread queue!!!
|
|
||||||
|
|
||||||
// But all listeners should have removed themselves
|
|
||||||
// so our list of groups should still be empty.
|
|
||||||
bassert (m_entries.empty ());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds the group to the Proxy.
|
|
||||||
// Caller must have the proxies mutex.
|
|
||||||
// Caller is responsible for preventing duplicates.
|
|
||||||
//
|
|
||||||
void ListenersBase::Proxy::add (Group* group, AllocatorType& allocator)
|
|
||||||
{
|
|
||||||
Entry* entry (new (allocator) Entry (group));
|
|
||||||
|
|
||||||
// Manual addref and put raw pointer in list
|
|
||||||
entry->incReferenceCount ();
|
|
||||||
m_entries.push_back (*entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the group from the Proxy.
|
|
||||||
// Caller must have the proxies mutex.
|
|
||||||
// Caller is responsible for making sure the group exists.
|
|
||||||
void ListenersBase::Proxy::remove (Group* group)
|
|
||||||
{
|
|
||||||
for (Entries::iterator iter = m_entries.begin (); iter != m_entries.end ();)
|
|
||||||
{
|
|
||||||
Entry* entry = & (*iter++);
|
|
||||||
|
|
||||||
if (entry->group == group)
|
|
||||||
{
|
|
||||||
// remove from list and manual release
|
|
||||||
m_entries.erase (m_entries.iterator_to (*entry));
|
|
||||||
entry->decReferenceCount ();
|
|
||||||
|
|
||||||
// Entry might still be in the empty group's thread queue
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each group, updates the call.
|
|
||||||
// Queues each group that isn't already queued.
|
|
||||||
// Caller must acquire the group read lock.
|
|
||||||
//
|
|
||||||
void ListenersBase::Proxy::update (Call* const c, const timestamp_t timestamp)
|
|
||||||
{
|
|
||||||
// why would we even want to be called?
|
|
||||||
bassert (!m_entries.empty ());
|
|
||||||
|
|
||||||
// With the read lock, this list can't change on us unless someone
|
|
||||||
// adds a listener to a new thread queue in response to a call.
|
|
||||||
for (Entries::iterator iter = m_entries.begin (); iter != m_entries.end ();)
|
|
||||||
{
|
|
||||||
Entry* entry = & (*iter++);
|
|
||||||
|
|
||||||
// Manually add a reference since we use a raw pointer
|
|
||||||
c->incReferenceCount ();
|
|
||||||
|
|
||||||
// Atomically exchange the new call for the old one
|
|
||||||
Call* old = entry->call.exchange (c);
|
|
||||||
|
|
||||||
// If no old call then they need to be queued
|
|
||||||
if (!old)
|
|
||||||
{
|
|
||||||
CallQueue& callQueue = entry->group->getCallQueue ();
|
|
||||||
callQueue.callp (new (callQueue.getAllocator ()) Work (this, entry, timestamp));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
old->decReferenceCount ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ListenersBase::Proxy::match (void const* const member, const size_t bytes) const
|
|
||||||
{
|
|
||||||
return m_bytes == bytes && memcmp (member, m_member, bytes) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ListenersBase
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ListenersBase::ListenersBase ()
|
|
||||||
: m_timestamp (0)
|
|
||||||
, m_allocator (AllocatorType::getInstance ())
|
|
||||||
, m_callAllocator (CallAllocatorType::getInstance ())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ListenersBase::~ListenersBase ()
|
|
||||||
{
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
|
|
||||||
// If this goes off it means a Listener forgot to remove.
|
|
||||||
bassert (group->empty ());
|
|
||||||
|
|
||||||
group->decReferenceCount ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxies are never deleted until here.
|
|
||||||
for (Proxies::iterator iter = m_proxies.begin (); iter != m_proxies.end ();)
|
|
||||||
delete & (*iter++);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::add_void (void* const listener, CallQueue& callQueue)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
#if BEAST_DEBUG
|
|
||||||
|
|
||||||
// Make sure the listener has not already been added
|
|
||||||
// SHOULD USE const_iterator!
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
|
|
||||||
// We can be in do_call() on another thread now, but it
|
|
||||||
// doesn't modify the list, and we have the write lock.
|
|
||||||
bassert (!group->contains (listener));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// See if we already have a Group for this thread queue.
|
|
||||||
Group::Ptr group;
|
|
||||||
|
|
||||||
// SHOULD USE const_iterator
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group::Ptr cur = & (*iter++);
|
|
||||||
|
|
||||||
if (&cur->getCallQueue () == &callQueue)
|
|
||||||
{
|
|
||||||
group = cur;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!group)
|
|
||||||
{
|
|
||||||
group = new (m_allocator) Group (callQueue);
|
|
||||||
|
|
||||||
// Add it to the list, and give it a manual ref
|
|
||||||
// since the list currently uses raw pointers.
|
|
||||||
group->incReferenceCount ();
|
|
||||||
m_groups.push_back (*group);
|
|
||||||
|
|
||||||
// Tell existing proxies to add the group
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_proxies_mutex);
|
|
||||||
|
|
||||||
for (Proxies::iterator iter = m_proxies.begin (); iter != m_proxies.end ();)
|
|
||||||
(iter++)->add (group, *m_allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the listener to the group with the current timestamp
|
|
||||||
group->add (listener, m_timestamp, *m_allocator);
|
|
||||||
|
|
||||||
// Increment the timestamp within the mutex so
|
|
||||||
// future calls will be newer than this listener.
|
|
||||||
++m_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::remove_void (void* const listener)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
// Make sure the listener exists
|
|
||||||
#if BEAST_DEBUG
|
|
||||||
{
|
|
||||||
bool exists = false;
|
|
||||||
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
|
|
||||||
// this should never happen while we hold the mutex
|
|
||||||
bassert (!group->empty ());
|
|
||||||
|
|
||||||
if (group->contains (listener))
|
|
||||||
{
|
|
||||||
bassert (!exists); // added twice?
|
|
||||||
|
|
||||||
exists = true;
|
|
||||||
// keep going to make sure there are no empty groups
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bassert (exists);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Find the group and remove
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group::Ptr group = & (*iter++);
|
|
||||||
|
|
||||||
// If the listener is in there, take it out.
|
|
||||||
if (group->remove (listener))
|
|
||||||
{
|
|
||||||
// Are we the last listener?
|
|
||||||
if (group->empty ())
|
|
||||||
{
|
|
||||||
// Tell proxies to remove the group
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_proxies_mutex);
|
|
||||||
|
|
||||||
for (Proxies::iterator iter = m_proxies.begin (); iter != m_proxies.end ();)
|
|
||||||
{
|
|
||||||
Proxy* proxy = & (*iter++);
|
|
||||||
proxy->remove (group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove it from the list and manually release
|
|
||||||
// the reference since the list uses raw pointers.
|
|
||||||
m_groups.erase (m_groups.iterator_to (*group.getObject ()));
|
|
||||||
group->decReferenceCount ();
|
|
||||||
|
|
||||||
// It is still possible for the group to exist at this
|
|
||||||
// point in a thread queue but it will get processed,
|
|
||||||
// do nothing, and release its own final reference.
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::callp (Call::Ptr cp)
|
|
||||||
{
|
|
||||||
Call* c = cp;
|
|
||||||
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
// can't be const iterator because queue() might cause called functors
|
|
||||||
// to modify the list.
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
(iter++)->call (c, m_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::queuep (Call::Ptr cp)
|
|
||||||
{
|
|
||||||
Call* c = cp;
|
|
||||||
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
// can't be const iterator because queue() might cause called functors
|
|
||||||
// to modify the list.
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
(iter++)->queue (c, m_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::call1p_void (void* const listener, Call* c)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
// can't be const iterator because queue() might cause called functors
|
|
||||||
// to modify the list.
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
|
|
||||||
if (group->contains (listener))
|
|
||||||
{
|
|
||||||
group->call1 (c, m_timestamp, listener);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListenersBase::queue1p_void (void* const listener, Call* c)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
// can't be const iterator because queue() might cause called functors
|
|
||||||
// to modify the list.
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
|
|
||||||
if (group->contains (listener))
|
|
||||||
{
|
|
||||||
group->queue1 (c, m_timestamp, listener);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for an existing Proxy that matches the pointer to
|
|
||||||
// member and replace it's Call, or create a new Proxy for it.
|
|
||||||
//
|
|
||||||
void ListenersBase::updatep (void const* const member,
|
|
||||||
const size_t bytes, Call::Ptr cp)
|
|
||||||
{
|
|
||||||
Call* c = cp;
|
|
||||||
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_groups_mutex);
|
|
||||||
|
|
||||||
if (!m_groups.empty ())
|
|
||||||
{
|
|
||||||
Proxy* proxy;
|
|
||||||
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedReadLockType lock (m_proxies_mutex);
|
|
||||||
|
|
||||||
// See if there's already a proxy
|
|
||||||
proxy = find_proxy (member, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Possibly create one
|
|
||||||
if (!proxy)
|
|
||||||
{
|
|
||||||
ReadWriteMutex::ScopedWriteLockType lock (m_proxies_mutex);
|
|
||||||
|
|
||||||
// Have to search for it again in case someone else added it
|
|
||||||
proxy = find_proxy (member, bytes);
|
|
||||||
|
|
||||||
if (!proxy)
|
|
||||||
{
|
|
||||||
// Create a new empty proxy
|
|
||||||
proxy = new (m_allocator) Proxy (member, bytes);
|
|
||||||
|
|
||||||
// Add all current groups to the Proxy.
|
|
||||||
// We need the group read lock for this (caller provided).
|
|
||||||
for (Groups::iterator iter = m_groups.begin (); iter != m_groups.end ();)
|
|
||||||
{
|
|
||||||
Group* group = & (*iter++);
|
|
||||||
proxy->add (group, *m_allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add it to the list.
|
|
||||||
m_proxies.push_front (*proxy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Requires the group read lock
|
|
||||||
proxy->update (c, m_timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Searches for a proxy that matches the pointer to member.
|
|
||||||
// Caller synchronizes.
|
|
||||||
//
|
|
||||||
ListenersBase::Proxy* ListenersBase::find_proxy (const void* member, size_t bytes)
|
|
||||||
{
|
|
||||||
for (Proxies::iterator iter = m_proxies.begin (); iter != m_proxies.end ();)
|
|
||||||
{
|
|
||||||
Proxy* proxy = & (*iter++);
|
|
||||||
|
|
||||||
if (proxy->match (member, bytes))
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,887 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_LISTENERS_BEASTHEADER
|
|
||||||
#define BEAST_LISTENERS_BEASTHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A group of concurrent Listeners.
|
|
||||||
|
|
||||||
A Listener is an object of class type which inherits from a defined
|
|
||||||
interface, and registers on a provided instance of Listeners to receive
|
|
||||||
asynchronous notifications of changes to concurrent states. Another way of
|
|
||||||
defining Listeners, is that it is similar to a Juce ListenerList but with
|
|
||||||
the provision that the Listener registers with the CallQueue upon which the
|
|
||||||
notification should be made.
|
|
||||||
|
|
||||||
Listeners makes extensive use of CallQueue for providing the notifications,
|
|
||||||
and provides a higher level facility for implementing the concurrent
|
|
||||||
synchronization strategy outlined in CallQueue. Therefore, the same notes
|
|
||||||
which apply to functors in CallQueue also apply to Listener member
|
|
||||||
invocations. Their execution time should be brief, limited in scope to
|
|
||||||
updating the recipient's view of a shared state, and use reference counting
|
|
||||||
for parameters of class type.
|
|
||||||
|
|
||||||
To use this system, first declare your Listener interface:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct Listener
|
|
||||||
{
|
|
||||||
// Sent on every output block
|
|
||||||
virtual void onOutputLevelChanged (const float outputLevel) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Now set up the place where you want to send the notifications. In this
|
|
||||||
example, we will set up the AudioIODeviceCallback to notify anyone who is
|
|
||||||
interested about changes in the current audio output level. We will use
|
|
||||||
this to implement a VU meter:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
Listeners <Listener> listeners;
|
|
||||||
|
|
||||||
// (Process audio data)
|
|
||||||
|
|
||||||
// Calculate output level
|
|
||||||
float outputLevel = calcOutputLevel ();
|
|
||||||
|
|
||||||
// Notify listeners
|
|
||||||
listeners.call (&Listener::onOutputLevelChanged, outputLevel);
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
To receive notifications, derive from Listener and then add yourself to the
|
|
||||||
Listeners object using the desired CallQueue.
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
// We want notifications on the message thread
|
|
||||||
GuiCallQueue fifo;
|
|
||||||
|
|
||||||
struct VUMeter : public Listener, public Component
|
|
||||||
{
|
|
||||||
VUMeter () : m_outputLevel (0)
|
|
||||||
{
|
|
||||||
listeners.add (this, fifo);
|
|
||||||
}
|
|
||||||
|
|
||||||
~VUMeter ()
|
|
||||||
{
|
|
||||||
listeners.remove (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onOutputLevelChanged (float outputLevel)
|
|
||||||
{
|
|
||||||
// Update our copy of the output level shared state.
|
|
||||||
m_outputLevel = outputLevel;
|
|
||||||
|
|
||||||
// Now trigger a redraw of the control.
|
|
||||||
repaint ();
|
|
||||||
}
|
|
||||||
|
|
||||||
float m_outputLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
In this example, the VUMeter constructs with the output level set to zero,
|
|
||||||
and must wait for a notification before it shows up to date data. For a
|
|
||||||
simple VU meter, this is likely not a problem. But if the shared state
|
|
||||||
contains complex information, such as dynamically allocated objects with
|
|
||||||
rich data, then we need a more solid system.
|
|
||||||
|
|
||||||
We will add some classes to create a complete robust example of the use of
|
|
||||||
Listeners to synchronize shared state:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
// Handles audio device output.
|
|
||||||
class AudioDeviceOutput : public AudioIODeviceCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct Listener
|
|
||||||
{
|
|
||||||
// Sent on every output block.
|
|
||||||
virtual void onOutputLevelChanged (float outputLevel) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
AudioDeviceOutput () : AudioDeviceOutput ("Audio CallQueue")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~AudioDeviceOutput ()
|
|
||||||
{
|
|
||||||
m_fifo.close ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addListener (Listener* listener, CallQueue& callQueue)
|
|
||||||
{
|
|
||||||
// Acquire read access to the shared state.
|
|
||||||
ConcurrentState <State>::ReadAccess state (m_state);
|
|
||||||
|
|
||||||
// Add the listener.
|
|
||||||
m_listeners.add (listener, callQueue);
|
|
||||||
|
|
||||||
// Queue an update for the listener to receive the initial state.
|
|
||||||
m_listeners.queue1 (listener,
|
|
||||||
&Listener::onOutputLevelChanged,
|
|
||||||
state->outputLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeListener (Listener* listener)
|
|
||||||
{
|
|
||||||
m_listeners.remove (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void audioDeviceIOCallback (const float** inputChannelData,
|
|
||||||
int numInputChannels,
|
|
||||||
float** outputChannelData,
|
|
||||||
int numOutputChannels,
|
|
||||||
int numSamples)
|
|
||||||
{
|
|
||||||
// Synchronize our call queue. Not needed for this example but
|
|
||||||
// included here as a best-practice for audio device I/O callbacks.
|
|
||||||
m_fifo.synchronize ();
|
|
||||||
|
|
||||||
// (Process audio data)
|
|
||||||
|
|
||||||
// Calculate output level.
|
|
||||||
float newOutputLevel = calcOutputLevel ();
|
|
||||||
|
|
||||||
// Update shared state.
|
|
||||||
{
|
|
||||||
ConcurrentState <State>::WriteAccess state (m_state);
|
|
||||||
|
|
||||||
m_state->outputLevel = newOutputLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify listeners.
|
|
||||||
listeners.call (&Listener::onOutputLevelChanged, newOutputLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct State
|
|
||||||
{
|
|
||||||
State () : outputLevel (0) { }
|
|
||||||
|
|
||||||
float outputLevel;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConcurrentState <State> m_state;
|
|
||||||
|
|
||||||
ManualCallQueue m_fifo;
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Although the rigor demonstrated in the example above is not strictly
|
|
||||||
required when the shared state consists only of a single float, it
|
|
||||||
becomes necessary when there are dynamically allocated objects with complex
|
|
||||||
interactions in the shared state.
|
|
||||||
|
|
||||||
@see CallQueue
|
|
||||||
|
|
||||||
@class Listeners
|
|
||||||
@ingroup beast_concurrent
|
|
||||||
*/
|
|
||||||
class ListenersBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct ListenersStructureTag { };
|
|
||||||
|
|
||||||
typedef GlobalFifoFreeStore <ListenersStructureTag> AllocatorType;
|
|
||||||
|
|
||||||
typedef GlobalFifoFreeStore <ListenersBase> CallAllocatorType;
|
|
||||||
|
|
||||||
class Call : public ReferenceCountedObject,
|
|
||||||
public AllocatedBy <CallAllocatorType>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ReferenceCountedObjectPtr <Call> Ptr;
|
|
||||||
virtual void operator () (void* const listener) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef unsigned long timestamp_t;
|
|
||||||
|
|
||||||
class Group;
|
|
||||||
typedef List <Group> Groups;
|
|
||||||
|
|
||||||
class Proxy;
|
|
||||||
typedef List <Proxy> Proxies;
|
|
||||||
|
|
||||||
class CallWork;
|
|
||||||
class GroupWork;
|
|
||||||
class GroupWork1;
|
|
||||||
|
|
||||||
// Maintains a list of listeners registered on the same CallQueue
|
|
||||||
//
|
|
||||||
class Group : public Groups::Node,
|
|
||||||
public ReferenceCountedObject,
|
|
||||||
public AllocatedBy <AllocatorType>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ReferenceCountedObjectPtr <Group> Ptr;
|
|
||||||
|
|
||||||
explicit Group (CallQueue& callQueue);
|
|
||||||
~Group ();
|
|
||||||
void add (void* listener, const timestamp_t timestamp,
|
|
||||||
AllocatorType& allocator);
|
|
||||||
bool remove (void* listener);
|
|
||||||
bool contains (void* const listener);
|
|
||||||
void call (Call* const c, const timestamp_t timestamp);
|
|
||||||
void queue (Call* const c, const timestamp_t timestamp);
|
|
||||||
void call1 (Call* const c, const timestamp_t timestamp,
|
|
||||||
void* const listener);
|
|
||||||
void queue1 (Call* const c, const timestamp_t timestamp,
|
|
||||||
void* const listener);
|
|
||||||
void do_call (Call* const c, const timestamp_t timestamp);
|
|
||||||
void do_call1 (Call* const c, const timestamp_t timestamp,
|
|
||||||
void* const listener);
|
|
||||||
|
|
||||||
bool empty () const
|
|
||||||
{
|
|
||||||
return m_list.empty ();
|
|
||||||
}
|
|
||||||
CallQueue& getCallQueue () const
|
|
||||||
{
|
|
||||||
return m_fifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Entry;
|
|
||||||
|
|
||||||
CallQueue& m_fifo;
|
|
||||||
List <Entry> m_list;
|
|
||||||
void* m_listener;
|
|
||||||
CacheLine::Aligned <ReadWriteMutex> m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A Proxy is keyed to a unique pointer-to-member of a
|
|
||||||
// ListenerClass and is used to consolidate multiple unprocessed
|
|
||||||
// Calls into a single call to prevent excess messaging. It is up
|
|
||||||
// to the user of the class to decide when this behavior is appropriate.
|
|
||||||
//
|
|
||||||
class Proxy : public Proxies::Node,
|
|
||||||
public AllocatedBy <AllocatorType>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
maxMemberBytes = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
Proxy (void const* const member, const size_t bytes);
|
|
||||||
~Proxy ();
|
|
||||||
|
|
||||||
void add (Group* group, AllocatorType& allocator);
|
|
||||||
void remove (Group* group);
|
|
||||||
void update (Call* const c, const timestamp_t timestamp);
|
|
||||||
|
|
||||||
bool match (void const* const member, const size_t bytes) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Work;
|
|
||||||
struct Entry;
|
|
||||||
typedef List <Entry> Entries;
|
|
||||||
char m_member [maxMemberBytes];
|
|
||||||
const size_t m_bytes;
|
|
||||||
Entries m_entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ListenersBase ();
|
|
||||||
~ListenersBase ();
|
|
||||||
|
|
||||||
inline CallAllocatorType& getCallAllocator ()
|
|
||||||
{
|
|
||||||
return *m_callAllocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_void (void* const listener, CallQueue& callQueue);
|
|
||||||
void remove_void (void* const listener);
|
|
||||||
|
|
||||||
void callp (Call::Ptr c);
|
|
||||||
void queuep (Call::Ptr c);
|
|
||||||
void call1p_void (void* const listener, Call* c);
|
|
||||||
void queue1p_void (void* const listener, Call* c);
|
|
||||||
void updatep (void const* const member,
|
|
||||||
const size_t bytes, Call::Ptr cp);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Proxy* find_proxy (const void* member, size_t bytes);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Groups m_groups;
|
|
||||||
Proxies m_proxies;
|
|
||||||
timestamp_t m_timestamp;
|
|
||||||
CacheLine::Aligned <ReadWriteMutex> m_groups_mutex;
|
|
||||||
CacheLine::Aligned <ReadWriteMutex> m_proxies_mutex;
|
|
||||||
AllocatorType::Ptr m_allocator;
|
|
||||||
CallAllocatorType::Ptr m_callAllocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
|
|
||||||
template <class ListenerClass>
|
|
||||||
class Listeners : public ListenersBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <class Functor>
|
|
||||||
class CallType : public Call
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CallType (Functor f) : m_f (f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator () (void* const listener)
|
|
||||||
{
|
|
||||||
ListenerClass* object = static_cast <ListenerClass*> (listener);
|
|
||||||
m_f.operator () (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Functor m_f;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
inline void callf (Functor f)
|
|
||||||
{
|
|
||||||
callp (new (getCallAllocator ()) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
inline void queuef (Functor f)
|
|
||||||
{
|
|
||||||
queuep (new (getCallAllocator ()) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void call1p (ListenerClass* const listener, Call::Ptr c)
|
|
||||||
{
|
|
||||||
call1p_void (listener, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void queue1p (ListenerClass* const listener, Call::Ptr c)
|
|
||||||
{
|
|
||||||
queue1p_void (listener, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
inline void call1f (ListenerClass* const listener, Functor f)
|
|
||||||
{
|
|
||||||
call1p (listener, new (getCallAllocator ()) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Functor>
|
|
||||||
inline void queue1f (ListenerClass* const listener, Functor f)
|
|
||||||
{
|
|
||||||
queue1p (listener, new (getCallAllocator ()) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Member, class Functor>
|
|
||||||
inline void updatef (Member member, Functor f)
|
|
||||||
{
|
|
||||||
updatep (reinterpret_cast <void*> (&member), sizeof (Member),
|
|
||||||
new (getCallAllocator ()) CallType <Functor> (f));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Add a listener.
|
|
||||||
|
|
||||||
The specified listener is associated with the specified CallQueue and
|
|
||||||
added to the list.
|
|
||||||
|
|
||||||
Invariants:
|
|
||||||
|
|
||||||
- All other members of Listeners are blocked during add().
|
|
||||||
|
|
||||||
- The listener is guaranteed to receive every subsequent call.
|
|
||||||
|
|
||||||
- The listener must not already exist in the list.
|
|
||||||
|
|
||||||
- Safe to call from any thread.
|
|
||||||
|
|
||||||
@param listener The listener to add.
|
|
||||||
|
|
||||||
@param callQueue The CallQueue to associate with the listener.
|
|
||||||
*/
|
|
||||||
void add (ListenerClass* const listener, CallQueue& callQueue)
|
|
||||||
{
|
|
||||||
add_void (listener, callQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Remove a listener.
|
|
||||||
|
|
||||||
The specified listener, which must have been previously added, is removed
|
|
||||||
from the list. A listener always needs to remove itself before the
|
|
||||||
associated CallQueue is closed.
|
|
||||||
|
|
||||||
Invariants:
|
|
||||||
|
|
||||||
- All other members of Listeners are blocked during remove().
|
|
||||||
|
|
||||||
- The listener is guaranteed not to receive calls after remove() returns.
|
|
||||||
|
|
||||||
- Safe to call from any thread.
|
|
||||||
|
|
||||||
@param listener The listener to remove.
|
|
||||||
*/
|
|
||||||
void remove (ListenerClass* const listener)
|
|
||||||
{
|
|
||||||
remove_void (listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Call a member function on every added listener, on its associated
|
|
||||||
CallQueue.
|
|
||||||
|
|
||||||
A listener's CallQueue will be synchronized if this function is called
|
|
||||||
from it's associated thread.
|
|
||||||
|
|
||||||
Invariants:
|
|
||||||
|
|
||||||
- A listener that later removes itself afterwards may not get called.
|
|
||||||
|
|
||||||
- Calls from the same thread always execute in order.
|
|
||||||
|
|
||||||
- A listener can remove itself even if it has a pending call.
|
|
||||||
|
|
||||||
@param mf The member function to call. This may be followed by up to 8
|
|
||||||
arguments.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Mf>
|
|
||||||
inline void call (Mf mf)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Mf, class T1>
|
|
||||||
void call (Mf mf, T1 t1)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Mf, class T1, class T2>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Mf, class T1, class T2, class T3>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void call (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
callf (bind (mf, _1, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Queue a member function on every added listener, without synchronizing.
|
|
||||||
|
|
||||||
Operates like call(), but no CallQueue synchronization takes place. This
|
|
||||||
can be necessary when the call to queue() is made inside a held lock.
|
|
||||||
|
|
||||||
@param mf The member function to call. This may be followed by up to 8
|
|
||||||
arguments.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Mf>
|
|
||||||
inline void queue (Mf mf)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Mf, class T1>
|
|
||||||
void queue (Mf mf, T1 t1)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Mf, class T1, class T2>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Mf, class T1, class T2, class T3>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void queue (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
queuef (bind (mf, _1, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Call a member function on every added listener, replacing pending
|
|
||||||
calls to the same member.
|
|
||||||
|
|
||||||
This operates like call(), except that if there are pending unprocessed
|
|
||||||
calls to the same member function,they will be replaced, with the previous
|
|
||||||
parameters destroyed normally. This functionality is useful for
|
|
||||||
high frequency notifications of non critical data, where the recipient
|
|
||||||
may not catch up often enough. For example, the output level of the
|
|
||||||
AudioIODeviceCallback in the example is a candidate for the use of
|
|
||||||
update().
|
|
||||||
|
|
||||||
@param mf The member function to call. This may be followed by up to 8
|
|
||||||
arguments.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Mf>
|
|
||||||
inline void update (Mf mf)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Mf, class T1>
|
|
||||||
void update (Mf mf, T1 t1)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Mf, class T1, class T2>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Mf, class T1, class T2, class T3>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void update (Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
updatef (mf, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Call a member function on a specific listener.
|
|
||||||
|
|
||||||
Like call(), except that one listener is targeted only. This is useful when
|
|
||||||
builing complex behaviors during the addition of a listener, such as
|
|
||||||
providing an initial state.
|
|
||||||
|
|
||||||
@param listener The listener to call.
|
|
||||||
|
|
||||||
@param mf The member function to call. This may be followed by up
|
|
||||||
to 8 arguments.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Mf>
|
|
||||||
inline void call1 (ListenerClass* const listener, Mf mf)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Mf, class T1>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Mf, class T1, class T2>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Mf, class T1, class T2, class T3>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void call1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
call1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** Queue a member function on a specific listener.
|
|
||||||
|
|
||||||
Like call1(), except that no CallQueue synchronization takes place.
|
|
||||||
|
|
||||||
@param listener The listener to call.
|
|
||||||
|
|
||||||
@param mf The member function to call. This may be followed by up
|
|
||||||
to 8 arguments.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
#if BEAST_VARIADIC_MAX >= 1
|
|
||||||
template <class Mf>
|
|
||||||
inline void queue1 (ListenerClass* const listener, Mf mf)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 2
|
|
||||||
template <class Mf, class T1>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 3
|
|
||||||
template <class Mf, class T1, class T2>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 4
|
|
||||||
template <class Mf, class T1, class T2, class T3>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 5
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3, t4));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 6
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3, t4, t5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 7
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 8
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BEAST_VARIADIC_MAX >= 9
|
|
||||||
template <class Mf, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
|
||||||
void queue1 (ListenerClass* const listener, Mf mf, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
|
||||||
{
|
|
||||||
queue1f (listener, bind (mf, _1, t1, t2, t3, t4, t5, t6, t7, t8));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
};
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*============================================================================*/
|
|
||||||
/*
|
|
||||||
VFLib: https://github.com/vinniefalco/VFLib
|
|
||||||
|
|
||||||
Copyright (C) 2008 by Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
This library contains portions of other open source products covered by
|
|
||||||
separate licenses. Please see the corresponding source files for specific
|
|
||||||
terms.
|
|
||||||
|
|
||||||
VFLib is provided under the terms of The MIT License (MIT):
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
/*============================================================================*/
|
|
||||||
|
|
||||||
ManualCallQueue::ManualCallQueue (String name)
|
|
||||||
: CallQueue (name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManualCallQueue::close ()
|
|
||||||
{
|
|
||||||
CallQueue::close ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ManualCallQueue::synchronize ()
|
|
||||||
{
|
|
||||||
return CallQueue::synchronize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManualCallQueue::signal ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ManualCallQueue::reset ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/*============================================================================*/
|
|
||||||
/*
|
|
||||||
VFLib: https://github.com/vinniefalco/VFLib
|
|
||||||
|
|
||||||
Copyright (C) 2008 by Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
This library contains portions of other open source products covered by
|
|
||||||
separate licenses. Please see the corresponding source files for specific
|
|
||||||
terms.
|
|
||||||
|
|
||||||
VFLib is provided under the terms of The MIT License (MIT):
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
/*============================================================================*/
|
|
||||||
|
|
||||||
#ifndef VF_MANUALCALLQUEUE_VFHEADER
|
|
||||||
#define VF_MANUALCALLQUEUE_VFHEADER
|
|
||||||
|
|
||||||
/*============================================================================*/
|
|
||||||
/**
|
|
||||||
A CallQueue that requires periodic manual synchronization.
|
|
||||||
|
|
||||||
To use this, declare an instance and then place calls into it as usual.
|
|
||||||
Every so often, you must call synchronize() from the thread you want to
|
|
||||||
associate with the queue. Typically this is done within an
|
|
||||||
AudioIODeviceCallback:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
class AudioIODeviceCallbackWithCallQueue
|
|
||||||
: public AudioIODeviceCallback
|
|
||||||
, public CallQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AudioIODeviceCallbackWithCallQueue () : m_fifo ("Audio CallQueue")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void audioDeviceIOCallback (const float** inputChannelData,
|
|
||||||
int numInputChannels,
|
|
||||||
float** outputChannelData,
|
|
||||||
int numOutputChannels,
|
|
||||||
int numSamples)
|
|
||||||
{
|
|
||||||
CallQueue::synchronize ();
|
|
||||||
|
|
||||||
// do audio i/o
|
|
||||||
}
|
|
||||||
|
|
||||||
void signal () { } // No action required
|
|
||||||
void reset () { } // No action required
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The close() function is provided for diagnostics. Call it as early as
|
|
||||||
possible based on the exit or shutdown logic of your application. If calls
|
|
||||||
are put into the queue after it is closed, it will generate an exception so
|
|
||||||
you can track it down.
|
|
||||||
|
|
||||||
@see CallQueue
|
|
||||||
|
|
||||||
@ingroup vf_concurrent
|
|
||||||
*/
|
|
||||||
class ManualCallQueue : public CallQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Create a ManualCallQueue.
|
|
||||||
|
|
||||||
@param name A string used to help identify the associated
|
|
||||||
thread for debugging.
|
|
||||||
*/
|
|
||||||
explicit ManualCallQueue (String name);
|
|
||||||
|
|
||||||
/** Close the queue. If calls are placed into a closed queue, an exception
|
|
||||||
is thrown.
|
|
||||||
*/
|
|
||||||
void close ();
|
|
||||||
|
|
||||||
/** Synchronize the queue by calling all pending functors.
|
|
||||||
|
|
||||||
@return `true` if any functors were called.
|
|
||||||
*/
|
|
||||||
bool synchronize ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void signal ();
|
|
||||||
void reset ();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user