Remove obsolete beast container classes

This commit is contained in:
Vinnie Falco
2013-10-03 08:18:44 -07:00
parent 1dfd655959
commit 228b664ecf
12 changed files with 5 additions and 2333 deletions

View File

@@ -219,8 +219,6 @@
<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\DynamicArray.h" />
<ClInclude Include="..\..\modules\beast_core\containers\HashMap.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" />
@@ -228,8 +226,6 @@
<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\SharedTable.h" />
<ClInclude Include="..\..\modules\beast_core\containers\SortedLookupTable.h" />
<ClInclude Include="..\..\modules\beast_core\containers\SortedSet.h" />
<ClInclude Include="..\..\modules\beast_core\containers\SparseSet.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|x64'">true</ExcludedFromBuild>
</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">
<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\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">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>

View File

@@ -587,12 +587,6 @@
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h">
<Filter>beast_core\threads</Filter>
</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">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
@@ -827,12 +821,6 @@
<ClInclude Include="..\..\modules\beast_core\containers\DynamicList.h">
<Filter>beast_core\containers</Filter>
</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">
<Filter>beast\intrusive</Filter>
</ClInclude>
@@ -1634,15 +1622,9 @@
<ClCompile Include="..\..\modules\beast_core\system\SystemStats.cpp">
<Filter>beast_core\system</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicArray.cpp">
<Filter>beast_core\containers</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicList.cpp">
<Filter>beast_core\containers</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_core\containers\HashMap.cpp">
<Filter>beast_core\containers</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\async\SharedHandler.cpp">
<Filter>beast_asio\async</Filter>
</ClCompile>

View File

@@ -17,13 +17,6 @@ BEAST TODO
- 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
- 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
- Make beast::HashMap support assignment via operator[]
- Reformat every Doxygen comment
- Fix Doxygen metatags
- update Beast Doxyfile

View File

@@ -134,9 +134,7 @@ namespace beast
#include "containers/NamedValueSet.cpp"
#include "containers/PropertySet.cpp"
#include "containers/Variant.cpp"
#include "containers/DynamicArray.cpp"
#include "containers/DynamicList.cpp"
#include "containers/HashMap.cpp"
#include "diagnostic/FatalError.cpp"
#include "diagnostic/FPUFlags.cpp"

View File

@@ -177,14 +177,10 @@ class FileOutputStream;
#include "containers/PropertySet.h"
#include "containers/SharedObjectArray.h"
#include "containers/ScopedValueSetter.h"
#include "containers/SharedTable.h"
#include "containers/SortedLookupTable.h"
#include "containers/SortedSet.h"
#include "maths/Range.h"
#include "containers/SparseSet.h"
# include "containers/DynamicList.h"
# include "containers/DynamicArray.h"
#include "containers/HashMap.h"
#include "memory/ScopedPointer.h"
#include "files/DirectoryIterator.h"
#include "streams/InputStream.h"

View File

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

View File

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

View File

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

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

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

View File

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

View File

@@ -46,7 +46,7 @@ public:
typedef value_type* 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
attackers from exploiting crafted inputs to produce degenerate
containers.
@@ -59,21 +59,21 @@ public:
will be generated from the system
@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)
{
}
/** 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);
return hash;
}
private:
HashValue m_seed;
std::size_t m_seed;
};
/** Determins if two UnsignedInteger objects are equal. */