mirror of
https://github.com/reactos/reactos.git
synced 2024-09-18 16:52:54 +00:00
469 lines
10 KiB
C++
469 lines
10 KiB
C++
//Has to be first for StackAllocator swap overload to be taken
|
|
//into account (at least using GCC 4.0.1)
|
|
#include "stack_allocator.h"
|
|
|
|
#include <list>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
|
|
#include "cppunit/cppunit_proxy.h"
|
|
|
|
#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
|
|
using namespace std;
|
|
#endif
|
|
|
|
//
|
|
// TestCase class
|
|
//
|
|
class ListTest : public CPPUNIT_NS::TestCase
|
|
{
|
|
CPPUNIT_TEST_SUITE(ListTest);
|
|
CPPUNIT_TEST(list1);
|
|
CPPUNIT_TEST(list2);
|
|
CPPUNIT_TEST(list3);
|
|
CPPUNIT_TEST(list4);
|
|
CPPUNIT_TEST(erase);
|
|
CPPUNIT_TEST(resize);
|
|
CPPUNIT_TEST(push_back);
|
|
CPPUNIT_TEST(push_front);
|
|
CPPUNIT_TEST(allocator_with_state);
|
|
CPPUNIT_TEST(swap);
|
|
CPPUNIT_TEST(adl);
|
|
//CPPUNIT_TEST(const_list);
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
protected:
|
|
void list1();
|
|
void list2();
|
|
void list3();
|
|
void list4();
|
|
void erase();
|
|
void resize();
|
|
void push_back();
|
|
void push_front();
|
|
void allocator_with_state();
|
|
void swap();
|
|
void adl();
|
|
//void const_list();
|
|
};
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(ListTest);
|
|
|
|
//
|
|
// tests implementation
|
|
//
|
|
void ListTest::list1()
|
|
{
|
|
int array1 [] = { 9, 16, 36 };
|
|
int array2 [] = { 1, 4 };
|
|
|
|
list<int> l1(array1, array1 + 3);
|
|
list<int> l2(array2, array2 + 2);
|
|
list<int>::iterator i1 = l1.begin();
|
|
list<int>::iterator i2 = l2.begin();
|
|
list<int>::const_iterator ci(i1);
|
|
list<int>::const_iterator ci1(ci);
|
|
l1.splice(i1, l2);
|
|
i1 = l1.begin();
|
|
CPPUNIT_ASSERT( *i1++ == 1 );
|
|
CPPUNIT_ASSERT( *i1++ == 4 );
|
|
CPPUNIT_ASSERT( *i1++ == 9 );
|
|
CPPUNIT_ASSERT( *i1++ == 16 );
|
|
CPPUNIT_ASSERT( *i1++ == 36 );
|
|
|
|
#if defined (STLPORT) && \
|
|
(!defined (_STLP_DEBUG) || (_STLP_DEBUG_LEVEL != _STLP_STANDARD_DBG_LEVEL))
|
|
CPPUNIT_ASSERT( i2 == l1.begin() );
|
|
#endif
|
|
|
|
//Default construct check (_STLP_DEF_CONST_PLCT_NEW_BUG)
|
|
list<int> l(2);
|
|
i1 = l.begin();
|
|
CPPUNIT_ASSERT( *(i1++) == 0 );
|
|
CPPUNIT_ASSERT( *i1 == 0 );
|
|
#if 0
|
|
//A small compilation time check to be activated from time to time,
|
|
//compilation should fail.
|
|
{
|
|
list<char>::iterator l_char_ite;
|
|
list<int>::iterator l_int_ite;
|
|
CPPUNIT_ASSERT( l_char_ite != l_int_ite );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ListTest::list2()
|
|
{
|
|
int array1 [] = { 1, 16 };
|
|
int array2 [] = { 4, 9 };
|
|
|
|
list<int> l1(array1, array1 + 2);
|
|
list<int> l2(array2, array2 + 2);
|
|
list<int>::iterator i = l1.begin();
|
|
i++;
|
|
l1.splice(i, l2, l2.begin(), l2.end());
|
|
i = l1.begin();
|
|
CPPUNIT_ASSERT(*i++==1);
|
|
CPPUNIT_ASSERT(*i++==4);
|
|
CPPUNIT_ASSERT(*i++==9);
|
|
CPPUNIT_ASSERT(*i++==16);
|
|
}
|
|
|
|
void ListTest::list3()
|
|
{
|
|
char array [] = { 'x', 'l', 'x', 't', 's', 's' };
|
|
|
|
list<char> str(array, array + 6);
|
|
list<char>::iterator i;
|
|
|
|
str.reverse();
|
|
i = str.begin();
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='t');
|
|
CPPUNIT_ASSERT(*i++=='x');
|
|
CPPUNIT_ASSERT(*i++=='l');
|
|
CPPUNIT_ASSERT(*i++=='x');
|
|
|
|
str.remove('x');
|
|
i = str.begin();
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='t');
|
|
CPPUNIT_ASSERT(*i++=='l');
|
|
|
|
str.unique();
|
|
i = str.begin();
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='t');
|
|
CPPUNIT_ASSERT(*i++=='l');
|
|
|
|
str.sort();
|
|
i = str.begin();
|
|
CPPUNIT_ASSERT(*i++=='l');
|
|
CPPUNIT_ASSERT(*i++=='s');
|
|
CPPUNIT_ASSERT(*i++=='t');
|
|
}
|
|
|
|
void ListTest::list4()
|
|
{
|
|
int array1 [] = { 1, 3, 6, 7 };
|
|
int array2 [] = { 2, 4 };
|
|
|
|
list<int> l1(array1, array1 + 4);
|
|
list<int> l2(array2, array2 + 2);
|
|
l1.merge(l2);
|
|
list<int>::iterator i = l1.begin();
|
|
CPPUNIT_ASSERT(*i++==1);
|
|
CPPUNIT_ASSERT(*i++==2);
|
|
CPPUNIT_ASSERT(*i++==3);
|
|
CPPUNIT_ASSERT(*i++==4);
|
|
CPPUNIT_ASSERT(*i++==6);
|
|
CPPUNIT_ASSERT(*i++==7);
|
|
|
|
//We use distance to avoid a simple call to an internal counter
|
|
CPPUNIT_ASSERT(distance(l1.begin(), l1.end()) == 6);
|
|
CPPUNIT_ASSERT(distance(l2.begin(), l2.end()) == 0);
|
|
|
|
l1.swap(l2);
|
|
|
|
CPPUNIT_ASSERT(distance(l1.begin(), l1.end()) == 0);
|
|
CPPUNIT_ASSERT(distance(l2.begin(), l2.end()) == 6);
|
|
}
|
|
|
|
void ListTest::erase()
|
|
{
|
|
list<int> l;
|
|
l.push_back( 1 );
|
|
l.erase(l.begin());
|
|
CPPUNIT_ASSERT( l.empty() );
|
|
|
|
int array[] = { 0, 1, 2, 3 };
|
|
l.assign(array, array + 4);
|
|
list<int>::iterator lit;
|
|
lit = l.erase(l.begin());
|
|
CPPUNIT_ASSERT( *lit == 1 );
|
|
|
|
lit = l.erase(l.begin(), --l.end());
|
|
CPPUNIT_ASSERT( *lit == 3 );
|
|
|
|
l.clear();
|
|
CPPUNIT_ASSERT( l.empty() );
|
|
}
|
|
|
|
|
|
void ListTest::resize()
|
|
{
|
|
{
|
|
list<int> l;
|
|
l.resize(5, 1);
|
|
|
|
size_t i;
|
|
list<int>::iterator lit(l.begin());
|
|
for (i = 0; i < 5; ++i) {
|
|
CPPUNIT_ASSERT( lit != l.end() );
|
|
CPPUNIT_ASSERT( *(lit++) == 1 );
|
|
}
|
|
CPPUNIT_ASSERT( lit == l.end() );
|
|
|
|
l.resize(3);
|
|
lit = l.begin();
|
|
for (i = 0; i < 3; ++i) {
|
|
CPPUNIT_ASSERT( lit != l.end() );
|
|
CPPUNIT_ASSERT( *(lit++) == 1 );
|
|
}
|
|
CPPUNIT_ASSERT( lit == l.end() );
|
|
}
|
|
|
|
{
|
|
list<int> l;
|
|
l.resize(5);
|
|
|
|
size_t i;
|
|
list<int>::iterator lit(l.begin());
|
|
for (i = 0; i < 5; ++i) {
|
|
CPPUNIT_ASSERT( lit != l.end() );
|
|
CPPUNIT_ASSERT( *(lit++) == 0 );
|
|
}
|
|
CPPUNIT_ASSERT( lit == l.end() );
|
|
}
|
|
}
|
|
|
|
void ListTest::push_back()
|
|
{
|
|
list<int> l;
|
|
l.push_back( 1 );
|
|
l.push_back( 2 );
|
|
l.push_back( 3 );
|
|
|
|
list<int>::reverse_iterator r = l.rbegin();
|
|
|
|
CPPUNIT_ASSERT( *r == 3 );
|
|
l.push_back( 4 );
|
|
/*
|
|
* Following lines are commented, because ones show standard contradiction
|
|
* (24.4.1 and 23.2.2.3); but present behaviour is valid, 24.4.1, paragraphs 1 and 2,
|
|
* 24.4.1.3.3 and 23.1 paragraph 9 (Table 66). The 24.4.1 is more common rule,
|
|
* so it has preference under 23.2.2.3, by my opinion.
|
|
*
|
|
* - ptr
|
|
*/
|
|
// CPPUNIT_ASSERT( *r == 3 );
|
|
// ++r;
|
|
// CPPUNIT_ASSERT( *r == 2 );
|
|
}
|
|
|
|
void ListTest::push_front()
|
|
{
|
|
list<int> l;
|
|
l.push_back( 1 );
|
|
l.push_back( 2 );
|
|
l.push_back( 3 );
|
|
|
|
list<int>::iterator i = l.begin();
|
|
|
|
CPPUNIT_ASSERT( *i == 1 );
|
|
l.push_front( 0 );
|
|
CPPUNIT_ASSERT( *i == 1 );
|
|
++i;
|
|
CPPUNIT_ASSERT( *i == 2 );
|
|
}
|
|
|
|
void ListTest::allocator_with_state()
|
|
{
|
|
char buf1[1024];
|
|
StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
|
|
|
|
char buf2[1024];
|
|
StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
|
|
|
|
typedef list<int, StackAllocator<int> > ListInt;
|
|
{
|
|
//Swap with both list non empty
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint1Cpy(lint1);
|
|
|
|
ListInt lint2(10, 1, stack2);
|
|
ListInt lint2Cpy(lint2);
|
|
|
|
lint1.swap(lint2);
|
|
|
|
CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
|
|
CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
|
|
|
|
CPPUNIT_ASSERT( lint1 == lint2Cpy );
|
|
CPPUNIT_ASSERT( lint2 == lint1Cpy );
|
|
CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
|
|
CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
//Swap with empty calle list
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint1Cpy(lint1);
|
|
|
|
ListInt lint2(stack2);
|
|
ListInt lint2Cpy(lint2);
|
|
|
|
lint1.swap(lint2);
|
|
|
|
CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
|
|
CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
|
|
|
|
CPPUNIT_ASSERT( lint1 == lint2Cpy );
|
|
CPPUNIT_ASSERT( lint2 == lint1Cpy );
|
|
CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
|
|
CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
//Swap with empty caller list
|
|
ListInt lint1(stack1);
|
|
ListInt lint1Cpy(lint1);
|
|
|
|
ListInt lint2(10, 0, stack2);
|
|
ListInt lint2Cpy(lint2);
|
|
|
|
lint1.swap(lint2);
|
|
|
|
CPPUNIT_ASSERT( lint1.get_allocator().swaped() );
|
|
CPPUNIT_ASSERT( lint2.get_allocator().swaped() );
|
|
|
|
CPPUNIT_ASSERT( lint1 == lint2Cpy );
|
|
CPPUNIT_ASSERT( lint2 == lint1Cpy );
|
|
CPPUNIT_ASSERT( lint1.get_allocator() == stack2 );
|
|
CPPUNIT_ASSERT( lint2.get_allocator() == stack1 );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint2(10, 1, stack2);
|
|
|
|
lint1.splice(lint1.begin(), lint2);
|
|
CPPUNIT_ASSERT( lint1.size() == 20 );
|
|
CPPUNIT_ASSERT( lint2.empty() );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint2(10, 1, stack2);
|
|
|
|
lint1.splice(lint1.begin(), lint2, lint2.begin());
|
|
CPPUNIT_ASSERT( lint1.size() == 11 );
|
|
CPPUNIT_ASSERT( lint2.size() == 9 );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint2(10, 1, stack2);
|
|
|
|
ListInt::iterator lit(lint2.begin());
|
|
advance(lit, 5);
|
|
lint1.splice(lint1.begin(), lint2, lint2.begin(), lit);
|
|
CPPUNIT_ASSERT( lint1.size() == 15 );
|
|
CPPUNIT_ASSERT( lint2.size() == 5 );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
stack1.reset(); stack2.reset();
|
|
|
|
{
|
|
ListInt lint1(10, 0, stack1);
|
|
ListInt lint2(10, 1, stack2);
|
|
|
|
ListInt lintref(stack2);
|
|
lintref.insert(lintref.begin(), 10, 1);
|
|
lintref.insert(lintref.begin(), 10, 0);
|
|
|
|
lint1.merge(lint2);
|
|
CPPUNIT_ASSERT( lint1.size() == 20 );
|
|
CPPUNIT_ASSERT( lint1 == lintref );
|
|
CPPUNIT_ASSERT( lint2.empty() );
|
|
}
|
|
CPPUNIT_CHECK( stack1.ok() );
|
|
CPPUNIT_CHECK( stack2.ok() );
|
|
|
|
#if defined (STLPORT) && !defined (_STLP_NO_MEMBER_TEMPLATES) && \
|
|
(!defined (_MSC_VER) || (_MSC_VER >= 1300))
|
|
{
|
|
//This is a compile time test.
|
|
//We check that sort implementation is correct when list is instanciated
|
|
//with an allocator that do not have a default constructor.
|
|
ListInt lint1(10, 0, stack1);
|
|
lint1.sort();
|
|
lint1.sort(greater<int>());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
void ListTest::const_list()
|
|
{
|
|
list<const int> cint_list;
|
|
cint_list.push_back(1);
|
|
cint_list.push_front(2);
|
|
}
|
|
*/
|
|
void ListTest::swap()
|
|
{
|
|
list<int> lst1;
|
|
list<int> lst2;
|
|
|
|
lst1.push_back(1);
|
|
lst2.push_back(2);
|
|
|
|
lst1.swap( lst2 );
|
|
|
|
CPPUNIT_CHECK( lst1.front() == 2 );
|
|
CPPUNIT_CHECK( lst2.front() == 1 );
|
|
CPPUNIT_CHECK( lst1.size() == 1 );
|
|
CPPUNIT_CHECK( lst2.size() == 1 );
|
|
|
|
lst1.pop_front();
|
|
lst2.pop_front();
|
|
|
|
CPPUNIT_CHECK( lst1.empty() );
|
|
CPPUNIT_CHECK( lst2.empty() );
|
|
}
|
|
|
|
namespace foo {
|
|
class bar {};
|
|
|
|
template <class _It>
|
|
size_t distance(_It, _It);
|
|
}
|
|
|
|
void ListTest::adl()
|
|
{
|
|
list<foo::bar> lbar;
|
|
CPPUNIT_ASSERT( lbar.size() == 0);
|
|
}
|
|
|
|
#if !defined (STLPORT) || \
|
|
!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
|
|
/* Simple compilation test: Check that nested types like iterator
|
|
* can be access even if type used to instanciate container is not
|
|
* yet completely defined.
|
|
*/
|
|
class IncompleteClass
|
|
{
|
|
list<IncompleteClass> instances;
|
|
typedef list<IncompleteClass>::iterator it;
|
|
};
|
|
#endif
|