mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Remove obsolete beast container classes
This commit is contained in:
@@ -219,8 +219,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\containers\ArrayAllocationBase.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\ArrayAllocationBase.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicObject.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\DynamicObject.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\ElementComparator.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\ElementComparator.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicArray.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\HashMap.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\LinkedListPointer.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\LinkedListPointer.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\LockFreeQueue.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\LockFreeQueue.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\NamedValueSet.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\NamedValueSet.h" />
|
||||||
@@ -228,8 +226,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\containers\PropertySet.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\PropertySet.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SharedObjectArray.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\SharedObjectArray.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\ScopedValueSetter.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\ScopedValueSetter.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SharedTable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SortedLookupTable.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SortedSet.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\SortedSet.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SparseSet.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\SparseSet.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicList.h" />
|
<ClInclude Include="..\..\modules\beast_core\containers\DynamicList.h" />
|
||||||
@@ -701,24 +697,12 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicArray.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\containers\DynamicList.cpp">
|
<ClCompile Include="..\..\modules\beast_core\containers\DynamicList.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\HashMap.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\diagnostic\Assert.cpp">
|
<ClCompile Include="..\..\modules\beast_core\diagnostic\Assert.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
|||||||
@@ -587,12 +587,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h">
|
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h">
|
||||||
<Filter>beast_core\threads</Filter>
|
<Filter>beast_core\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SharedTable.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\SortedLookupTable.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\diagnostic\FPUFlags.h">
|
<ClInclude Include="..\..\modules\beast_core\diagnostic\FPUFlags.h">
|
||||||
<Filter>beast_core\diagnostic</Filter>
|
<Filter>beast_core\diagnostic</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -827,12 +821,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicList.h">
|
<ClInclude Include="..\..\modules\beast_core\containers\DynamicList.h">
|
||||||
<Filter>beast_core\containers</Filter>
|
<Filter>beast_core\containers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\DynamicArray.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\containers\HashMap.h">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\beast\intrusive\ForwardList.h">
|
<ClInclude Include="..\..\beast\intrusive\ForwardList.h">
|
||||||
<Filter>beast\intrusive</Filter>
|
<Filter>beast\intrusive</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1634,15 +1622,9 @@
|
|||||||
<ClCompile Include="..\..\modules\beast_core\system\SystemStats.cpp">
|
<ClCompile Include="..\..\modules\beast_core\system\SystemStats.cpp">
|
||||||
<Filter>beast_core\system</Filter>
|
<Filter>beast_core\system</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicArray.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicList.cpp">
|
<ClCompile Include="..\..\modules\beast_core\containers\DynamicList.cpp">
|
||||||
<Filter>beast_core\containers</Filter>
|
<Filter>beast_core\containers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\HashMap.cpp">
|
|
||||||
<Filter>beast_core\containers</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_asio\async\SharedHandler.cpp">
|
<ClCompile Include="..\..\modules\beast_asio\async\SharedHandler.cpp">
|
||||||
<Filter>beast_asio\async</Filter>
|
<Filter>beast_asio\async</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
9
TODO.txt
9
TODO.txt
@@ -17,13 +17,6 @@ BEAST TODO
|
|||||||
|
|
||||||
- Import secp256k1 from sipa
|
- Import secp256k1 from sipa
|
||||||
|
|
||||||
- HashMap work:
|
|
||||||
- Add unit test
|
|
||||||
- Return size_t from hash function, take out upperLimit, move mod % to caller
|
|
||||||
- Make hash function a functor using operator()
|
|
||||||
- Implement HardenedHashFunctions
|
|
||||||
- Fix problem with assigning to the result of operator[] maybe use a proxy?
|
|
||||||
|
|
||||||
- Set sqlite thread safety model to '2' in beast_sqlite
|
- Set sqlite thread safety model to '2' in beast_sqlite
|
||||||
|
|
||||||
- Document and rename all the sqdb files and classes
|
- Document and rename all the sqdb files and classes
|
||||||
@@ -60,8 +53,6 @@ BEAST TODO
|
|||||||
|
|
||||||
- Rename malloc/calloc JUCE members that conflict with the debug CRT from MSVC
|
- Rename malloc/calloc JUCE members that conflict with the debug CRT from MSVC
|
||||||
|
|
||||||
- Make beast::HashMap support assignment via operator[]
|
|
||||||
|
|
||||||
- Reformat every Doxygen comment
|
- Reformat every Doxygen comment
|
||||||
- Fix Doxygen metatags
|
- Fix Doxygen metatags
|
||||||
- update Beast Doxyfile
|
- update Beast Doxyfile
|
||||||
|
|||||||
@@ -134,9 +134,7 @@ namespace beast
|
|||||||
#include "containers/NamedValueSet.cpp"
|
#include "containers/NamedValueSet.cpp"
|
||||||
#include "containers/PropertySet.cpp"
|
#include "containers/PropertySet.cpp"
|
||||||
#include "containers/Variant.cpp"
|
#include "containers/Variant.cpp"
|
||||||
#include "containers/DynamicArray.cpp"
|
|
||||||
#include "containers/DynamicList.cpp"
|
#include "containers/DynamicList.cpp"
|
||||||
#include "containers/HashMap.cpp"
|
|
||||||
|
|
||||||
#include "diagnostic/FatalError.cpp"
|
#include "diagnostic/FatalError.cpp"
|
||||||
#include "diagnostic/FPUFlags.cpp"
|
#include "diagnostic/FPUFlags.cpp"
|
||||||
|
|||||||
@@ -177,14 +177,10 @@ class FileOutputStream;
|
|||||||
#include "containers/PropertySet.h"
|
#include "containers/PropertySet.h"
|
||||||
#include "containers/SharedObjectArray.h"
|
#include "containers/SharedObjectArray.h"
|
||||||
#include "containers/ScopedValueSetter.h"
|
#include "containers/ScopedValueSetter.h"
|
||||||
#include "containers/SharedTable.h"
|
|
||||||
#include "containers/SortedLookupTable.h"
|
|
||||||
#include "containers/SortedSet.h"
|
#include "containers/SortedSet.h"
|
||||||
#include "maths/Range.h"
|
#include "maths/Range.h"
|
||||||
#include "containers/SparseSet.h"
|
#include "containers/SparseSet.h"
|
||||||
# include "containers/DynamicList.h"
|
# include "containers/DynamicList.h"
|
||||||
# include "containers/DynamicArray.h"
|
|
||||||
#include "containers/HashMap.h"
|
|
||||||
#include "memory/ScopedPointer.h"
|
#include "memory/ScopedPointer.h"
|
||||||
#include "files/DirectoryIterator.h"
|
#include "files/DirectoryIterator.h"
|
||||||
#include "streams/InputStream.h"
|
#include "streams/InputStream.h"
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class DynamicArrayTests : public UnitTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct T
|
|
||||||
{
|
|
||||||
T ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit T (String what)
|
|
||||||
: msg (what)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator= (T const& other)
|
|
||||||
{
|
|
||||||
msg = other.msg;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
numberToAssign = 1000 * 1000,
|
|
||||||
numberToReserve = 1000 * 1000,
|
|
||||||
numberToMutate = 12139
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void testAssign ()
|
|
||||||
{
|
|
||||||
String s;
|
|
||||||
s << "assign (" << String::fromNumber <int> (numberToAssign) << ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
|
|
||||||
DynamicArray <T> v;
|
|
||||||
v.assign (numberToAssign);
|
|
||||||
|
|
||||||
pass ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void testReserve ()
|
|
||||||
{
|
|
||||||
String s;
|
|
||||||
s << "reserve (" << String::fromNumber <int> (numberToReserve) << ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
|
|
||||||
DynamicArray <T> v;
|
|
||||||
v.reserve (numberToReserve);
|
|
||||||
|
|
||||||
v.assign (numberToReserve);
|
|
||||||
|
|
||||||
pass ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void testMutate ()
|
|
||||||
{
|
|
||||||
String s;
|
|
||||||
DynamicArray <T> v;
|
|
||||||
|
|
||||||
s = "push_back (" + String::fromNumber <int> (numberToMutate) + ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
for (std::size_t i = 0; i < numberToMutate; ++i)
|
|
||||||
v.push_back (T (String::fromNumber (i)));
|
|
||||||
pass ();
|
|
||||||
|
|
||||||
s = "read [] (" + String::fromNumber <int> (numberToMutate) + ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
for (std::size_t i = 0; i < numberToMutate; ++i)
|
|
||||||
expect (v [i].msg == String::fromNumber (i));
|
|
||||||
|
|
||||||
s = "write [] (" + String::fromNumber <int> (numberToMutate) + ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
for (std::size_t i = 0; i < numberToMutate; ++i)
|
|
||||||
v [i].msg = "+" + String::fromNumber (i);
|
|
||||||
pass ();
|
|
||||||
|
|
||||||
s = "verify [] (" + String::fromNumber <int> (numberToMutate) + ")";
|
|
||||||
beginTestCase (s);
|
|
||||||
for (std::size_t i = 0; i < numberToMutate; ++i)
|
|
||||||
expect (v [i].msg == String ("+") + String::fromNumber (i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void testIterate ()
|
|
||||||
{
|
|
||||||
typedef DynamicArray <T> V;
|
|
||||||
|
|
||||||
V v;
|
|
||||||
for (std::size_t i = 0; i < numberToMutate; ++i)
|
|
||||||
v.push_back (T (String::fromNumber (i)));
|
|
||||||
|
|
||||||
{
|
|
||||||
int step = 1;
|
|
||||||
beginTestCase ("iterator");
|
|
||||||
V::iterator iter;
|
|
||||||
for (iter = v.begin (); iter + step < v.end (); iter += step)
|
|
||||||
{
|
|
||||||
step ++;
|
|
||||||
V::difference_type d = iter - v.begin ();
|
|
||||||
expect (iter->msg == String::fromNumber (d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int step = 1;
|
|
||||||
beginTestCase ("const_iterator");
|
|
||||||
V::const_iterator iter;
|
|
||||||
for (iter = v.begin (); iter + step < v.end (); iter += step)
|
|
||||||
{
|
|
||||||
step ++;
|
|
||||||
V::difference_type d = iter - v.begin ();
|
|
||||||
expect (iter->msg == String::fromNumber (d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int step = 1;
|
|
||||||
beginTestCase ("reverse_iterator");
|
|
||||||
V::reverse_iterator iter;
|
|
||||||
for (iter = v.rbegin (); iter + step < v.rend (); iter += step)
|
|
||||||
{
|
|
||||||
step ++;
|
|
||||||
iter - v.rend ();
|
|
||||||
}
|
|
||||||
pass ();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int step = 1;
|
|
||||||
beginTestCase ("const_reverse_iterator");
|
|
||||||
V::const_reverse_iterator iter;
|
|
||||||
for (iter = v.crbegin (); iter + step < v.crend (); iter += step)
|
|
||||||
{
|
|
||||||
step ++;
|
|
||||||
iter - v.crend ();
|
|
||||||
}
|
|
||||||
pass ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void runTest ()
|
|
||||||
{
|
|
||||||
testAssign ();
|
|
||||||
testReserve ();
|
|
||||||
testMutate ();
|
|
||||||
testIterate ();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayTests () : UnitTest ("DynamicArray", "beast")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static DynamicArrayTests dynamicArrayTests;
|
|
||||||
@@ -1,728 +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_CORE_CONTAINERS_DYNAMICARRAY_H_INCLUDED
|
|
||||||
#define BEAST_CORE_CONTAINERS_DYNAMICARRAY_H_INCLUDED
|
|
||||||
|
|
||||||
template <typename, typename>
|
|
||||||
class DynamicArray;
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
class DynamicArrayIterator
|
|
||||||
: public std::iterator <std::random_access_iterator_tag,
|
|
||||||
typename V::size_type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename mpl::CopyConst <V, typename V::value_type>::type
|
|
||||||
|
|
||||||
value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef typename V::size_type size_type;
|
|
||||||
|
|
||||||
DynamicArrayIterator (V* v = nullptr, size_type pos = 0) noexcept
|
|
||||||
: m_v (v)
|
|
||||||
, m_pos (pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
DynamicArrayIterator (DynamicArrayIterator <W> const& u) noexcept
|
|
||||||
: m_v (u.m_v)
|
|
||||||
, m_pos (u.m_pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
DynamicArrayIterator& operator= (DynamicArrayIterator <W> const& u) noexcept
|
|
||||||
{
|
|
||||||
m_v = u.m_v;
|
|
||||||
m_pos = u.m_pos;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator== (DynamicArrayIterator <W> const& u) const noexcept
|
|
||||||
{
|
|
||||||
return (m_v == u.m_v) && (m_pos == u.m_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator!= (DynamicArrayIterator <W> const& u) const noexcept
|
|
||||||
{
|
|
||||||
return ! ((*this) == u);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator* () const noexcept
|
|
||||||
{
|
|
||||||
return dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator& operator++ () noexcept
|
|
||||||
{
|
|
||||||
increment (1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator operator++ (int) noexcept
|
|
||||||
{
|
|
||||||
DynamicArrayIterator const result (*this);
|
|
||||||
increment (1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator& operator-- () noexcept
|
|
||||||
{
|
|
||||||
decrement (1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator operator-- (int) noexcept
|
|
||||||
{
|
|
||||||
DynamicArrayIterator const result (*this);
|
|
||||||
decrement (1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator& operator+= (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
increment (n);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator& operator-= (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
decrement (n);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator operator+ (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return DynamicArrayIterator (m_v, m_pos + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayIterator operator- (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return DynamicArrayIterator (m_v, m_pos - n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
difference_type operator- (DynamicArrayIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos - rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator< (DynamicArrayIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos < rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator> (DynamicArrayIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos > rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator<= (DynamicArrayIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos <= rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator>= (DynamicArrayIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos >= rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator[] (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return (*m_v)[m_pos + n];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
reference dereference () const noexcept
|
|
||||||
{
|
|
||||||
return (*m_v) [m_pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
m_pos += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
m_pos -= n;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename>
|
|
||||||
friend class DynamicArrayIterator;
|
|
||||||
|
|
||||||
V* m_v;
|
|
||||||
size_type m_pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
DynamicArrayIterator <V> operator+ (
|
|
||||||
typename DynamicArrayIterator <V>::difference_type n,
|
|
||||||
DynamicArrayIterator <V> iter) noexcept
|
|
||||||
{
|
|
||||||
return iter + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
DynamicArrayIterator <V> operator- (
|
|
||||||
typename DynamicArrayIterator <V>::difference_type n,
|
|
||||||
DynamicArrayIterator <V> iter) noexcept
|
|
||||||
{
|
|
||||||
return iter - n;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
class DynamicArrayReverseIterator
|
|
||||||
: public std::iterator <std::random_access_iterator_tag,
|
|
||||||
typename V::size_type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename mpl::CopyConst<V, typename V::value_type>::type
|
|
||||||
|
|
||||||
value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef typename V::size_type size_type;
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator (V* v = nullptr, difference_type pos = 0) noexcept
|
|
||||||
: m_v (v)
|
|
||||||
, m_pos (pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
DynamicArrayReverseIterator (DynamicArrayReverseIterator <W> const& u) noexcept
|
|
||||||
: m_v (u.m_v)
|
|
||||||
, m_pos (u.m_pos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
DynamicArrayReverseIterator& operator= (DynamicArrayReverseIterator <W> const& u) noexcept
|
|
||||||
{
|
|
||||||
m_v = u.m_v;
|
|
||||||
m_pos = u.m_pos;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator== (DynamicArrayReverseIterator <W> const& u) const noexcept
|
|
||||||
{
|
|
||||||
return (m_v == u.m_v) && (m_pos == u.m_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator!= (DynamicArrayReverseIterator <W> const& u) const noexcept
|
|
||||||
{
|
|
||||||
return ! ((*this) == u);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator* () const noexcept
|
|
||||||
{
|
|
||||||
return dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator& operator++ () noexcept
|
|
||||||
{
|
|
||||||
increment (1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator operator++ (int) noexcept
|
|
||||||
{
|
|
||||||
DynamicArrayReverseIterator const result (*this);
|
|
||||||
increment (1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator& operator-- () noexcept
|
|
||||||
{
|
|
||||||
decrement (1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator operator-- (int) noexcept
|
|
||||||
{
|
|
||||||
DynamicArrayReverseIterator const result (*this);
|
|
||||||
decrement (1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator& operator+= (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
increment (n);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator& operator-= (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
decrement (n);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator operator+ (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return DynamicArrayReverseIterator (m_v, m_pos - n);
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicArrayReverseIterator operator- (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return DynamicArrayReverseIterator (m_v, m_pos + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
difference_type operator- (DynamicArrayReverseIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return rhs.m_pos - m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator< (DynamicArrayReverseIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos > rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator> (DynamicArrayReverseIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos < rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator<= (DynamicArrayReverseIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos >= rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename W>
|
|
||||||
bool operator>= (DynamicArrayReverseIterator <W> const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return m_pos <= rhs.m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator[] (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
return (*m_v)[(m_pos - 1) - n];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename>
|
|
||||||
friend class DynamicArrayReverseIterator;
|
|
||||||
|
|
||||||
reference dereference () const noexcept
|
|
||||||
{
|
|
||||||
return (*m_v) [m_pos - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
m_pos -= n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement (difference_type n) noexcept
|
|
||||||
{
|
|
||||||
m_pos += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
V* m_v;
|
|
||||||
difference_type m_pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
DynamicArrayReverseIterator <V> operator+ (
|
|
||||||
typename DynamicArrayReverseIterator <V>::difference_type n,
|
|
||||||
DynamicArrayReverseIterator <V> iter) noexcept
|
|
||||||
{
|
|
||||||
return iter + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
DynamicArrayReverseIterator <V> operator- (
|
|
||||||
typename DynamicArrayReverseIterator <V>::difference_type n,
|
|
||||||
DynamicArrayReverseIterator <V> iter) noexcept
|
|
||||||
{
|
|
||||||
return iter - n;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename T,
|
|
||||||
typename Allocator = std::allocator <char> >
|
|
||||||
class DynamicArray
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef PARAMETER_TYPE (T) TParam;
|
|
||||||
|
|
||||||
typedef std::vector <T*> handles_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
defaultBlocksize = 1000,
|
|
||||||
growthPercentage = 10
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef T value_type;
|
|
||||||
typedef Allocator allocator_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef value_type const* const_pointer;
|
|
||||||
typedef value_type const& const_reference;
|
|
||||||
|
|
||||||
typedef detail::DynamicArrayIterator <DynamicArray <T> > iterator;
|
|
||||||
|
|
||||||
typedef detail::DynamicArrayIterator <DynamicArray <T> const> const_iterator;
|
|
||||||
|
|
||||||
typedef detail::DynamicArrayReverseIterator <DynamicArray <T> > reverse_iterator;
|
|
||||||
|
|
||||||
typedef detail::DynamicArrayReverseIterator <DynamicArray <T> const> const_reverse_iterator;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
explicit DynamicArray (size_type blocksize = defaultBlocksize) noexcept
|
|
||||||
: m_blocksize (blocksize)
|
|
||||||
, m_capacity (0)
|
|
||||||
, m_size (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~DynamicArray()
|
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
shrink_to_fit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Replace the array with 'count' copies of a default-constructed T.
|
|
||||||
*/
|
|
||||||
void assign (size_type count)
|
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
resize (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
reference at (size_type pos)
|
|
||||||
{
|
|
||||||
if (pos >= size ())
|
|
||||||
Throw (std::out_of_range ("bad pos"), __FILE__, __LINE__);
|
|
||||||
return get (pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference at (size_type pos) const
|
|
||||||
{
|
|
||||||
if (pos >= size ())
|
|
||||||
Throw (std::out_of_range ("bad pos"), __FILE__, __LINE__);
|
|
||||||
return get (pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator[] (size_type pos) noexcept
|
|
||||||
{
|
|
||||||
return get (pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference operator[] (size_type pos) const noexcept
|
|
||||||
{
|
|
||||||
return get (pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference front () noexcept
|
|
||||||
{
|
|
||||||
return get (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference front () const noexcept
|
|
||||||
{
|
|
||||||
return get (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference back () noexcept
|
|
||||||
{
|
|
||||||
return get (size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference back () const noexcept
|
|
||||||
{
|
|
||||||
return get (size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
iterator begin () noexcept
|
|
||||||
{
|
|
||||||
return iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end () noexcept
|
|
||||||
{
|
|
||||||
return iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rbegin () noexcept
|
|
||||||
{
|
|
||||||
return reverse_iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator rbegin () const noexcept
|
|
||||||
{
|
|
||||||
return const_reverse_iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator crbegin () const noexcept
|
|
||||||
{
|
|
||||||
return const_reverse_iterator (this, size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rend () noexcept
|
|
||||||
{
|
|
||||||
return reverse_iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator rend () const noexcept
|
|
||||||
{
|
|
||||||
return const_reverse_iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator crend () const noexcept
|
|
||||||
{
|
|
||||||
return const_reverse_iterator (this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool empty () const noexcept
|
|
||||||
{
|
|
||||||
return m_size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type size () const noexcept
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type max_size () const noexcept
|
|
||||||
{
|
|
||||||
return std::numeric_limits <size_type>::max ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve (size_type new_cap)
|
|
||||||
{
|
|
||||||
new_cap = m_blocksize * (
|
|
||||||
(new_cap + m_blocksize - 1) / m_blocksize);
|
|
||||||
if (new_cap > max_size ())
|
|
||||||
Throw (std::length_error ("new_cap > max_size"), __FILE__, __LINE__);
|
|
||||||
if (new_cap <= m_capacity)
|
|
||||||
return;
|
|
||||||
size_type const n (new_cap / m_blocksize);
|
|
||||||
m_handles.reserve (n);
|
|
||||||
for (size_type i = m_handles.size (); i < n; ++i)
|
|
||||||
m_handles.push_back (static_cast <T*> (std::malloc (
|
|
||||||
m_blocksize * sizeof (T))));
|
|
||||||
m_capacity = new_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type capacity () const noexcept
|
|
||||||
{
|
|
||||||
return m_capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink_to_fit ()
|
|
||||||
{
|
|
||||||
size_type const handles (
|
|
||||||
(size () + m_blocksize - 1) / m_blocksize);
|
|
||||||
m_capacity = handles * m_blocksize;
|
|
||||||
for (size_type i = m_handles.size (); i-- > handles;)
|
|
||||||
{
|
|
||||||
std::free (m_handles [i]);
|
|
||||||
m_handles.erase (m_handles.begin () + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void clear ()
|
|
||||||
{
|
|
||||||
resize (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator push_back (TParam value)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (value);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator emplace_back ()
|
|
||||||
{
|
|
||||||
new (alloc ()) T ();
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A1>
|
|
||||||
iterator emplace_back (A1 a1)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (a1);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A1, class A2>
|
|
||||||
iterator emplace_back (A1 a1, A2 a2)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (a1, a2);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3>
|
|
||||||
iterator emplace_back (A1 a1, A2 a2, A3 a3)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (a1, a2, a3);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4>
|
|
||||||
iterator emplace_back (A1 a1, A2 a2, A3 a3, A4 a4)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (a1, a2, a3, a4);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5>
|
|
||||||
iterator emplace_back (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
|
|
||||||
{
|
|
||||||
new (alloc ()) T (a1, a2, a3, a4, a5);
|
|
||||||
return iterator (this, size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back ()
|
|
||||||
{
|
|
||||||
resize (size () - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize (size_type count)
|
|
||||||
{
|
|
||||||
while (count > size ())
|
|
||||||
new (alloc ()) T;
|
|
||||||
|
|
||||||
while (count < size ())
|
|
||||||
get (--m_size).~T ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize (size_type count, TParam value)
|
|
||||||
{
|
|
||||||
while (count > size ())
|
|
||||||
new (alloc ()) T (value);
|
|
||||||
|
|
||||||
while (count < size ())
|
|
||||||
get (--m_size).~T ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap (DynamicArray& other)
|
|
||||||
{
|
|
||||||
std::swap (m_blocksize, other.m_blocksize);
|
|
||||||
std::swap (m_size, other.m_size);
|
|
||||||
std::swap (m_capacity, other.m_capacity);
|
|
||||||
std::swap (m_handles, other.m_handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
reference get (size_type pos) noexcept
|
|
||||||
{
|
|
||||||
size_type const index (pos / m_blocksize);
|
|
||||||
size_type const offset (pos % m_blocksize);
|
|
||||||
return m_handles [index] [offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reference get (size_type pos) const noexcept
|
|
||||||
{
|
|
||||||
size_type const index (pos / m_blocksize);
|
|
||||||
size_type const offset (pos % m_blocksize);
|
|
||||||
return m_handles [index] [offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
T* alloc () noexcept
|
|
||||||
{
|
|
||||||
size_type const needed (size () + 1);
|
|
||||||
if (capacity () < needed)
|
|
||||||
reserve ((needed * (100 + growthPercentage) + 99) / 100);
|
|
||||||
return &get (m_size++);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Allocator m_allocator;
|
|
||||||
size_type m_blocksize;
|
|
||||||
size_type m_capacity;
|
|
||||||
size_type m_size;
|
|
||||||
handles_t m_handles;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class HashMapTests : public UnitTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
numberOfItems = 100 * 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int keyBytes>
|
|
||||||
class TestTraits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct Value
|
|
||||||
{
|
|
||||||
int unused;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Key
|
|
||||||
{
|
|
||||||
class Equal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator() (Key const& lhs, Key const& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return memcmp (lhs.data, rhs.data, keyBytes) == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// stateful hardened hash
|
|
||||||
class Hash
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Hash (HashValue seedToUse = Random::getSystemRandom ().nextInt ())
|
|
||||||
: m_seed (seedToUse)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HashValue generateHash (Key const& key) const noexcept
|
|
||||||
{
|
|
||||||
HashValue hash;
|
|
||||||
Murmur::Hash (key.data, keyBytes, m_seed, &hash);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HashValue m_seed;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Key ()
|
|
||||||
: std::memset (data, 0, keyBytes)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint8 data [keyBytes];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Key key_type;
|
|
||||||
typedef Value value_type;
|
|
||||||
typedef typename Key::Hash hasher;
|
|
||||||
typedef typename Key::Equal key_equal;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
TestTraits (size_type const numberOfKeys, Random& random)
|
|
||||||
{
|
|
||||||
// need to static_bassert keyBytes can represent numberOfKeys. Log base 256 or something?
|
|
||||||
|
|
||||||
m_keys.reserve (numberOfKeys);
|
|
||||||
m_shuffled_keys.reserve (numberOfKeys);
|
|
||||||
for (size_type i = 0; i < numberOfKeys; ++i)
|
|
||||||
{
|
|
||||||
// VFALCO NOTE std::vector is garbage..want to emplace_back() here
|
|
||||||
Key key;
|
|
||||||
memset (key.data, 0, sizeof (key.data));
|
|
||||||
memcpy (& key.data [0], &i, std::min (sizeof (key.data), sizeof (i)));
|
|
||||||
m_keys.push_back (key);
|
|
||||||
m_shuffled_keys.push_back (&m_keys [i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnitTestUtilities::repeatableShuffle (numberOfKeys, m_shuffled_keys, random);
|
|
||||||
}
|
|
||||||
|
|
||||||
Key const& getKey (size_type index) const noexcept
|
|
||||||
{
|
|
||||||
return *m_shuffled_keys [index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector <Key> m_keys;
|
|
||||||
std::vector <Key*> m_shuffled_keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int keyBytes>
|
|
||||||
void testInsert (std::size_t numberOfKeys, Random& random)
|
|
||||||
{
|
|
||||||
beginTestCase (String
|
|
||||||
("insertion, numberOfKeys = ") + String::fromNumber (numberOfKeys) +
|
|
||||||
", keyBytes = " + String::fromNumber (keyBytes));
|
|
||||||
|
|
||||||
typedef TestTraits <keyBytes> Traits;
|
|
||||||
Traits traits (numberOfKeys, random);
|
|
||||||
|
|
||||||
typedef HashMap <
|
|
||||||
typename Traits::key_type,
|
|
||||||
typename Traits::value_type,
|
|
||||||
typename Traits::hasher,
|
|
||||||
typename Traits::key_equal> Map;
|
|
||||||
Map map;
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < numberOfKeys; ++i)
|
|
||||||
map.insert (traits.getKey (i));
|
|
||||||
|
|
||||||
String s (
|
|
||||||
"load_factor = " + String::fromNumber (map.load_factor (), 2) +
|
|
||||||
", bucket_count = " + String::fromNumber (map.bucket_count ()));
|
|
||||||
this->logMessage (s);
|
|
||||||
|
|
||||||
expect (map.size () == numberOfKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
void runTest ()
|
|
||||||
{
|
|
||||||
int64 const seedValue = 072472;
|
|
||||||
Random random (seedValue);
|
|
||||||
testInsert <4> (numberOfItems, random);
|
|
||||||
testInsert <20> (numberOfItems, random);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapTests () : UnitTest ("HashMap", "beast")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static HashMapTests hashMapTests;
|
|
||||||
@@ -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_HASHMAP_H_INCLUDED
|
|
||||||
#define BEAST_HASHMAP_H_INCLUDED
|
|
||||||
|
|
||||||
/** The integral type for holding a non cryptographic hash.
|
|
||||||
HashValue is used for fast comparisons, bloom filters, and hash maps.
|
|
||||||
*/
|
|
||||||
typedef uint32 HashValue;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Simple hash functions for use with HashMap.
|
|
||||||
|
|
||||||
@see HashMap
|
|
||||||
*/
|
|
||||||
// VFALCO TODO Rewrite the hash functions to return a uint32, and not
|
|
||||||
// take the upperLimit parameter. Just do the mod in the
|
|
||||||
// calling function for simplicity.
|
|
||||||
class DefaultHashFunctions
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Generates a simple hash from an integer. */
|
|
||||||
HashValue generateHash (const int key) const noexcept
|
|
||||||
{
|
|
||||||
return HashValue (std::abs (key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates a simple hash from an int64. */
|
|
||||||
HashValue generateHash (const int64 key) const noexcept
|
|
||||||
{
|
|
||||||
return HashValue (key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates a simple hash from a string. */
|
|
||||||
HashValue generateHash (const String& key) const noexcept
|
|
||||||
{
|
|
||||||
return HashValue (key.hashCode ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates a simple hash from a variant. */
|
|
||||||
HashValue generateHash (const var& key) const noexcept
|
|
||||||
{
|
|
||||||
return generateHash (key.toString ());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/** Hardened hash functions for use with HashMap.
|
|
||||||
|
|
||||||
The seed is used to make the hash unpredictable. This prevents
|
|
||||||
attackers from exploiting crafted inputs to produce degenerate
|
|
||||||
containers.
|
|
||||||
*/
|
|
||||||
class HardenedHashFunctions
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Construct a hash function.
|
|
||||||
|
|
||||||
If a seed is specified it will be used, else a random seed
|
|
||||||
will be generated from the system.
|
|
||||||
|
|
||||||
@param seedToUse An optional seed to use.
|
|
||||||
*/
|
|
||||||
explicit HardenedHashFunctions (int seedToUse = Random::getSystemRandom ().nextInt ())
|
|
||||||
: m_seed (seedToUse)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// VFALCO TODO Need hardened versions of these functions which use the seed!
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_seed;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
struct BucketTag { };
|
|
||||||
|
|
||||||
template <typename M, typename I>
|
|
||||||
class HashMapLocalIterator
|
|
||||||
: public std::iterator <std::forward_iterator_tag, typename M::size_type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename M::Pair value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef typename M::size_type size_type;
|
|
||||||
|
|
||||||
HashMapLocalIterator (M* map = nullptr, I iter = I ())
|
|
||||||
: m_map (map)
|
|
||||||
, m_iter (iter)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N, typename J>
|
|
||||||
HashMapLocalIterator (HashMapLocalIterator <N, J> const& other)
|
|
||||||
: m_map (other.m_map)
|
|
||||||
, m_iter (other.m_iter)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N, typename J>
|
|
||||||
HashMapLocalIterator& operator= (HashMapLocalIterator <N, J> const& other)
|
|
||||||
{
|
|
||||||
m_map = other.m_map;
|
|
||||||
m_iter = other.m_iter;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N, typename J>
|
|
||||||
bool operator== (HashMapLocalIterator <N, J> const& other)
|
|
||||||
{
|
|
||||||
return m_map == other.m_map && m_iter == other.m_iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N, typename J>
|
|
||||||
bool operator!= (HashMapLocalIterator <N, J> const& other)
|
|
||||||
{
|
|
||||||
return ! ((*this)==other);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator* () const noexcept
|
|
||||||
{
|
|
||||||
return dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapLocalIterator& operator++ () noexcept
|
|
||||||
{
|
|
||||||
increment ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapLocalIterator operator++ (int) noexcept
|
|
||||||
{
|
|
||||||
HashMapLocalIterator const result (*this);
|
|
||||||
increment ();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
reference dereference () const noexcept
|
|
||||||
{
|
|
||||||
return m_iter->pair ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment () noexcept
|
|
||||||
{
|
|
||||||
++m_iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
M* m_map;
|
|
||||||
I m_iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
template <typename M>
|
|
||||||
class HashMapIterator
|
|
||||||
: public std::iterator <std::forward_iterator_tag, typename M::size_type>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename M::Item Item;
|
|
||||||
typedef typename M::Bucket Bucket;
|
|
||||||
typedef detail::ListIterator <typename mpl::CopyConst <M,
|
|
||||||
typename List <Bucket>::Node>::type> bucket_iterator;
|
|
||||||
typedef detail::ListIterator <typename mpl::CopyConst <M,
|
|
||||||
typename List <Item, detail::BucketTag>::Node>::type> item_iterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename M::Pair value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef typename M::size_type size_type;
|
|
||||||
|
|
||||||
HashMapIterator ()
|
|
||||||
: m_map (nullptr)
|
|
||||||
, m_bucket (bucket_iterator ())
|
|
||||||
, m_local (item_iterator ())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// represents end()
|
|
||||||
explicit HashMapIterator (M* map)
|
|
||||||
: m_map (map)
|
|
||||||
, m_bucket (bucket_iterator ())
|
|
||||||
, m_local (item_iterator ())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapIterator (M* map, bucket_iterator const& bucket, item_iterator const& local)
|
|
||||||
: m_map (map)
|
|
||||||
, m_bucket (bucket)
|
|
||||||
, m_local (local)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
HashMapIterator (HashMapIterator const& other) noexcept
|
|
||||||
: m_map (other.m_map)
|
|
||||||
, m_bucket (other.m_bucket)
|
|
||||||
, m_local (other.m_local)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N>
|
|
||||||
HashMapIterator (HashMapIterator <N> const& other) noexcept
|
|
||||||
: m_map (other.m_map)
|
|
||||||
, m_bucket (other.m_bucket)
|
|
||||||
, m_local (other.m_local)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
template <typename N>
|
|
||||||
HashMapIterator& operator= (HashMapIterator <N> const& other) noexcept
|
|
||||||
{
|
|
||||||
m_map = other.m_map;
|
|
||||||
m_bucket = other.m_bucket;
|
|
||||||
m_local = other.m_local;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N>
|
|
||||||
bool operator== (HashMapIterator <N> const& other) noexcept
|
|
||||||
{
|
|
||||||
return m_map == other.m_map &&
|
|
||||||
m_bucket == other.m_bucket &&
|
|
||||||
m_local == other.m_local;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename N>
|
|
||||||
bool operator!= (HashMapIterator <N> const& other) noexcept
|
|
||||||
{
|
|
||||||
return ! ((*this) == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator* () const noexcept
|
|
||||||
{
|
|
||||||
return dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator-> () const noexcept
|
|
||||||
{
|
|
||||||
return &dereference ();
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapIterator& operator++ () noexcept
|
|
||||||
{
|
|
||||||
increment ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMapIterator operator++ (int) noexcept
|
|
||||||
{
|
|
||||||
HashMapIterator const result (*this);
|
|
||||||
increment ();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename, typename, typename, typename, typename>
|
|
||||||
friend class HashMap;
|
|
||||||
|
|
||||||
reference dereference () const noexcept
|
|
||||||
{
|
|
||||||
return m_local->pair ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment () noexcept
|
|
||||||
{
|
|
||||||
++m_local;
|
|
||||||
if (m_local == m_bucket->items.end ())
|
|
||||||
{
|
|
||||||
++m_bucket;
|
|
||||||
if (m_bucket != m_map->m_bucketlist.end ())
|
|
||||||
m_local = m_bucket->items.begin ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
M* m_map;
|
|
||||||
bucket_iterator m_bucket;
|
|
||||||
item_iterator m_local;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Associative container mapping Key to T pairs.
|
|
||||||
*/
|
|
||||||
template <typename Key,
|
|
||||||
typename T,
|
|
||||||
typename Hash = DefaultHashFunctions,
|
|
||||||
typename KeyEqual = std::equal_to <Key>,
|
|
||||||
typename Allocator = std::allocator <char> >
|
|
||||||
class HashMap
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef PARAMETER_TYPE (Key) KeyParam;
|
|
||||||
typedef PARAMETER_TYPE (T) TParam;
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct Pair
|
|
||||||
{
|
|
||||||
explicit Pair (Key key)
|
|
||||||
: m_key (key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair (Key key, T t)
|
|
||||||
: m_key (key)
|
|
||||||
, m_t (t)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Key const& key () const noexcept
|
|
||||||
{
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& value () noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
T const& value () const noexcept
|
|
||||||
{
|
|
||||||
return m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Key m_key;
|
|
||||||
T m_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename M, typename I>
|
|
||||||
friend class detail::HashMapLocalIterator;
|
|
||||||
|
|
||||||
class Item;
|
|
||||||
|
|
||||||
// Each non-empty bucket is in the linked list.
|
|
||||||
struct Bucket : List <Bucket>::Node
|
|
||||||
{
|
|
||||||
Bucket ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool empty () const noexcept
|
|
||||||
{
|
|
||||||
return items.empty ();
|
|
||||||
}
|
|
||||||
|
|
||||||
List <Item, detail::BucketTag> items;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Bucket& operator= (Bucket const&);
|
|
||||||
Bucket (Bucket const&);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Every item in the map is in one linked list
|
|
||||||
struct Item
|
|
||||||
: List <Item>::Node
|
|
||||||
, List <Item, detail::BucketTag>::Node
|
|
||||||
{
|
|
||||||
Item (Pair const& pair_)
|
|
||||||
: m_pair (pair_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair& pair () noexcept
|
|
||||||
{
|
|
||||||
return m_pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair const& pair () const noexcept
|
|
||||||
{
|
|
||||||
return m_pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Pair m_pair;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Key key_type;
|
|
||||||
typedef T mapped_type;
|
|
||||||
typedef Pair value_type;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef Hash hasher;
|
|
||||||
typedef KeyEqual key_equal;
|
|
||||||
typedef Allocator allocator_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef value_type const* const_pointer;
|
|
||||||
typedef value_type const& const_reference;
|
|
||||||
|
|
||||||
typedef HashMap <Key, T, Hash, KeyEqual, Allocator> container_type;
|
|
||||||
|
|
||||||
typedef detail::HashMapIterator <container_type> iterator;
|
|
||||||
typedef detail::HashMapIterator <container_type const> const_iterator;
|
|
||||||
|
|
||||||
typedef detail::HashMapLocalIterator <container_type,
|
|
||||||
typename List <Item, detail::BucketTag>::iterator> local_iterator;
|
|
||||||
|
|
||||||
typedef detail::HashMapLocalIterator <container_type const,
|
|
||||||
typename List <Item, detail::BucketTag>::const_iterator> const_local_iterator;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
initialBucketCount = 101,
|
|
||||||
percentageIncrease = 25
|
|
||||||
};
|
|
||||||
|
|
||||||
static float getDefaultLoadFactor () noexcept
|
|
||||||
{
|
|
||||||
return 1.2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit HashMap (
|
|
||||||
size_type bucket_count = initialBucketCount,
|
|
||||||
KeyEqual const& equal = KeyEqual (),
|
|
||||||
Hash const& hash = Hash (),
|
|
||||||
Allocator const& allocator = Allocator ())
|
|
||||||
: m_hash (hash)
|
|
||||||
, m_equal (equal)
|
|
||||||
, m_allocator (allocator)
|
|
||||||
, m_max_load_factor (getDefaultLoadFactor ())
|
|
||||||
{
|
|
||||||
rehash (bucket_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap (
|
|
||||||
size_type bucket_count,
|
|
||||||
Allocator const& allocator = Allocator ())
|
|
||||||
: m_allocator (allocator)
|
|
||||||
, m_max_load_factor (getDefaultLoadFactor ())
|
|
||||||
{
|
|
||||||
rehash (bucket_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap (
|
|
||||||
size_type bucket_count,
|
|
||||||
Hash const& hash = Hash (),
|
|
||||||
Allocator const& allocator = Allocator ())
|
|
||||||
: m_hash (hash)
|
|
||||||
, m_allocator (allocator)
|
|
||||||
, m_max_load_factor (getDefaultLoadFactor ())
|
|
||||||
{
|
|
||||||
rehash (bucket_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit HashMap (Allocator const& allocator)
|
|
||||||
: m_allocator (allocator)
|
|
||||||
, m_max_load_factor (getDefaultLoadFactor ())
|
|
||||||
{
|
|
||||||
rehash (initialBucketCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
~HashMap()
|
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap& operator= (HashMap const& other)
|
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
for (iterator iter = other.begin (); iter != other.end (); ++iter)
|
|
||||||
(*this)[iter->key ()] = iter->value ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocator_type get_allocator () const noexcept
|
|
||||||
{
|
|
||||||
return m_allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
iterator begin () noexcept
|
|
||||||
{
|
|
||||||
if (m_bucketlist.size () > 0)
|
|
||||||
return iterator (this, m_bucketlist.begin (),
|
|
||||||
m_bucketlist.front ().items.begin ());
|
|
||||||
return end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin () const noexcept
|
|
||||||
{
|
|
||||||
if (m_bucketlist.size () > 0)
|
|
||||||
return const_iterator (this, m_bucketlist.begin (),
|
|
||||||
m_bucketlist.front ().items.begin ());
|
|
||||||
return end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin () const noexcept
|
|
||||||
{
|
|
||||||
if (m_bucketlist.size () > 0)
|
|
||||||
return const_iterator (this, m_bucketlist.begin (),
|
|
||||||
m_bucketlist.front ().items.begin ());
|
|
||||||
return end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end () noexcept
|
|
||||||
{
|
|
||||||
return iterator (static_cast <container_type*> (this));
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend () const noexcept
|
|
||||||
{
|
|
||||||
return const_iterator (this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool empty () const noexcept
|
|
||||||
{
|
|
||||||
return size () == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type size () const noexcept
|
|
||||||
{
|
|
||||||
return m_itemlist.size ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type max_size () const noexcept
|
|
||||||
{
|
|
||||||
return std::numeric_limits <size_type>::max ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
for (typename DynamicList <Item>::iterator iter = m_items.begin ();
|
|
||||||
iter != m_items.end ();)
|
|
||||||
{
|
|
||||||
typename DynamicList <Item>::iterator const cur (iter++);
|
|
||||||
m_items.erase (cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_itemlist.clear ();
|
|
||||||
m_bucketlist.clear ();
|
|
||||||
size_type const count (m_buckets.size ());
|
|
||||||
m_buckets.assign (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Result
|
|
||||||
{
|
|
||||||
Result (iterator iter_ = iterator (), bool inserted_ = false)
|
|
||||||
: iter (iter_)
|
|
||||||
, inserted (inserted_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator iter;
|
|
||||||
bool inserted;
|
|
||||||
};
|
|
||||||
|
|
||||||
Result insert (Pair const& p)
|
|
||||||
{
|
|
||||||
size_type const n (bucket (p.key ()));
|
|
||||||
iterator iter (find (p.key (), n));
|
|
||||||
if (iter != end ())
|
|
||||||
return Result (iter, false);
|
|
||||||
check_load ();
|
|
||||||
return Result (store (*m_items.emplace_back (p), n), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result insert (KeyParam key)
|
|
||||||
{
|
|
||||||
return insert (Pair (key));
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase (const_iterator pos)
|
|
||||||
{
|
|
||||||
iterator iter = pos;
|
|
||||||
++iter;
|
|
||||||
Bucket& b (*pos.m_iter);
|
|
||||||
erase (b, pos->m_local);
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type erase (KeyParam key)
|
|
||||||
{
|
|
||||||
size_type found (0);
|
|
||||||
Bucket& b (m_buckets [bucket (key)]);
|
|
||||||
for (typename List <Item, detail::BucketTag>::iterator iter (b.items.begin ());
|
|
||||||
iter != b.items.end ();)
|
|
||||||
{
|
|
||||||
typename List <Item, detail::BucketTag>::iterator cur (iter++);
|
|
||||||
if (m_equal (cur->pair ().key (), key))
|
|
||||||
{
|
|
||||||
erase (b, cur);
|
|
||||||
++found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
T& at (KeyParam key)
|
|
||||||
{
|
|
||||||
iterator const iter (find (key));
|
|
||||||
if (iter == end ())
|
|
||||||
Throw (std::out_of_range ("key not found"), __FILE__, __LINE__);
|
|
||||||
return iter->value ();
|
|
||||||
}
|
|
||||||
|
|
||||||
T const& at (KeyParam key) const
|
|
||||||
{
|
|
||||||
const_iterator const iter (find (key));
|
|
||||||
if (iter == end ())
|
|
||||||
Throw (std::out_of_range ("key not found"), __FILE__, __LINE__);
|
|
||||||
return iter->value ();
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator[] (KeyParam key) noexcept
|
|
||||||
{
|
|
||||||
return insert (key).iter->value ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type count (KeyParam key) const noexcept
|
|
||||||
{
|
|
||||||
size_type n = 0;
|
|
||||||
Bucket const& b (m_buckets [bucket (key)]);
|
|
||||||
for (typename List <Item, detail::BucketTag>::iterator iter = b.items.begin ();
|
|
||||||
iter != b.items.end (); ++iter)
|
|
||||||
if (m_equal (iter->key (), key))
|
|
||||||
++n;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator find (KeyParam key) noexcept
|
|
||||||
{
|
|
||||||
return find (key, bucket (key));
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator find (KeyParam key) const noexcept
|
|
||||||
{
|
|
||||||
return find (key, bucket (key));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local_iterator begin (size_type n) noexcept
|
|
||||||
{
|
|
||||||
return local_iterator (this, m_buckets [n].items.begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_local_iterator begin (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return const_local_iterator (this, m_buckets [n].items.begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_local_iterator cbegin (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return const_local_iterator (this, m_buckets [n].items.cbegin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
local_iterator end (size_type n) noexcept
|
|
||||||
{
|
|
||||||
return local_iterator (this, m_buckets [n].items.end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_local_iterator end (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return const_local_iterator (this, m_buckets [n].items.end ());
|
|
||||||
}
|
|
||||||
|
|
||||||
const_local_iterator cend (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return const_local_iterator (this, m_buckets [n].items.cend ());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type bucket_count () const noexcept
|
|
||||||
{
|
|
||||||
return m_buckets.size ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type max_bucket_count () const noexcept
|
|
||||||
{
|
|
||||||
return std::numeric_limits <size_type>::max ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type bucket_size (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return m_buckets [n].items.size ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type bucket (KeyParam key) const noexcept
|
|
||||||
{
|
|
||||||
HashValue const hash (m_hash.generateHash (key));
|
|
||||||
return hash % bucket_count ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
float load_factor () const noexcept
|
|
||||||
{
|
|
||||||
return float (m_items.size ()) / float (m_buckets.size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
float max_load_factor () const noexcept
|
|
||||||
{
|
|
||||||
return m_max_load_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void max_load_factor (float ml) noexcept
|
|
||||||
{
|
|
||||||
m_max_load_factor = ml;
|
|
||||||
check_load ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rehash (size_type const count)
|
|
||||||
{
|
|
||||||
m_bucketlist.clear ();
|
|
||||||
m_buckets.assign (count);
|
|
||||||
for (typename List <Item>::iterator iter = m_itemlist.begin ();
|
|
||||||
iter != m_itemlist.end (); ++iter)
|
|
||||||
{
|
|
||||||
Item& item (*iter);
|
|
||||||
size_type const n (bucket (item.pair ().key ()));
|
|
||||||
Bucket& b (m_buckets [n]);
|
|
||||||
if (b.empty ())
|
|
||||||
m_bucketlist.push_front (b);
|
|
||||||
b.items.push_front (item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve (size_type count)
|
|
||||||
{
|
|
||||||
m_items.reserve (count);
|
|
||||||
rehash (std::ceil (count / max_load_factor ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// rehashes if adding one more item would put us over
|
|
||||||
void check_load () noexcept
|
|
||||||
{
|
|
||||||
if ( (float (m_items.size () + 1) /
|
|
||||||
float (m_buckets.size ())) >=
|
|
||||||
max_load_factor ())
|
|
||||||
{
|
|
||||||
grow_buckets ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void grow_buckets ()
|
|
||||||
{
|
|
||||||
double const scale = 1. + (double (percentageIncrease) / 100.);
|
|
||||||
size_type const count (size_type (std::ceil (
|
|
||||||
(double (size ()) / double (max_load_factor ())) * scale)));
|
|
||||||
rehash (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator find (KeyParam key, size_type n) noexcept
|
|
||||||
{
|
|
||||||
Bucket& b (m_buckets [n]);
|
|
||||||
for (typename List <Item, detail::BucketTag>::iterator iter =
|
|
||||||
b.items.begin (); iter != b.items.end (); ++iter)
|
|
||||||
if (m_equal (iter->pair ().key (), key))
|
|
||||||
return iterator (this, m_bucketlist.iterator_to (b), iter);
|
|
||||||
return end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator find (KeyParam key, size_type n) const noexcept
|
|
||||||
{
|
|
||||||
Bucket const& b (m_buckets [n]);
|
|
||||||
for (typename List <Item, detail::BucketTag>::const_iterator iter =
|
|
||||||
b.items.begin (); iter != b.items.end (); ++iter)
|
|
||||||
if (m_equal (iter->pair ().key (), key))
|
|
||||||
return const_iterator (this,
|
|
||||||
m_bucketlist.const_iterator_to (b), iter);
|
|
||||||
return end ();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator store (Item& item, size_type n)
|
|
||||||
{
|
|
||||||
check_load ();
|
|
||||||
Bucket& b (m_buckets [n]);
|
|
||||||
if (b.empty ())
|
|
||||||
m_bucketlist.push_front (b);
|
|
||||||
b.items.push_front (item);
|
|
||||||
m_itemlist.push_front (item);
|
|
||||||
return iterator (this,
|
|
||||||
m_bucketlist.iterator_to (b),
|
|
||||||
b.items.begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase (Bucket& b, typename List <Item, detail::BucketTag>::iterator pos)
|
|
||||||
{
|
|
||||||
Item& item (*pos);
|
|
||||||
b.items.erase (b.items.iterator_to (item));
|
|
||||||
if (b.empty ())
|
|
||||||
m_bucketlist.erase (m_bucketlist.iterator_to (b));
|
|
||||||
m_itemlist.erase (m_itemlist.iterator_to (item));
|
|
||||||
m_items.erase (m_items.iterator_to (item));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename M>
|
|
||||||
friend class detail::HashMapIterator;
|
|
||||||
|
|
||||||
Hash m_hash;
|
|
||||||
KeyEqual m_equal;
|
|
||||||
Allocator m_allocator;
|
|
||||||
DynamicList <Item> m_items;
|
|
||||||
DynamicArray <Bucket> m_buckets;
|
|
||||||
List <Item> m_itemlist;
|
|
||||||
List <Bucket> m_bucketlist;
|
|
||||||
float m_max_load_factor;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SHAREDTABLE_H_INCLUDED
|
|
||||||
#define BEAST_SHAREDTABLE_H_INCLUDED
|
|
||||||
|
|
||||||
/** Handle to a reference counted fixed size table.
|
|
||||||
|
|
||||||
@note Currently, ElementType must be an aggregate of POD.
|
|
||||||
|
|
||||||
@tparam ElementType The type of element.
|
|
||||||
|
|
||||||
@ingroup beast_basics
|
|
||||||
*/
|
|
||||||
template <class ElementType>
|
|
||||||
class SharedTable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ElementType Entry;
|
|
||||||
|
|
||||||
static SharedTable <ElementType> const null;
|
|
||||||
|
|
||||||
/** Creates a null table.
|
|
||||||
*/
|
|
||||||
SharedTable ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a table with the specified number of entries.
|
|
||||||
|
|
||||||
The entries are uninitialized.
|
|
||||||
|
|
||||||
@param numEntries The number of entries in the table.
|
|
||||||
|
|
||||||
@todo Initialize the data if ElementType is not POD.
|
|
||||||
*/
|
|
||||||
explicit SharedTable (int numEntries)
|
|
||||||
: m_data (new Data (numEntries))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a shared reference to another table.
|
|
||||||
*/
|
|
||||||
SharedTable (SharedTable const& other)
|
|
||||||
: m_data (other.m_data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes this table refer to another table.
|
|
||||||
*/
|
|
||||||
SharedTable& operator= (SharedTable const& other)
|
|
||||||
{
|
|
||||||
m_data = other.m_data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
|
||||||
SharedTable (SharedTable&& other) noexcept
|
|
||||||
: m_data (static_cast < typename Data::Ptr&& > (other.m_data))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedTable& operator= (SharedTable && other) noexcept
|
|
||||||
{
|
|
||||||
m_data = static_cast < typename Data::Ptr && > (other.m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Destructor.
|
|
||||||
*/
|
|
||||||
~SharedTable ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the two tables share the same set of entries.
|
|
||||||
*/
|
|
||||||
bool operator== (SharedTable const& other) const noexcept
|
|
||||||
{
|
|
||||||
return m_data == other.m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the two tables do not share the same set of entries.
|
|
||||||
*/
|
|
||||||
bool operator!= (SharedTable const& other) const noexcept
|
|
||||||
{
|
|
||||||
return m_data != other.m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the table is not null.
|
|
||||||
*/
|
|
||||||
inline bool isValid () const noexcept
|
|
||||||
{
|
|
||||||
return m_data != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the table is null.
|
|
||||||
*/
|
|
||||||
inline bool isNull () const noexcept
|
|
||||||
{
|
|
||||||
return m_data == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the number of tables referring to the same shared entries.
|
|
||||||
*/
|
|
||||||
int getReferenceCount () const noexcept
|
|
||||||
{
|
|
||||||
return m_data == nullptr ? 0 : m_data->getReferenceCount ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a physical duplicate of the table.
|
|
||||||
*/
|
|
||||||
SharedTable createCopy () const
|
|
||||||
{
|
|
||||||
return SharedTable (m_data != nullptr ? m_data->clone () : nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Makes sure no other tables share the same entries as this table.
|
|
||||||
*/
|
|
||||||
void duplicateIfShared ()
|
|
||||||
{
|
|
||||||
if (m_data != nullptr && m_data->getReferenceCount () > 1)
|
|
||||||
m_data = m_data->clone ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the number of entries in this table.
|
|
||||||
*/
|
|
||||||
inline int getNumEntries () const noexcept
|
|
||||||
{
|
|
||||||
return m_data->getNumEntries ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve a table entry.
|
|
||||||
|
|
||||||
@param index The index of the entry, from 0 to getNumEntries ().
|
|
||||||
*/
|
|
||||||
inline ElementType& operator [] (int index) const noexcept
|
|
||||||
{
|
|
||||||
return m_data->getReference (index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Data : public SharedObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef SharedPtr <Data> Ptr;
|
|
||||||
|
|
||||||
explicit Data (int numEntries)
|
|
||||||
: m_numEntries (numEntries)
|
|
||||||
, m_table (numEntries)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Data* clone () const
|
|
||||||
{
|
|
||||||
Data* data = new Data (m_numEntries);
|
|
||||||
|
|
||||||
memcpy (
|
|
||||||
data->m_table.getData (),
|
|
||||||
m_table.getData (),
|
|
||||||
m_numEntries * sizeof (ElementType));
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int getNumEntries () const
|
|
||||||
{
|
|
||||||
return m_numEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ElementType& getReference (int index) const
|
|
||||||
{
|
|
||||||
bassert (index >= 0 && index < m_numEntries);
|
|
||||||
return m_table [index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int const m_numEntries;
|
|
||||||
HeapBlock <ElementType> const m_table;
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit SharedTable (Data* data)
|
|
||||||
: m_data (data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedPtr <Data> m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ElementType>
|
|
||||||
SharedTable <ElementType> const SharedTable <ElementType>::null;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SORTEDLOOKUPTABLE_H_INCLUDED
|
|
||||||
#define BEAST_SORTEDLOOKUPTABLE_H_INCLUDED
|
|
||||||
|
|
||||||
/** Sorted map for fast lookups.
|
|
||||||
|
|
||||||
This container is optimized for a data set with fixed elements.
|
|
||||||
|
|
||||||
SchemaType obeys this concept:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
struct SchemaType
|
|
||||||
{
|
|
||||||
typename KeyType;
|
|
||||||
typename ValueType;
|
|
||||||
|
|
||||||
// Retrieve the key for a specified value.
|
|
||||||
KeyType getKey (Value const& value);
|
|
||||||
};
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
To use the table, reserve space with reserveSpaceForValues() if the number
|
|
||||||
of elements is known ahead of time. Then, call insert() for all the your
|
|
||||||
elements. Call prepareForLookups() once then call lookupValueByKey ()
|
|
||||||
*/
|
|
||||||
template <class SchemaType>
|
|
||||||
class SortedLookupTable
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename SchemaType::KeyType KeyType;
|
|
||||||
typedef typename SchemaType::ValueType ValueType;
|
|
||||||
typedef std::vector <ValueType> values_t;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct SortCompare
|
|
||||||
{
|
|
||||||
bool operator () (ValueType const& lhs, ValueType const& rhs) const
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FindCompare
|
|
||||||
{
|
|
||||||
bool operator () (ValueType const& lhs, ValueType const& rhs)
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator () (KeyType const& key, ValueType const& rhs)
|
|
||||||
{
|
|
||||||
return key < SchemaType ().getKey (rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator () (ValueType const& lhs, KeyType const& key)
|
|
||||||
{
|
|
||||||
return SchemaType ().getKey (lhs) < key;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename values_t::size_type size_type;
|
|
||||||
|
|
||||||
/** Reserve space for values.
|
|
||||||
|
|
||||||
Although not necessary, this can help with memory usage if the
|
|
||||||
number of values is known ahead of time.
|
|
||||||
|
|
||||||
@param numberOfValues The amount of space to reserve.
|
|
||||||
*/
|
|
||||||
void reserveSpaceForValues (size_type numberOfValues)
|
|
||||||
{
|
|
||||||
m_values.reserve (numberOfValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Insert a value into the index.
|
|
||||||
|
|
||||||
@invariant The value must not already exist in the index.
|
|
||||||
|
|
||||||
@param valueToInsert The value to insert.
|
|
||||||
*/
|
|
||||||
void insert (ValueType const& valueToInsert)
|
|
||||||
{
|
|
||||||
m_values.push_back (valueToInsert);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Prepare the index for lookups.
|
|
||||||
|
|
||||||
This must be called at least once after calling insert()
|
|
||||||
and before calling find().
|
|
||||||
*/
|
|
||||||
void prepareForLookups ()
|
|
||||||
{
|
|
||||||
std::sort (m_values.begin (), m_values.end (), SortCompare ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find the value for a key.
|
|
||||||
|
|
||||||
Quickly locates a value matching the key, or returns false
|
|
||||||
indicating no value was found.
|
|
||||||
|
|
||||||
@invariant You must call prepareForLookups() once, after all
|
|
||||||
insertions, before calling this function.
|
|
||||||
|
|
||||||
@param key The key to locate.
|
|
||||||
@param pFoundValue Pointer to store the value if a matching
|
|
||||||
key was found.
|
|
||||||
@return `true` if the value was found.
|
|
||||||
*/
|
|
||||||
bool lookupValueByKey (KeyType const& key, ValueType* pFoundValue)
|
|
||||||
{
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
std::pair <typename values_t::iterator, typename values_t::iterator> result =
|
|
||||||
std::equal_range (m_values.begin (), m_values.end (), key, FindCompare ());
|
|
||||||
|
|
||||||
if (result.first != result.second)
|
|
||||||
{
|
|
||||||
*pFoundValue = *result.first;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
values_t m_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
typedef value_type* iterator;
|
typedef value_type* iterator;
|
||||||
typedef value_type const* const_iterator;
|
typedef value_type const* const_iterator;
|
||||||
|
|
||||||
/** Hardened hash function for use with HashMap.
|
/** Hardened hash function for use with hash based containers.
|
||||||
The seed is used to make the hash unpredictable. This prevents
|
The seed is used to make the hash unpredictable. This prevents
|
||||||
attackers from exploiting crafted inputs to produce degenerate
|
attackers from exploiting crafted inputs to produce degenerate
|
||||||
containers.
|
containers.
|
||||||
@@ -59,21 +59,21 @@ public:
|
|||||||
will be generated from the system
|
will be generated from the system
|
||||||
@param seedToUse An optional seed to use.
|
@param seedToUse An optional seed to use.
|
||||||
*/
|
*/
|
||||||
explicit hasher (HashValue seedToUse = Random::getSystemRandom ().nextInt ())
|
explicit hasher (std::size_t seedToUse = Random::getSystemRandom ().nextInt ())
|
||||||
: m_seed (seedToUse)
|
: m_seed (seedToUse)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generates a simple hash from an UnsignedInteger. */
|
/** Generates a simple hash from an UnsignedInteger. */
|
||||||
HashValue operator() (UnsignedInteger const& key) const
|
std::size_t operator() (UnsignedInteger const& key) const
|
||||||
{
|
{
|
||||||
HashValue hash;
|
std::size_t hash;
|
||||||
Murmur::Hash (key.cbegin (), key.size, m_seed, &hash);
|
Murmur::Hash (key.cbegin (), key.size, m_seed, &hash);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HashValue m_seed;
|
std::size_t m_seed;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Determins if two UnsignedInteger objects are equal. */
|
/** Determins if two UnsignedInteger objects are equal. */
|
||||||
|
|||||||
Reference in New Issue
Block a user