a Set() method. Also, new HasKey() method.legacy
@@ -20,37 +20,34 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
/* A stupidly linear map for now */ | |||||
/* A stupidly linear map for now. */ | |||||
template<typename K, typename V> class Map : protected Hash<K> | template<typename K, typename V> class Map : protected Hash<K> | ||||
{ | { | ||||
public: | public: | ||||
/* I choose to make this inline because passing the key by reference | |||||
* is usually suboptimal. */ | |||||
inline V const& operator[] (K const &key) const | inline V const& operator[] (K const &key) const | ||||
{ | { | ||||
/* Look for the hash in our table and return the value. */ | |||||
uint32_t hash = ((Hash<K> const &)*this)(key); | uint32_t hash = ((Hash<K> const &)*this)(key); | ||||
for (int i = 0; i < m_array.Count(); ++i) | for (int i = 0; i < m_array.Count(); ++i) | ||||
if (m_array[i].m1 == hash) | if (m_array[i].m1 == hash) | ||||
if (m_array[i].m2 == key) | if (m_array[i].m2 == key) | ||||
return m_array[i].m3; | return m_array[i].m3; | ||||
/* XXX: this in an error! */ | |||||
return V(); | return V(); | ||||
} | } | ||||
inline V & operator[] (K const &key) | inline V & operator[] (K const &key) | ||||
{ | { | ||||
return const_cast<V &>((const_cast<Map<K,V> const &>(*this))[key]); | |||||
} | |||||
inline V & Set(K const &key, V const &val) | |||||
{ | |||||
/* Look for the hash in our table and return the value if found. */ | |||||
uint32_t hash = ((Hash<K> const &)*this)(key); | uint32_t hash = ((Hash<K> const &)*this)(key); | ||||
for (int i = 0; i < m_array.Count(); ++i) | for (int i = 0; i < m_array.Count(); ++i) | ||||
if (m_array[i].m1 == hash) | if (m_array[i].m1 == hash) | ||||
if (m_array[i].m2 == key) | if (m_array[i].m2 == key) | ||||
{ | |||||
m_array[i].m3.~V(); | |||||
return m_array[i].m3 = val; | |||||
} | |||||
m_array.Push(hash, key, val); | |||||
return m_array[i].m3; | |||||
/* If not found, insert a new value. */ | |||||
m_array.Push(hash, key, V()); | |||||
return m_array.Last().m3; | return m_array.Last().m3; | ||||
} | } | ||||
@@ -66,6 +63,16 @@ public: | |||||
} | } | ||||
} | } | ||||
inline bool HasKey(K const &key) | |||||
{ | |||||
uint32_t hash = ((Hash<K> const &)*this)(key); | |||||
for (int i = 0; i < m_array.Count(); ++i) | |||||
if (m_array[i].m1 == hash) | |||||
if (m_array[i].m2 == key) | |||||
return true; | |||||
return false; | |||||
} | |||||
private: | private: | ||||
Array<uint32_t, K, V> m_array; | Array<uint32_t, K, V> m_array; | ||||
}; | }; | ||||
@@ -22,7 +22,7 @@ endif | |||||
testsuite_SOURCES = testsuite.cpp \ | testsuite_SOURCES = testsuite.cpp \ | ||||
unit/vector.cpp unit/matrix.cpp unit/half.cpp unit/trig.cpp \ | unit/vector.cpp unit/matrix.cpp unit/half.cpp unit/trig.cpp \ | ||||
unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp \ | unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp \ | ||||
unit/array.cpp unit/rotation.cpp unit/string.cpp | |||||
unit/array.cpp unit/rotation.cpp unit/string.cpp unit/map.cpp | |||||
testsuite_CPPFLAGS = @LOL_CFLAGS@ | testsuite_CPPFLAGS = @LOL_CFLAGS@ | ||||
testsuite_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ | testsuite_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ | ||||
testsuite_DEPENDENCIES = $(top_builddir)/src/liblol.a | testsuite_DEPENDENCIES = $(top_builddir)/src/liblol.a | ||||
@@ -41,10 +41,12 @@ | |||||
<ClCompile Include="unit\cmplx.cpp" /> | <ClCompile Include="unit\cmplx.cpp" /> | ||||
<ClCompile Include="unit\half.cpp" /> | <ClCompile Include="unit\half.cpp" /> | ||||
<ClCompile Include="unit\image.cpp" /> | <ClCompile Include="unit\image.cpp" /> | ||||
<ClCompile Include="unit\map.cpp" /> | |||||
<ClCompile Include="unit\matrix.cpp" /> | <ClCompile Include="unit\matrix.cpp" /> | ||||
<ClCompile Include="unit\quat.cpp" /> | <ClCompile Include="unit\quat.cpp" /> | ||||
<ClCompile Include="unit\real.cpp" /> | <ClCompile Include="unit\real.cpp" /> | ||||
<ClCompile Include="unit\rotation.cpp" /> | <ClCompile Include="unit\rotation.cpp" /> | ||||
<ClCompile Include="unit\string.cpp" /> | |||||
<ClCompile Include="unit\trig.cpp" /> | <ClCompile Include="unit\trig.cpp" /> | ||||
<ClCompile Include="unit\vector.cpp" /> | <ClCompile Include="unit\vector.cpp" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -73,4 +75,4 @@ | |||||
<ImportGroup Label="ExtensionTargets"> | <ImportGroup Label="ExtensionTargets"> | ||||
<Import Project="$(SolutionDir)\Lol.Fx.targets" /> | <Import Project="$(SolutionDir)\Lol.Fx.targets" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
</Project> | |||||
</Project> |
@@ -0,0 +1,63 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||||
// | |||||
#if defined HAVE_CONFIG_H | |||||
# include "config.h" | |||||
#endif | |||||
#include "core.h" | |||||
#include "lol/unit.h" | |||||
namespace lol | |||||
{ | |||||
LOLUNIT_FIXTURE(MapTest) | |||||
{ | |||||
void SetUp() {} | |||||
void TearDown() {} | |||||
LOLUNIT_TEST(MapDeclare) | |||||
{ | |||||
Map<uint8_t, uint8_t> m1; | |||||
Map<int, int> m2; | |||||
Map<float, float> m3; | |||||
Map<char const *, char const *> m4; | |||||
} | |||||
LOLUNIT_TEST(MapSet) | |||||
{ | |||||
Map<int, int> map; | |||||
for (int i = 0; i < 100000; i++) | |||||
map[i] = -1; | |||||
for (int i = 0; i < 100000; i++) | |||||
map[i] = i; | |||||
for (int i = 0; i < 100000; i++) | |||||
LOLUNIT_ASSERT_EQUAL(map[i], i); | |||||
} | |||||
LOLUNIT_TEST(MapHasKey) | |||||
{ | |||||
Map<int, int> map; | |||||
map[0] = 1; | |||||
map[2] = 2; | |||||
LOLUNIT_ASSERT(map.HasKey(0)); | |||||
LOLUNIT_ASSERT(!map.HasKey(1)); | |||||
LOLUNIT_ASSERT(map.HasKey(2)); | |||||
} | |||||
}; | |||||
} /* namespace lol */ | |||||