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:
Vinnie Falco
2013-12-31 08:28:12 -08:00
parent 3a895ccfaa
commit 496b337b27
82 changed files with 396 additions and 7789 deletions

View File

@@ -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>

View File

@@ -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">

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -34,4 +34,6 @@
#include "threads/WaitableEvent.h"
#include "threads/ScopedWrapperContext.h"
#include "threads/semaphore.h"
#endif

View File

@@ -20,5 +20,4 @@
#ifndef BEAST_CRYPTO_BINARYENCODING_H_INCLUDED
#define BEAST_CRYPTO_BINARYENCODING_H_INCLUDED
#endif

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -20,15 +20,16 @@
#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;
};

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -29,7 +29,7 @@ namespace insight {
class NullCollector : public Collector
{
public:
static shared_ptr <Collector> New ();
static std::shared_ptr <Collector> New ();
};
}

View File

@@ -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);
};

View File

@@ -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> ();
}
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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,8 +74,8 @@ 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 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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
};
}

View File

@@ -19,7 +19,4 @@
#include "BeastConfig.h"
#include "function.h"
#include "shared_ptr.h"
#include "thread.h"
#include "unique_ptr.h"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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
View 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

View File

@@ -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.

View File

@@ -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"

View File

@@ -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"
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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!

View File

@@ -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

View File

@@ -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

View File

@@ -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"
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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
{
}

View File

@@ -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

View File

@@ -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