Commit 6eb1fa1e authored by cutealien's avatar cutealien

Add swap functions to irrMath and to the core classes.

Deprecate map::isEmpty() and replace it with map::empty() to make it similar to other base classes.
Rename array-test and add tests for list and map.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3060 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 12c53b2c
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "irrTypes.h" #include "irrTypes.h"
#include "heapsort.h" #include "heapsort.h"
#include "irrAllocator.h" #include "irrAllocator.h"
#include "irrMath.h"
namespace irr namespace irr
{ {
...@@ -249,7 +250,7 @@ public: ...@@ -249,7 +250,7 @@ public:
//! Assignment operator //! Assignment operator
const array<T, TAlloc>& operator=(const array<T, TAlloc>& other) const array<T, TAlloc>& operator=(const array<T, TAlloc>& other)
{ {
if (this == &other) if (this == &other)
return *this; return *this;
strategy = other.strategy; strategy = other.strategy;
...@@ -269,7 +270,7 @@ public: ...@@ -269,7 +270,7 @@ public:
for (u32 i=0; i<other.used; ++i) for (u32 i=0; i<other.used; ++i)
allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i]; allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i];
return *this; return *this;
} }
...@@ -567,6 +568,28 @@ public: ...@@ -567,6 +568,28 @@ public:
} }
//! Swap the content of this array container with the content of another array
/** Afterwards this object will contain the content of the other object and the other
object will contain the content of this object.
\param other Swap content with this object */
void swap(array<T, TAlloc>& other)
{
core::swap(data, other.data);
core::swap(allocated, other.allocated);
core::swap(used, other.used);
core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
eAllocStrategy helper_strategy(strategy); // can't use core::swap with bitfields
strategy = other.strategy;
other.strategy = helper_strategy;
bool helper_free_when_destroyed(free_when_destroyed);
free_when_destroyed = other.free_when_destroyed;
other.free_when_destroyed = helper_free_when_destroyed;
bool helper_is_sorted(is_sorted);
is_sorted = other.is_sorted;
other.is_sorted = helper_is_sorted;
}
private: private:
T* data; T* data;
u32 allocated; u32 allocated;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "irrTypes.h" #include "irrTypes.h"
#include "irrAllocator.h" #include "irrAllocator.h"
#include "irrMath.h"
namespace irr namespace irr
{ {
...@@ -382,8 +383,22 @@ public: ...@@ -382,8 +383,22 @@ public:
return returnIterator; return returnIterator;
} }
//! Swap the content of this list container with the content of another list
/** Afterwards this object will contain the content of the other object and the other
object will contain the content of this object. Iterators will afterwards be valid for
the swapped object.
\param other Swap content with this object */
void swap(list<T>& other)
{
core::swap(First, other.First);
core::swap(Last, other.Last);
core::swap(Size, other.Size);
core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
}
private: private:
SKListNode* First; SKListNode* First;
SKListNode* Last; SKListNode* Last;
u32 Size; u32 Size;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define __IRR_MAP_H_INCLUDED__ #define __IRR_MAP_H_INCLUDED__
#include "irrTypes.h" #include "irrTypes.h"
#include "irrMath.h"
namespace irr namespace irr
{ {
...@@ -49,7 +50,7 @@ class map ...@@ -49,7 +50,7 @@ class map
RBTree* getLeftChild() const { return LeftChild; } RBTree* getLeftChild() const { return LeftChild; }
RBTree* getRightChild() const { return RightChild; } RBTree* getRightChild() const { return RightChild; }
RBTree* getParent() const { return Parent; } RBTree* getParent() const { return Parent; }
ValueTypeRB getValue() const ValueTypeRB getValue() const
{ {
...@@ -730,12 +731,18 @@ class map ...@@ -730,12 +731,18 @@ class map
//! Is the tree empty? //! Is the tree empty?
//! \return Returns true if empty, false if not //! \return Returns true if empty, false if not
bool isEmpty() const bool empty() const
{ {
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return Root == 0; return Root == 0;
} }
//! \deprecated Use empty() instead.
_IRR_DEPRECATED_ bool isEmpty() const
{
return empty();
}
//! Search for a node with the specified key. //! Search for a node with the specified key.
//! \param keyToFind: The key to find //! \param keyToFind: The key to find
//! \return Returns 0 if node couldn't be found. //! \return Returns 0 if node couldn't be found.
...@@ -772,6 +779,17 @@ class map ...@@ -772,6 +779,17 @@ class map
return Size; return Size;
} }
//! Swap the content of this map container with the content of another map
/** Afterwards this object will contain the content of the other object and the other
object will contain the content of this object. Iterators will afterwards be valid for
the swapped object.
\param other Swap content with this object */
void swap(map<KeyType, ValueType>& other)
{
core::swap(Root, other.Root);
core::swap(Size, other.Size);
}
//------------------------------ //------------------------------
// Public Iterators // Public Iterators
//------------------------------ //------------------------------
......
...@@ -47,7 +47,7 @@ namespace core ...@@ -47,7 +47,7 @@ namespace core
#endif #endif
//! Constant for PI. //! Constant for PI.
const f32 PI = 3.14159265359f; const f32 PI = 3.14159265359f;
//! Constant for reciprocal of PI. //! Constant for reciprocal of PI.
const f32 RECIPROCAL_PI = 1.0f/PI; const f32 RECIPROCAL_PI = 1.0f/PI;
...@@ -161,6 +161,15 @@ namespace core ...@@ -161,6 +161,15 @@ namespace core
return min_ (max_(value,low), high); return min_ (max_(value,low), high);
} }
//! swaps the content of the passed parameters
template <class T>
inline void swap(T& a, T& b)
{
T c(a);
a = b;
b = c;
}
//! returns if a equals b, taking possible rounding errors into account //! returns if a equals b, taking possible rounding errors into account
inline bool equals(const f64 a, const f64 b, const f64 tolerance = ROUNDING_ERROR_f64) inline bool equals(const f64 a, const f64 b, const f64 tolerance = ROUNDING_ERROR_f64)
{ {
...@@ -462,7 +471,7 @@ namespace core ...@@ -462,7 +471,7 @@ namespace core
__asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f)
__asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f)
__asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f)
__asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f)
// - f * rcpss(f) * rcpss(f) // - f * rcpss(f) * rcpss(f)
__asm movss rec, xmm0 // return xmm0 __asm movss rec, xmm0 // return xmm0
return rec; return rec;
...@@ -502,7 +511,7 @@ namespace core ...@@ -502,7 +511,7 @@ namespace core
__asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f)
__asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f)
__asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f)
__asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f)
// - f * rcpss(f) * rcpss(f) // - f * rcpss(f) * rcpss(f)
__asm movss rec, xmm0 // return xmm0 __asm movss rec, xmm0 // return xmm0
return rec; return rec;
......
...@@ -13,7 +13,7 @@ struct VarArray ...@@ -13,7 +13,7 @@ struct VarArray
core::array < int, core::irrAllocatorFast<int> > MyArray; core::array < int, core::irrAllocatorFast<int> > MyArray;
}; };
bool testSelfAssignment() static bool testSelfAssignment()
{ {
core::array<int> myArray; core::array<int> myArray;
myArray.push_back(1); myArray.push_back(1);
...@@ -22,7 +22,7 @@ bool testSelfAssignment() ...@@ -22,7 +22,7 @@ bool testSelfAssignment()
} }
// this will (did once) simply crash when wrong, so no return value // this will (did once) simply crash when wrong, so no return value
void crashTestFastAlloc() static void crashTestFastAlloc()
{ {
core::array < VarArray, core::irrAllocatorFast<VarArray> > ArrayArray; core::array < VarArray, core::irrAllocatorFast<VarArray> > ArrayArray;
ArrayArray.setAllocStrategy(core::ALLOC_STRATEGY_SAFE); // force more re-allocations ArrayArray.setAllocStrategy(core::ALLOC_STRATEGY_SAFE); // force more re-allocations
...@@ -37,14 +37,38 @@ void crashTestFastAlloc() ...@@ -37,14 +37,38 @@ void crashTestFastAlloc()
} }
} }
static bool testSwap()
{
bool result = true;
core::array<int> array1, array2, copy1, copy2;
for ( int i=0; i<99; ++i )
{
array1.push_back(i);
if ( i < 10 ) // we want also different container sizes
array2.push_back(99-i);
}
copy1 = array1;
copy2 = array2;
array1.swap(array2);
result &= (array1 == copy2);
result &= (array2 == copy1);
assert( result );
return result;
}
// Test the functionality of core::array // Test the functionality of core::array
bool testArray(void) bool testIrrArray(void)
{ {
bool allExpected = true; bool allExpected = true;
logTestString("crashTestFastAlloc\n"); logTestString("crashTestFastAlloc\n");
crashTestFastAlloc(); crashTestFastAlloc();
allExpected &= testSelfAssignment(); allExpected &= testSelfAssignment();
allExpected &= testSwap();
if(allExpected) if(allExpected)
logTestString("\nAll tests passed\n"); logTestString("\nAll tests passed\n");
......
#include "testUtils.h"
#include <irrlicht.h>
#include <assert.h>
using namespace irr;
using namespace core;
// list has no operator== currently so we have to check manually
// TODO: Add an operator== to core::list and the kick this function out
template <typename T>
static bool compareLists(core::list<T> & a, core::list<T> & b)
{
if ( a.size() != b.size() )
return false;
// can't test allocator because we have no access to it here
typename core::list<T>::Iterator iterA = a.begin(); // TODO: why can't we use ConstIterator here? Strange... this has to work!
typename core::list<T>::Iterator iterB = b.begin();
for ( ; iterA != a.end(); ++iterA, ++iterB )
{
if ( (*iterA) != (*iterB) )
return false;
}
return true;
}
static bool testSwap()
{
bool result = true;
core::list<int> list1, list2, copy1, copy2;
for ( int i=0; i<99; ++i )
{
list1.push_back(i);
if ( i < 10 ) // we want also different container sizes i < 50 )
list2.push_back(99-i);
}
copy1 = list1;
copy2 = list2;
list1.swap(list2);
result &= compareLists<int>(list1, copy2);
result &= compareLists<int>(list2, copy1);
assert( result );
return result;
}
// Test the functionality of core::list
bool testIrrList(void)
{
bool success = true;
success &= testSwap();
if(success)
logTestString("\nAll tests passed\n");
else
logTestString("\nFAIL!\n");
return success;
}
#include "testUtils.h"
#include <irrlicht.h>
#include <assert.h>
using namespace irr;
using namespace core;
// map has no operator== currently so we have to check manually
// TODO: Add an operator== to core::map and the kick this function out
template <class KeyType, class ValueType>
static bool compareMaps(core::map<KeyType,ValueType> & a, core::map<KeyType,ValueType> & b)
{
if ( a.size() != b.size() )
return false;
// can't test allocator because we have no access to it here
typename core::map<KeyType, ValueType>::Iterator iterA = a.getIterator();
typename core::map<KeyType, ValueType>::Iterator iterB = b.getIterator();
for ( ; !iterA.atEnd(); iterA++, iterB++ ) // TODO: only iter++, no ++iter in irr::map
{
if ( iterA->getValue() != iterB->getValue() )
return false;
}
return true;
}
static bool testSwap()
{
bool result = true;
core::map<int, int> map1, map2, copy1, copy2;
for ( int i=0; i<99; ++i )
{
map1[i] = i;
copy1[i] = i; // TODO: whatever the reason - irr::map does not want operator= so we have to assign to identical values
if ( i < 10 ) // we want also different container sizes
{
map2[i] = 99-i;
copy2[i] = 99-i; // TODO: whatever the reason - irr::map does not want operator= so we have to assign to identical values
}
}
map1.swap(map2);
result &= compareMaps(map1, copy2);
result &= compareMaps(map2, copy1);
assert( result );
return result;
}
// Test the functionality of core::list
bool testIrrMap(void)
{
bool success = true;
success &= testSwap();
if(success)
logTestString("\nAll tests passed\n");
else
logTestString("\nFAIL!\n");
return success;
}
...@@ -52,7 +52,9 @@ int main(int argumentCount, char * arguments[]) ...@@ -52,7 +52,9 @@ int main(int argumentCount, char * arguments[])
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory. TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
// Now the simple tests without device // Now the simple tests without device
TEST(testArray); TEST(testIrrArray);
TEST(testIrrMap);
TEST(testIrrList);
TEST(exports); TEST(exports);
TEST(irrCoreEquals); TEST(irrCoreEquals);
TEST(testIrrString); TEST(testIrrString);
......
Test suite pass at GMT Sat Dec 12 09:13:16 2009 Test suite pass at GMT Sun Dec 20 16:52:22 2009
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment