mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
General refactoring, using C++11
* Remove broken RecycledObjectPool * Fix beast::ServiceQueue using List instead of LockFreeStack * Add class semaphore, fixes broken Semaphore * Move crytpo module files to new beast directory * Use c++11 replacements for boost and beast types: - std::atomic instead of beast::Atomic - std::function instead of boost::function, beast::function - std::unique_ptr instead of beast::ScopedPointer - std::shared_ptr instead of boost::shared_ptr * Remove modules: - beast_db - beast_crypto - beast_extras * Remove unnecessary classes: - AbstractFifo - AddConst - AtomicCounter - AtomicFlag - AtomicPointer - AtomicState - CopyConst - Expression - ForwardList - IfCond - Interval - IntrusiveArray - KeyvaDB - PointerToOther - PointerTraits - RemoveConst - RemoveConstVolatile - RemoveReference - RemoveVolatile - SharedObjectArray - SingleThreadedSharedObject - SophiaDB factory - SortedSet - WeakReference - beast::unique_ptr
This commit is contained in:
@@ -110,9 +110,12 @@
|
||||
<ClInclude Include="..\..\beast\config\SelectStdlibConfig.h" />
|
||||
<ClInclude Include="..\..\beast\config\StandardConfig.h" />
|
||||
<ClInclude Include="..\..\beast\Crypto.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\BinaryEncoding.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\impl\sha2\sha2.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\MurmurHash.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\Sha256.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\UnsignedInteger.h" />
|
||||
<ClInclude Include="..\..\beast\crypto\UnsignedIntegerCalc.h" />
|
||||
<ClInclude Include="..\..\beast\CStdInt.h" />
|
||||
<ClInclude Include="..\..\beast\cyclic_iterator.h" />
|
||||
<ClInclude Include="..\..\beast\FixedArray.h" />
|
||||
@@ -136,22 +139,11 @@
|
||||
<ClInclude Include="..\..\beast\insight\NullCollector.h" />
|
||||
<ClInclude Include="..\..\beast\insight\StatsDCollector.h" />
|
||||
<ClInclude Include="..\..\beast\Intrusive.h" />
|
||||
<ClInclude Include="..\..\beast\intrusive\ForwardList.h" />
|
||||
<ClInclude Include="..\..\beast\intrusive\IntrusiveArray.h" />
|
||||
<ClInclude Include="..\..\beast\intrusive\List.h" />
|
||||
<ClInclude Include="..\..\beast\intrusive\LockFreeStack.h" />
|
||||
<ClInclude Include="..\..\beast\intrusive\PointerTraits.h" />
|
||||
<ClInclude Include="..\..\beast\Memory.h" />
|
||||
<ClInclude Include="..\..\beast\MPL.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\AddConst.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\CopyConst.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\IfCond.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\PointerToOther.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveConst.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveConstVolatile.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveReference.h" />
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveVolatile.h" />
|
||||
<ClInclude Include="..\..\beast\Net.h" />
|
||||
<ClInclude Include="..\..\beast\net\BufferType.h" />
|
||||
<ClInclude Include="..\..\beast\net\DynamicBuffer.h" />
|
||||
@@ -165,10 +157,7 @@
|
||||
<ClInclude Include="..\..\beast\smart_ptr\SharedPtr.h" />
|
||||
<ClInclude Include="..\..\beast\StaticAssert.h" />
|
||||
<ClInclude Include="..\..\beast\STL.h" />
|
||||
<ClInclude Include="..\..\beast\stl\function.h" />
|
||||
<ClInclude Include="..\..\beast\stl\shared_ptr.h" />
|
||||
<ClInclude Include="..\..\beast\stl\thread.h" />
|
||||
<ClInclude Include="..\..\beast\stl\unique_ptr.h" />
|
||||
<ClInclude Include="..\..\beast\Strings.h" />
|
||||
<ClInclude Include="..\..\beast\strings\CharacterFunctions.h" />
|
||||
<ClInclude Include="..\..\beast\strings\CharPointer_ASCII.h" />
|
||||
@@ -185,6 +174,7 @@
|
||||
<ClInclude Include="..\..\beast\threads\detail\DispatchedHandler.h" />
|
||||
<ClInclude Include="..\..\beast\threads\LockGuard.h" />
|
||||
<ClInclude Include="..\..\beast\threads\RecursiveMutex.h" />
|
||||
<ClInclude Include="..\..\beast\threads\semaphore.h" />
|
||||
<ClInclude Include="..\..\beast\threads\ServiceQueue.h" />
|
||||
<ClInclude Include="..\..\beast\threads\SharedData.h" />
|
||||
<ClInclude Include="..\..\beast\threads\SharedLockGuard.h" />
|
||||
@@ -265,19 +255,15 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\PeerTest.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\TestPeerType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\AbstractFifo.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\Array.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\ArrayAllocationBase.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicObject.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\ElementComparator.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\LinkedListPointer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\LockFreeQueue.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\NamedValueSet.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\OwnedArray.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\PropertySet.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SharedObjectArray.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\ScopedValueSetter.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SortedSet.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SparseSet.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\Variant.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h" />
|
||||
@@ -299,24 +285,16 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\logging\FileLogger.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\logging\Logger.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\BigInteger.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Expression.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Interval.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Math.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Random.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Range.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\uint24.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicCounter.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicFlag.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicPointer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicState.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\CacheLine.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\MemoryAlignment.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\MemoryBlock.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\OptionalScopedPointer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\RecycledObjectPool.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedFunction.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\WeakReference.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\misc\Main.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\misc\Result.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\misc\Uuid.h" />
|
||||
@@ -363,7 +341,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedWriteLock.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\DeadlineTimer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\Semaphore.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\Workers.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\detail\ScopedLock.h" />
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\detail\TrackedMutex.h" />
|
||||
@@ -391,14 +368,6 @@
|
||||
<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="..\..\modules\beast_crypto\beast_crypto.h" />
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\BinaryEncoding.h" />
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\UnsignedInteger.h" />
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\UnsignedIntegerCalc.h" />
|
||||
<ClInclude Include="..\..\modules\beast_db\beast_db.h" />
|
||||
<ClInclude Include="..\..\modules\beast_db\keyvalue\KeyvaDB.h" />
|
||||
<ClInclude Include="..\..\modules\beast_extras\beast_extras.h" />
|
||||
<ClInclude Include="..\..\modules\beast_extras\traits\BoostLockableTraits.h" />
|
||||
<ClInclude Include="..\..\modules\beast_sqdb\api\backend.h" />
|
||||
<ClInclude Include="..\..\modules\beast_sqdb\api\blob.h" />
|
||||
<ClInclude Include="..\..\modules\beast_sqdb\api\into.h" />
|
||||
@@ -446,6 +415,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\Crypto.cpp" />
|
||||
<ClCompile Include="..\..\beast\crypto\impl\BinaryEncoding.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\MurmurHash.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -476,6 +451,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\UnsignedInteger.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\http\HTTP.cpp" />
|
||||
<ClCompile Include="..\..\beast\http\impl\http_parser.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -814,12 +795,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -938,12 +913,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\maths\Expression.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\maths\Random.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -1244,12 +1213,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\thread\Semaphore.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\thread\Workers.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -1376,27 +1339,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_crypto\beast_crypto.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_crypto\math\BinaryEncoding.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_crypto\math\UnsignedInteger.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_db\beast_db.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_db\keyvalue\KeyvaDB.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_extras\beast_extras.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_sqdb\beast_sqdb.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_sqdb\source\blob.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -68,10 +68,10 @@
|
||||
<Filter>beast_core</Filter>
|
||||
</None>
|
||||
<None Include="..\..\beast\crypto\impl\sha2\README">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</None>
|
||||
<None Include="..\..\beast\crypto\impl\sha2\sha2test.pl">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</None>
|
||||
<None Include="..\..\scripts\compile.sh">
|
||||
<Filter>scripts</Filter>
|
||||
@@ -135,18 +135,6 @@
|
||||
<Filter Include="beast_core\diagnostic">
|
||||
<UniqueIdentifier>{69e28551-92ea-420b-a465-75ed248e3b59}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_crypto">
|
||||
<UniqueIdentifier>{62b1f8e3-79e4-46cc-b3fb-a12754aef249}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_crypto\math">
|
||||
<UniqueIdentifier>{1170f2bc-2456-410a-ab2b-c45f6ed37b9e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_db">
|
||||
<UniqueIdentifier>{4834218f-f13f-41bc-a8a0-50314a3a99a3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_db\keyvalue">
|
||||
<UniqueIdentifier>{15a98fee-1b52-45eb-9480-514b8750d755}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_sqlite">
|
||||
<UniqueIdentifier>{cbf5f5a3-5d66-4b6d-996d-20ed14b41793}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -195,12 +183,6 @@
|
||||
<Filter Include="beast_core\thread\impl">
|
||||
<UniqueIdentifier>{91538dcf-b219-4c80-9861-bb4949089775}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_extras">
|
||||
<UniqueIdentifier>{2f5b95a8-1adf-4319-8464-ddc2b2e03f0b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_extras\traits">
|
||||
<UniqueIdentifier>{bf498396-2e1f-4903-be68-3053ba439af5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\protocol">
|
||||
<UniqueIdentifier>{c0724499-ab69-40c3-90e2-65242dbd2eaa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -294,15 +276,6 @@
|
||||
<Filter Include="beast\asio\impl">
|
||||
<UniqueIdentifier>{30b0fdfb-02b6-47dd-bdd9-ffc1f57e1f2c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\http\crypto">
|
||||
<UniqueIdentifier>{9c1ef4c4-5623-4500-859f-12d6ce5ae362}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\http\crypto\impl">
|
||||
<UniqueIdentifier>{fc3d3f14-9ba1-43e4-b086-cbbd2f63b944}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\http\crypto\impl\sha2">
|
||||
<UniqueIdentifier>{44489531-f44a-439a-a6ea-d32c252b1e8b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\smart_ptr\impl">
|
||||
<UniqueIdentifier>{df4f2935-13a1-4afe-90cc-d86472ec2466}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -315,14 +288,20 @@
|
||||
<Filter Include="beast\insight\impl">
|
||||
<UniqueIdentifier>{04f27818-7843-4ef3-967c-1761dc892342}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\crypto">
|
||||
<UniqueIdentifier>{9c1ef4c4-5623-4500-859f-12d6ce5ae362}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\crypto\impl">
|
||||
<UniqueIdentifier>{fc3d3f14-9ba1-43e4-b086-cbbd2f63b944}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\crypto\impl\sha2">
|
||||
<UniqueIdentifier>{44489531-f44a-439a-a6ea-d32c252b1e8b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||
<Filter>beast_core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\AbstractFifo.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\Array.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
@@ -350,9 +329,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\ScopedValueSetter.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SortedSet.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SparseSet.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
@@ -392,9 +368,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\BigInteger.h">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Expression.h">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Random.h">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClInclude>
|
||||
@@ -407,9 +380,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\OptionalScopedPointer.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\WeakReference.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\misc\Result.h">
|
||||
<Filter>beast_core\misc</Filter>
|
||||
</ClInclude>
|
||||
@@ -575,21 +545,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\MemoryAlignment.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicCounter.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicFlag.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicPointer.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\AtomicState.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\LockFreeQueue.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h">
|
||||
<Filter>beast_core\threads</Filter>
|
||||
</ClInclude>
|
||||
@@ -599,33 +554,15 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\Throw.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\maths\Interval.h">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\UnitTest.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_crypto\beast_crypto.h">
|
||||
<Filter>beast_crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\containers\SharedObjectArray.h">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\files\RandomAccessFile.h">
|
||||
<Filter>beast_core\files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\UnitTestUtilities.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\RecycledObjectPool.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_db\beast_db.h">
|
||||
<Filter>beast_db</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_db\keyvalue\KeyvaDB.h">
|
||||
<Filter>beast_db\keyvalue</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_sqlite\beast_sqlite.h">
|
||||
<Filter>beast_sqlite</Filter>
|
||||
</ClInclude>
|
||||
@@ -731,9 +668,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\DeadlineTimer.h">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\Semaphore.h">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\thread\Workers.h">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClInclude>
|
||||
@@ -752,12 +686,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\BoostIncludes.h">
|
||||
<Filter>beast_asio\system</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_extras\traits\BoostLockableTraits.h">
|
||||
<Filter>beast_extras\traits</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_extras\beast_extras.h">
|
||||
<Filter>beast_extras</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\system\BeforeBoost.h">
|
||||
<Filter>beast_core\system</Filter>
|
||||
</ClInclude>
|
||||
@@ -776,30 +704,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\system\SystemStats.h">
|
||||
<Filter>beast_core\system</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\intrusive\ForwardList.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\intrusive\PointerTraits.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveConst.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveConstVolatile.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveReference.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\RemoveVolatile.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\AddConst.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\PointerToOther.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\ComposedAsyncOperation.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
@@ -914,9 +818,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParserImpl.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\IfCond.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\BuffersType.h">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClInclude>
|
||||
@@ -932,15 +833,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\UnsignedInteger.h">
|
||||
<Filter>beast_crypto\math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\UnsignedIntegerCalc.h">
|
||||
<Filter>beast_crypto\math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_crypto\math\BinaryEncoding.h">
|
||||
<Filter>beast_crypto\math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\SharedFunction.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
@@ -1004,12 +896,6 @@
|
||||
<ClInclude Include="..\..\beast\intrusive\LockFreeStack.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\intrusive\List.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\mpl\CopyConst.h">
|
||||
<Filter>beast\mpl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\http\impl\http-parser\http_parser.h">
|
||||
<Filter>beast\http\impl\http-parser</Filter>
|
||||
</ClInclude>
|
||||
@@ -1091,17 +977,14 @@
|
||||
<ClInclude Include="..\..\beast\FixedArray.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\intrusive\IntrusiveArray.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\Crypto.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\impl\sha2\sha2.h">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\Sha256.h">
|
||||
<Filter>beast\http\crypto</Filter>
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\WrapHandler.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
@@ -1273,23 +1156,14 @@
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\MurmurHash.h">
|
||||
<Filter>beast\http\crypto</Filter>
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h">
|
||||
<Filter>beast\smart_ptr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\stl\function.h">
|
||||
<Filter>beast\stl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\stl\shared_ptr.h">
|
||||
<Filter>beast\stl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\stl\thread.h">
|
||||
<Filter>beast\stl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\stl\unique_ptr.h">
|
||||
<Filter>beast\stl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\STL.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
@@ -1338,11 +1212,23 @@
|
||||
<ClInclude Include="..\..\beast\cyclic_iterator.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\threads\semaphore.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\intrusive\List.h">
|
||||
<Filter>beast\intrusive</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\BinaryEncoding.h">
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\UnsignedInteger.h">
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\beast\crypto\UnsignedIntegerCalc.h">
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
|
||||
<Filter>beast_core\containers</Filter>
|
||||
</ClCompile>
|
||||
@@ -1385,9 +1271,6 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\maths\BigInteger.cpp">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\maths\Expression.cpp">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\maths\Random.cpp">
|
||||
<Filter>beast_core\maths</Filter>
|
||||
</ClCompile>
|
||||
@@ -1589,12 +1472,6 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\UnitTestUtilities.cpp">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_db\beast_db.cpp">
|
||||
<Filter>beast_db</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_db\keyvalue\KeyvaDB.cpp">
|
||||
<Filter>beast_db\keyvalue</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_sqlite\beast_sqlite.c">
|
||||
<Filter>beast_sqlite</Filter>
|
||||
</ClCompile>
|
||||
@@ -1652,9 +1529,6 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\thread\DeadlineTimer.cpp">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\thread\Semaphore.cpp">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\thread\Workers.cpp">
|
||||
<Filter>beast_core\thread</Filter>
|
||||
</ClCompile>
|
||||
@@ -1733,9 +1607,6 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPParser.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_crypto\beast_crypto.cpp">
|
||||
<Filter>beast_crypto</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
<Filter>beast_core</Filter>
|
||||
</ClCompile>
|
||||
@@ -1751,15 +1622,6 @@
|
||||
<ClCompile Include="..\..\modules\beast_core\diagnostic\FatalError.cpp">
|
||||
<Filter>beast_core\diagnostic</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_crypto\math\UnsignedInteger.cpp">
|
||||
<Filter>beast_crypto\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_crypto\math\BinaryEncoding.cpp">
|
||||
<Filter>beast_crypto\math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_extras\beast_extras.cpp">
|
||||
<Filter>beast_extras</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\net\Net.cpp">
|
||||
<Filter>beast\net</Filter>
|
||||
</ClCompile>
|
||||
@@ -1806,19 +1668,19 @@
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2.c">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2prog.c">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2speed.c">
|
||||
<Filter>beast\http\crypto\impl\sha2</Filter>
|
||||
<Filter>beast\crypto\impl\sha2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\Crypto.cpp">
|
||||
<Filter>beast\http\crypto</Filter>
|
||||
<Filter>beast\crypto</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\Sha256.cpp">
|
||||
<Filter>beast\http\crypto\impl</Filter>
|
||||
<Filter>beast\crypto\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\chrono\impl\RelativeTime.cpp">
|
||||
<Filter>beast\chrono\impl</Filter>
|
||||
@@ -1890,7 +1752,7 @@
|
||||
<Filter>beast\asio\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\MurmurHash.cpp">
|
||||
<Filter>beast\http\crypto\impl</Filter>
|
||||
<Filter>beast\crypto\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\smart_ptr\impl\AbstractObject.cpp">
|
||||
<Filter>beast\smart_ptr\impl</Filter>
|
||||
@@ -1916,6 +1778,12 @@
|
||||
<ClCompile Include="..\..\beast\insight\impl\Hook.cpp">
|
||||
<Filter>beast\insight\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\BinaryEncoding.cpp">
|
||||
<Filter>beast\crypto\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\beast\crypto\impl\UnsignedInteger.cpp">
|
||||
<Filter>beast\crypto\impl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\TODO.txt">
|
||||
|
||||
2
TODO.txt
2
TODO.txt
@@ -52,8 +52,6 @@ BEAST TODO
|
||||
|
||||
- Rename include guards to boost style, e.g. BEAST_THROW_H_INCLUDED
|
||||
|
||||
- Decide if we should get rid of AtomicCounter, AtomicFlag, AtomicPointer, AtomicState
|
||||
|
||||
- Clean up CacheLine, StaticObject
|
||||
|
||||
- Clean up ConcurrentObject
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
#ifndef BEAST_CRYPTO_H_INCLUDED
|
||||
#define BEAST_CRYPTO_H_INCLUDED
|
||||
|
||||
#include "crypto/BinaryEncoding.h"
|
||||
#include "crypto/MurmurHash.h"
|
||||
#include "crypto/Sha256.h"
|
||||
#include "crypto/UnsignedInteger.h"
|
||||
#include "crypto/UnsignedIntegerCalc.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -139,7 +139,8 @@ bool operator!= (FixedArray <T, N> const& lhs, FixedArray <T, N> const& rhs)
|
||||
template <class T, std::size_t N>
|
||||
bool operator< (FixedArray <T, N> const& lhs, FixedArray <T, N> const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare (lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
return std::lexicographical_compare (
|
||||
lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#ifndef BEAST_INTRUSIVE_H_INCLUDED
|
||||
#define BEAST_INTRUSIVE_H_INCLUDED
|
||||
|
||||
#include "intrusive/ForwardList.h"
|
||||
#include "intrusive/IntrusiveArray.h"
|
||||
#include "intrusive/List.h"
|
||||
#include "intrusive/LockFreeStack.h"
|
||||
|
||||
|
||||
@@ -20,14 +20,6 @@
|
||||
#ifndef BEAST_MPL_H_INCLUDED
|
||||
#define BEAST_MPL_H_INCLUDED
|
||||
|
||||
#include "mpl/AddConst.h"
|
||||
#include "mpl/CopyConst.h"
|
||||
#include "mpl/IfCond.h"
|
||||
#include "mpl/IsCallPossible.h"
|
||||
#include "mpl/PointerToOther.h"
|
||||
#include "mpl/RemoveConst.h"
|
||||
#include "mpl/RemoveConstVolatile.h"
|
||||
#include "mpl/RemoveReference.h"
|
||||
#include "mpl/RemoveVolatile.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
#ifndef BEAST_STL_H_INCLUDED
|
||||
#define BEAST_STL_H_INCLUDED
|
||||
|
||||
#include "stl/function.h"
|
||||
#include "stl/shared_ptr.h"
|
||||
#include "stl/thread.h"
|
||||
#include "stl/unique_ptr.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,4 +34,6 @@
|
||||
#include "threads/WaitableEvent.h"
|
||||
#include "threads/ScopedWrapperContext.h"
|
||||
|
||||
#include "threads/semaphore.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,5 +20,4 @@
|
||||
#ifndef BEAST_CRYPTO_BINARYENCODING_H_INCLUDED
|
||||
#define BEAST_CRYPTO_BINARYENCODING_H_INCLUDED
|
||||
|
||||
|
||||
#endif
|
||||
@@ -19,5 +19,9 @@
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "../../modules/beast_core/beast_core.h" // for UnitTest
|
||||
|
||||
#include "impl/BinaryEncoding.cpp"
|
||||
#include "impl/MurmurHash.cpp"
|
||||
#include "impl/Sha256.cpp"
|
||||
#include "impl/UnsignedInteger.cpp"
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||
#define BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||
|
||||
#include "../SafeBool.h"
|
||||
#include "UnsignedIntegerCalc.h"
|
||||
#include "MurmurHash.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Represents a set of bits of fixed size.
|
||||
|
||||
The data is stored in "canonical" format which is network (big endian)
|
||||
@@ -36,13 +45,13 @@ public:
|
||||
static std::size_t const size = Bytes;
|
||||
|
||||
// The underlying integer type we use when converting to calculation format.
|
||||
typedef uint32 IntCalcType;
|
||||
typedef std::uint32_t IntCalcType;
|
||||
|
||||
// The type of object resulting from a conversion to calculation format.
|
||||
typedef UnsignedIntegerCalc <IntCalcType> CalcType;
|
||||
|
||||
// Standard container compatibility
|
||||
typedef uint8 value_type;
|
||||
typedef std::uint8_t value_type;
|
||||
typedef value_type* iterator;
|
||||
typedef value_type const* const_iterator;
|
||||
|
||||
@@ -135,7 +144,8 @@ public:
|
||||
template <class UnsignedIntegralType>
|
||||
static UnsignedInteger createFromInteger (UnsignedIntegralType value)
|
||||
{
|
||||
static_bassert (Bytes >= sizeof (UnsignedIntegralType));
|
||||
static_assert (Bytes >= sizeof (UnsignedIntegralType),
|
||||
"Bytes is too small.");
|
||||
UnsignedInteger <Bytes> result;
|
||||
value = toNetworkByteOrder <UnsignedIntegralType> (value);
|
||||
result.clear ();
|
||||
@@ -296,4 +306,6 @@ private:
|
||||
IntCalcType m_values [CalcCount];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,22 +20,25 @@
|
||||
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
|
||||
#define BEAST_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename UInt>
|
||||
struct DoubleWidthUInt;
|
||||
|
||||
template <>
|
||||
struct DoubleWidthUInt <uint16>
|
||||
struct DoubleWidthUInt <std::uint16_t>
|
||||
{
|
||||
typedef uint32 type;
|
||||
typedef std::uint32_t type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DoubleWidthUInt <uint32>
|
||||
struct DoubleWidthUInt <std::uint32_t>
|
||||
{
|
||||
typedef uint64 type;
|
||||
typedef std::uint64_t type;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -427,4 +430,6 @@ private:
|
||||
UInt* m_values;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -17,6 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "../BinaryEncoding.h"
|
||||
#include "../UnsignedInteger.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Generic algorithms for base encoding and decoding. */
|
||||
class BinaryEncoding
|
||||
{
|
||||
@@ -393,3 +401,5 @@ public:
|
||||
};
|
||||
|
||||
static BinaryEncodingTests BinaryEncodingTests;
|
||||
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions are Copyright (c) 2013 the authors listed at the following URL,
|
||||
and/or the authors of referenced articles or incorporated external code:
|
||||
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?action=history&offset=20100923155004
|
||||
|
||||
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.
|
||||
@@ -17,7 +21,13 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#include "../UnsignedInteger.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace multiprecsion {
|
||||
|
||||
#if 0
|
||||
|
||||
/* Copyright (c) 2013 the authors listed at the following URL, and/or
|
||||
the authors of referenced articles or incorporated external code:
|
||||
@@ -41,15 +51,11 @@
|
||||
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.
|
||||
|
||||
Retrieved from: http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?oldid=16902
|
||||
*/
|
||||
|
||||
namespace multiprecsion
|
||||
{
|
||||
|
||||
#if 0
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Retrieved from: http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?oldid=16902
|
||||
//
|
||||
|
||||
typedef unsigned short component_t;
|
||||
typedef unsigned long double_component_t;
|
||||
@@ -394,3 +400,5 @@ private:
|
||||
};
|
||||
|
||||
static UnsignedIntegerTests unsignedIntegerTests;
|
||||
|
||||
}
|
||||
@@ -20,8 +20,7 @@
|
||||
#ifndef BEAST_INSIGHT_COLLECTOR_H_INCLUDED
|
||||
#define BEAST_INSIGHT_COLLECTOR_H_INCLUDED
|
||||
|
||||
#include "../stl/function.h"
|
||||
#include "../stl/shared_ptr.h"
|
||||
#include <string>
|
||||
|
||||
#include "Counter.h"
|
||||
#include "Event.h"
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef BEAST_INSIGHT_COUNTER_H_INCLUDED
|
||||
#define BEAST_INSIGHT_COUNTER_H_INCLUDED
|
||||
|
||||
#include "CounterImpl.h"
|
||||
#include <memory>
|
||||
|
||||
#include "../stl/shared_ptr.h"
|
||||
#include "CounterImpl.h"
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
factory function in the Collector interface.
|
||||
@see Collector.
|
||||
*/
|
||||
explicit Counter (shared_ptr <CounterImpl> const& impl)
|
||||
explicit Counter (std::shared_ptr <CounterImpl> const& impl)
|
||||
: m_impl (impl)
|
||||
{
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
shared_ptr <CounterImpl> m_impl;
|
||||
std::shared_ptr <CounterImpl> m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,16 +20,19 @@
|
||||
#ifndef BEAST_INSIGHT_COUNTERIMPL_H_INCLUDED
|
||||
#define BEAST_INSIGHT_COUNTERIMPL_H_INCLUDED
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
|
||||
class Counter;
|
||||
|
||||
class CounterImpl : public enable_shared_from_this <CounterImpl>
|
||||
class CounterImpl : public std::enable_shared_from_this <CounterImpl>
|
||||
{
|
||||
public:
|
||||
typedef int64 value_type;
|
||||
typedef beast::function <void (Counter const&)> HandlerType;
|
||||
typedef std::function <void (Counter const&)> HandlerType;
|
||||
|
||||
virtual ~CounterImpl () = 0;
|
||||
virtual void increment (value_type amount) = 0;
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef BEAST_INSIGHT_EVENT_H_INCLUDED
|
||||
#define BEAST_INSIGHT_EVENT_H_INCLUDED
|
||||
|
||||
#include "EventImpl.h"
|
||||
#include <memory>
|
||||
|
||||
#include "../stl/shared_ptr.h"
|
||||
#include "EventImpl.h"
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
factory function in the Collector interface.
|
||||
@see Collector.
|
||||
*/
|
||||
explicit Event (shared_ptr <EventImpl> const& impl)
|
||||
explicit Event (std::shared_ptr <EventImpl> const& impl)
|
||||
: m_impl (impl)
|
||||
{
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr <EventImpl> m_impl;
|
||||
std::shared_ptr <EventImpl> m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
#ifndef BEAST_INSIGHT_EVENTIMPL_H_INCLUDED
|
||||
#define BEAST_INSIGHT_EVENTIMPL_H_INCLUDED
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
|
||||
class Event;
|
||||
|
||||
class EventImpl : public enable_shared_from_this <EventImpl>
|
||||
class EventImpl : public std::enable_shared_from_this <EventImpl>
|
||||
{
|
||||
public:
|
||||
typedef uint64 value_type;
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef BEAST_INSIGHT_GAUGE_H_INCLUDED
|
||||
#define BEAST_INSIGHT_GAUGE_H_INCLUDED
|
||||
|
||||
#include "GaugeImpl.h"
|
||||
#include <memory>
|
||||
|
||||
#include "../stl/shared_ptr.h"
|
||||
#include "GaugeImpl.h"
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
factory function in the Collector interface.
|
||||
@see Collector.
|
||||
*/
|
||||
explicit Gauge (shared_ptr <GaugeImpl> const& impl)
|
||||
explicit Gauge (std::shared_ptr <GaugeImpl> const& impl)
|
||||
: m_impl (impl)
|
||||
{
|
||||
}
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
shared_ptr <GaugeImpl> m_impl;
|
||||
std::shared_ptr <GaugeImpl> m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace insight {
|
||||
|
||||
class Gauge;
|
||||
|
||||
class GaugeImpl : public enable_shared_from_this <GaugeImpl>
|
||||
class GaugeImpl : public std::enable_shared_from_this <GaugeImpl>
|
||||
{
|
||||
public:
|
||||
typedef uint64 value_type;
|
||||
typedef int64 difference_type;
|
||||
typedef beast::function <void (Gauge const&)> HandlerType;
|
||||
typedef std::function <void (Gauge const&)> HandlerType;
|
||||
|
||||
virtual ~GaugeImpl () = 0;
|
||||
virtual void set (value_type value) = 0;
|
||||
|
||||
@@ -42,13 +42,13 @@ public:
|
||||
factory function in the Collector interface.
|
||||
@see Collector.
|
||||
*/
|
||||
explicit Hook (shared_ptr <HookImpl> const& impl)
|
||||
explicit Hook (std::shared_ptr <HookImpl> const& impl)
|
||||
: m_impl (impl)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr <HookImpl> m_impl;
|
||||
std::shared_ptr <HookImpl> m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,16 +20,17 @@
|
||||
#ifndef BEAST_INSIGHT_HOOKIMPL_H_INCLUDED
|
||||
#define BEAST_INSIGHT_HOOKIMPL_H_INCLUDED
|
||||
|
||||
#include "../stl/shared_ptr.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
|
||||
class HookImpl : public enable_shared_from_this <HookImpl>
|
||||
class HookImpl : public std::enable_shared_from_this <HookImpl>
|
||||
{
|
||||
public:
|
||||
typedef beast::function <void (void)> HandlerType;
|
||||
|
||||
typedef std::function <void (void)> HandlerType;
|
||||
|
||||
virtual ~HookImpl () = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
factory function in the Collector interface.
|
||||
@see Collector.
|
||||
*/
|
||||
explicit Meter (shared_ptr <MeterImpl> const& impl)
|
||||
explicit Meter (std::shared_ptr <MeterImpl> const& impl)
|
||||
: m_impl (impl)
|
||||
{
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
shared_ptr <MeterImpl> m_impl;
|
||||
std::shared_ptr <MeterImpl> m_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,16 +20,19 @@
|
||||
#ifndef BEAST_INSIGHT_METERIMPL_H_INCLUDED
|
||||
#define BEAST_INSIGHT_METERIMPL_H_INCLUDED
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace insight {
|
||||
|
||||
class Meter;
|
||||
|
||||
class MeterImpl : public enable_shared_from_this <MeterImpl>
|
||||
class MeterImpl : public std::enable_shared_from_this <MeterImpl>
|
||||
{
|
||||
public:
|
||||
typedef uint64 value_type;
|
||||
typedef beast::function <void (Meter const&)> HandlerType;
|
||||
typedef std::function <void (Meter const&)> HandlerType;
|
||||
|
||||
virtual ~MeterImpl () = 0;
|
||||
virtual void increment (value_type amount) = 0;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace insight {
|
||||
class NullCollector : public Collector
|
||||
{
|
||||
public:
|
||||
static shared_ptr <Collector> New ();
|
||||
static std::shared_ptr <Collector> New ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
@param prefix A string pre-pended before each metric name.
|
||||
@param journal Destination for logging output.
|
||||
*/
|
||||
static shared_ptr <StatsDCollector> New (IPAddress const& address,
|
||||
static std::shared_ptr <StatsDCollector> New (IPAddress const& address,
|
||||
std::string const& prefix, Journal journal);
|
||||
};
|
||||
|
||||
|
||||
@@ -112,27 +112,27 @@ public:
|
||||
|
||||
Hook make_hook (HookImpl::HandlerType const&)
|
||||
{
|
||||
return Hook (make_shared <detail::NullHookImpl> ());
|
||||
return Hook (std::make_shared <detail::NullHookImpl> ());
|
||||
}
|
||||
|
||||
Counter make_counter (std::string const&)
|
||||
{
|
||||
return Counter (make_shared <detail::NullCounterImpl> ());
|
||||
return Counter (std::make_shared <detail::NullCounterImpl> ());
|
||||
}
|
||||
|
||||
Event make_event (std::string const&)
|
||||
{
|
||||
return Event (make_shared <detail::NullEventImpl> ());
|
||||
return Event (std::make_shared <detail::NullEventImpl> ());
|
||||
}
|
||||
|
||||
Gauge make_gauge (std::string const&)
|
||||
{
|
||||
return Gauge (make_shared <detail::NullGaugeImpl> ());
|
||||
return Gauge (std::make_shared <detail::NullGaugeImpl> ());
|
||||
}
|
||||
|
||||
Meter make_meter (std::string const&)
|
||||
{
|
||||
return Meter (make_shared <detail::NullMeterImpl> ());
|
||||
return Meter (std::make_shared <detail::NullMeterImpl> ());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,9 +140,9 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
shared_ptr <Collector> NullCollector::New ()
|
||||
std::shared_ptr <Collector> NullCollector::New ()
|
||||
{
|
||||
return beast::make_shared <detail::NullCollectorImp> ();
|
||||
return std::make_shared <detail::NullCollectorImp> ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#include <climits>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
@@ -57,7 +59,7 @@ class StatsDHookImpl
|
||||
public:
|
||||
StatsDHookImpl (
|
||||
HandlerType const& handler,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
|
||||
~StatsDHookImpl ();
|
||||
|
||||
@@ -66,7 +68,7 @@ public:
|
||||
private:
|
||||
StatsDHookImpl& operator= (StatsDHookImpl const&);
|
||||
|
||||
beast::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
HandlerType m_handler;
|
||||
};
|
||||
|
||||
@@ -78,7 +80,7 @@ class StatsDCounterImpl
|
||||
{
|
||||
public:
|
||||
StatsDCounterImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
|
||||
~StatsDCounterImpl ();
|
||||
|
||||
@@ -86,14 +88,13 @@ public:
|
||||
void set_handler (HandlerType const& handler);
|
||||
|
||||
void flush ();
|
||||
void do_increment (CounterImpl::value_type amount,
|
||||
shared_ptr <CounterImpl> const& ptr);
|
||||
void do_increment (CounterImpl::value_type amount);
|
||||
void do_process ();
|
||||
|
||||
private:
|
||||
StatsDCounterImpl& operator= (StatsDCounterImpl const&);
|
||||
|
||||
beast::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
CounterImpl::value_type m_value;
|
||||
bool m_dirty;
|
||||
@@ -107,20 +108,19 @@ class StatsDEventImpl
|
||||
{
|
||||
public:
|
||||
StatsDEventImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
|
||||
~StatsDEventImpl ();
|
||||
|
||||
void notify (EventImpl::value_type value);
|
||||
|
||||
void do_notify (EventImpl::value_type value,
|
||||
shared_ptr <EventImpl> const& ptr);
|
||||
void do_notify (EventImpl::value_type value);
|
||||
void do_process ();
|
||||
|
||||
private:
|
||||
StatsDEventImpl& operator= (StatsDEventImpl const&);
|
||||
|
||||
beast::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ class StatsDGaugeImpl
|
||||
{
|
||||
public:
|
||||
StatsDGaugeImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
|
||||
~StatsDGaugeImpl ();
|
||||
|
||||
@@ -141,16 +141,14 @@ public:
|
||||
void set_handler (HandlerType const& handler);
|
||||
|
||||
void flush ();
|
||||
void do_set (GaugeImpl::value_type value,
|
||||
shared_ptr <GaugeImpl> const& ptr);
|
||||
void do_increment (GaugeImpl::difference_type amount,
|
||||
shared_ptr <GaugeImpl> const& ptr);
|
||||
void do_set (GaugeImpl::value_type value);
|
||||
void do_increment (GaugeImpl::difference_type amount);
|
||||
void do_process ();
|
||||
|
||||
private:
|
||||
StatsDGaugeImpl& operator= (StatsDGaugeImpl const&);
|
||||
|
||||
beast::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
GaugeImpl::value_type m_last_value;
|
||||
GaugeImpl::value_type m_value;
|
||||
@@ -166,7 +164,7 @@ class StatsDMeterImpl
|
||||
{
|
||||
public:
|
||||
explicit StatsDMeterImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl);
|
||||
|
||||
~StatsDMeterImpl ();
|
||||
|
||||
@@ -174,14 +172,13 @@ public:
|
||||
void set_handler (HandlerType const& handler);
|
||||
|
||||
void flush ();
|
||||
void do_increment (MeterImpl::value_type amount,
|
||||
shared_ptr <MeterImpl> const& ptr);
|
||||
void do_increment (MeterImpl::value_type amount);
|
||||
void do_process ();
|
||||
|
||||
private:
|
||||
StatsDMeterImpl& operator= (StatsDMeterImpl const&);
|
||||
|
||||
beast::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::shared_ptr <StatsDCollectorImp> m_impl;
|
||||
std::string m_name;
|
||||
MeterImpl::value_type m_value;
|
||||
bool m_dirty;
|
||||
@@ -192,7 +189,7 @@ private:
|
||||
|
||||
class StatsDCollectorImp
|
||||
: public StatsDCollector
|
||||
, public beast::enable_shared_from_this <StatsDCollectorImp>
|
||||
, public std::enable_shared_from_this <StatsDCollectorImp>
|
||||
{
|
||||
private:
|
||||
enum
|
||||
@@ -219,7 +216,7 @@ private:
|
||||
State m_state;
|
||||
|
||||
// Must come last for order of init
|
||||
beast::thread m_thread;
|
||||
std::thread m_thread;
|
||||
|
||||
static boost::asio::ip::udp::endpoint to_endpoint (
|
||||
IPAddress const &address)
|
||||
@@ -263,31 +260,31 @@ public:
|
||||
|
||||
Hook make_hook (HookImpl::HandlerType const& handler)
|
||||
{
|
||||
return Hook (beast::make_shared <detail::StatsDHookImpl> (
|
||||
return Hook (std::make_shared <detail::StatsDHookImpl> (
|
||||
handler, shared_from_this ()));
|
||||
}
|
||||
|
||||
Counter make_counter (std::string const& name)
|
||||
{
|
||||
return Counter (beast::make_shared <detail::StatsDCounterImpl> (
|
||||
return Counter (std::make_shared <detail::StatsDCounterImpl> (
|
||||
name, shared_from_this ()));
|
||||
}
|
||||
|
||||
Event make_event (std::string const& name)
|
||||
{
|
||||
return Event (beast::make_shared <detail::StatsDEventImpl> (
|
||||
return Event (std::make_shared <detail::StatsDEventImpl> (
|
||||
name, shared_from_this ()));
|
||||
}
|
||||
|
||||
Gauge make_gauge (std::string const& name)
|
||||
{
|
||||
return Gauge (beast::make_shared <detail::StatsDGaugeImpl> (
|
||||
return Gauge (std::make_shared <detail::StatsDGaugeImpl> (
|
||||
name, shared_from_this ()));
|
||||
}
|
||||
|
||||
Meter make_meter (std::string const& name)
|
||||
{
|
||||
return Meter (beast::make_shared <detail::StatsDMeterImpl> (
|
||||
return Meter (std::make_shared <detail::StatsDMeterImpl> (
|
||||
name, shared_from_this ()));
|
||||
}
|
||||
|
||||
@@ -327,9 +324,9 @@ public:
|
||||
|
||||
void post_buffer (std::string&& buffer)
|
||||
{
|
||||
m_io_service.dispatch (boost::bind (
|
||||
m_io_service.dispatch (std::bind (
|
||||
&StatsDCollectorImp::do_post_buffer, this,
|
||||
boost::move (buffer)));
|
||||
std::move (buffer)));
|
||||
}
|
||||
|
||||
void on_send (boost::system::error_code ec, std::size_t)
|
||||
@@ -443,7 +440,7 @@ public:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StatsDHookImpl::StatsDHookImpl (HandlerType const& handler,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
: m_impl (impl)
|
||||
, m_handler (handler)
|
||||
{
|
||||
@@ -463,7 +460,7 @@ void StatsDHookImpl::do_process ()
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StatsDCounterImpl::StatsDCounterImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
: m_impl (impl)
|
||||
, m_name (name)
|
||||
, m_value (0)
|
||||
@@ -479,8 +476,10 @@ StatsDCounterImpl::~StatsDCounterImpl ()
|
||||
|
||||
void StatsDCounterImpl::increment (CounterImpl::value_type amount)
|
||||
{
|
||||
m_impl->get_io_service().dispatch (boost::bind (
|
||||
&StatsDCounterImpl::do_increment, this, amount, shared_from_this()));
|
||||
m_impl->get_io_service().dispatch (std::bind (
|
||||
&StatsDCounterImpl::do_increment,
|
||||
std::static_pointer_cast <StatsDCounterImpl> (
|
||||
shared_from_this ()), amount));
|
||||
}
|
||||
|
||||
void StatsDCounterImpl::set_handler (HandlerType const& handler)
|
||||
@@ -504,8 +503,7 @@ void StatsDCounterImpl::flush ()
|
||||
}
|
||||
}
|
||||
|
||||
void StatsDCounterImpl::do_increment (CounterImpl::value_type amount,
|
||||
shared_ptr <CounterImpl> const&)
|
||||
void StatsDCounterImpl::do_increment (CounterImpl::value_type amount)
|
||||
{
|
||||
m_value += amount;
|
||||
m_dirty = true;
|
||||
@@ -521,7 +519,7 @@ void StatsDCounterImpl::do_process ()
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StatsDEventImpl::StatsDEventImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
: m_impl (impl)
|
||||
, m_name (name)
|
||||
{
|
||||
@@ -533,12 +531,13 @@ StatsDEventImpl::~StatsDEventImpl ()
|
||||
|
||||
void StatsDEventImpl::notify (EventImpl::value_type value)
|
||||
{
|
||||
m_impl->get_io_service().dispatch (boost::bind (
|
||||
&StatsDEventImpl::do_notify, this, value, shared_from_this()));
|
||||
m_impl->get_io_service().dispatch (std::bind (
|
||||
&StatsDEventImpl::do_notify,
|
||||
std::static_pointer_cast <StatsDEventImpl> (
|
||||
shared_from_this ()), value));
|
||||
}
|
||||
|
||||
void StatsDEventImpl::do_notify (EventImpl::value_type value,
|
||||
shared_ptr <EventImpl> const&)
|
||||
void StatsDEventImpl::do_notify (EventImpl::value_type value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
@@ -552,7 +551,7 @@ void StatsDEventImpl::do_notify (EventImpl::value_type value,
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StatsDGaugeImpl::StatsDGaugeImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
: m_impl (impl)
|
||||
, m_name (name)
|
||||
, m_last_value (0)
|
||||
@@ -569,14 +568,18 @@ StatsDGaugeImpl::~StatsDGaugeImpl ()
|
||||
|
||||
void StatsDGaugeImpl::set (GaugeImpl::value_type value)
|
||||
{
|
||||
m_impl->get_io_service().dispatch (boost::bind (
|
||||
&StatsDGaugeImpl::do_set, this, value, shared_from_this ()));
|
||||
m_impl->get_io_service().dispatch (std::bind (
|
||||
&StatsDGaugeImpl::do_set,
|
||||
std::static_pointer_cast <StatsDGaugeImpl> (
|
||||
shared_from_this ()), value));
|
||||
}
|
||||
|
||||
void StatsDGaugeImpl::increment (GaugeImpl::difference_type amount)
|
||||
{
|
||||
m_impl->get_io_service().dispatch (boost::bind (
|
||||
&StatsDGaugeImpl::do_increment, this, amount, shared_from_this()));
|
||||
m_impl->get_io_service().dispatch (std::bind (
|
||||
&StatsDGaugeImpl::do_increment,
|
||||
std::static_pointer_cast <StatsDGaugeImpl> (
|
||||
shared_from_this ()), amount));
|
||||
}
|
||||
|
||||
void StatsDGaugeImpl::set_handler (HandlerType const& handler)
|
||||
@@ -599,8 +602,7 @@ void StatsDGaugeImpl::flush ()
|
||||
}
|
||||
}
|
||||
|
||||
void StatsDGaugeImpl::do_set (GaugeImpl::value_type value,
|
||||
shared_ptr <GaugeImpl> const&)
|
||||
void StatsDGaugeImpl::do_set (GaugeImpl::value_type value)
|
||||
{
|
||||
m_value = value;
|
||||
|
||||
@@ -611,8 +613,7 @@ void StatsDGaugeImpl::do_set (GaugeImpl::value_type value,
|
||||
}
|
||||
}
|
||||
|
||||
void StatsDGaugeImpl::do_increment (GaugeImpl::difference_type amount,
|
||||
shared_ptr <GaugeImpl> const& ptr)
|
||||
void StatsDGaugeImpl::do_increment (GaugeImpl::difference_type amount)
|
||||
{
|
||||
GaugeImpl::value_type value (m_value);
|
||||
|
||||
@@ -631,7 +632,7 @@ void StatsDGaugeImpl::do_increment (GaugeImpl::difference_type amount,
|
||||
: std::abs (amount);
|
||||
}
|
||||
|
||||
do_set (value, ptr);
|
||||
do_set (value);
|
||||
}
|
||||
|
||||
void StatsDGaugeImpl::do_process ()
|
||||
@@ -644,7 +645,7 @@ void StatsDGaugeImpl::do_process ()
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StatsDMeterImpl::StatsDMeterImpl (std::string const& name,
|
||||
beast::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
std::shared_ptr <StatsDCollectorImp> const& impl)
|
||||
: m_impl (impl)
|
||||
, m_name (name)
|
||||
, m_value (0)
|
||||
@@ -660,8 +661,10 @@ StatsDMeterImpl::~StatsDMeterImpl ()
|
||||
|
||||
void StatsDMeterImpl::increment (MeterImpl::value_type amount)
|
||||
{
|
||||
m_impl->get_io_service().dispatch (boost::bind (
|
||||
&StatsDMeterImpl::do_increment, this, amount, shared_from_this()));
|
||||
m_impl->get_io_service().dispatch (std::bind (
|
||||
&StatsDMeterImpl::do_increment,
|
||||
std::static_pointer_cast <StatsDMeterImpl> (
|
||||
shared_from_this ()), amount));
|
||||
}
|
||||
|
||||
void StatsDMeterImpl::set_handler (HandlerType const& handler)
|
||||
@@ -685,8 +688,7 @@ void StatsDMeterImpl::flush ()
|
||||
}
|
||||
}
|
||||
|
||||
void StatsDMeterImpl::do_increment (MeterImpl::value_type amount,
|
||||
shared_ptr <MeterImpl> const&)
|
||||
void StatsDMeterImpl::do_increment (MeterImpl::value_type amount)
|
||||
{
|
||||
m_value += amount;
|
||||
m_dirty = true;
|
||||
@@ -703,10 +705,10 @@ void StatsDMeterImpl::do_process ()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
shared_ptr <StatsDCollector> StatsDCollector::New (
|
||||
std::shared_ptr <StatsDCollector> StatsDCollector::New (
|
||||
IPAddress const& address, std::string const& prefix, Journal journal)
|
||||
{
|
||||
return beast::make_shared <detail::StatsDCollectorImp> (
|
||||
return std::make_shared <detail::StatsDCollectorImp> (
|
||||
address, prefix, journal);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,448 +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_INTRUSIVE_FORWARDLIST_H_INCLUDED
|
||||
#define BEAST_INTRUSIVE_FORWARDLIST_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
#include "PointerTraits.h"
|
||||
|
||||
#include "../MPL.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
namespace beast {
|
||||
namespace intrusive {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Holds the size field
|
||||
struct SizeHolder
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
inline size_type size () const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline void set (size_type new_size) noexcept
|
||||
{
|
||||
m_size = new_size;
|
||||
}
|
||||
|
||||
inline void increment () noexcept
|
||||
{
|
||||
++m_size;
|
||||
}
|
||||
|
||||
inline void decrement () noexcept
|
||||
{
|
||||
--m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
size_type m_size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class VoidPointer>
|
||||
struct ForwardListNode
|
||||
{
|
||||
typedef typename PointerTraits <VoidPointer>::template rebind_pointer <ForwardListNode>::type node_ptr;
|
||||
|
||||
node_ptr next;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Provides value_traits for when T derives from Node
|
||||
template <class T, class NodeTraits>
|
||||
struct DerivedValueTraits
|
||||
{
|
||||
typedef NodeTraits node_traits;
|
||||
typedef T value_type;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename mpl::PointerToOther <node_ptr, T>::type pointer;
|
||||
typedef typename mpl::PointerToOther <node_ptr, const T>::type const_pointer;
|
||||
typedef typename PointerTraits <pointer>::reference reference;
|
||||
typedef typename PointerTraits <const_pointer>::reference const_reference;
|
||||
|
||||
static node_ptr to_node_ptr (reference value)
|
||||
{
|
||||
return node_ptr (&value);
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr (const_reference value)
|
||||
{
|
||||
return node_ptr (&value);
|
||||
}
|
||||
|
||||
static pointer to_value_ptr (node_ptr const& n)
|
||||
{
|
||||
return pointer (&static_cast <value_type&> (*n));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr (const_node_ptr const &n)
|
||||
{
|
||||
return const_pointer (&static_cast <value_type const&> (*n));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class VoidPointer, typename Tag>
|
||||
struct ForwardListNodeTraits
|
||||
{
|
||||
typedef ForwardListNode <VoidPointer> node;
|
||||
|
||||
typedef typename PointerTraits <VoidPointer>::
|
||||
template rebind_pointer <node> node_ptr;
|
||||
|
||||
typedef typename PointerTraits <VoidPointer>::
|
||||
template rebind_pointer <node const> const_node_ptr;
|
||||
|
||||
static node_ptr get_next (const_node_ptr const& n)
|
||||
{
|
||||
return n->m_next;
|
||||
}
|
||||
|
||||
static node_ptr get_next (node_ptr const& n)
|
||||
{
|
||||
return n->m_next;
|
||||
}
|
||||
|
||||
static void set_next (node_ptr const& n, node_ptr const& next)
|
||||
{
|
||||
n->m_next = next;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Container, bool IsConst>
|
||||
class ForwardListIterator
|
||||
: public std::iterator <
|
||||
std::forward_iterator_tag,
|
||||
typename Container::value_type,
|
||||
typename Container::difference_type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type>
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::value_traits value_traits;
|
||||
typedef typename Container::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename PointerTraits <node_ptr>::
|
||||
template rebind_pointer <void>::type void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type pointer;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type reference;
|
||||
|
||||
ForwardListIterator ()
|
||||
: m_node ()
|
||||
{
|
||||
}
|
||||
|
||||
explicit ForwardListIterator (ForwardListIterator <Container, false> const& other)
|
||||
: m_node (other.pointed_node ())
|
||||
{
|
||||
}
|
||||
|
||||
node_ptr const& pointed_node () const noexcept
|
||||
{
|
||||
return m_node;
|
||||
}
|
||||
|
||||
ForwardListIterator& operator= (node_ptr const& node)
|
||||
{
|
||||
m_node = node;
|
||||
return static_cast <ForwardListIterator&> (*this);
|
||||
}
|
||||
|
||||
ForwardListIterator& operator++ ()
|
||||
{
|
||||
m_node = node_traits::get_next (m_node);
|
||||
return static_cast <ForwardListIterator&> (*this);
|
||||
}
|
||||
|
||||
ForwardListIterator operator++ (int)
|
||||
{
|
||||
ForwardListIterator result (*this);
|
||||
m_node = node_traits::get_next (m_node);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (ForwardListIterator const& lhs,
|
||||
ForwardListIterator const& rhs)
|
||||
{
|
||||
return lhs.m_node == rhs.m_node;
|
||||
}
|
||||
|
||||
friend bool operator!= (ForwardListIterator const& lhs,
|
||||
ForwardListIterator const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
reference operator* () const
|
||||
{
|
||||
return *this->operator-> ();
|
||||
}
|
||||
|
||||
pointer operator-> () const
|
||||
{
|
||||
return value_traits::to_value_ptr (m_node);
|
||||
}
|
||||
|
||||
private:
|
||||
node_ptr m_node;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class NodeTraits>
|
||||
class ForwardListAlgorithms
|
||||
{
|
||||
public:
|
||||
typedef typename NodeTraits::node node;
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
typedef typename NodeTraits::const_node_ptr const_node_ptr;
|
||||
typedef NodeTraits node_traits;
|
||||
|
||||
static void init (node_ptr const& n)
|
||||
{
|
||||
NodeTraits::set_next (n, node_ptr());
|
||||
}
|
||||
|
||||
static bool unique (const_node_ptr const& this_node)
|
||||
{
|
||||
node_ptr next = NodeTraits::get_next (this_node);
|
||||
return !next || next == this_node;
|
||||
}
|
||||
|
||||
static void link_after (node_ptr const& prev_node, node_ptr const& this_node)
|
||||
{
|
||||
NodeTraits::set_next (this_node, NodeTraits::get_next (prev_node));
|
||||
NodeTraits::set_next (prev_node, this_node);
|
||||
}
|
||||
|
||||
static void unlink_after (node_ptr const& prev_node)
|
||||
{
|
||||
const_node_ptr this_node (NodeTraits::get_next (prev_node));
|
||||
NodeTraits::set_next (prev_node, NodeTraits::get_next (this_node));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Singly-linked intrusive list. */
|
||||
template <typename T, typename Tag = void>
|
||||
class ForwardList
|
||||
{
|
||||
public:
|
||||
typedef DerivedValueTraits <T, ForwardListNodeTraits <T, Tag> >
|
||||
value_traits;
|
||||
typedef typename value_traits::pointer pointer;
|
||||
typedef typename value_traits::const_pointer const_pointer;
|
||||
typedef typename PointerTraits <pointer>::element_type value_type;
|
||||
typedef typename PointerTraits <pointer>::reference reference;
|
||||
typedef typename PointerTraits <pointer>::const_reference const_reference;
|
||||
typedef typename PointerTraits <pointer>::difference_type difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef ForwardListIterator <ForwardList, false> iterator;
|
||||
typedef ForwardListIterator <ForwardList, true> const_iterator;
|
||||
typedef typename value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef ForwardListAlgorithms <node_traits> node_algorithms;
|
||||
|
||||
typedef node Node;
|
||||
|
||||
private:
|
||||
typedef detail::SizeHolder size_traits;
|
||||
|
||||
void default_construct ()
|
||||
{
|
||||
get_size_traits ().set (size_type (0));
|
||||
node_algorithms::init (this->get_root_node ());
|
||||
}
|
||||
|
||||
node_ptr get_end_node ()
|
||||
{
|
||||
return node_ptr ();
|
||||
}
|
||||
|
||||
const_node_ptr get_end_node () const
|
||||
{
|
||||
return const_node_ptr ();
|
||||
}
|
||||
|
||||
node_ptr get_root_node ()
|
||||
{
|
||||
return PointerTraits <node_ptr>::pointer_to (m_root);
|
||||
}
|
||||
|
||||
const_node_ptr get_root_node () const
|
||||
{
|
||||
return PointerTraits <const_node_ptr>::pointer_to (m_root);
|
||||
}
|
||||
|
||||
size_traits& get_size_traits () noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_traits const& get_size_traits () const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
static node_ptr uncast (const_node_ptr const& ptr)
|
||||
{
|
||||
return PointerTraits <node_ptr>::const_cast_from (ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
ForwardList ()
|
||||
{
|
||||
default_construct ();
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
default_construct ();
|
||||
}
|
||||
|
||||
void push_front (reference value)
|
||||
{
|
||||
node_ptr this_node (value_traits::to_node_ptr (value));
|
||||
node_algorithms::link_after (this->get_root_node (), this_node);
|
||||
this->get_size_traits ().increment ();
|
||||
}
|
||||
|
||||
void pop_front ()
|
||||
{
|
||||
//node_ptr this_node (node_traits::get_next (this->get_root ()));
|
||||
node_algorithms::unlink_after (this->get_root_node ());
|
||||
this->get_size_traits ().decrement ();
|
||||
}
|
||||
|
||||
reference front ()
|
||||
{
|
||||
return *value_traits::to_value_ptr (node_traits::get_next (this->get_root_node ()));
|
||||
}
|
||||
|
||||
const_reference front () const
|
||||
{
|
||||
return *value_traits::to_value_ptr (uncat (node_traits::get_next (this->get_root_node ())));
|
||||
}
|
||||
|
||||
iterator begin ()
|
||||
{
|
||||
return iterator (node_traits::get_next (this->get_root_node (), this));
|
||||
}
|
||||
|
||||
const_iterator begin () const
|
||||
{
|
||||
return const_iterator (node_traits::get_next (this->get_root_node (), this));
|
||||
}
|
||||
|
||||
const_iterator cbegin () const
|
||||
{
|
||||
return this->begin ();
|
||||
}
|
||||
|
||||
iterator end ()
|
||||
{
|
||||
return iterator (this->get_end_node (), this);
|
||||
}
|
||||
|
||||
const_iterator end () const
|
||||
{
|
||||
return const_iterator (this->get_end_node (), this);
|
||||
}
|
||||
|
||||
const_iterator cend () const
|
||||
{
|
||||
return this->end ();
|
||||
}
|
||||
|
||||
iterator before_begin ()
|
||||
{
|
||||
return iterator (this->get_root_node (), this);
|
||||
}
|
||||
|
||||
const_iterator before_begin () const
|
||||
{
|
||||
return const_iterator (this->get_root_node (), this);
|
||||
}
|
||||
|
||||
const_iterator cbefore_begin () const
|
||||
{
|
||||
return before_begin ();
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return node_algorithms::unique (this->get_root_node ());
|
||||
}
|
||||
|
||||
iterator iterator_to (reference value)
|
||||
{
|
||||
return iterator (value_traits::to_node_ptr (value), this);
|
||||
}
|
||||
|
||||
const_iterator iterator_to (const_reference value) const
|
||||
{
|
||||
return const_iterator (value_traits::to_node_ptr (const_cast <reference> (value)), this);
|
||||
}
|
||||
|
||||
private:
|
||||
node m_root;
|
||||
size_traits m_size;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#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_INTRUSIVE_INTRUSIVEARRAY_H_INCLUDED
|
||||
#define BEAST_INTRUSIVE_INTRUSIVEARRAY_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A run-time fixed size array that references outside storage.
|
||||
The interface tries to follow std::vector as closely as possible within
|
||||
the limitations of a fixed size and unowned storage.
|
||||
*/
|
||||
template <class T>
|
||||
class IntrusiveArray
|
||||
{
|
||||
private:
|
||||
T* m_begin;
|
||||
T* m_end;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
// Calling methods on a default constructed
|
||||
// array results in undefined behavior!
|
||||
//
|
||||
IntrusiveArray ()
|
||||
: m_begin (nullptr), m_end (nullptr)
|
||||
{ }
|
||||
IntrusiveArray (T* begin, T* end)
|
||||
: m_begin (begin), m_end (end)
|
||||
{ }
|
||||
IntrusiveArray (IntrusiveArray const& other)
|
||||
: m_begin (other.m_begin), m_end (other.m_end)
|
||||
{ }
|
||||
IntrusiveArray (std::vector <T> const& v)
|
||||
: m_begin (&v.front()), m_end (&v.back()+1)
|
||||
{ }
|
||||
IntrusiveArray (std::vector <T>& v)
|
||||
: m_begin (&v.front()), m_end (&v.back()+1)
|
||||
{ }
|
||||
IntrusiveArray& operator= (IntrusiveArray const& other)
|
||||
{
|
||||
m_begin = other.m_begin;
|
||||
m_end = other.m_end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// iterators
|
||||
iterator begin() { return m_begin; }
|
||||
const_iterator begin() const { return m_begin; }
|
||||
const_iterator cbegin() const { return m_begin; }
|
||||
iterator end() { return m_end; }
|
||||
const_iterator end() const { return m_end; }
|
||||
const_iterator cend() const { return m_end; }
|
||||
|
||||
typedef std::reverse_iterator <iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
reference operator[](size_type i)
|
||||
{
|
||||
bassert (i < size());
|
||||
return m_begin[i];
|
||||
}
|
||||
|
||||
const_reference operator[](size_type i) const
|
||||
{
|
||||
bassert (i < size());
|
||||
return m_begin[i];
|
||||
}
|
||||
|
||||
reference at(size_type i) { rangecheck(i); return m_begin[i]; }
|
||||
const_reference at(size_type i) const { rangecheck(i); return m_begin[i]; }
|
||||
|
||||
reference front() { return m_begin[0]; }
|
||||
reference back() { return m_end[-1]; }
|
||||
const_reference front () const { return m_begin; }
|
||||
const_reference back() const { return m_end[-1]; }
|
||||
|
||||
size_type size() const { return std::distance (m_begin, m_end); }
|
||||
bool empty() const { return m_begin == m_end; }
|
||||
|
||||
T const* data() const { return m_begin; }
|
||||
T* data() { return m_begin; }
|
||||
T* c_array() { return m_begin; }
|
||||
|
||||
void assign (T const& value) { fill (value); }
|
||||
|
||||
void fill (T const& value)
|
||||
{
|
||||
std::fill_n (begin(), size(), value);
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
fill (T ());
|
||||
}
|
||||
|
||||
void rangecheck (size_type i)
|
||||
{
|
||||
if (i >= size())
|
||||
throw std::out_of_range ("IntrusiveArray<>: index out of range");
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
bool operator== (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
if ((lhs.begin() == rhs.begin()) && (lhs.end() == rhs.end()))
|
||||
return true;
|
||||
if (lhs.size() != rhs.size())
|
||||
return false;
|
||||
return std::equal (lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool operator!= (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
return !(lhs==rhs);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool operator< (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
if ((lhs.begin() == rhs.begin()) && (lhs.end() == rhs.end()))
|
||||
return false;
|
||||
return std::lexicographical_compare (lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool operator> (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
return rhs<lhs;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool operator<= (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
return !(rhs<lhs);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool operator>= (IntrusiveArray <T> const& lhs, IntrusiveArray <T> const& rhs)
|
||||
{
|
||||
return !(lhs<rhs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -21,20 +21,32 @@
|
||||
#define BEAST_INTRUSIVE_LIST_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
#include "../mpl/CopyConst.h"
|
||||
|
||||
#include "../Uncopyable.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <typename, typename>
|
||||
class List;
|
||||
|
||||
namespace detail
|
||||
namespace detail {
|
||||
|
||||
/** Copy `const` attribute from T to U if present. */
|
||||
/** @{ */
|
||||
template <typename T, typename U>
|
||||
struct CopyConst
|
||||
{
|
||||
typedef typename std::remove_const <U>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct CopyConst <T const, U>
|
||||
{
|
||||
typedef typename std::remove_const <U>::type const type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
// This is the intrusive portion of the doubly linked list.
|
||||
// One derivation per list that the object may appear on
|
||||
@@ -62,11 +74,11 @@ class ListIterator : public std::iterator <
|
||||
std::bidirectional_iterator_tag, std::size_t>
|
||||
{
|
||||
public:
|
||||
typedef typename mpl::CopyConst<N, typename N::value_type>::type
|
||||
value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef typename detail::CopyConst <
|
||||
N, typename N::value_type>::type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
ListIterator (N* node = nullptr) noexcept
|
||||
: m_node (node)
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#ifndef BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
|
||||
#define BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
#include "../mpl/IfCond.h"
|
||||
#include "../Atomic.h"
|
||||
#include "../Uncopyable.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -35,23 +36,24 @@ class LockFreeStackIterator
|
||||
std::forward_iterator_tag,
|
||||
typename Container::value_type,
|
||||
typename Container::difference_type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename std::conditional <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename std::conditional <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type>
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::Node Node;
|
||||
typedef typename mpl::IfCond <IsConst, Node const*, Node*>::type NodePtr;
|
||||
typedef typename std::conditional <
|
||||
IsConst, Node const*, Node*>::type NodePtr;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typedef typename std::conditional <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type pointer;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typedef typename std::conditional <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type reference;
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_INTRUSIVE_POINTERTRAITS_H_INCLUDED
|
||||
#define BEAST_INTRUSIVE_POINTERTRAITS_H_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace beast {
|
||||
namespace intrusive {
|
||||
|
||||
// an unspecialized PointerTraits is ill-defined
|
||||
template <typename P>
|
||||
struct PointerTraits;
|
||||
|
||||
// specializations to remove cv-qualifiers
|
||||
template <typename P>
|
||||
struct PointerTraits <P const> : PointerTraits <P> { };
|
||||
template <typename P>
|
||||
struct PointerTraits <P volatile> : PointerTraits <P> { };
|
||||
template <typename P>
|
||||
struct PointerTraits <P const volatile> : PointerTraits <P> { };
|
||||
// specialization to remove a reference attribute
|
||||
template <typename P>
|
||||
struct PointerTraits <P&> : PointerTraits <P> { };
|
||||
|
||||
// specialization for raw pointers
|
||||
template <typename T>
|
||||
struct PointerTraits <T*>
|
||||
{
|
||||
typedef T element_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template <class U>
|
||||
struct rebind_pointer
|
||||
{
|
||||
typedef U* type;
|
||||
};
|
||||
|
||||
static pointer pointer_to (reference r)
|
||||
{
|
||||
return static_cast <pointer> (
|
||||
static_cast <void*> (
|
||||
const_cast <char*> (
|
||||
&reinterpret_cast <const char&> (
|
||||
r))));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static pointer static_cast_from (U* u)
|
||||
{
|
||||
return static_cast <pointer> (u);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static pointer const_cast_from (U* u)
|
||||
{
|
||||
return const_cast <pointer> (u);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
static pointer dynamic_cast_from (U* u)
|
||||
{
|
||||
return dynamic_cast <pointer> (u);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MPL_ADDCONST_H_INCLUDED
|
||||
#define BEAST_MPL_ADDCONST_H_INCLUDED
|
||||
|
||||
#include "RemoveConst.h"
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
/** Add the `const` qualifier to a type. */
|
||||
template <typename T>
|
||||
struct AddConst
|
||||
{
|
||||
typedef typename RemoveConst<T>::type const type;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,46 +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_MPL_COPYCONST_H_INCLUDED
|
||||
#define BEAST_MPL_COPYCONST_H_INCLUDED
|
||||
|
||||
#include "RemoveConst.h"
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
/** Copy `const` attribute from T to U if present. */
|
||||
/** @{ */
|
||||
template <typename T, typename U>
|
||||
struct CopyConst
|
||||
{
|
||||
typedef typename RemoveConst<U>::type type;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct CopyConst <T const, U>
|
||||
{
|
||||
typedef typename RemoveConst<U>::type const type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,46 +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_MPL_IFCOND_H_INCLUDED
|
||||
#define BEAST_MPL_IFCOND_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
/** Select between T1 or T2 depending on Condition. */
|
||||
/** @{ */
|
||||
template <bool Condition, typename T1, typename T2>
|
||||
struct IfCond
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct IfCond <false, T1, T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,68 +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_MPL_POINTERTOOTHERH_INCLUDED
|
||||
#define BEAST_MPL_POINTERTOOTHERH_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
/** Declares a type which is a pointer or smart pointer to U, depending on T.
|
||||
This works for smart pointer containers with up to three template
|
||||
parameters. More specializations can be added for containers with
|
||||
more than three template parameters.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class T, class U>
|
||||
struct PointerToOther;
|
||||
|
||||
template <class T, class U,
|
||||
template <class> class SmartPointer>
|
||||
struct PointerToOther <SmartPointer <T>, U>
|
||||
{
|
||||
typedef SmartPointer <U> type;
|
||||
};
|
||||
|
||||
template <class T, class T2, class U,
|
||||
template <class, class> class SmartPointer>
|
||||
struct PointerToOther <SmartPointer <T, T2>, U>
|
||||
{
|
||||
typedef SmartPointer <U, T2> type;
|
||||
};
|
||||
|
||||
template <class T, class T2, class T3, class U,
|
||||
template<class, class, class> class SmartPointer>
|
||||
struct PointerToOther <SmartPointer <T, T2, T3>, U>
|
||||
{
|
||||
typedef SmartPointer <U, T2, T3> type;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct PointerToOther <T*, U>
|
||||
{
|
||||
typedef U* type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,46 +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_MPL_REMOVECONST_H_INCLUDED
|
||||
#define BEAST_MPL_REMOVECONST_H_INCLUDED
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
/** Remove the `const` qualifier from a type. */
|
||||
/** @{ */
|
||||
template <typename T>
|
||||
struct RemoveConst
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct RemoveConst <T const>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,43 +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_MPL_REMOVECONSTVOLATILE_H_INCLUDED
|
||||
#define BEAST_MPL_REMOVECONSTVOLATILE_H_INCLUDED
|
||||
|
||||
#include "RemoveConst.h"
|
||||
#include "RemoveVolatile.h"
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
/** Remove both the `const` and `volatile` qualifiers from a type. */
|
||||
template <typename T>
|
||||
struct RemoveConstVolatile
|
||||
{
|
||||
typedef typename RemoveConst <
|
||||
typename RemoveVolatile <T>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,46 +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_MPL_REMOVEREFERENCE_H_INCLUDED
|
||||
#define BEAST_MPL_REMOVEREFERENCE_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
/** Remove the reference qualifier from a type. */
|
||||
/** @{ */
|
||||
template <class T>
|
||||
struct RemoveReference
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct RemoveReference <T&>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,46 +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_MPL_REMOVEVOLATILE_H_INCLUDED
|
||||
#define BEAST_MPL_REMOVEVOLATILE_H_INCLUDED
|
||||
|
||||
// Ideas based on boost
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
/** Remove the `volatile` qualifier from a type. */
|
||||
/** @{ */
|
||||
template <typename T>
|
||||
struct RemoveVolatile
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct RemoveVolatile <T volatile>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
||||
#define BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
||||
|
||||
#include "../mpl/IfCond.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -34,13 +34,11 @@ template <bool IsConst>
|
||||
class BufferType
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
void const*,
|
||||
void*>::type pointer_type;
|
||||
typedef typename std::conditional <IsConst,
|
||||
void const*, void*>::type pointer_type;
|
||||
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
uint8 const,
|
||||
uint8>::type byte_type;
|
||||
typedef typename std::conditional <IsConst,
|
||||
uint8 const, uint8>::type byte_type;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "../CStdInt.h"
|
||||
#include "../mpl/IfCond.h"
|
||||
|
||||
namespace std {
|
||||
|
||||
@@ -115,7 +114,8 @@ public:
|
||||
class Proxy
|
||||
{
|
||||
public:
|
||||
typedef typename mpl::IfCond <IsConst, uint32 const*, uint32*>::type Pointer;
|
||||
typedef typename std::conditional <
|
||||
IsConst, uint32 const*, uint32*>::type Pointer;
|
||||
|
||||
Proxy (int shift, Pointer value)
|
||||
: m_shift (shift)
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
#ifndef BEAST_SHAREDOBJECT_H_INCLUDED
|
||||
#define BEAST_SHAREDOBJECT_H_INCLUDED
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "../Config.h"
|
||||
#include "../Atomic.h"
|
||||
#include "../Uncopyable.h"
|
||||
|
||||
namespace beast {
|
||||
@@ -71,7 +72,7 @@ public:
|
||||
This is done automatically by the smart pointer, but is public just
|
||||
in case it's needed for nefarious purposes.
|
||||
*/
|
||||
inline void incReferenceCount() const noexcept
|
||||
void incReferenceCount() const noexcept
|
||||
{
|
||||
++refCount;
|
||||
}
|
||||
@@ -93,15 +94,16 @@ public:
|
||||
}
|
||||
|
||||
/** Returns the object's current reference count. */
|
||||
inline int getReferenceCount() const noexcept
|
||||
int getReferenceCount() const noexcept
|
||||
{
|
||||
return refCount.get();
|
||||
return refCount.load();
|
||||
}
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the reference-counted object (with an initial ref count of zero). */
|
||||
SharedObject()
|
||||
: refCount (0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -125,79 +127,12 @@ protected:
|
||||
*/
|
||||
void resetReferenceCount() noexcept
|
||||
{
|
||||
refCount = 0;
|
||||
refCount.store (0);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Atomic <int> mutable refCount;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Adds reference-counting to an object.
|
||||
|
||||
This is effectively a version of the SharedObject class, but which
|
||||
uses a non-atomic counter, and so is not thread-safe (but which will be more
|
||||
efficient).
|
||||
For more details on how to use it, see the SharedObject class notes.
|
||||
|
||||
@see SharedObject, SharedPtr, SharedObjectArray
|
||||
*/
|
||||
class BEAST_API SingleThreadedSharedObject : public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Increments the object's reference count.
|
||||
|
||||
This is done automatically by the smart pointer, but is public just
|
||||
in case it's needed for nefarious purposes.
|
||||
*/
|
||||
inline void incReferenceCount() noexcept
|
||||
{
|
||||
++refCount;
|
||||
}
|
||||
|
||||
/** Decreases the object's reference count.
|
||||
|
||||
If doDelete is true the object will be deleted when the reference
|
||||
count drops to zero. The delete is performed using the regular
|
||||
operator and does NOT go through the ContainerDeletePolicy.
|
||||
|
||||
The return value indicates if the reference count dropped to zero,
|
||||
so callers who know the derived type can use the ContainerDeletePolicy.
|
||||
*/
|
||||
inline void decReferenceCount ()
|
||||
{
|
||||
bassert (getReferenceCount() > 0);
|
||||
if (--refCount == 0)
|
||||
destroy ();
|
||||
}
|
||||
|
||||
/** Returns the object's current reference count. */
|
||||
inline int getReferenceCount() const noexcept { return refCount; }
|
||||
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the reference-counted object (with an initial ref count of zero). */
|
||||
SingleThreadedSharedObject() : refCount (0) {}
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~SingleThreadedSharedObject()
|
||||
{
|
||||
// it's dangerous to delete an object that's still referenced by something else!
|
||||
bassert (getReferenceCount() == 0);
|
||||
}
|
||||
|
||||
virtual void destroy () const
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int refCount;
|
||||
std::atomic <int> mutable refCount;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,4 @@
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "function.h"
|
||||
#include "shared_ptr.h"
|
||||
#include "thread.h"
|
||||
#include "unique_ptr.h"
|
||||
|
||||
@@ -1,31 +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_STL_FUNCTION_H_INCLUDED
|
||||
#define BEAST_STL_FUNCTION_H_INCLUDED
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
using boost::function;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,35 +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_STL_THREAD_H_INCLUDED
|
||||
#define BEAST_STL_THREAD_H_INCLUDED
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
using boost::thread;
|
||||
|
||||
namespace this_thread {
|
||||
using namespace boost::this_thread;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STL_UNIQUE_PTR_H_INCLUDED
|
||||
#define BEAST_STL_UNIQUE_PTR_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
#include "../Uncopyable.h"
|
||||
|
||||
#ifndef BEAST_UNIQUE_PTR_USES_STL
|
||||
# if BEAST_USE_CPLUSPLUS11
|
||||
# define BEAST_UNIQUE_PTR_USES_STL 1
|
||||
# else
|
||||
# define BEAST_UNIQUE_PTR_USES_STL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if BEAST_UNIQUE_PTR_USES_STL
|
||||
# include <memory>
|
||||
namespace beast {
|
||||
using std::unique_ptr;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <class ObjectType>
|
||||
class unique_ptr : public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a unique_ptr containing a null pointer. */
|
||||
inline unique_ptr()
|
||||
: object (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a unique_ptr that owns the specified object. */
|
||||
inline unique_ptr (ObjectType* const objectToTakePossessionOf)
|
||||
: object (objectToTakePossessionOf)
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a unique_ptr that takes its pointer from another unique_ptr.
|
||||
|
||||
Because a pointer can only belong to one unique_ptr, this transfers
|
||||
the pointer from the other object to this one, and the other object is reset to
|
||||
be a null pointer.
|
||||
*/
|
||||
unique_ptr (unique_ptr& objectToTransferFrom)
|
||||
: object (objectToTransferFrom.object)
|
||||
{
|
||||
objectToTransferFrom.object = nullptr;
|
||||
}
|
||||
|
||||
/** Destructor.
|
||||
This will delete the object that this unique_ptr currently refers to.
|
||||
*/
|
||||
inline ~unique_ptr()
|
||||
{
|
||||
ContainerDeletePolicy <ObjectType>::destroy (object);
|
||||
}
|
||||
|
||||
/** Changes this unique_ptr to point to a new object.
|
||||
|
||||
Because a pointer can only belong to one unique_ptr, this transfers
|
||||
the pointer from the other object to this one, and the other object is reset to
|
||||
be a null pointer.
|
||||
|
||||
If this unique_ptr already points to an object, that object
|
||||
will first be deleted.
|
||||
*/
|
||||
unique_ptr& operator= (unique_ptr& objectToTransferFrom)
|
||||
{
|
||||
if (this != objectToTransferFrom.getAddress())
|
||||
{
|
||||
// Two ScopedPointers should never be able to refer to the same object - if
|
||||
// this happens, you must have done something dodgy!
|
||||
bassert (object == nullptr || object != objectToTransferFrom.object);
|
||||
|
||||
ObjectType* const oldObject = object;
|
||||
object = objectToTransferFrom.object;
|
||||
objectToTransferFrom.object = nullptr;
|
||||
ContainerDeletePolicy <ObjectType>::destroy (oldObject);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Changes this unique_ptr to point to a new object.
|
||||
|
||||
If this unique_ptr already points to an object, that object
|
||||
will first be deleted.
|
||||
|
||||
The pointer that you pass in may be a nullptr.
|
||||
*/
|
||||
unique_ptr& operator= (ObjectType* const newObjectToTakePossessionOf)
|
||||
{
|
||||
if (object != newObjectToTakePossessionOf)
|
||||
{
|
||||
ObjectType* const oldObject = object;
|
||||
object = newObjectToTakePossessionOf;
|
||||
ContainerDeletePolicy <ObjectType>::destroy (oldObject);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
unique_ptr (unique_ptr&& other)
|
||||
: object (other.object)
|
||||
{
|
||||
other.object = nullptr;
|
||||
}
|
||||
|
||||
unique_ptr& operator= (unique_ptr&& other)
|
||||
{
|
||||
object = other.object;
|
||||
other.object = nullptr;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the object that this unique_ptr refers to. */
|
||||
inline operator ObjectType*() const { return object; }
|
||||
|
||||
/** Returns the object that this unique_ptr refers to. */
|
||||
inline ObjectType* get() const { return object; }
|
||||
|
||||
/** Returns the object that this unique_ptr refers to. */
|
||||
inline ObjectType& operator*() const { return *object; }
|
||||
|
||||
/** Lets you access methods and properties of the object that this unique_ptr refers to. */
|
||||
inline ObjectType* operator->() const { return object; }
|
||||
|
||||
//==============================================================================
|
||||
/** Removes the current object from this unique_ptr without deleting it.
|
||||
This will return the current object, and set the unique_ptr to a null pointer.
|
||||
*/
|
||||
ObjectType* release() { ObjectType* const o = object; object = nullptr; return o; }
|
||||
|
||||
//==============================================================================
|
||||
/** Swaps this object with that of another unique_ptr.
|
||||
The two objects simply exchange their pointers.
|
||||
*/
|
||||
void swapWith (unique_ptr <ObjectType>& other)
|
||||
{
|
||||
// Two ScopedPointers should never be able to refer to the same object - if
|
||||
// this happens, you must have done something dodgy!
|
||||
bassert (object != other.object || this == other.getAddress());
|
||||
std::swap (object, other.object);
|
||||
}
|
||||
|
||||
inline ObjectType* createCopy() const { return createCopyIfNotNull (object); }
|
||||
|
||||
private:
|
||||
ObjectType* object;
|
||||
const unique_ptr* getAddress() const { return this; }
|
||||
};
|
||||
|
||||
template <class ObjectType>
|
||||
bool operator== (const unique_ptr<ObjectType>& pointer1, ObjectType* const pointer2)
|
||||
{
|
||||
return static_cast <ObjectType*> (pointer1) == pointer2;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
bool operator!= (const unique_ptr<ObjectType>& pointer1, ObjectType* const pointer2)
|
||||
{
|
||||
return static_cast <ObjectType*> (pointer1) != pointer2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> make_unique ()
|
||||
{
|
||||
return unique_ptr <T> (new T ());
|
||||
}
|
||||
|
||||
template <class T, class P1>
|
||||
unique_ptr <T> make_unique (P1 p1)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3, class P4>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3, P4 p4)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3, p4));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3, p4, p5));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3, p4, p5, p6));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3, p4, p5, p6, p7));
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||
unique_ptr <T> make_unique (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
return unique_ptr <T> (new T (p1, p2, p3, p4, p5, p6, p7, p8));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "../chrono/CPUMeter.h"
|
||||
#include "../intrusive/List.h"
|
||||
#include "../intrusive/LockFreeStack.h"
|
||||
#include "SharedData.h"
|
||||
#include "ThreadLocalValue.h"
|
||||
#include "WaitableEvent.h"
|
||||
@@ -371,7 +370,7 @@ protected:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class Waiter : public LockFreeStack <Waiter>::Node
|
||||
class Waiter : public List <Waiter>::Node
|
||||
{
|
||||
public:
|
||||
Waiter()
|
||||
@@ -390,8 +389,8 @@ protected:
|
||||
{
|
||||
// handlers
|
||||
List <Item> handlers;
|
||||
LockFreeStack <Waiter> waiting;
|
||||
LockFreeStack <Waiter> unused;
|
||||
List <Waiter> waiting;
|
||||
List <Waiter> unused;
|
||||
};
|
||||
|
||||
typedef SharedData <State> SharedState;
|
||||
@@ -440,9 +439,8 @@ public:
|
||||
typename Allocator::template rebind <Waiter>::other a (m_alloc);
|
||||
SharedState::Access state (m_state);
|
||||
while (expectedConcurrency--)
|
||||
{
|
||||
state->unused.push_front (new (a.allocate (1)) Waiter);
|
||||
}
|
||||
state->unused.push_front (
|
||||
*new (a.allocate (1)) Waiter);
|
||||
}
|
||||
|
||||
~ServiceQueueType()
|
||||
@@ -456,11 +454,10 @@ public:
|
||||
bassert (state->waiting.empty());
|
||||
|
||||
typename Allocator::template rebind <Waiter>::other a (m_alloc);
|
||||
for(;;)
|
||||
while (! state->unused.empty ())
|
||||
{
|
||||
Waiter* const waiter (state->unused.pop_front());
|
||||
if (waiter == nullptr)
|
||||
break;
|
||||
Waiter* const waiter (&state->unused.front ());
|
||||
state->unused.pop_front ();
|
||||
a.destroy (waiter);
|
||||
a.deallocate (waiter, 1);
|
||||
}
|
||||
|
||||
@@ -119,12 +119,11 @@ void ServiceQueueBase::stop ()
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
m_stopped.set (1);
|
||||
for(;;)
|
||||
while (! state->waiting.empty ())
|
||||
{
|
||||
Waiter* waiting (state->waiting.pop_front());
|
||||
if (waiting == nullptr)
|
||||
break;
|
||||
waiting->signal();
|
||||
Waiter& waiting (state->waiting.front());
|
||||
state->waiting.pop_front ();
|
||||
waiting.signal ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,14 +143,24 @@ void ServiceQueueBase::wait ()
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
if (stopped ())
|
||||
return;
|
||||
|
||||
if (! state->handlers.empty())
|
||||
return;
|
||||
waiter = state->unused.pop_front();
|
||||
if (! waiter)
|
||||
|
||||
if (state->unused.empty ())
|
||||
{
|
||||
waiter = new_waiter();
|
||||
state->waiting.push_front (waiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
waiter = &state->unused.front ();
|
||||
state->unused.pop_front ();
|
||||
}
|
||||
|
||||
state->waiting.push_front (*waiter);
|
||||
}
|
||||
|
||||
waiter->wait();
|
||||
@@ -160,19 +169,22 @@ void ServiceQueueBase::wait ()
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
state->unused.push_front (waiter);
|
||||
state->unused.push_front (*waiter);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceQueueBase::enqueue (Item* item)
|
||||
{
|
||||
Waiter* waiter;
|
||||
Waiter* waiter (nullptr);
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
state->handlers.push_back (*item);
|
||||
// Signal a Waiter if one exists
|
||||
waiter = state->waiting.pop_front();
|
||||
if (! state->waiting.empty ())
|
||||
{
|
||||
waiter = &state->waiting.front ();
|
||||
state->waiting.pop_front ();
|
||||
}
|
||||
}
|
||||
|
||||
if (waiter != nullptr)
|
||||
|
||||
86
beast/threads/semaphore.h
Normal file
86
beast/threads/semaphore.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_THREADS_SEMAPHORE_H_INCLUDED
|
||||
#define BEAST_THREADS_SEMAPHORE_H_INCLUDED
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <class Mutex, class CondVar>
|
||||
class basic_semaphore
|
||||
{
|
||||
private:
|
||||
typedef std::unique_lock <Mutex> scoped_lock;
|
||||
|
||||
Mutex m_mutex;
|
||||
CondVar m_cond;
|
||||
std::size_t m_count;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
/** Create the semaphore, with an optional initial count.
|
||||
If unspecified, the initial count is zero.
|
||||
*/
|
||||
explicit basic_semaphore (size_type count = 0)
|
||||
: m_count (count)
|
||||
{
|
||||
}
|
||||
|
||||
/** Increment the count and unblock one waiting thread. */
|
||||
void notify ()
|
||||
{
|
||||
scoped_lock lock (m_mutex);
|
||||
++m_count;
|
||||
m_cond.notify_one ();
|
||||
}
|
||||
|
||||
// Deprecated, for backward compatibility
|
||||
void signal () { notify (); }
|
||||
|
||||
/** Block until notify is called. */
|
||||
void wait ()
|
||||
{
|
||||
scoped_lock lock (m_mutex);
|
||||
while (m_count == 0)
|
||||
m_cond.wait (lock);
|
||||
--m_count;
|
||||
}
|
||||
|
||||
/** Perform a non-blocking wait.
|
||||
@return `true` If the wait would be satisfied.
|
||||
*/
|
||||
bool try_wait ()
|
||||
{
|
||||
scoped_lock lock (m_mutex);
|
||||
if (m_count == 0)
|
||||
return false;
|
||||
--m_count;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_semaphore <std::mutex, std::condition_variable> semaphore;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
This class is compatible with std::allocator and can be used in any
|
||||
boost interface which takes a template parameter of type Allocator.
|
||||
This includes boost::function and especially boost::asio::streambuf
|
||||
This includes std::function and especially boost::asio::streambuf
|
||||
and relatives. This is vastly more efficient in a variety of situations
|
||||
especially during an upcall and when using stackful coroutines.
|
||||
|
||||
|
||||
@@ -129,7 +129,6 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#include "containers/AbstractFifo.cpp"
|
||||
#include "containers/DynamicObject.cpp"
|
||||
#include "containers/NamedValueSet.cpp"
|
||||
#include "containers/PropertySet.cpp"
|
||||
@@ -155,7 +154,6 @@ namespace beast
|
||||
#include "logging/Logger.cpp"
|
||||
|
||||
#include "maths/BigInteger.cpp"
|
||||
#include "maths/Expression.cpp"
|
||||
#include "maths/Random.cpp"
|
||||
|
||||
#include "memory/MemoryBlock.cpp"
|
||||
@@ -188,7 +186,6 @@ namespace beast
|
||||
|
||||
#include "thread/impl/TrackedMutex.cpp"
|
||||
#include "thread/DeadlineTimer.cpp"
|
||||
#include "thread/Semaphore.cpp"
|
||||
#include "thread/Workers.cpp"
|
||||
|
||||
#include "threads/ChildProcess.cpp"
|
||||
|
||||
@@ -77,10 +77,6 @@ class FileOutputStream;
|
||||
|
||||
#include "diagnostic/Throw.h"
|
||||
#include "system/Functional.h"
|
||||
#include "memory/AtomicCounter.h"
|
||||
#include "memory/AtomicFlag.h"
|
||||
#include "memory/AtomicPointer.h"
|
||||
#include "memory/AtomicState.h"
|
||||
#include "threads/SpinDelay.h"
|
||||
|
||||
#include "time/AtExitHook.h"
|
||||
@@ -155,7 +151,6 @@ class FileOutputStream;
|
||||
#include "logging/Logger.h"
|
||||
#include "diagnostic/FPUFlags.h"
|
||||
#include "memory/SharedFunction.h"
|
||||
#include "containers/AbstractFifo.h"
|
||||
#include "text/Identifier.h"
|
||||
#include "containers/Variant.h"
|
||||
#include "containers/LinkedListPointer.h"
|
||||
@@ -163,13 +158,10 @@ class FileOutputStream;
|
||||
#include "containers/DynamicObject.h"
|
||||
#include "maths/BigInteger.h"
|
||||
#include "maths/Random.h"
|
||||
#include "containers/LockFreeQueue.h"
|
||||
#include "containers/OwnedArray.h"
|
||||
#include "text/StringPairArray.h"
|
||||
#include "containers/PropertySet.h"
|
||||
#include "containers/SharedObjectArray.h"
|
||||
#include "containers/ScopedValueSetter.h"
|
||||
#include "containers/SortedSet.h"
|
||||
#include "maths/Range.h"
|
||||
#include "containers/SparseSet.h"
|
||||
#include "files/DirectoryIterator.h"
|
||||
@@ -186,12 +178,8 @@ class FileOutputStream;
|
||||
#include "json/JSON.h"
|
||||
#include "logging/FileLogger.h"
|
||||
#include "logging/Logger.h"
|
||||
#include "maths/Expression.h"
|
||||
#include "maths/Interval.h"
|
||||
#include "memory/OptionalScopedPointer.h"
|
||||
#include "memory/SharedSingleton.h"
|
||||
#include "memory/WeakReference.h"
|
||||
#include "memory/RecycledObjectPool.h"
|
||||
#include "misc/Main.h"
|
||||
#include "misc/Uuid.h"
|
||||
#include "misc/WindowsRegistry.h"
|
||||
@@ -228,7 +216,6 @@ class FileOutputStream;
|
||||
|
||||
#include "thread/DeadlineTimer.h"
|
||||
|
||||
#include "thread/Semaphore.h"
|
||||
#include "thread/Workers.h"
|
||||
|
||||
}
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
AbstractFifo::AbstractFifo (const int capacity) noexcept
|
||||
: bufferSize (capacity)
|
||||
{
|
||||
bassert (bufferSize > 0);
|
||||
}
|
||||
|
||||
AbstractFifo::~AbstractFifo() {}
|
||||
|
||||
int AbstractFifo::getTotalSize() const noexcept { return bufferSize; }
|
||||
int AbstractFifo::getFreeSpace() const noexcept { return bufferSize - getNumReady(); }
|
||||
|
||||
int AbstractFifo::getNumReady() const noexcept
|
||||
{
|
||||
const int vs = validStart.get();
|
||||
const int ve = validEnd.get();
|
||||
return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
|
||||
}
|
||||
|
||||
void AbstractFifo::reset() noexcept
|
||||
{
|
||||
validEnd = 0;
|
||||
validStart = 0;
|
||||
}
|
||||
|
||||
void AbstractFifo::setTotalSize (int newSize) noexcept
|
||||
{
|
||||
bassert (newSize > 0);
|
||||
reset();
|
||||
bufferSize = newSize;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
|
||||
{
|
||||
const int vs = validStart.get();
|
||||
const int ve = validEnd.value;
|
||||
|
||||
const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve);
|
||||
numToWrite = bmin (numToWrite, freeSpace - 1);
|
||||
|
||||
if (numToWrite <= 0)
|
||||
{
|
||||
startIndex1 = 0;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = 0;
|
||||
blockSize2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex1 = ve;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = bmin (bufferSize - ve, numToWrite);
|
||||
numToWrite -= blockSize1;
|
||||
blockSize2 = numToWrite <= 0 ? 0 : bmin (numToWrite, vs);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractFifo::finishedWrite (int numWritten) noexcept
|
||||
{
|
||||
bassert (numWritten >= 0 && numWritten < bufferSize);
|
||||
int newEnd = validEnd.value + numWritten;
|
||||
if (newEnd >= bufferSize)
|
||||
newEnd -= bufferSize;
|
||||
|
||||
validEnd = newEnd;
|
||||
}
|
||||
|
||||
void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
|
||||
{
|
||||
const int vs = validStart.value;
|
||||
const int ve = validEnd.get();
|
||||
|
||||
const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
|
||||
numWanted = bmin (numWanted, numReady);
|
||||
|
||||
if (numWanted <= 0)
|
||||
{
|
||||
startIndex1 = 0;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = 0;
|
||||
blockSize2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex1 = vs;
|
||||
startIndex2 = 0;
|
||||
blockSize1 = bmin (bufferSize - vs, numWanted);
|
||||
numWanted -= blockSize1;
|
||||
blockSize2 = numWanted <= 0 ? 0 : bmin (numWanted, ve);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractFifo::finishedRead (int numRead) noexcept
|
||||
{
|
||||
bassert (numRead >= 0 && numRead <= bufferSize);
|
||||
|
||||
int newStart = validStart.value + numRead;
|
||||
if (newStart >= bufferSize)
|
||||
newStart -= bufferSize;
|
||||
|
||||
validStart = newStart;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
class AbstractFifoTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
AbstractFifoTests() : UnitTest ("Abstract Fifo", "beast")
|
||||
{
|
||||
}
|
||||
|
||||
class WriteThread : public Thread
|
||||
{
|
||||
public:
|
||||
WriteThread (AbstractFifo& fifo_, int* buffer_)
|
||||
: Thread ("fifo writer"), fifo (fifo_), buffer (buffer_)
|
||||
{
|
||||
startThread();
|
||||
}
|
||||
|
||||
~WriteThread()
|
||||
{
|
||||
stopThread (5000);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int n = 0;
|
||||
Random r;
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
int num = r.nextInt (2000) + 1;
|
||||
|
||||
int start1, size1, start2, size2;
|
||||
fifo.prepareToWrite (num, start1, size1, start2, size2);
|
||||
|
||||
bassert (size1 >= 0 && size2 >= 0);
|
||||
bassert (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize()));
|
||||
bassert (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize()));
|
||||
|
||||
for (int i = 0; i < size1; ++i)
|
||||
buffer [start1 + i] = n++;
|
||||
|
||||
for (int i = 0; i < size2; ++i)
|
||||
buffer [start2 + i] = n++;
|
||||
|
||||
fifo.finishedWrite (size1 + size2);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
AbstractFifo& fifo;
|
||||
int* buffer;
|
||||
};
|
||||
|
||||
void runTest()
|
||||
{
|
||||
beginTestCase ("AbstractFifo");
|
||||
|
||||
int buffer [5000];
|
||||
AbstractFifo fifo (numElementsInArray (buffer));
|
||||
|
||||
WriteThread writer (fifo, buffer);
|
||||
|
||||
int n = 0;
|
||||
Random r;
|
||||
|
||||
bool failed = false;
|
||||
|
||||
for (int count = 100000; --count >= 0;)
|
||||
{
|
||||
int num = r.nextInt (6000) + 1;
|
||||
|
||||
int start1, size1, start2, size2;
|
||||
fifo.prepareToRead (num, start1, size1, start2, size2);
|
||||
|
||||
if (! (size1 >= 0 && size2 >= 0)
|
||||
&& (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize()))
|
||||
&& (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize())))
|
||||
{
|
||||
expect (false, "prepareToRead returned negative values");
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size1; ++i)
|
||||
failed = (buffer [start1 + i] != n++) || failed;
|
||||
|
||||
for (int i = 0; i < size2; ++i)
|
||||
failed = (buffer [start2 + i] != n++) || failed;
|
||||
|
||||
if (failed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fifo.finishedRead (size1 + size2);
|
||||
}
|
||||
|
||||
expect (! failed, "read values were incorrect");
|
||||
}
|
||||
};
|
||||
|
||||
static AbstractFifoTests abstractFifoTests;
|
||||
@@ -1,212 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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_ABSTRACTFIFO_H_INCLUDED
|
||||
#define BEAST_ABSTRACTFIFO_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Encapsulates the logic required to implement a lock-free FIFO.
|
||||
|
||||
This class handles the logic needed when building a single-reader,
|
||||
single-writer FIFO.
|
||||
|
||||
It doesn't actually hold any data itself, but your FIFO class can use one of
|
||||
these to manage its position and status when reading or writing to it.
|
||||
|
||||
To use it, you can call prepareToWrite() to determine the position within
|
||||
your own buffer that an incoming block of data should be stored, and
|
||||
prepareToRead() to find out when the next outgoing block should be read from.
|
||||
|
||||
e.g.
|
||||
@code
|
||||
class MyFifo
|
||||
{
|
||||
public:
|
||||
MyFifo() : abstractFifo (1024)
|
||||
{
|
||||
}
|
||||
|
||||
void addToFifo (const int* someData, int numItems)
|
||||
{
|
||||
int start1, size1, start2, size2;
|
||||
abstractFifo.prepareToWrite (numItems, start1, size1, start2, size2);
|
||||
|
||||
if (size1 > 0)
|
||||
copySomeData (myBuffer + start1, someData, size1);
|
||||
|
||||
if (size2 > 0)
|
||||
copySomeData (myBuffer + start2, someData + size1, size2);
|
||||
|
||||
abstractFifo.finishedWrite (size1 + size2);
|
||||
}
|
||||
|
||||
void readFromFifo (int* someData, int numItems)
|
||||
{
|
||||
int start1, size1, start2, size2;
|
||||
abstractFifo.prepareToRead (numSamples, start1, size1, start2, size2);
|
||||
|
||||
if (size1 > 0)
|
||||
copySomeData (someData, myBuffer + start1, size1);
|
||||
|
||||
if (size2 > 0)
|
||||
copySomeData (someData + size1, myBuffer + start2, size2);
|
||||
|
||||
abstractFifo.finishedRead (size1 + size2);
|
||||
}
|
||||
|
||||
private:
|
||||
AbstractFifo abstractFifo;
|
||||
int myBuffer [1024];
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
class BEAST_API AbstractFifo : LeakChecked <AbstractFifo>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FIFO to manage a buffer with the specified capacity. */
|
||||
AbstractFifo (int capacity) noexcept;
|
||||
|
||||
/** Destructor */
|
||||
~AbstractFifo();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total size of the buffer being managed. */
|
||||
int getTotalSize() const noexcept;
|
||||
|
||||
/** Returns the number of items that can currently be added to the buffer without it overflowing. */
|
||||
int getFreeSpace() const noexcept;
|
||||
|
||||
/** Returns the number of items that can currently be read from the buffer. */
|
||||
int getNumReady() const noexcept;
|
||||
|
||||
/** Clears the buffer positions, so that it appears empty. */
|
||||
void reset() noexcept;
|
||||
|
||||
/** Changes the buffer's total size.
|
||||
Note that this isn't thread-safe, so don't call it if there's any danger that it
|
||||
might overlap with a call to any other method in this class!
|
||||
*/
|
||||
void setTotalSize (int newSize) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the location within the buffer at which an incoming block of data should be written.
|
||||
|
||||
Because the section of data that you want to add to the buffer may overlap the end
|
||||
and wrap around to the start, two blocks within your buffer are returned, and you
|
||||
should copy your data into the first one, with any remaining data spilling over into
|
||||
the second.
|
||||
|
||||
If the number of items you ask for is too large to fit within the buffer's free space, then
|
||||
blockSize1 + blockSize2 may add up to a lower value than numToWrite. If this happens, you
|
||||
may decide to keep waiting and re-trying the method until there's enough space available.
|
||||
|
||||
After calling this method, if you choose to write your data into the blocks returned, you
|
||||
must call finishedWrite() to tell the FIFO how much data you actually added.
|
||||
|
||||
e.g.
|
||||
@code
|
||||
void addToFifo (const int* someData, int numItems)
|
||||
{
|
||||
int start1, size1, start2, size2;
|
||||
prepareToWrite (numItems, start1, size1, start2, size2);
|
||||
|
||||
if (size1 > 0)
|
||||
copySomeData (myBuffer + start1, someData, size1);
|
||||
|
||||
if (size2 > 0)
|
||||
copySomeData (myBuffer + start2, someData + size1, size2);
|
||||
|
||||
finishedWrite (size1 + size2);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param numToWrite indicates how many items you'd like to add to the buffer
|
||||
@param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written
|
||||
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1
|
||||
@param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into
|
||||
the first block should be written
|
||||
@param blockSize2 on exit, this indicates how many items can be written to the block starting at startIndex2
|
||||
@see finishedWrite
|
||||
*/
|
||||
void prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept;
|
||||
|
||||
/** Called after writing from the FIFO, to indicate that this many items have been added.
|
||||
@see prepareToWrite
|
||||
*/
|
||||
void finishedWrite (int numWritten) noexcept;
|
||||
|
||||
/** Returns the location within the buffer from which the next block of data should be read.
|
||||
|
||||
Because the section of data that you want to read from the buffer may overlap the end
|
||||
and wrap around to the start, two blocks within your buffer are returned, and you
|
||||
should read from both of them.
|
||||
|
||||
If the number of items you ask for is greater than the amount of data available, then
|
||||
blockSize1 + blockSize2 may add up to a lower value than numWanted. If this happens, you
|
||||
may decide to keep waiting and re-trying the method until there's enough data available.
|
||||
|
||||
After calling this method, if you choose to read the data, you must call finishedRead() to
|
||||
tell the FIFO how much data you have consumed.
|
||||
|
||||
e.g.
|
||||
@code
|
||||
void readFromFifo (int* someData, int numItems)
|
||||
{
|
||||
int start1, size1, start2, size2;
|
||||
prepareToRead (numSamples, start1, size1, start2, size2);
|
||||
|
||||
if (size1 > 0)
|
||||
copySomeData (someData, myBuffer + start1, size1);
|
||||
|
||||
if (size2 > 0)
|
||||
copySomeData (someData + size1, myBuffer + start2, size2);
|
||||
|
||||
finishedRead (size1 + size2);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param numWanted indicates how many items you'd like to add to the buffer
|
||||
@param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written
|
||||
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1
|
||||
@param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into
|
||||
the first block should be written
|
||||
@param blockSize2 on exit, this indicates how many items can be written to the block starting at startIndex2
|
||||
@see finishedRead
|
||||
*/
|
||||
void prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept;
|
||||
|
||||
/** Called after reading from the FIFO, to indicate that this many items have now been consumed.
|
||||
@see prepareToRead
|
||||
*/
|
||||
void finishedRead (int numRead) noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int bufferSize;
|
||||
Atomic <int> validStart, validEnd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,856 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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_SHAREDOBJECTARRAY_H_INCLUDED
|
||||
#define BEAST_SHAREDOBJECTARRAY_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Holds a list of objects derived from SharedObject.
|
||||
|
||||
A SharedObjectArray holds objects derived from SharedObject,
|
||||
and takes care of incrementing and decrementing their ref counts when they
|
||||
are added and removed from the array.
|
||||
|
||||
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
||||
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
||||
|
||||
@see Array, OwnedArray, StringArray
|
||||
*/
|
||||
template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
||||
class SharedObjectArray
|
||||
{
|
||||
public:
|
||||
typedef SharedPtr<ObjectClass> ObjectClassPtr;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates an empty array.
|
||||
@see SharedObject, Array, OwnedArray
|
||||
*/
|
||||
SharedObjectArray() noexcept
|
||||
: numUsed (0)
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a copy of another array */
|
||||
SharedObjectArray (const SharedObjectArray& other) noexcept
|
||||
{
|
||||
const ScopedLockType lock (other.getLock());
|
||||
numUsed = other.size();
|
||||
data.setAllocatedSize (numUsed);
|
||||
memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*));
|
||||
|
||||
for (int i = numUsed; --i >= 0;)
|
||||
if (ObjectClass* o = data.elements[i])
|
||||
o->incReferenceCount();
|
||||
}
|
||||
|
||||
/** Creates a copy of another array */
|
||||
template <class OtherObjectClass, class OtherCriticalSection>
|
||||
SharedObjectArray (const SharedObjectArray<OtherObjectClass, OtherCriticalSection>& other) noexcept
|
||||
{
|
||||
const typename SharedObjectArray<OtherObjectClass, OtherCriticalSection>::ScopedLockType lock (other.getLock());
|
||||
numUsed = other.size();
|
||||
data.setAllocatedSize (numUsed);
|
||||
memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*));
|
||||
|
||||
for (int i = numUsed; --i >= 0;)
|
||||
if (ObjectClass* o = data.elements[i])
|
||||
o->incReferenceCount();
|
||||
}
|
||||
|
||||
/** Copies another array into this one.
|
||||
Any existing objects in this array will first be released.
|
||||
*/
|
||||
SharedObjectArray& operator= (const SharedObjectArray& other) noexcept
|
||||
{
|
||||
SharedObjectArray otherCopy (other);
|
||||
swapWith (otherCopy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Copies another array into this one.
|
||||
Any existing objects in this array will first be released.
|
||||
*/
|
||||
template <class OtherObjectClass>
|
||||
SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const SharedObjectArray<OtherObjectClass, TypeOfCriticalSectionToUse>& other) noexcept
|
||||
{
|
||||
SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other);
|
||||
swapWith (otherCopy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Destructor.
|
||||
Any objects in the array will be released, and may be deleted if not referenced from elsewhere.
|
||||
*/
|
||||
~SharedObjectArray()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Removes all objects from the array.
|
||||
|
||||
Any objects in the array that are not referenced from elsewhere will be deleted.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
while (numUsed > 0)
|
||||
if (ObjectClass* o = data.elements [--numUsed])
|
||||
o->decReferenceCount();
|
||||
|
||||
bassert (numUsed == 0);
|
||||
data.setAllocatedSize (0);
|
||||
}
|
||||
|
||||
/** Returns the current number of objects in the array. */
|
||||
inline int size() const noexcept
|
||||
{
|
||||
return numUsed;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the object at this index in the array.
|
||||
|
||||
If the index is out-of-range, this will return a null pointer, (and
|
||||
it could be null anyway, because it's ok for the array to hold null
|
||||
pointers as well as objects).
|
||||
|
||||
@see getUnchecked
|
||||
*/
|
||||
inline ObjectClassPtr operator[] (const int index) const noexcept
|
||||
{
|
||||
return getObjectPointer (index);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the object at this index in the array, without checking
|
||||
whether the index is in-range.
|
||||
|
||||
This is a faster and less safe version of operator[] which doesn't check the index passed in, so
|
||||
it can be used when you're sure the index is always going to be legal.
|
||||
*/
|
||||
inline ObjectClassPtr getUnchecked (const int index) const noexcept
|
||||
{
|
||||
return getObjectPointerUnchecked (index);
|
||||
}
|
||||
|
||||
/** Returns a raw pointer to the object at this index in the array.
|
||||
|
||||
If the index is out-of-range, this will return a null pointer, (and
|
||||
it could be null anyway, because it's ok for the array to hold null
|
||||
pointers as well as objects).
|
||||
|
||||
@see getUnchecked
|
||||
*/
|
||||
inline ObjectClass* getObjectPointer (const int index) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
return isPositiveAndBelow (index, numUsed) ? data.elements [index]
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/** Returns a raw pointer to the object at this index in the array, without checking
|
||||
whether the index is in-range.
|
||||
*/
|
||||
inline ObjectClass* getObjectPointerUnchecked (const int index) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
bassert (isPositiveAndBelow (index, numUsed));
|
||||
return data.elements [index];
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first object in the array.
|
||||
|
||||
This will return a null pointer if the array's empty.
|
||||
@see getLast
|
||||
*/
|
||||
inline ObjectClassPtr getFirst() const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
return numUsed > 0 ? data.elements [0]
|
||||
: static_cast <ObjectClass*> (nullptr);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the last object in the array.
|
||||
|
||||
This will return a null pointer if the array's empty.
|
||||
@see getFirst
|
||||
*/
|
||||
inline ObjectClassPtr getLast() const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
return numUsed > 0 ? data.elements [numUsed - 1]
|
||||
: static_cast <ObjectClass*> (nullptr);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the actual array data.
|
||||
This pointer will only be valid until the next time a non-const method
|
||||
is called on the array.
|
||||
*/
|
||||
inline ObjectClass** getRawDataPointer() const noexcept
|
||||
{
|
||||
return data.elements;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a pointer to the first element in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ObjectClass** begin() const noexcept
|
||||
{
|
||||
return data.elements;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the element which follows the last element in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ObjectClass** end() const noexcept
|
||||
{
|
||||
return data.elements + numUsed;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Finds the index of the first occurrence of an object in the array.
|
||||
|
||||
@param objectToLookFor the object to look for
|
||||
@returns the index at which the object was found, or -1 if it's not found
|
||||
*/
|
||||
int indexOf (const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
ObjectClass** e = data.elements.getData();
|
||||
ObjectClass** const endPointer = e + numUsed;
|
||||
|
||||
while (e != endPointer)
|
||||
{
|
||||
if (objectToLookFor == *e)
|
||||
return static_cast <int> (e - data.elements.getData());
|
||||
|
||||
++e;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns true if the array contains a specified object.
|
||||
|
||||
@param objectToLookFor the object to look for
|
||||
@returns true if the object is in the array
|
||||
*/
|
||||
bool contains (const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
ObjectClass** e = data.elements.getData();
|
||||
ObjectClass** const endPointer = e + numUsed;
|
||||
|
||||
while (e != endPointer)
|
||||
{
|
||||
if (objectToLookFor == *e)
|
||||
return true;
|
||||
|
||||
++e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Appends a new object to the end of the array.
|
||||
|
||||
This will increase the new object's reference count.
|
||||
|
||||
@param newObject the new object to add to the array
|
||||
@see set, insert, addIfNotAlreadyThere, addSorted, addArray
|
||||
*/
|
||||
ObjectClass* add (ObjectClass* const newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
bassert (data.elements != nullptr);
|
||||
data.elements [numUsed++] = newObject;
|
||||
|
||||
if (newObject != nullptr)
|
||||
newObject->incReferenceCount();
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
/** Inserts a new object into the array at the given index.
|
||||
|
||||
If the index is less than 0 or greater than the size of the array, the
|
||||
element will be added to the end of the array.
|
||||
Otherwise, it will be inserted into the array, moving all the later elements
|
||||
along to make room.
|
||||
|
||||
This will increase the new object's reference count.
|
||||
|
||||
@param indexToInsertAt the index at which the new element should be inserted
|
||||
@param newObject the new object to add to the array
|
||||
@see add, addSorted, addIfNotAlreadyThere, set
|
||||
*/
|
||||
ObjectClass* insert (int indexToInsertAt,
|
||||
ObjectClass* const newObject) noexcept
|
||||
{
|
||||
if (indexToInsertAt >= 0)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (indexToInsertAt > numUsed)
|
||||
indexToInsertAt = numUsed;
|
||||
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
bassert (data.elements != nullptr);
|
||||
|
||||
ObjectClass** const e = data.elements + indexToInsertAt;
|
||||
const int numToMove = numUsed - indexToInsertAt;
|
||||
|
||||
if (numToMove > 0)
|
||||
memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove);
|
||||
|
||||
*e = newObject;
|
||||
|
||||
if (newObject != nullptr)
|
||||
newObject->incReferenceCount();
|
||||
|
||||
++numUsed;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
return add (newObject);
|
||||
}
|
||||
}
|
||||
|
||||
/** Appends a new object at the end of the array as long as the array doesn't
|
||||
already contain it.
|
||||
|
||||
If the array already contains a matching object, nothing will be done.
|
||||
|
||||
@param newObject the new object to add to the array
|
||||
*/
|
||||
void addIfNotAlreadyThere (ObjectClass* const newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
if (! contains (newObject))
|
||||
add (newObject);
|
||||
}
|
||||
|
||||
/** Replaces an object in the array with a different one.
|
||||
|
||||
If the index is less than zero, this method does nothing.
|
||||
If the index is beyond the end of the array, the new object is added to the end of the array.
|
||||
|
||||
The object being added has its reference count increased, and if it's replacing
|
||||
another object, then that one has its reference count decreased, and may be deleted.
|
||||
|
||||
@param indexToChange the index whose value you want to change
|
||||
@param newObject the new value to set for this index.
|
||||
@see add, insert, remove
|
||||
*/
|
||||
void set (const int indexToChange,
|
||||
ObjectClass* const newObject)
|
||||
{
|
||||
if (indexToChange >= 0)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (newObject != nullptr)
|
||||
newObject->incReferenceCount();
|
||||
|
||||
if (indexToChange < numUsed)
|
||||
{
|
||||
if (ObjectClass* o = data.elements [indexToChange])
|
||||
o->decReferenceCount();
|
||||
|
||||
data.elements [indexToChange] = newObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
bassert (data.elements != nullptr);
|
||||
data.elements [numUsed++] = newObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds elements from another array to the end of this array.
|
||||
|
||||
@param arrayToAddFrom the array from which to copy the elements
|
||||
@param startIndex the first element of the other array to start copying from
|
||||
@param numElementsToAdd how many elements to add from the other array. If this
|
||||
value is negative or greater than the number of available elements,
|
||||
all available elements will be copied.
|
||||
@see add
|
||||
*/
|
||||
void addArray (const SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1) noexcept
|
||||
{
|
||||
const ScopedLockType lock1 (arrayToAddFrom.getLock());
|
||||
|
||||
{
|
||||
const ScopedLockType lock2 (getLock());
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
bassertfalse;
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
|
||||
numElementsToAdd = arrayToAddFrom.size() - startIndex;
|
||||
|
||||
if (numElementsToAdd > 0)
|
||||
{
|
||||
data.ensureAllocatedSize (numUsed + numElementsToAdd);
|
||||
|
||||
while (--numElementsToAdd >= 0)
|
||||
add (arrayToAddFrom.getUnchecked (startIndex++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Inserts a new object into the array assuming that the array is sorted.
|
||||
|
||||
This will use a comparator to find the position at which the new object
|
||||
should go. If the array isn't sorted, the behaviour of this
|
||||
method will be unpredictable.
|
||||
|
||||
@param comparator the comparator object to use to compare the elements - see the
|
||||
sort() method for details about this object's form
|
||||
@param newObject the new object to insert to the array
|
||||
@returns the index at which the new object was added
|
||||
@see add, sort
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
int addSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed);
|
||||
insert (index, newObject);
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Inserts or replaces an object in the array, assuming it is sorted.
|
||||
|
||||
This is similar to addSorted, but if a matching element already exists, then it will be
|
||||
replaced by the new one, rather than the new one being added as well.
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
void addOrReplaceSorted (ElementComparator& comparator,
|
||||
ObjectClass* newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed);
|
||||
|
||||
if (index > 0 && comparator.compareElements (newObject, data.elements [index - 1]) == 0)
|
||||
set (index - 1, newObject); // replace an existing object that matches
|
||||
else
|
||||
insert (index, newObject); // no match, so insert the new one
|
||||
}
|
||||
|
||||
/** Finds the index of an object in the array, assuming that the array is sorted.
|
||||
|
||||
This will use a comparator to do a binary-chop to find the index of the given
|
||||
element, if it exists. If the array isn't sorted, the behaviour of this
|
||||
method will be unpredictable.
|
||||
|
||||
@param comparator the comparator to use to compare the elements - see the sort()
|
||||
method for details about the form this object should take
|
||||
@param objectToLookFor the object to search for
|
||||
@returns the index of the element, or -1 if it's not found
|
||||
@see addSorted, sort
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
int indexOfSorted (ElementComparator& comparator,
|
||||
const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
(void) comparator;
|
||||
const ScopedLockType lock (getLock());
|
||||
int s = 0, e = numUsed;
|
||||
|
||||
while (s < e)
|
||||
{
|
||||
if (comparator.compareElements (objectToLookFor, data.elements [s]) == 0)
|
||||
return s;
|
||||
|
||||
const int halfway = (s + e) / 2;
|
||||
if (halfway == s)
|
||||
break;
|
||||
|
||||
if (comparator.compareElements (objectToLookFor, data.elements [halfway]) >= 0)
|
||||
s = halfway;
|
||||
else
|
||||
e = halfway;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Removes an object from the array.
|
||||
|
||||
This will remove the object at a given index and move back all the
|
||||
subsequent objects to close the gap.
|
||||
|
||||
If the index passed in is out-of-range, nothing will happen.
|
||||
|
||||
The object that is removed will have its reference count decreased,
|
||||
and may be deleted if not referenced from elsewhere.
|
||||
|
||||
@param indexToRemove the index of the element to remove
|
||||
@see removeObject, removeRange
|
||||
*/
|
||||
void remove (const int indexToRemove)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (indexToRemove, numUsed))
|
||||
{
|
||||
ObjectClass** const e = data.elements + indexToRemove;
|
||||
|
||||
if (ObjectClass* o = *e)
|
||||
o->decReferenceCount();
|
||||
|
||||
--numUsed;
|
||||
const int numberToShift = numUsed - indexToRemove;
|
||||
|
||||
if (numberToShift > 0)
|
||||
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift);
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes and returns an object from the array.
|
||||
|
||||
This will remove the object at a given index and return it, moving back all
|
||||
the subsequent objects to close the gap. If the index passed in is out-of-range,
|
||||
nothing will happen and a null pointer will be returned.
|
||||
|
||||
@param indexToRemove the index of the element to remove
|
||||
@see remove, removeObject, removeRange
|
||||
*/
|
||||
ObjectClassPtr removeAndReturn (const int indexToRemove)
|
||||
{
|
||||
ObjectClassPtr removedItem;
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (indexToRemove, numUsed))
|
||||
{
|
||||
ObjectClass** const e = data.elements + indexToRemove;
|
||||
|
||||
if (ObjectClass* o = *e)
|
||||
{
|
||||
removedItem = o;
|
||||
o->decReferenceCount();
|
||||
}
|
||||
|
||||
--numUsed;
|
||||
const int numberToShift = numUsed - indexToRemove;
|
||||
|
||||
if (numberToShift > 0)
|
||||
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift);
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
return removedItem;
|
||||
}
|
||||
|
||||
/** Removes the first occurrence of a specified object from the array.
|
||||
|
||||
If the item isn't found, no action is taken. If it is found, it is
|
||||
removed and has its reference count decreased.
|
||||
|
||||
@param objectToRemove the object to try to remove
|
||||
@see remove, removeRange
|
||||
*/
|
||||
void removeObject (ObjectClass* const objectToRemove)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
remove (indexOf (objectToRemove));
|
||||
}
|
||||
|
||||
/** Removes a range of objects from the array.
|
||||
|
||||
This will remove a set of objects, starting from the given index,
|
||||
and move any subsequent elements down to close the gap.
|
||||
|
||||
If the range extends beyond the bounds of the array, it will
|
||||
be safely clipped to the size of the array.
|
||||
|
||||
The objects that are removed will have their reference counts decreased,
|
||||
and may be deleted if not referenced from elsewhere.
|
||||
|
||||
@param startIndex the index of the first object to remove
|
||||
@param numberToRemove how many objects should be removed
|
||||
@see remove, removeObject
|
||||
*/
|
||||
void removeRange (const int startIndex,
|
||||
const int numberToRemove)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
const int start = blimit (0, numUsed, startIndex);
|
||||
const int endIndex = blimit (0, numUsed, startIndex + numberToRemove);
|
||||
|
||||
if (endIndex > start)
|
||||
{
|
||||
int i;
|
||||
for (i = start; i < endIndex; ++i)
|
||||
{
|
||||
if (ObjectClass* o = data.elements[i])
|
||||
{
|
||||
o->decReferenceCount();
|
||||
data.elements[i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer)
|
||||
}
|
||||
}
|
||||
|
||||
const int rangeSize = endIndex - start;
|
||||
ObjectClass** e = data.elements + start;
|
||||
i = numUsed - endIndex;
|
||||
numUsed -= rangeSize;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
*e = e [rangeSize];
|
||||
++e;
|
||||
}
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the last n objects from the array.
|
||||
|
||||
The objects that are removed will have their reference counts decreased,
|
||||
and may be deleted if not referenced from elsewhere.
|
||||
|
||||
@param howManyToRemove how many objects to remove from the end of the array
|
||||
@see remove, removeObject, removeRange
|
||||
*/
|
||||
void removeLast (int howManyToRemove = 1)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (howManyToRemove > numUsed)
|
||||
howManyToRemove = numUsed;
|
||||
|
||||
while (--howManyToRemove >= 0)
|
||||
remove (numUsed - 1);
|
||||
}
|
||||
|
||||
/** Swaps a pair of objects in the array.
|
||||
|
||||
If either of the indexes passed in is out-of-range, nothing will happen,
|
||||
otherwise the two objects at these positions will be exchanged.
|
||||
*/
|
||||
void swap (const int index1,
|
||||
const int index2) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (index1, numUsed)
|
||||
&& isPositiveAndBelow (index2, numUsed))
|
||||
{
|
||||
std::swap (data.elements [index1],
|
||||
data.elements [index2]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Moves one of the objects to a different position.
|
||||
|
||||
This will move the object to a specified index, shuffling along
|
||||
any intervening elements as required.
|
||||
|
||||
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
||||
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
||||
|
||||
@param currentIndex the index of the object to be moved. If this isn't a
|
||||
valid index, then nothing will be done
|
||||
@param newIndex the index at which you'd like this object to end up. If this
|
||||
is less than zero, it will be moved to the end of the array
|
||||
*/
|
||||
void move (const int currentIndex,
|
||||
int newIndex) noexcept
|
||||
{
|
||||
if (currentIndex != newIndex)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (currentIndex, numUsed))
|
||||
{
|
||||
if (! isPositiveAndBelow (newIndex, numUsed))
|
||||
newIndex = numUsed - 1;
|
||||
|
||||
ObjectClass* const value = data.elements [currentIndex];
|
||||
|
||||
if (newIndex > currentIndex)
|
||||
{
|
||||
memmove (data.elements + currentIndex,
|
||||
data.elements + currentIndex + 1,
|
||||
sizeof (ObjectClass*) * (size_t) (newIndex - currentIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove (data.elements + newIndex + 1,
|
||||
data.elements + newIndex,
|
||||
sizeof (ObjectClass*) * (size_t) (currentIndex - newIndex));
|
||||
}
|
||||
|
||||
data.elements [newIndex] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** This swaps the contents of this array with those of another array.
|
||||
|
||||
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
|
||||
because it just swaps their internal pointers.
|
||||
*/
|
||||
template <class OtherArrayType>
|
||||
void swapWith (OtherArrayType& otherArray) noexcept
|
||||
{
|
||||
const ScopedLockType lock1 (getLock());
|
||||
const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
|
||||
|
||||
data.swapWith (otherArray.data);
|
||||
std::swap (numUsed, otherArray.numUsed);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Compares this array to another one.
|
||||
|
||||
@returns true only if the other array contains the same objects in the same order
|
||||
*/
|
||||
bool operator== (const SharedObjectArray& other) const noexcept
|
||||
{
|
||||
const ScopedLockType lock2 (other.getLock());
|
||||
const ScopedLockType lock1 (getLock());
|
||||
|
||||
if (numUsed != other.numUsed)
|
||||
return false;
|
||||
|
||||
for (int i = numUsed; --i >= 0;)
|
||||
if (data.elements [i] != other.data.elements [i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Compares this array to another one.
|
||||
|
||||
@see operator==
|
||||
*/
|
||||
bool operator!= (const SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the elements in the array.
|
||||
|
||||
This will use a comparator object to sort the elements into order. The object
|
||||
passed must have a method of the form:
|
||||
@code
|
||||
int compareElements (ElementType first, ElementType second);
|
||||
@endcode
|
||||
|
||||
..and this method must return:
|
||||
- a value of < 0 if the first comes before the second
|
||||
- a value of 0 if the two objects are equivalent
|
||||
- a value of > 0 if the second comes before the first
|
||||
|
||||
To improve performance, the compareElements() method can be declared as static or const.
|
||||
|
||||
@param comparator the comparator to use for comparing elements.
|
||||
@param retainOrderOfEquivalentItems if this is true, then items
|
||||
which the comparator says are equivalent will be
|
||||
kept in the order in which they currently appear
|
||||
in the array. This is slower to perform, but may
|
||||
be important in some cases. If it's false, a faster
|
||||
algorithm is used, but equivalent elements may be
|
||||
rearranged.
|
||||
|
||||
@see sortArray
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
void sort (ElementComparator& comparator,
|
||||
const bool retainOrderOfEquivalentItems = false) const noexcept
|
||||
{
|
||||
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
||||
// avoids getting warning messages about the parameter being unused
|
||||
|
||||
const ScopedLockType lock (getLock());
|
||||
sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Reduces the amount of storage being used by the array.
|
||||
|
||||
Arrays typically allocate slightly more storage than they need, and after
|
||||
removing elements, they may have quite a lot of unused space allocated.
|
||||
This method will reduce the amount of allocated storage to a minimum.
|
||||
*/
|
||||
void minimiseStorageOverheads() noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.shrinkToNoMoreThan (numUsed);
|
||||
}
|
||||
|
||||
/** Increases the array's internal storage to hold a minimum number of elements.
|
||||
|
||||
Calling this before adding a large known number of elements means that
|
||||
the array won't have to keep dynamically resizing itself as the elements
|
||||
are added, and it'll therefore be more efficient.
|
||||
*/
|
||||
void ensureStorageAllocated (const int minNumElements)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (minNumElements);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the CriticalSection that locks this array.
|
||||
To lock, you can call getLock().enter() and getLock().exit(), or preferably use
|
||||
an object of ScopedLockType as an RAII lock for it.
|
||||
*/
|
||||
inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data; }
|
||||
|
||||
/** Returns the type of scoped lock to use for locking this array */
|
||||
typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ArrayAllocationBase <ObjectClass*, TypeOfCriticalSectionToUse> data;
|
||||
int numUsed;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,492 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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_SORTEDSET_H_INCLUDED
|
||||
#define BEAST_SORTEDSET_H_INCLUDED
|
||||
|
||||
#if BEAST_MSVC
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4512)
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Holds a set of unique primitive objects, such as ints or doubles.
|
||||
|
||||
A set can only hold one item with a given value, so if for example it's a
|
||||
set of integers, attempting to add the same integer twice will do nothing
|
||||
the second time.
|
||||
|
||||
Internally, the list of items is kept sorted (which means that whatever
|
||||
kind of primitive type is used must support the ==, <, >, <= and >= operators
|
||||
to determine the order), and searching the set for known values is very fast
|
||||
because it uses a binary-chop method.
|
||||
|
||||
Note that if you're using a class or struct as the element type, it must be
|
||||
capable of being copied or moved with a straightforward memcpy, rather than
|
||||
needing construction and destruction code.
|
||||
|
||||
To make all the set's methods thread-safe, pass in "CriticalSection" as the templated
|
||||
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
||||
|
||||
@see Array, OwnedArray, SharedObjectArray, StringArray, CriticalSection
|
||||
*/
|
||||
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
||||
class SortedSet
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty set. */
|
||||
SortedSet() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a copy of another set.
|
||||
@param other the set to copy
|
||||
*/
|
||||
SortedSet (const SortedSet& other)
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~SortedSet() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
/** Copies another set over this one.
|
||||
@param other the set to copy
|
||||
*/
|
||||
SortedSet& operator= (const SortedSet& other) noexcept
|
||||
{
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Compares this set to another one.
|
||||
Two sets are considered equal if they both contain the same set of elements.
|
||||
@param other the other set to compare with
|
||||
*/
|
||||
bool operator== (const SortedSet<ElementType>& other) const noexcept
|
||||
{
|
||||
return data == other.data;
|
||||
}
|
||||
|
||||
/** Compares this set to another one.
|
||||
Two sets are considered equal if they both contain the same set of elements.
|
||||
@param other the other set to compare with
|
||||
*/
|
||||
bool operator!= (const SortedSet<ElementType>& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Removes all elements from the set.
|
||||
|
||||
This will remove all the elements, and free any storage that the set is
|
||||
using. To clear it without freeing the storage, use the clearQuick()
|
||||
method instead.
|
||||
|
||||
@see clearQuick
|
||||
*/
|
||||
void clear() noexcept
|
||||
{
|
||||
data.clear();
|
||||
}
|
||||
|
||||
/** Removes all elements from the set without freeing the array's allocated storage.
|
||||
|
||||
@see clear
|
||||
*/
|
||||
void clearQuick() noexcept
|
||||
{
|
||||
data.clearQuick();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the current number of elements in the set.
|
||||
*/
|
||||
inline int size() const noexcept
|
||||
{
|
||||
return data.size();
|
||||
}
|
||||
|
||||
/** Returns one of the elements in the set.
|
||||
|
||||
If the index passed in is beyond the range of valid elements, this
|
||||
will return zero.
|
||||
|
||||
If you're certain that the index will always be a valid element, you
|
||||
can call getUnchecked() instead, which is faster.
|
||||
|
||||
@param index the index of the element being requested (0 is the first element in the set)
|
||||
@see getUnchecked, getFirst, getLast
|
||||
*/
|
||||
inline ElementType operator[] (const int index) const noexcept
|
||||
{
|
||||
return data [index];
|
||||
}
|
||||
|
||||
/** Returns one of the elements in the set, without checking the index passed in.
|
||||
Unlike the operator[] method, this will try to return an element without
|
||||
checking that the index is within the bounds of the set, so should only
|
||||
be used when you're confident that it will always be a valid index.
|
||||
|
||||
@param index the index of the element being requested (0 is the first element in the set)
|
||||
@see operator[], getFirst, getLast
|
||||
*/
|
||||
inline ElementType getUnchecked (const int index) const noexcept
|
||||
{
|
||||
return data.getUnchecked (index);
|
||||
}
|
||||
|
||||
/** Returns a direct reference to one of the elements in the set, without checking the index passed in.
|
||||
|
||||
This is like getUnchecked, but returns a direct reference to the element, so that
|
||||
you can alter it directly. Obviously this can be dangerous, so only use it when
|
||||
absolutely necessary.
|
||||
|
||||
@param index the index of the element being requested (0 is the first element in the array)
|
||||
*/
|
||||
inline ElementType& getReference (const int index) const noexcept
|
||||
{
|
||||
return data.getReference (index);
|
||||
}
|
||||
|
||||
/** Returns the first element in the set, or 0 if the set is empty.
|
||||
|
||||
@see operator[], getUnchecked, getLast
|
||||
*/
|
||||
inline ElementType getFirst() const noexcept
|
||||
{
|
||||
return data.getFirst();
|
||||
}
|
||||
|
||||
/** Returns the last element in the set, or 0 if the set is empty.
|
||||
|
||||
@see operator[], getUnchecked, getFirst
|
||||
*/
|
||||
inline ElementType getLast() const noexcept
|
||||
{
|
||||
return data.getLast();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a pointer to the first element in the set.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ElementType* begin() const noexcept
|
||||
{
|
||||
return data.begin();
|
||||
}
|
||||
|
||||
/** Returns a pointer to the element which follows the last element in the set.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ElementType* end() const noexcept
|
||||
{
|
||||
return data.end();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Finds the index of the first element which matches the value passed in.
|
||||
|
||||
This will search the set for the given object, and return the index
|
||||
of its first occurrence. If the object isn't found, the method will return -1.
|
||||
|
||||
@param elementToLookFor the value or object to look for
|
||||
@returns the index of the object, or -1 if it's not found
|
||||
*/
|
||||
int indexOf (const ElementType& elementToLookFor) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (data.getLock());
|
||||
|
||||
int s = 0;
|
||||
int e = data.size();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (s >= e)
|
||||
return -1;
|
||||
|
||||
if (elementToLookFor == data.getReference (s))
|
||||
return s;
|
||||
|
||||
const int halfway = (s + e) / 2;
|
||||
|
||||
if (halfway == s)
|
||||
return -1;
|
||||
else if (elementToLookFor < data.getReference (halfway))
|
||||
e = halfway;
|
||||
else
|
||||
s = halfway;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if the set contains at least one occurrence of an object.
|
||||
|
||||
@param elementToLookFor the value or object to look for
|
||||
@returns true if the item is found
|
||||
*/
|
||||
bool contains (const ElementType& elementToLookFor) const noexcept
|
||||
{
|
||||
return indexOf (elementToLookFor) >= 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a new element to the set, (as long as it's not already in there).
|
||||
|
||||
Note that if a matching element already exists, the new value will be assigned
|
||||
to the existing one using operator=, so that if there are any differences between
|
||||
the objects which were not recognised by the object's operator==, then the
|
||||
set will always contain a copy of the most recently added one.
|
||||
|
||||
@param newElement the new object to add to the set
|
||||
@returns true if the value was added, or false if it already existed
|
||||
@see set, insert, addIfNotAlreadyThere, addSorted, addSet, addArray
|
||||
*/
|
||||
bool add (const ElementType& newElement) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
int s = 0;
|
||||
int e = data.size();
|
||||
|
||||
while (s < e)
|
||||
{
|
||||
ElementType& elem = data.getReference (s);
|
||||
if (newElement == elem)
|
||||
{
|
||||
elem = newElement; // force an update in case operator== permits differences.
|
||||
return false;
|
||||
}
|
||||
|
||||
const int halfway = (s + e) / 2;
|
||||
const bool isBeforeHalfway = (newElement < data.getReference (halfway));
|
||||
|
||||
if (halfway == s)
|
||||
{
|
||||
if (! isBeforeHalfway)
|
||||
++s;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (isBeforeHalfway)
|
||||
e = halfway;
|
||||
else
|
||||
s = halfway;
|
||||
}
|
||||
|
||||
data.insert (s, newElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Adds elements from an array to this set.
|
||||
|
||||
@param elementsToAdd the array of elements to add
|
||||
@param numElementsToAdd how many elements are in this other array
|
||||
@see add
|
||||
*/
|
||||
void addArray (const ElementType* elementsToAdd,
|
||||
int numElementsToAdd) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
while (--numElementsToAdd >= 0)
|
||||
add (*elementsToAdd++);
|
||||
}
|
||||
|
||||
/** Adds elements from another set to this one.
|
||||
|
||||
@param setToAddFrom the set from which to copy the elements
|
||||
@param startIndex the first element of the other set to start copying from
|
||||
@param numElementsToAdd how many elements to add from the other set. If this
|
||||
value is negative or greater than the number of available elements,
|
||||
all available elements will be copied.
|
||||
@see add
|
||||
*/
|
||||
template <class OtherSetType>
|
||||
void addSet (const OtherSetType& setToAddFrom,
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1) noexcept
|
||||
{
|
||||
const typename OtherSetType::ScopedLockType lock1 (setToAddFrom.getLock());
|
||||
|
||||
{
|
||||
const ScopedLockType lock2 (getLock());
|
||||
bassert (this != &setToAddFrom);
|
||||
|
||||
if (this != &setToAddFrom)
|
||||
{
|
||||
if (startIndex < 0)
|
||||
{
|
||||
bassertfalse;
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > setToAddFrom.size())
|
||||
numElementsToAdd = setToAddFrom.size() - startIndex;
|
||||
|
||||
if (numElementsToAdd > 0)
|
||||
addArray (&setToAddFrom.data.getReference (startIndex), numElementsToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Removes an element from the set.
|
||||
|
||||
This will remove the element at a given index.
|
||||
If the index passed in is out-of-range, nothing will happen.
|
||||
|
||||
@param indexToRemove the index of the element to remove
|
||||
@returns the element that has been removed
|
||||
@see removeValue, removeRange
|
||||
*/
|
||||
ElementType remove (const int indexToRemove) noexcept
|
||||
{
|
||||
return data.remove (indexToRemove);
|
||||
}
|
||||
|
||||
/** Removes an item from the set.
|
||||
|
||||
This will remove the given element from the set, if it's there.
|
||||
|
||||
@param valueToRemove the object to try to remove
|
||||
@see remove, removeRange
|
||||
*/
|
||||
void removeValue (const ElementType valueToRemove) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.remove (indexOf (valueToRemove));
|
||||
}
|
||||
|
||||
/** Removes any elements which are also in another set.
|
||||
|
||||
@param otherSet the other set in which to look for elements to remove
|
||||
@see removeValuesNotIn, remove, removeValue, removeRange
|
||||
*/
|
||||
template <class OtherSetType>
|
||||
void removeValuesIn (const OtherSetType& otherSet) noexcept
|
||||
{
|
||||
const typename OtherSetType::ScopedLockType lock1 (otherSet.getLock());
|
||||
const ScopedLockType lock2 (getLock());
|
||||
|
||||
if (this == &otherSet)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else if (otherSet.size() > 0)
|
||||
{
|
||||
for (int i = data.size(); --i >= 0;)
|
||||
if (otherSet.contains (data.getReference (i)))
|
||||
remove (i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes any elements which are not found in another set.
|
||||
|
||||
Only elements which occur in this other set will be retained.
|
||||
|
||||
@param otherSet the set in which to look for elements NOT to remove
|
||||
@see removeValuesIn, remove, removeValue, removeRange
|
||||
*/
|
||||
template <class OtherSetType>
|
||||
void removeValuesNotIn (const OtherSetType& otherSet) noexcept
|
||||
{
|
||||
const typename OtherSetType::ScopedLockType lock1 (otherSet.getLock());
|
||||
const ScopedLockType lock2 (getLock());
|
||||
|
||||
if (this != &otherSet)
|
||||
{
|
||||
if (otherSet.size() <= 0)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = data.size(); --i >= 0;)
|
||||
if (! otherSet.contains (data.getReference (i)))
|
||||
remove (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This swaps the contents of this array with those of another array.
|
||||
|
||||
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
|
||||
because it just swaps their internal pointers.
|
||||
*/
|
||||
template <class OtherSortedSetType>
|
||||
void swapWith (OtherSortedSetType& otherSet) noexcept
|
||||
{
|
||||
data.swapWith (otherSet.data);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Reduces the amount of storage being used by the set.
|
||||
|
||||
Sets typically allocate slightly more storage than they need, and after
|
||||
removing elements, they may have quite a lot of unused space allocated.
|
||||
This method will reduce the amount of allocated storage to a minimum.
|
||||
*/
|
||||
void minimiseStorageOverheads() noexcept
|
||||
{
|
||||
data.minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
/** Increases the set's internal storage to hold a minimum number of elements.
|
||||
|
||||
Calling this before adding a large known number of elements means that
|
||||
the set won't have to keep dynamically resizing itself as the elements
|
||||
are added, and it'll therefore be more efficient.
|
||||
*/
|
||||
void ensureStorageAllocated (const int minNumElements)
|
||||
{
|
||||
data.ensureStorageAllocated (minNumElements);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the CriticalSection that locks this array.
|
||||
To lock, you can call getLock().enter() and getLock().exit(), or preferably use
|
||||
an object of ScopedLockType as an RAII lock for it.
|
||||
*/
|
||||
inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data.getLock(); }
|
||||
|
||||
/** Returns the type of scoped lock to use for locking this array */
|
||||
typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Array <ElementType, TypeOfCriticalSectionToUse> data;
|
||||
};
|
||||
|
||||
#if BEAST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,264 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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_EXPRESSION_H_INCLUDED
|
||||
#define BEAST_EXPRESSION_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for dynamically evaluating simple numeric expressions.
|
||||
|
||||
This class can parse a simple C-style string expression involving floating point
|
||||
numbers, named symbols and functions. The basic arithmetic operations of +, -, *, /
|
||||
are supported, as well as parentheses, and any alphanumeric identifiers are
|
||||
assumed to be named symbols which will be resolved when the expression is
|
||||
evaluated.
|
||||
|
||||
Expressions which use identifiers and functions require a subclass of
|
||||
Expression::Scope to be supplied when evaluating them, and this object
|
||||
is expected to be able to resolve the symbol names and perform the functions that
|
||||
are used.
|
||||
*/
|
||||
class BEAST_API Expression
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a simple expression with a value of 0. */
|
||||
Expression();
|
||||
|
||||
/** Destructor. */
|
||||
~Expression();
|
||||
|
||||
/** Creates a simple expression with a specified constant value. */
|
||||
explicit Expression (double constant);
|
||||
|
||||
/** Creates a copy of an expression. */
|
||||
Expression (const Expression& other);
|
||||
|
||||
/** Copies another expression. */
|
||||
Expression& operator= (const Expression& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Expression (Expression&& other) noexcept;
|
||||
Expression& operator= (Expression&& other) noexcept;
|
||||
#endif
|
||||
|
||||
/** Creates an expression by parsing a string.
|
||||
If there's a syntax error in the string, this will throw a ParseError exception.
|
||||
@throws ParseError
|
||||
*/
|
||||
explicit Expression (const String& stringToParse);
|
||||
|
||||
/** Returns a string version of the expression. */
|
||||
String toString() const;
|
||||
|
||||
/** Returns an expression which is an addtion operation of two existing expressions. */
|
||||
Expression operator+ (const Expression& other) const;
|
||||
/** Returns an expression which is a subtraction operation of two existing expressions. */
|
||||
Expression operator- (const Expression& other) const;
|
||||
/** Returns an expression which is a multiplication operation of two existing expressions. */
|
||||
Expression operator* (const Expression& other) const;
|
||||
/** Returns an expression which is a division operation of two existing expressions. */
|
||||
Expression operator/ (const Expression& other) const;
|
||||
/** Returns an expression which performs a negation operation on an existing expression. */
|
||||
Expression operator-() const;
|
||||
|
||||
/** Returns an Expression which is an identifier reference. */
|
||||
static Expression symbol (const String& symbol);
|
||||
|
||||
/** Returns an Expression which is a function call. */
|
||||
static Expression function (const String& functionName, const Array<Expression>& parameters);
|
||||
|
||||
/** Returns an Expression which parses a string from a character pointer, and updates the pointer
|
||||
to indicate where it finished.
|
||||
|
||||
The pointer is incremented so that on return, it indicates the character that follows
|
||||
the end of the expression that was parsed.
|
||||
|
||||
If there's a syntax error in the string, this will throw a ParseError exception.
|
||||
@throws ParseError
|
||||
*/
|
||||
static Expression parse (String::CharPointerType& stringToParse);
|
||||
|
||||
//==============================================================================
|
||||
/** When evaluating an Expression object, this class is used to resolve symbols and
|
||||
perform functions that the expression uses.
|
||||
*/
|
||||
class BEAST_API Scope
|
||||
{
|
||||
public:
|
||||
Scope();
|
||||
virtual ~Scope();
|
||||
|
||||
/** Returns some kind of globally unique ID that identifies this scope. */
|
||||
virtual String getScopeUID() const;
|
||||
|
||||
/** Returns the value of a symbol.
|
||||
If the symbol is unknown, this can throw an Expression::EvaluationError exception.
|
||||
The member value is set to the part of the symbol that followed the dot, if there is
|
||||
one, e.g. for "foo.bar", symbol = "foo" and member = "bar".
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual Expression getSymbolValue (const String& symbol) const;
|
||||
|
||||
/** Executes a named function.
|
||||
If the function name is unknown, this can throw an Expression::EvaluationError exception.
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
virtual double evaluateFunction (const String& functionName,
|
||||
const double* parameters, int numParameters) const;
|
||||
|
||||
/** Used as a callback by the Scope::visitRelativeScope() method.
|
||||
You should never create an instance of this class yourself, it's used by the
|
||||
expression evaluation code.
|
||||
*/
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() {}
|
||||
virtual void visit (const Scope&) = 0;
|
||||
};
|
||||
|
||||
/** Creates a Scope object for a named scope, and then calls a visitor
|
||||
to do some kind of processing with this new scope.
|
||||
|
||||
If the name is valid, this method must create a suitable (temporary) Scope
|
||||
object to represent it, and must call the Visitor::visit() method with this
|
||||
new scope.
|
||||
*/
|
||||
virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const;
|
||||
};
|
||||
|
||||
/** Evaluates this expression, without using a Scope.
|
||||
Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan,
|
||||
min, max are available.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate() const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
To find out about any errors during evaluation, use the other version of this method which
|
||||
takes a String parameter.
|
||||
*/
|
||||
double evaluate (const Scope& scope) const;
|
||||
|
||||
/** Evaluates this expression, providing a scope that should be able to evaluate any symbols
|
||||
or functions that it uses.
|
||||
*/
|
||||
double evaluate (const Scope& scope, String& evaluationError) const;
|
||||
|
||||
/** Attempts to return an expression which is a copy of this one, but with a constant adjusted
|
||||
to make the expression resolve to a target value.
|
||||
|
||||
E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return
|
||||
the expression "x + 3". Obviously some expressions can't be reversed in this way, in which
|
||||
case they might just be adjusted by adding a constant to the original expression.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const;
|
||||
|
||||
/** Represents a symbol that is used in an Expression. */
|
||||
struct Symbol
|
||||
{
|
||||
Symbol (const String& scopeUID, const String& symbolName);
|
||||
bool operator== (const Symbol&) const noexcept;
|
||||
bool operator!= (const Symbol&) const noexcept;
|
||||
|
||||
String scopeUID; /**< The unique ID of the Scope that contains this symbol. */
|
||||
String symbolName; /**< The name of the symbol. */
|
||||
};
|
||||
|
||||
/** Returns a copy of this expression in which all instances of a given symbol have been renamed. */
|
||||
Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression makes use of the specified symbol.
|
||||
If a suitable scope is supplied, the search will dereference and recursively check
|
||||
all symbols, so that it can be determined whether this expression relies on the given
|
||||
symbol at any level in its evaluation. If the scope parameter is null, this just checks
|
||||
whether the expression contains any direct references to the symbol.
|
||||
|
||||
@throws Expression::EvaluationError
|
||||
*/
|
||||
bool referencesSymbol (const Symbol& symbol, const Scope& scope) const;
|
||||
|
||||
/** Returns true if this expression contains any symbols. */
|
||||
bool usesAnySymbols() const;
|
||||
|
||||
/** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */
|
||||
void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const;
|
||||
|
||||
//==============================================================================
|
||||
/** An exception that can be thrown by Expression::parse(). */
|
||||
class ParseError : public std::exception
|
||||
{
|
||||
public:
|
||||
ParseError (const String& message);
|
||||
|
||||
String description;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Expression type.
|
||||
@see Expression::getType()
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
constantType,
|
||||
functionType,
|
||||
operatorType,
|
||||
symbolType
|
||||
};
|
||||
|
||||
/** Returns the type of this expression. */
|
||||
Type getType() const noexcept;
|
||||
|
||||
/** If this expression is a symbol, function or operator, this returns its identifier. */
|
||||
String getSymbolOrFunction() const;
|
||||
|
||||
/** Returns the number of inputs to this expression.
|
||||
@see getInput
|
||||
*/
|
||||
int getNumInputs() const;
|
||||
|
||||
/** Retrieves one of the inputs to this expression.
|
||||
@see getNumInputs
|
||||
*/
|
||||
Expression getInput (int index) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class Term;
|
||||
struct Helpers;
|
||||
friend class Term;
|
||||
friend struct Helpers;
|
||||
friend class ScopedPointer<Term>;
|
||||
friend class SharedPtr<Term>;
|
||||
SharedPtr<Term> term;
|
||||
|
||||
explicit Expression (Term*);
|
||||
};
|
||||
|
||||
#endif // BEAST_EXPRESSION_H_INCLUDED
|
||||
@@ -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_H_INCLUDED
|
||||
#define BEAST_INTERVAL_H_INCLUDED
|
||||
|
||||
/** 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,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_H_INCLUDED
|
||||
#define BEAST_ATOMICCOUNTER_H_INCLUDED
|
||||
|
||||
/*============================================================================*/
|
||||
/**
|
||||
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 BEAST_API 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_H_INCLUDED
|
||||
#define BEAST_ATOMICFLAG_H_INCLUDED
|
||||
|
||||
/*============================================================================*/
|
||||
/**
|
||||
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 BEAST_API 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_H_INCLUDED
|
||||
#define BEAST_ATOMICPOINTER_H_INCLUDED
|
||||
|
||||
/*============================================================================*/
|
||||
/**
|
||||
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_H_INCLUDED
|
||||
#define BEAST_ATOMICSTATE_H_INCLUDED
|
||||
|
||||
/*============================================================================*/
|
||||
/**
|
||||
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 BEAST_API 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,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_RECYCLEDOBJECTPOOL_H_INCLUDED
|
||||
#define BEAST_RECYCLEDOBJECTPOOL_H_INCLUDED
|
||||
|
||||
/** A pool of objects which may be recycled.
|
||||
|
||||
This is a thread safe pool of objects that get re-used. It is
|
||||
primarily designed to eliminate the need for many memory allocations
|
||||
and frees when temporary buffers are needed for operations.
|
||||
|
||||
To use it, first declare a structure containing the information
|
||||
that you want to recycle. Then when you want to use a recycled object
|
||||
put a ScopedItem on your stack:
|
||||
|
||||
@code
|
||||
|
||||
struct StdString
|
||||
{
|
||||
std::string data;
|
||||
};
|
||||
|
||||
RecycledObjectPool <StdString> pool;
|
||||
|
||||
void foo ()
|
||||
{
|
||||
RecycledObjectPool <StdString>::ScopedItem item;
|
||||
|
||||
item.getObject ().data = "text";
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
template <class Object>
|
||||
class RecycledObjectPool
|
||||
{
|
||||
public:
|
||||
struct Item : Object, LockFreeStack <Item>::Node, LeakChecked <Item>
|
||||
{
|
||||
};
|
||||
|
||||
class ScopedItem
|
||||
{
|
||||
public:
|
||||
explicit ScopedItem (RecycledObjectPool <Object>& pool)
|
||||
: m_pool (pool)
|
||||
, m_item (pool.get ())
|
||||
{
|
||||
}
|
||||
|
||||
~ScopedItem ()
|
||||
{
|
||||
m_pool.release (m_item);
|
||||
}
|
||||
|
||||
Object& getObject () noexcept
|
||||
{
|
||||
return *m_item;
|
||||
}
|
||||
|
||||
private:
|
||||
RecycledObjectPool <Object>& m_pool;
|
||||
Item* const m_item;
|
||||
};
|
||||
|
||||
public:
|
||||
RecycledObjectPool () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
~RecycledObjectPool ()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Item* const item = m_stack.pop_front ();
|
||||
|
||||
if (item != nullptr)
|
||||
delete item;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Item* get ()
|
||||
{
|
||||
Item* item = m_stack.pop_front ();
|
||||
|
||||
if (item == nullptr)
|
||||
{
|
||||
item = new Item;
|
||||
|
||||
if (item == nullptr)
|
||||
Throw (std::bad_alloc ());
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void release (Item* item) noexcept
|
||||
{
|
||||
m_stack.push_front (item);
|
||||
}
|
||||
|
||||
private:
|
||||
LockFreeStack <Item> m_stack;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,204 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.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_WEAKREFERENCE_H_INCLUDED
|
||||
#define BEAST_WEAKREFERENCE_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This class acts as a pointer which will automatically become null if the object
|
||||
to which it points is deleted.
|
||||
|
||||
To accomplish this, the source object needs to cooperate by performing a couple of simple tasks.
|
||||
It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear
|
||||
this master pointer in its destructor.
|
||||
|
||||
E.g.
|
||||
@code
|
||||
class MyObject
|
||||
{
|
||||
public:
|
||||
MyObject()
|
||||
{
|
||||
// If you're planning on using your WeakReferences in a multi-threaded situation, you may choose
|
||||
// to create a WeakReference to the object here in the constructor, which will pre-initialise the
|
||||
// embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple
|
||||
// threads overlap while creating the first WeakReference to it.
|
||||
}
|
||||
|
||||
~MyObject()
|
||||
{
|
||||
// This will zero all the references - you need to call this in your destructor.
|
||||
masterReference.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
// You need to embed a variable of this type, with the name "masterReference" inside your object. If the
|
||||
// variable is not public, you should make your class a friend of WeakReference<MyObject> so that the
|
||||
// WeakReference class can access it.
|
||||
WeakReference<MyObject>::Master masterReference;
|
||||
friend class WeakReference<MyObject>;
|
||||
};
|
||||
|
||||
// Here's an example of using a pointer..
|
||||
|
||||
MyObject* n = new MyObject();
|
||||
WeakReference<MyObject> myObjectRef = n;
|
||||
|
||||
MyObject* pointer1 = myObjectRef; // returns a valid pointer to 'n'
|
||||
delete n;
|
||||
MyObject* pointer2 = myObjectRef; // returns a null pointer
|
||||
@endcode
|
||||
|
||||
@see WeakReference::Master
|
||||
*/
|
||||
template <class ObjectType, class ReferenceCountingType = SharedObject>
|
||||
class WeakReference
|
||||
{
|
||||
public:
|
||||
/** Creates a null SafePointer. */
|
||||
inline WeakReference() noexcept {}
|
||||
|
||||
/** Creates a WeakReference that points at the given object. */
|
||||
WeakReference (ObjectType* const object) : holder (getRef (object)) {}
|
||||
|
||||
/** Creates a copy of another WeakReference. */
|
||||
WeakReference (const WeakReference& other) noexcept : holder (other.holder) {}
|
||||
|
||||
/** Copies another pointer to this one. */
|
||||
WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; }
|
||||
|
||||
/** Copies another pointer to this one. */
|
||||
WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; }
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
WeakReference (WeakReference&& other) noexcept : holder (static_cast <SharedRef&&> (other.holder)) {}
|
||||
WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast <SharedRef&&> (other.holder); return *this; }
|
||||
#endif
|
||||
|
||||
/** Returns the object that this pointer refers to, or null if the object no longer exists. */
|
||||
ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; }
|
||||
|
||||
/** Returns the object that this pointer refers to, or null if the object no longer exists. */
|
||||
operator ObjectType*() const noexcept { return get(); }
|
||||
|
||||
/** Returns the object that this pointer refers to, or null if the object no longer exists. */
|
||||
ObjectType* operator->() noexcept { return get(); }
|
||||
|
||||
/** Returns the object that this pointer refers to, or null if the object no longer exists. */
|
||||
const ObjectType* operator->() const noexcept { return get(); }
|
||||
|
||||
/** This returns true if this reference has been pointing at an object, but that object has
|
||||
since been deleted.
|
||||
|
||||
If this reference was only ever pointing at a null pointer, this will return false. Using
|
||||
operator=() to make this refer to a different object will reset this flag to match the status
|
||||
of the reference from which you're copying.
|
||||
*/
|
||||
bool wasObjectDeleted() const noexcept { return holder != nullptr && holder->get() == nullptr; }
|
||||
|
||||
bool operator== (ObjectType* const object) const noexcept { return get() == object; }
|
||||
bool operator!= (ObjectType* const object) const noexcept { return get() != object; }
|
||||
|
||||
//==============================================================================
|
||||
/** This class is used internally by the WeakReference class - don't use it directly
|
||||
in your code!
|
||||
@see WeakReference
|
||||
*/
|
||||
class SharedPointer
|
||||
: public ReferenceCountingType
|
||||
, public Uncopyable
|
||||
{
|
||||
public:
|
||||
explicit SharedPointer (ObjectType* const obj) noexcept : owner (obj) {}
|
||||
|
||||
inline ObjectType* get() const noexcept { return owner; }
|
||||
void clearPointer() noexcept { owner = nullptr; }
|
||||
|
||||
private:
|
||||
ObjectType* volatile owner;
|
||||
};
|
||||
|
||||
typedef SharedPtr<SharedPointer> SharedRef;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This class is embedded inside an object to which you want to attach WeakReference pointers.
|
||||
See the WeakReference class notes for an example of how to use this class.
|
||||
@see WeakReference
|
||||
*/
|
||||
class Master : public Uncopyable
|
||||
{
|
||||
public:
|
||||
Master() noexcept {}
|
||||
|
||||
~Master()
|
||||
{
|
||||
// You must remember to call clear() in your source object's destructor! See the notes
|
||||
// for the WeakReference class for an example of how to do this.
|
||||
bassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);
|
||||
}
|
||||
|
||||
/** The first call to this method will create an internal object that is shared by all weak
|
||||
references to the object.
|
||||
*/
|
||||
SharedPointer* getSharedPointer (ObjectType* const object)
|
||||
{
|
||||
if (sharedPointer == nullptr)
|
||||
{
|
||||
sharedPointer = new SharedPointer (object);
|
||||
}
|
||||
else
|
||||
{
|
||||
// You're trying to create a weak reference to an object that has already been deleted!!
|
||||
bassert (sharedPointer->get() != nullptr);
|
||||
}
|
||||
|
||||
return sharedPointer;
|
||||
}
|
||||
|
||||
/** The object that owns this master pointer should call this before it gets destroyed,
|
||||
to zero all the references to this object that may be out there. See the WeakReference
|
||||
class notes for an example of how to do this.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
if (sharedPointer != nullptr)
|
||||
sharedPointer->clearPointer();
|
||||
}
|
||||
|
||||
private:
|
||||
SharedRef sharedPointer;
|
||||
};
|
||||
|
||||
private:
|
||||
SharedRef holder;
|
||||
|
||||
static inline SharedPointer* getRef (ObjectType* const o)
|
||||
{
|
||||
return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // BEAST_WEAKREFERENCE_H_INCLUDED
|
||||
@@ -63,7 +63,8 @@ namespace functional
|
||||
using std::ref;
|
||||
using std::cref;
|
||||
using std::bind;
|
||||
using std::function;
|
||||
|
||||
//using std::function;
|
||||
|
||||
}
|
||||
|
||||
@@ -166,7 +167,8 @@ namespace functional
|
||||
using std::tr1::ref;
|
||||
using std::tr1::cref;
|
||||
using std::tr1::bind;
|
||||
using std::tr1::function;
|
||||
|
||||
//using std::tr1::function;
|
||||
|
||||
}
|
||||
|
||||
@@ -269,7 +271,8 @@ namespace functional
|
||||
using boost::ref;
|
||||
using boost::cref;
|
||||
using boost::bind;
|
||||
using boost::function;
|
||||
|
||||
//using boost::function;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,125 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
Semaphore::Semaphore (int initialCount)
|
||||
: m_counter (initialCount)
|
||||
{
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore ()
|
||||
{
|
||||
// Can't delete the semaphore while threads are waiting on it!!
|
||||
bassert (m_waitingThreads.pop_front () == nullptr);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
WaitingThread* waitingThread = m_deleteList.pop_front ();
|
||||
|
||||
if (waitingThread != nullptr)
|
||||
delete waitingThread;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Semaphore::signal (int amount)
|
||||
{
|
||||
bassert (amount > 0);
|
||||
|
||||
while (amount--)
|
||||
{
|
||||
// Make counter and list operations atomic.
|
||||
LockType::ScopedLockType lock (m_mutex);
|
||||
|
||||
if (++m_counter <= 0)
|
||||
{
|
||||
WaitingThread* waitingThread = m_waitingThreads.pop_front ();
|
||||
|
||||
bassert (waitingThread != nullptr);
|
||||
|
||||
waitingThread->signal ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Semaphore::wait (int timeOutMilliseconds)
|
||||
{
|
||||
bool signaled = true;
|
||||
|
||||
// Always prepare the WaitingThread object first, either
|
||||
// from the delete list or through a new allocation.
|
||||
//
|
||||
WaitingThread* waitingThread = m_deleteList.pop_front ();
|
||||
|
||||
if (waitingThread == nullptr)
|
||||
waitingThread = new WaitingThread;
|
||||
|
||||
{
|
||||
// Make counter and list operations atomic.
|
||||
LockType::ScopedLockType lock (m_mutex);
|
||||
|
||||
if (--m_counter >= 0)
|
||||
{
|
||||
// Acquired the resource so put waitingThread back.
|
||||
m_deleteList.push_front (waitingThread);
|
||||
|
||||
waitingThread = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Out of resources, go on to the waiting list.
|
||||
m_waitingThreads.push_front (waitingThread);
|
||||
}
|
||||
}
|
||||
|
||||
// Do we need to wait?
|
||||
if (waitingThread != nullptr)
|
||||
{
|
||||
// Yes so do it.
|
||||
signaled = waitingThread->wait (timeOutMilliseconds);
|
||||
|
||||
// If the wait is satisfied, then we've been taken off the
|
||||
// waiting list so put waitingThread back in the delete list.
|
||||
//
|
||||
m_deleteList.push_front (waitingThread);
|
||||
}
|
||||
|
||||
return signaled;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Semaphore::WaitingThread::WaitingThread ()
|
||||
: m_event (false) // auto-reset
|
||||
{
|
||||
}
|
||||
|
||||
bool Semaphore::WaitingThread::wait (int timeOutMilliseconds)
|
||||
{
|
||||
return m_event.wait (timeOutMilliseconds);
|
||||
}
|
||||
|
||||
void Semaphore::WaitingThread::signal ()
|
||||
{
|
||||
m_event.signal ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// VFALCO TODO Unit Tests!
|
||||
@@ -1,82 +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_SEMAPHORE_H_INCLUDED
|
||||
#define BEAST_SEMAPHORE_H_INCLUDED
|
||||
|
||||
/*============================================================================*/
|
||||
/**
|
||||
A semaphore.
|
||||
|
||||
This provides a traditional semaphore synchronization primitive. There is no
|
||||
upper limit on the number of signals.
|
||||
|
||||
@note There is no tryWait() or timeout facility for acquiring a resource.
|
||||
|
||||
@ingroup beast_core
|
||||
*/
|
||||
class BEAST_API Semaphore
|
||||
{
|
||||
public:
|
||||
/** Create a semaphore with the specified number of resources.
|
||||
|
||||
@param initialCount The starting number of resources.
|
||||
*/
|
||||
explicit Semaphore (int initialCount = 0);
|
||||
|
||||
~Semaphore ();
|
||||
|
||||
/** Increase the number of available resources.
|
||||
|
||||
@param amount The number of new resources available.
|
||||
*/
|
||||
void signal (int amount = 1);
|
||||
|
||||
/** Wait for a resource.
|
||||
|
||||
A negative time-out value means that the method will wait indefinitely.
|
||||
|
||||
@returns true if the event has been signalled, false if the timeout expires.
|
||||
*/
|
||||
bool wait (int timeOutMilliseconds = -1);
|
||||
|
||||
private:
|
||||
class WaitingThread
|
||||
: public LockFreeStack <WaitingThread>::Node
|
||||
, LeakChecked <WaitingThread>
|
||||
{
|
||||
public:
|
||||
WaitingThread ();
|
||||
|
||||
bool wait (int timeOutMilliseconds);
|
||||
void signal ();
|
||||
|
||||
private:
|
||||
WaitableEvent m_event;
|
||||
};
|
||||
|
||||
typedef SpinLock LockType;
|
||||
|
||||
LockType m_mutex;
|
||||
Atomic <int> m_counter;
|
||||
LockFreeStack <WaitingThread> m_waitingThreads;
|
||||
LockFreeStack <WaitingThread> m_deleteList;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -134,7 +134,7 @@ private:
|
||||
CPUMeter m_usage; // CPU utilization across threads
|
||||
String m_threadNames; // The name to give each thread
|
||||
WaitableEvent m_allPaused; // signaled when all threads paused
|
||||
Semaphore m_semaphore; // each pending task is 1 resource
|
||||
semaphore m_semaphore; // each pending task is 1 resource
|
||||
int m_numberOfThreads; // how many we want active now
|
||||
Atomic <int> m_activeCount; // to know when all are paused
|
||||
Atomic <int> m_pauseCount; // how many threads need to pause now
|
||||
|
||||
@@ -1,30 +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 "BeastConfig.h"
|
||||
|
||||
#include "beast_crypto.h"
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#include "math/BinaryEncoding.cpp"
|
||||
#include "math/UnsignedInteger.cpp"
|
||||
|
||||
}
|
||||
@@ -1,53 +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_BEAST_CRYPTO_H_INCLUDED
|
||||
#define BEAST_BEAST_CRYPTO_H_INCLUDED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* If you fail to make sure that all your compile units are building Beast with
|
||||
the same set of option flags, then there's a risk that different compile
|
||||
units will treat the classes as having different memory layouts, leading to
|
||||
very nasty memory corruption errors when they all get linked together.
|
||||
That's why it's best to always include the BeastConfig.h file before any
|
||||
beast headers.
|
||||
*/
|
||||
#ifndef BEAST_BEASTCONFIG_H_INCLUDED
|
||||
# ifdef _MSC_VER
|
||||
# pragma message ("Have you included your BeastConfig.h file before including the Beast headers?")
|
||||
# else
|
||||
# warning "Have you included your BeastConfig.h file before including the Beast headers?"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "../beast_core/beast_core.h"
|
||||
#include "../../beast/crypto/MurmurHash.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast {
|
||||
|
||||
# include "math/UnsignedIntegerCalc.h"
|
||||
#include "math/UnsignedInteger.h"
|
||||
#include "math/BinaryEncoding.h"
|
||||
|
||||
}
|
||||
|
||||
#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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "beast_db.h"
|
||||
|
||||
#include "../beast_crypto/beast_crypto.h"
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#if BEAST_GCC
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#include "keyvalue/KeyvaDB.cpp"
|
||||
#if BEAST_GCC
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,51 +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_BEAST_DB_H_INCLUDED
|
||||
#define BEAST_BEAST_DB_H_INCLUDED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* If you fail to make sure that all your compile units are building Beast with
|
||||
the same set of option flags, then there's a risk that different compile
|
||||
units will treat the classes as having different memory layouts, leading to
|
||||
very nasty memory corruption errors when they all get linked together.
|
||||
That's why it's best to always include the BeastConfig.h file before any
|
||||
beast headers.
|
||||
*/
|
||||
#ifndef BEAST_BEASTCONFIG_H_INCLUDED
|
||||
# ifdef _MSC_VER
|
||||
# pragma message ("Have you included your BeastConfig.h file before including the Beast headers?")
|
||||
# else
|
||||
# warning "Have you included your BeastConfig.h file before including the Beast headers?"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "../beast_core/beast_core.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#include "keyvalue/KeyvaDB.h"
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,861 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
|
||||
TODO
|
||||
|
||||
- Check consistency / range checking on read
|
||||
|
||||
- Cache top level tree nodes
|
||||
|
||||
- Coalesce I/O in RandomAccessFile
|
||||
|
||||
- Delete / file compaction
|
||||
|
||||
*/
|
||||
|
||||
class KeyvaDBImp : public KeyvaDB
|
||||
{
|
||||
private:
|
||||
// These are stored in big endian format in the file.
|
||||
|
||||
// A file offset.
|
||||
typedef int64 FileOffset;
|
||||
|
||||
// Index of a key.
|
||||
//
|
||||
// The value is broken up into two parts. The key block index,
|
||||
// and a 1 based index within the keyblock corresponding to the
|
||||
// internal key number.
|
||||
//
|
||||
typedef int32 KeyIndex;
|
||||
typedef int32 KeyBlockIndex;
|
||||
|
||||
// Size of a value.
|
||||
typedef uint32 ByteSize;
|
||||
|
||||
private:
|
||||
// returns the number of keys in a key block with the specified depth
|
||||
static int calcKeysAtDepth (int depth)
|
||||
{
|
||||
return (1U << depth) - 1;
|
||||
}
|
||||
|
||||
// returns the number of bytes in a key record
|
||||
static int calcKeyRecordBytes (int keyBytes)
|
||||
{
|
||||
// This depends on the format of a serialized key record
|
||||
return
|
||||
sizeof (FileOffset) +
|
||||
sizeof (ByteSize) +
|
||||
sizeof (KeyIndex) +
|
||||
sizeof (KeyIndex) +
|
||||
keyBytes
|
||||
;
|
||||
}
|
||||
|
||||
// returns the number of bytes in a key block
|
||||
static int calcKeyBlockBytes (int depth, int keyBytes)
|
||||
{
|
||||
return calcKeysAtDepth (depth) * calcKeyRecordBytes (keyBytes);
|
||||
}
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
currentVersion = 1
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct KeyAddress
|
||||
{
|
||||
// 1 based key block number
|
||||
uint32 blockNumber;
|
||||
|
||||
// 1 based key index within the block, breadth-first left to right
|
||||
uint32 keyNumber;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// The size of the fixed area at the beginning of the key file.
|
||||
// This is used to store some housekeeping information like the
|
||||
// key size and version number.
|
||||
//
|
||||
masterHeaderBytes = 1000
|
||||
};
|
||||
|
||||
// The master record is at the beginning of the key file
|
||||
struct MasterRecord
|
||||
{
|
||||
// version number, starting from 1
|
||||
int32 version;
|
||||
|
||||
KeyBlockIndex nextKeyBlockIndex;
|
||||
|
||||
void write (OutputStream& stream)
|
||||
{
|
||||
stream.writeTypeBigEndian (version);
|
||||
}
|
||||
|
||||
void read (InputStream& stream)
|
||||
{
|
||||
stream.readTypeBigEndianInto (&version);
|
||||
}
|
||||
};
|
||||
|
||||
// Key records are indexed starting at one.
|
||||
struct KeyRecord : public Uncopyable
|
||||
{
|
||||
explicit KeyRecord (void* const keyStorage)
|
||||
: key (keyStorage)
|
||||
{
|
||||
}
|
||||
|
||||
// Absolute byte FileOffset in the value file.
|
||||
FileOffset valFileOffset;
|
||||
|
||||
// Size of the corresponding value, in bytes.
|
||||
ByteSize valSize;
|
||||
|
||||
// Key record index of left node, or 0.
|
||||
KeyIndex leftIndex;
|
||||
|
||||
// Key record index of right node, or 0.
|
||||
KeyIndex rightIndex;
|
||||
|
||||
// Points to keyBytes storage of the key.
|
||||
void* const key;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// A complete keyblock. The contents of the memory for the key block
|
||||
// are identical to the format on disk. Therefore it is necessary to
|
||||
// use the serialization routines to extract or update the key records.
|
||||
//
|
||||
class KeyBlock : public Uncopyable
|
||||
{
|
||||
public:
|
||||
KeyBlock (int depth, int keyBytes)
|
||||
: m_depth (depth)
|
||||
, m_keyBytes (keyBytes)
|
||||
, m_storage (calcKeyBlockBytes (depth, keyBytes))
|
||||
{
|
||||
}
|
||||
|
||||
void read (InputStream& stream)
|
||||
{
|
||||
stream.read (m_storage.getData (), calcKeyBlockBytes (m_depth, m_keyBytes));
|
||||
}
|
||||
|
||||
void write (OutputStream& stream)
|
||||
{
|
||||
stream.write (m_storage.getData (), calcKeyBlockBytes (m_depth, m_keyBytes));
|
||||
}
|
||||
|
||||
void readKeyRecord (KeyRecord* keyRecord, int keyIndex)
|
||||
{
|
||||
bassert (keyIndex >=1 && keyIndex <= calcKeysAtDepth (m_depth));
|
||||
|
||||
size_t const byteOffset = (keyIndex - 1) * calcKeyRecordBytes (m_keyBytes);
|
||||
|
||||
MemoryInputStream stream (
|
||||
addBytesToPointer (m_storage.getData (), byteOffset),
|
||||
calcKeyRecordBytes (m_keyBytes),
|
||||
false);
|
||||
|
||||
stream.readTypeBigEndianInto (&keyRecord->valFileOffset);
|
||||
stream.readTypeBigEndianInto (&keyRecord->valSize);
|
||||
stream.readTypeBigEndianInto (&keyRecord->leftIndex);
|
||||
stream.readTypeBigEndianInto (&keyRecord->rightIndex);
|
||||
stream.read (keyRecord->key, m_keyBytes);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void writeKeyRecord (KeyRecord const& keyRecord, int keyIndex)
|
||||
{
|
||||
bassert (keyIndex >=1 && keyIndex <= calcKeysAtDepth (m_depth));
|
||||
|
||||
#if 0
|
||||
size_t const byteOffset = (keyIndex - 1) * calcKeyRecordBytes (m_keyBytes);
|
||||
|
||||
MemoryOutputStream stream (
|
||||
addBytesToPointer (m_storage.getData (), byteOffset),
|
||||
calcKeyRecordBytes (m_keyBytes));
|
||||
|
||||
stream.writeTypeBigEndian (keyRecord.valFileOffset);
|
||||
stream.writeTypeBigEndian (keyRecord.valSize);
|
||||
stream.writeTypeBigEndian (keyRecord.leftIndex);
|
||||
stream.writeTypeBigEndian (keyRecord.rightIndex);
|
||||
stream.write (keyRecord.key, m_keyBytes);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
int const m_depth;
|
||||
int const m_keyBytes;
|
||||
MemoryBlock m_storage;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Concurrent data
|
||||
//
|
||||
struct State
|
||||
{
|
||||
RandomAccessFile keyFile;
|
||||
RandomAccessFile valFile;
|
||||
MasterRecord masterRecord;
|
||||
KeyIndex newKeyIndex;
|
||||
FileOffset valFileSize;
|
||||
|
||||
bool hasKeys () const noexcept
|
||||
{
|
||||
return newKeyIndex > 1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedData <State> SharedState;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
int const m_keyBytes;
|
||||
int const m_keyBlockDepth;
|
||||
SharedState m_state;
|
||||
HeapBlock <char> m_keyStorage;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
KeyvaDBImp (int keyBytes,
|
||||
int keyBlockDepth,
|
||||
File keyPath,
|
||||
File valPath)
|
||||
: m_keyBytes (keyBytes)
|
||||
, m_keyBlockDepth (keyBlockDepth)
|
||||
, m_keyStorage (keyBytes)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
openFile (&state->keyFile, keyPath);
|
||||
|
||||
int64 const fileSize = state->keyFile.getFile ().getSize ();
|
||||
|
||||
if (fileSize == 0)
|
||||
{
|
||||
// VFALCO TODO Better error handling here
|
||||
// initialize the key file
|
||||
Result result = state->keyFile.setPosition (masterHeaderBytes - 1);
|
||||
if (result.wasOk ())
|
||||
{
|
||||
char byte = 0;
|
||||
|
||||
result = state->keyFile.write (&byte, 1);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
state->keyFile.flush ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state->newKeyIndex = 1 + static_cast <KeyIndex> ((state->keyFile.getFile ().getSize () - masterHeaderBytes)
|
||||
/ calcKeyRecordBytes (m_keyBytes));
|
||||
|
||||
openFile (&state->valFile, valPath);
|
||||
|
||||
state->valFileSize = state->valFile.getFile ().getSize ();
|
||||
}
|
||||
|
||||
~KeyvaDBImp ()
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
flushInternal (state);
|
||||
}
|
||||
|
||||
// Open a file for reading and writing.
|
||||
// Creates the file if it doesn't exist.
|
||||
static void openFile (RandomAccessFile* file, File path)
|
||||
{
|
||||
Result const result = file->open (path, RandomAccessFile::readWrite);
|
||||
|
||||
if (! result)
|
||||
{
|
||||
String s;
|
||||
s << "KeyvaDB: Couldn't open " << path.getFileName () << " for writing.";
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Result createMasterRecord (SharedState::Access& state)
|
||||
{
|
||||
MemoryBlock buffer (masterHeaderBytes, true);
|
||||
|
||||
Result result = state->keyFile.setPosition (0);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
//MasterRecord mr;
|
||||
|
||||
//mr.version = 1;
|
||||
|
||||
result = state->keyFile.write (buffer.getData (), buffer.getSize ());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
FileOffset calcKeyRecordOffset (KeyIndex keyIndex)
|
||||
{
|
||||
bassert (keyIndex > 0);
|
||||
|
||||
FileOffset const byteOffset = masterHeaderBytes + (keyIndex - 1) * calcKeyRecordBytes (m_keyBytes);
|
||||
|
||||
return byteOffset;
|
||||
}
|
||||
|
||||
// Read a key record into memory.
|
||||
// VFALCO TODO Return a Result and do validity checking on all inputs
|
||||
//
|
||||
void readKeyRecord (KeyRecord* const keyRecord,
|
||||
KeyIndex const keyIndex,
|
||||
SharedState::Access& state)
|
||||
{
|
||||
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
||||
|
||||
Result result = state->keyFile.setPosition (byteOffset);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
MemoryBlock data (calcKeyRecordBytes (m_keyBytes));
|
||||
|
||||
size_t bytesRead;
|
||||
|
||||
result = state->keyFile.read (data.getData (), calcKeyRecordBytes (m_keyBytes), &bytesRead);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
if (bytesRead == static_cast <size_t> (calcKeyRecordBytes (m_keyBytes)))
|
||||
{
|
||||
MemoryInputStream stream (data, false);
|
||||
|
||||
// This defines the file format!
|
||||
stream.readTypeBigEndianInto (&keyRecord->valFileOffset);
|
||||
stream.readTypeBigEndianInto (&keyRecord->valSize);
|
||||
stream.readTypeBigEndianInto (&keyRecord->leftIndex);
|
||||
stream.readTypeBigEndianInto (&keyRecord->rightIndex);
|
||||
|
||||
// Grab the key
|
||||
stream.read (keyRecord->key, m_keyBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Result::fail ("KeyvaDB: amountRead != calcKeyRecordBytes()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! result.wasOk ())
|
||||
{
|
||||
String s;
|
||||
s << "KeyvaDB readKeyRecord failed in " << state->keyFile.getFile ().getFileName ();
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
|
||||
// Write a key record from memory
|
||||
void writeKeyRecord (KeyRecord const& keyRecord,
|
||||
KeyIndex const keyIndex,
|
||||
SharedState::Access& state,
|
||||
bool includingKey)
|
||||
{
|
||||
FileOffset const byteOffset = calcKeyRecordOffset (keyIndex);
|
||||
|
||||
int const bytes = calcKeyRecordBytes (m_keyBytes) - (includingKey ? 0 : m_keyBytes);
|
||||
|
||||
// VFALCO TODO Recycle this buffer
|
||||
MemoryBlock data (bytes);
|
||||
|
||||
{
|
||||
MemoryOutputStream stream (data, false);
|
||||
|
||||
// This defines the file format!
|
||||
stream.writeTypeBigEndian (keyRecord.valFileOffset);
|
||||
stream.writeTypeBigEndian (keyRecord.valSize);
|
||||
stream.writeTypeBigEndian (keyRecord.leftIndex);
|
||||
stream.writeTypeBigEndian (keyRecord.rightIndex);
|
||||
|
||||
// Write the key
|
||||
if (includingKey)
|
||||
stream.write (keyRecord.key, m_keyBytes);
|
||||
}
|
||||
|
||||
Result result = state->keyFile.setPosition (byteOffset);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
size_t bytesWritten;
|
||||
|
||||
result = state->keyFile.write (data.getData (), bytes, &bytesWritten);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
if (bytesWritten != static_cast <size_t> (bytes))
|
||||
{
|
||||
result = Result::fail ("KeyvaDB: bytesWritten != bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.wasOk ())
|
||||
{
|
||||
String s;
|
||||
s << "KeyvaDB: writeKeyRecord failed in " << state->keyFile.getFile ().getFileName ();
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
|
||||
// Append a value to the value file.
|
||||
// VFALCO TODO return a Result
|
||||
void writeValue (void const* const value, ByteSize valueBytes, SharedState::Access& state)
|
||||
{
|
||||
Result result = state->valFile.setPosition (state->valFileSize);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
size_t bytesWritten;
|
||||
|
||||
result = state->valFile.write (value, valueBytes, &bytesWritten);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
if (bytesWritten == valueBytes)
|
||||
{
|
||||
state->valFileSize += valueBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Result::fail ("KeyvaDB: bytesWritten != valueBytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! result.wasOk ())
|
||||
{
|
||||
String s;
|
||||
s << "KeyvaDB: writeValue failed in " << state->valFile.getFile ().getFileName ();
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct FindResult : public Uncopyable
|
||||
{
|
||||
FindResult (void* const keyStorage)
|
||||
: keyRecord (keyStorage)
|
||||
{
|
||||
}
|
||||
|
||||
int compare; // result of the last comparison
|
||||
KeyIndex keyIndex; // index we looked at last
|
||||
//KeyBlock keyBlock; // KeyBlock we looked at last
|
||||
KeyRecord keyRecord; // KeyRecord we looked at last
|
||||
};
|
||||
|
||||
// Find a key. If the key doesn't exist, enough information
|
||||
// is left behind in the result to perform an insertion.
|
||||
//
|
||||
// Returns true if the key was found.
|
||||
//
|
||||
bool find (FindResult* findResult, void const* key, SharedState::Access& state)
|
||||
{
|
||||
// Not okay to call this with an empty key file!
|
||||
bassert (state->hasKeys ());
|
||||
|
||||
// This performs a standard binary search
|
||||
|
||||
findResult->keyIndex = 1;
|
||||
|
||||
do
|
||||
{
|
||||
readKeyRecord (&findResult->keyRecord, findResult->keyIndex, state);
|
||||
|
||||
findResult->compare = memcmp (key, findResult->keyRecord.key, m_keyBytes);
|
||||
|
||||
if (findResult->compare < 0)
|
||||
{
|
||||
if (findResult->keyRecord.leftIndex != 0)
|
||||
{
|
||||
// Go left
|
||||
findResult->keyIndex = findResult->keyRecord.leftIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert position is to the left
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (findResult->compare > 0)
|
||||
{
|
||||
if (findResult->keyRecord.rightIndex != 0)
|
||||
{
|
||||
// Go right
|
||||
findResult->keyIndex = findResult->keyRecord.rightIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert position is to the right
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (findResult->compare != 0);
|
||||
|
||||
return findResult->compare == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool get (void const* key, GetCallback* callback)
|
||||
{
|
||||
FindResult findResult (m_keyStorage.getData ());
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
bool found = false;
|
||||
|
||||
if (state->hasKeys ())
|
||||
{
|
||||
found = find (&findResult, key, state);
|
||||
|
||||
if (found)
|
||||
{
|
||||
void* const destStorage = callback->getStorageForValue (findResult.keyRecord.valSize);
|
||||
|
||||
Result result = state->valFile.setPosition (findResult.keyRecord.valFileOffset);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
size_t bytesRead;
|
||||
|
||||
result = state->valFile.read (destStorage, findResult.keyRecord.valSize, &bytesRead);
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
if (bytesRead != findResult.keyRecord.valSize)
|
||||
{
|
||||
result = Result::fail ("KeyvaDB: bytesRead != valSize");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! result.wasOk ())
|
||||
{
|
||||
String s;
|
||||
s << "KeyvaDB: get in " << state->valFile.getFile ().getFileName ();
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Write a key value pair. Does nothing if the key exists.
|
||||
void put (void const* key, void const* value, int valueBytes)
|
||||
{
|
||||
bassert (valueBytes > 0);
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
if (state->hasKeys ())
|
||||
{
|
||||
// Search for the key
|
||||
|
||||
FindResult findResult (m_keyStorage.getData ());
|
||||
|
||||
bool const found = find (&findResult, key, state);
|
||||
|
||||
if (! found )
|
||||
{
|
||||
bassert (findResult.compare != 0);
|
||||
|
||||
// Binary tree insertion.
|
||||
// Link the last key record to the new key
|
||||
{
|
||||
if (findResult.compare < 0)
|
||||
{
|
||||
findResult.keyRecord.leftIndex = state->newKeyIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
findResult.keyRecord.rightIndex = state->newKeyIndex;
|
||||
}
|
||||
|
||||
writeKeyRecord (findResult.keyRecord, findResult.keyIndex, state, false);
|
||||
}
|
||||
|
||||
// Write the new key
|
||||
{
|
||||
findResult.keyRecord.valFileOffset = state->valFileSize;
|
||||
findResult.keyRecord.valSize = valueBytes;
|
||||
findResult.keyRecord.leftIndex = 0;
|
||||
findResult.keyRecord.rightIndex = 0;
|
||||
|
||||
memcpy (findResult.keyRecord.key, key, m_keyBytes);
|
||||
|
||||
writeKeyRecord (findResult.keyRecord, state->newKeyIndex, state, true);
|
||||
}
|
||||
|
||||
// Key file has grown by one.
|
||||
++state->newKeyIndex;
|
||||
|
||||
// Write the value
|
||||
writeValue (value, valueBytes, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key already exists, do nothing.
|
||||
// We could check to make sure the payloads are the same.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Write first key
|
||||
//
|
||||
|
||||
KeyRecord keyRecord (m_keyStorage.getData ());
|
||||
|
||||
keyRecord.valFileOffset = state->valFileSize;
|
||||
keyRecord.valSize = valueBytes;
|
||||
keyRecord.leftIndex = 0;
|
||||
keyRecord.rightIndex = 0;
|
||||
|
||||
memcpy (keyRecord.key, key, m_keyBytes);
|
||||
|
||||
writeKeyRecord (keyRecord, state->newKeyIndex, state, true);
|
||||
|
||||
// Key file has grown by one.
|
||||
++state->newKeyIndex;
|
||||
|
||||
//
|
||||
// Write value
|
||||
//
|
||||
|
||||
bassert (state->valFileSize == 0);
|
||||
|
||||
writeValue (value, valueBytes, state);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void flush ()
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
flushInternal (state);
|
||||
}
|
||||
|
||||
void flushInternal (SharedState::Access& state)
|
||||
{
|
||||
state->keyFile.flush ();
|
||||
state->valFile.flush ();
|
||||
}
|
||||
};
|
||||
|
||||
KeyvaDB* KeyvaDB::New (int keyBytes, int keyBlockDepth, File keyPath, File valPath)
|
||||
{
|
||||
return new KeyvaDBImp (keyBytes, keyBlockDepth, keyPath, valPath);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class KeyvaDBTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
maxPayloadBytes = 8 * 1024
|
||||
};
|
||||
|
||||
// Retrieval callback stores the value in a Payload object for comparison
|
||||
struct PayloadGetCallback : KeyvaDB::GetCallback
|
||||
{
|
||||
UnitTestUtilities::Payload payload;
|
||||
|
||||
PayloadGetCallback () : payload (maxPayloadBytes)
|
||||
{
|
||||
}
|
||||
|
||||
void* getStorageForValue (int valueBytes)
|
||||
{
|
||||
bassert (valueBytes <= maxPayloadBytes);
|
||||
|
||||
payload.bytes = valueBytes;
|
||||
|
||||
return payload.data.getData ();
|
||||
}
|
||||
};
|
||||
|
||||
KeyvaDB* createDB (unsigned int keyBytes, File const& path)
|
||||
{
|
||||
File const keyPath = path.withFileExtension (".key");
|
||||
File const valPath = path.withFileExtension (".val");
|
||||
|
||||
return KeyvaDB::New (keyBytes, 1, keyPath, valPath);
|
||||
}
|
||||
|
||||
void deleteDBFiles (File const& path)
|
||||
{
|
||||
File const keyPath = path.withFileExtension (".key");
|
||||
File const valPath = path.withFileExtension (".val");
|
||||
|
||||
keyPath.deleteFile ();
|
||||
valPath.deleteFile ();
|
||||
}
|
||||
|
||||
template <size_t KeyBytes>
|
||||
void testKeySize (unsigned int const maxItems)
|
||||
{
|
||||
using namespace UnitTestUtilities;
|
||||
|
||||
typedef UnsignedInteger <KeyBytes> KeyType;
|
||||
|
||||
int64 const seedValue = 50;
|
||||
|
||||
String s;
|
||||
|
||||
s << "keyBytes=" << String (uint64(KeyBytes)) << ", maxItems=" << String (maxItems);
|
||||
beginTestCase (s);
|
||||
|
||||
// Set up the key and value files
|
||||
File const path (File::createTempFile (""));
|
||||
|
||||
{
|
||||
// open the db
|
||||
ScopedPointer <KeyvaDB> db (createDB (KeyBytes, path));
|
||||
|
||||
Payload payload (maxPayloadBytes);
|
||||
Payload check (maxPayloadBytes);
|
||||
|
||||
{
|
||||
// Create an array of ascending integers.
|
||||
HeapBlock <unsigned int> items (maxItems);
|
||||
for (unsigned int i = 0; i < maxItems; ++i)
|
||||
items [i] = i;
|
||||
|
||||
// Now shuffle it deterministically.
|
||||
repeatableShuffle (maxItems, items, seedValue);
|
||||
|
||||
// Write all the keys of integers.
|
||||
for (unsigned int i = 0; i < maxItems; ++i)
|
||||
{
|
||||
unsigned int keyIndex = items [i];
|
||||
|
||||
KeyType const key = KeyType::createFromInteger (keyIndex);
|
||||
|
||||
payload.repeatableRandomFill (1, maxPayloadBytes, keyIndex + seedValue);
|
||||
|
||||
db->put (key.cbegin (), payload.data.getData (), payload.bytes);
|
||||
|
||||
{
|
||||
// VFALCO TODO Check what we just wrote?
|
||||
//db->get (key.cbegin (), check.data.getData (), payload.bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Go through all of our keys and try to retrieve them.
|
||||
// since this is done in ascending order, we should get
|
||||
// random seeks at this point.
|
||||
//
|
||||
PayloadGetCallback cb;
|
||||
for (unsigned int keyIndex = 0; keyIndex < maxItems; ++keyIndex)
|
||||
{
|
||||
KeyType const v = KeyType::createFromInteger (keyIndex);
|
||||
|
||||
bool const found = db->get (v.cbegin (), &cb);
|
||||
|
||||
expect (found, "Should be found");
|
||||
|
||||
if (found)
|
||||
{
|
||||
payload.repeatableRandomFill (1, maxPayloadBytes, keyIndex + seedValue);
|
||||
|
||||
expect (payload == cb.payload, "Should be equal");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Re-open the database and confirm the data
|
||||
ScopedPointer <KeyvaDB> db (createDB (KeyBytes, path));
|
||||
|
||||
Payload payload (maxPayloadBytes);
|
||||
Payload check (maxPayloadBytes);
|
||||
|
||||
PayloadGetCallback cb;
|
||||
for (unsigned int keyIndex = 0; keyIndex < maxItems; ++keyIndex)
|
||||
{
|
||||
KeyType const v = KeyType::createFromInteger (keyIndex);
|
||||
|
||||
bool const found = db->get (v.cbegin (), &cb);
|
||||
|
||||
expect (found, "Should be found");
|
||||
|
||||
if (found)
|
||||
{
|
||||
payload.repeatableRandomFill (1, maxPayloadBytes, keyIndex + seedValue);
|
||||
|
||||
expect (payload == cb.payload, "Should be equal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deleteDBFiles (path);
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testKeySize <4> (500);
|
||||
testKeySize <32> (4000);
|
||||
}
|
||||
|
||||
KeyvaDBTests () : UnitTest ("KeyvaDB", "beast", runManual)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static KeyvaDBTests keyvaDBTests;
|
||||
@@ -1,55 +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_KEYVADB_H_INCLUDED
|
||||
#define BEAST_KEYVADB_H_INCLUDED
|
||||
|
||||
/** Specialized Key/value database
|
||||
|
||||
Once written, a value can never be modified.
|
||||
*/
|
||||
class KeyvaDB : LeakChecked <KeyvaDB>
|
||||
{
|
||||
public:
|
||||
class GetCallback
|
||||
{
|
||||
public:
|
||||
virtual void* getStorageForValue (int valueBytes) = 0;
|
||||
};
|
||||
|
||||
static KeyvaDB* New (int keyBytes,
|
||||
int keyBlockDepth,
|
||||
File keyPath,
|
||||
File valPath);
|
||||
|
||||
virtual ~KeyvaDB () { }
|
||||
|
||||
// VFALCO TODO Make the return value a Result so we can
|
||||
// detect corruption and errors!
|
||||
//
|
||||
virtual bool get (void const* key, GetCallback* callback) = 0;
|
||||
|
||||
// VFALCO TODO Use Result for return value
|
||||
//
|
||||
virtual void put (void const* key, void const* value, int valueBytes) = 0;
|
||||
|
||||
virtual void flush () = 0;
|
||||
};
|
||||
|
||||
#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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "beast_extras.h"
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,43 +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_EXTRAS_H_INCLUDED
|
||||
#define BEAST_EXTRAS_H_INCLUDED
|
||||
|
||||
// Adds boost-specific features to beast.
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// lockable_traits was added in 1.53.0
|
||||
#ifndef BEAST_BOOST_HAS_LOCKABLES
|
||||
# if BOOST_VERSION >= 105300
|
||||
# define BEAST_BOOST_HAS_LOCKABLES 1
|
||||
# else
|
||||
# define BEAST_BOOST_HAS_LOCKABLES 0
|
||||
# endif
|
||||
#endif
|
||||
#if BEAST_BOOST_HAS_LOCKABLES
|
||||
# include <boost/thread/lockable_traits.hpp>
|
||||
#endif
|
||||
|
||||
#if BEAST_BOOST_HAS_LOCKABLES
|
||||
# include "traits/BoostLockableTraits.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,125 +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_BOOSTLOCKABLERAITS_H_INCLUDED
|
||||
#define BEAST_BOOSTLOCKABLERAITS_H_INCLUDED
|
||||
|
||||
// Adds beast specializations for boost lockables.
|
||||
|
||||
// beast forward declarations
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
class CriticalSection;
|
||||
|
||||
template <typename Mutex>
|
||||
class TrackedMutex;
|
||||
|
||||
template <typename Mutex>
|
||||
class UntrackedMutex;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// boost Mutex concepts
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace sync
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// CriticalSection
|
||||
//
|
||||
|
||||
// BasicLockable
|
||||
//
|
||||
template <>
|
||||
struct is_basic_lockable <beast::CriticalSection>
|
||||
: public boost::true_type { };
|
||||
|
||||
// Lockable
|
||||
//
|
||||
template <>
|
||||
struct is_lockable <beast::CriticalSection>
|
||||
: public boost::true_type { };
|
||||
|
||||
// RecursiveLockable
|
||||
//
|
||||
template <>
|
||||
struct is_recursive_mutex_sur_parole <beast::CriticalSection>
|
||||
: public boost::true_type { };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// TrackedMutex <>
|
||||
//
|
||||
|
||||
// BasicLockable
|
||||
//
|
||||
template <class Mutex>
|
||||
class is_basic_lockable <beast::TrackedMutex <Mutex> >
|
||||
: public boost::sync::is_basic_lockable <Mutex> { };
|
||||
|
||||
// Lockable
|
||||
//
|
||||
template <class Mutex>
|
||||
class is_lockable <beast::TrackedMutex <Mutex> >
|
||||
: public boost::sync::is_lockable <Mutex> { };
|
||||
|
||||
// RecursiveLockable
|
||||
//
|
||||
template <class Mutex>
|
||||
struct is_recursive_mutex_sur_parole <beast::TrackedMutex <Mutex> >
|
||||
: public boost::true_type { };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// UntrackedMutex <>
|
||||
//
|
||||
|
||||
// BasicLockable
|
||||
//
|
||||
template <class Mutex>
|
||||
class is_basic_lockable <beast::UntrackedMutex <Mutex> >
|
||||
: public boost::sync::is_basic_lockable <Mutex> { };
|
||||
|
||||
// Lockable
|
||||
//
|
||||
template <class Mutex>
|
||||
class is_lockable <beast::UntrackedMutex <Mutex> >
|
||||
: public boost::sync::is_lockable <Mutex> { };
|
||||
|
||||
// RecursiveLockable
|
||||
//
|
||||
template <class Mutex>
|
||||
struct is_recursive_mutex_sur_parole <beast::UntrackedMutex <Mutex> >
|
||||
: public boost::true_type { };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user