//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 <algorithm>
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
# include <slist>
# if !defined (_STLP_USE_NO_IOSTREAMS)
# include <sstream>
# endif
# include <iterator>
# include <functional>
#endif
#include "cppunit/cppunit_proxy.h"
#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
using namespace std;
#endif
#if !defined (STLPORT) && defined(__GNUC__)
using namespace __gnu_cxx;
#endif
//
// TestCase class
//
class SlistTest : public CPPUNIT_NS::TestCase
{
CPPUNIT_TEST_SUITE(SlistTest);
#if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
CPPUNIT_IGNORE;
#endif
CPPUNIT_TEST(slist1);
#if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS)
CPPUNIT_STOP_IGNORE;
#endif
CPPUNIT_TEST(erase);
CPPUNIT_TEST(insert);
CPPUNIT_TEST(splice);
CPPUNIT_TEST(allocator_with_state);
CPPUNIT_TEST_SUITE_END();
protected:
void slist1();
void erase();
void insert();
void splice();
void allocator_with_state();
};
CPPUNIT_TEST_SUITE_REGISTRATION(SlistTest);
//
// tests implementation
//
void SlistTest::slist1()
{
#if defined (STLPORT) && !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_NO_EXTENSIONS)
/*
original: xlxtss
reversed: sstxlx
removed: sstl
uniqued: stl
sorted: lst
*/
char array [] = { 'x', 'l', 'x', 't', 's', 's' };
ostringstream os;
ostream_iterator<char> o(os,"");
slist<char> str(array+0, array + 6);
slist<char>::iterator i;
//Check const_iterator construction from iterator
slist<char>::const_iterator ci(i);
slist<char>::const_iterator ci2(ci);
// cout << "reversed: ";
str.reverse();
for(i = str.begin(); i != str.end(); i++)
os << *i;
stringbuf* buff=os.rdbuf();
string result=buff->str();
CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstxlx"));
//cout << "removed: ";
str.remove('x');
ostringstream os2;
for(i = str.begin(); i != str.end(); i++)
os2 << *i;
buff=os2.rdbuf();
result=buff->str();
CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstl"));
//cout << "uniqued: ";
str.unique();
ostringstream os3;
for(i = str.begin(); i != str.end(); i++)
os3 << *i;
buff=os3.rdbuf();
result=buff->str();
CPPUNIT_ASSERT(!strcmp(result.c_str(),"stl"));
//cout << "sorted: ";
str.sort();
ostringstream os4;
for(i = str.begin(); i != str.end(); i++)
os4 << *i;
buff = os4.rdbuf();
result = buff->str();
CPPUNIT_ASSERT(!strcmp(result.c_str(),"lst"));
//A small compilation time check to be activated from time to time:
# if 0
{
slist<char>::iterator sl_char_ite;
slist<int>::iterator sl_int_ite;
CPPUNIT_ASSERT( sl_char_ite != sl_int_ite );
}
# endif
#endif
}
void SlistTest::erase()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
int array[] = { 0, 1, 2, 3, 4 };
slist<int> sl(array, array + 5);
slist<int>::iterator slit;
slit = sl.erase(sl.begin());
CPPUNIT_ASSERT( *slit == 1);
++slit++; ++slit;
slit = sl.erase(sl.begin(), slit);
CPPUNIT_ASSERT( *slit == 3 );
sl.assign(array, array + 5);
slit = sl.erase_after(sl.begin());
CPPUNIT_ASSERT( *slit == 2 );
slit = sl.begin(); ++slit; ++slit;
slit = sl.erase_after(sl.begin(), slit);
CPPUNIT_ASSERT( *slit == 3 );
sl.erase_after(sl.before_begin());
CPPUNIT_ASSERT( sl.front() == 3 );
#endif
}
void SlistTest::insert()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
int array[] = { 0, 1, 2, 3, 4 };
//insert
{
slist<int> sl;
sl.insert(sl.begin(), 5);
CPPUNIT_ASSERT( sl.front() == 5 );
CPPUNIT_ASSERT( sl.size() == 1 );
//debug mode check:
//sl.insert(sl.before_begin(), array, array + 5);
sl.insert(sl.begin(), array, array + 5);
CPPUNIT_ASSERT( sl.size() == 6 );
int i;
slist<int>::iterator slit(sl.begin());
for (i = 0; slit != sl.end(); ++slit, ++i) {
CPPUNIT_ASSERT( *slit == i );
}
}
//insert_after
{
slist<int> sl;
//debug check:
//sl.insert_after(sl.begin(), 5);
sl.insert_after(sl.before_begin(), 5);
CPPUNIT_ASSERT( sl.front() == 5 );
CPPUNIT_ASSERT( sl.size() == 1 );
sl.insert_after(sl.before_begin(), array, array + 5);
CPPUNIT_ASSERT( sl.size() == 6 );
int i;
slist<int>::iterator slit(sl.begin());
for (i = 0; slit != sl.end(); ++slit, ++i) {
CPPUNIT_ASSERT( *slit == i );
}
}
#endif
}
void SlistTest::splice()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
int array[] = { 0, 1, 2, 3, 4 };
//splice
{
slist<int> sl1(array, array + 5);
slist<int> sl2(array, array + 5);
slist<int>::iterator slit;
//a no op:
sl1.splice(sl1.begin(), sl1, sl1.begin());
CPPUNIT_ASSERT( sl1 == sl2 );
slit = sl1.begin(); ++slit;
//a no op:
sl1.splice(slit, sl1, sl1.begin());
CPPUNIT_ASSERT( sl1 == sl2 );
sl1.splice(sl1.end(), sl1, sl1.begin());
slit = sl1.begin();
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *(slit++) == 2 );
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *(slit++) == 4 );
CPPUNIT_ASSERT( *slit == 0 );
sl1.splice(sl1.begin(), sl1, slit);
CPPUNIT_ASSERT( sl1 == sl2 );
sl1.splice(sl1.begin(), sl2);
size_t i;
for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
if (i == 5) i = 0;
CPPUNIT_ASSERT( *slit == array[i] );
}
slit = sl1.begin();
advance(slit, 5);
CPPUNIT_ASSERT( *slit == 0 );
sl2.splice(sl2.begin(), sl1, sl1.begin(), slit);
CPPUNIT_ASSERT( sl1 == sl2 );
slit = sl1.begin(); ++slit;
sl1.splice(sl1.begin(), sl1, slit, sl1.end());
slit = sl1.begin();
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *(slit++) == 2 );
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *(slit++) == 4 );
CPPUNIT_ASSERT( *slit == 0 );
// a no op
sl2.splice(sl2.end(), sl2, sl2.begin(), sl2.end());
for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
CPPUNIT_ASSERT( i < 5 );
CPPUNIT_ASSERT( *slit == array[i] );
}
slit = sl2.begin();
advance(slit, 3);
sl2.splice(sl2.end(), sl2, sl2.begin(), slit);
slit = sl2.begin();
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *(slit++) == 4 );
CPPUNIT_ASSERT( *(slit++) == 0 );
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *slit == 2 );
}
//splice_after
{
slist<int> sl1(array, array + 5);
slist<int> sl2(array, array + 5);
slist<int>::iterator slit;
//a no op:
sl1.splice_after(sl1.begin(), sl1, sl1.begin());
CPPUNIT_ASSERT( sl1 == sl2 );
sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
slit = sl1.begin();
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *(slit++) == 0 );
CPPUNIT_ASSERT( *(slit++) == 2 );
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *slit == 4 );
sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
CPPUNIT_ASSERT( sl1 == sl2 );
sl1.splice_after(sl1.before_begin(), sl2);
size_t i;
for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
if (i == 5) i = 0;
CPPUNIT_ASSERT( *slit == array[i] );
}
slit = sl1.begin();
advance(slit, 4);
CPPUNIT_ASSERT( *slit == 4 );
sl2.splice_after(sl2.before_begin(), sl1, sl1.before_begin(), slit);
CPPUNIT_ASSERT( sl1 == sl2 );
sl1.splice_after(sl1.before_begin(), sl1, sl1.begin(), sl1.previous(sl1.end()));
slit = sl1.begin();
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *(slit++) == 2 );
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *(slit++) == 4 );
CPPUNIT_ASSERT( *slit == 0 );
// a no op
sl2.splice_after(sl2.before_begin(), sl2, sl2.before_begin(), sl2.previous(sl2.end()));
for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
CPPUNIT_ASSERT( i < 5 );
CPPUNIT_ASSERT( *slit == array[i] );
}
slit = sl2.begin();
advance(slit, 2);
sl2.splice_after(sl2.previous(sl2.end()), sl2, sl2.before_begin(), slit);
slit = sl2.begin();
CPPUNIT_ASSERT( *(slit++) == 3 );
CPPUNIT_ASSERT( *(slit++) == 4 );
CPPUNIT_ASSERT( *(slit++) == 0 );
CPPUNIT_ASSERT( *(slit++) == 1 );
CPPUNIT_ASSERT( *slit == 2 );
}
#endif
}
void SlistTest::allocator_with_state()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
char buf1[1024];
StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
char buf2[1024];
StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
typedef slist<int, StackAllocator<int> > SlistInt;
{
SlistInt slint1(10, 0, stack1);
SlistInt slint1Cpy(slint1);
SlistInt slint2(10, 1, stack2);
SlistInt slint2Cpy(slint2);
slint1.swap(slint2);
CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
CPPUNIT_ASSERT( slint1 == slint2Cpy );
CPPUNIT_ASSERT( slint2 == slint1Cpy );
CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
{
SlistInt slint1(stack1);
SlistInt slint1Cpy(slint1);
SlistInt slint2(10, 1, stack2);
SlistInt slint2Cpy(slint2);
slint1.swap(slint2);
CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
CPPUNIT_ASSERT( slint1 == slint2Cpy );
CPPUNIT_ASSERT( slint2 == slint1Cpy );
CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
{
SlistInt slint1(10, 0, stack1);
SlistInt slint1Cpy(slint1);
SlistInt slint2(stack2);
SlistInt slint2Cpy(slint2);
slint1.swap(slint2);
CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
CPPUNIT_ASSERT( slint1 == slint2Cpy );
CPPUNIT_ASSERT( slint2 == slint1Cpy );
CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice(iterator, slist)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
slint1.splice(slint1.begin(), slint2);
CPPUNIT_ASSERT( slint1.size() == 20 );
CPPUNIT_ASSERT( slint2.empty() );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice(iterator, slist, iterator)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
slint1.splice(slint1.begin(), slint2, slint2.begin());
CPPUNIT_ASSERT( slint1.size() == 11 );
CPPUNIT_ASSERT( slint2.size() == 9 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice(iterator, slist, iterator, iterator)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
SlistInt::iterator lit(slint2.begin());
advance(lit, 5);
slint1.splice(slint1.begin(), slint2, slint2.begin(), lit);
CPPUNIT_ASSERT( slint1.size() == 15 );
CPPUNIT_ASSERT( slint2.size() == 5 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice_after(iterator, slist)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
slint1.splice_after(slint1.before_begin(), slint2);
CPPUNIT_ASSERT( slint1.size() == 20 );
CPPUNIT_ASSERT( slint2.empty() );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice_after(iterator, slist, iterator)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin());
CPPUNIT_ASSERT( slint1.size() == 11 );
CPPUNIT_ASSERT( slint2.size() == 9 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//splice_after(iterator, slist, iterator, iterator)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
SlistInt::iterator lit(slint2.begin());
advance(lit, 4);
slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin(), lit);
CPPUNIT_ASSERT( slint1.size() == 15 );
CPPUNIT_ASSERT( slint2.size() == 5 );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
stack1.reset(); stack2.reset();
//merge(slist)
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
SlistInt slintref(stack2);
slintref.insert_after(slintref.before_begin(), 10, 1);
slintref.insert_after(slintref.before_begin(), 10, 0);
slint1.merge(slint2);
CPPUNIT_ASSERT( slint1.size() == 20 );
CPPUNIT_ASSERT( slint1 == slintref );
CPPUNIT_ASSERT( slint2.empty() );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
//merge(slist, predicate)
# if (!defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)) && \
(!defined (_MSC_VER) || (_MSC_VER >= 1300))
{
SlistInt slint1(10, 0, stack1);
SlistInt slint2(10, 1, stack2);
SlistInt slintref(stack2);
slintref.insert_after(slintref.before_begin(), 10, 0);
slintref.insert_after(slintref.before_begin(), 10, 1);
slint1.merge(slint2, greater<int>());
CPPUNIT_ASSERT( slint1.size() == 20 );
CPPUNIT_ASSERT( slint1 == slintref );
CPPUNIT_ASSERT( slint2.empty() );
}
CPPUNIT_CHECK( stack1.ok() );
CPPUNIT_CHECK( stack2.ok() );
//sort
{
//This is rather 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.
SlistInt slint1(stack1);
slint1.push_front(1);
slint1.insert_after(slint1.before_begin(), 10, 0);
greater<int> gt;
slint1.sort(gt);
CPPUNIT_ASSERT( slint1.front() == 1 );
slint1.sort();
SlistInt::iterator slit(slint1.begin());
advance(slit, 10);
CPPUNIT_ASSERT( *slit == 1 );
}
# endif
#endif
}
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \
(!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION))
# if !defined (__DMC__)
/* 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
{
slist<IncompleteClass> instances;
typedef slist<IncompleteClass>::iterator it;
};
# endif
#endif