| //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 <set> |
| #include <algorithm> |
| |
| #include "cppunit/cppunit_proxy.h" |
| |
| #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) |
| using namespace std; |
| #endif |
| |
| // |
| // TestCase class |
| // |
| class SetTest : public CPPUNIT_NS::TestCase |
| { |
| CPPUNIT_TEST_SUITE(SetTest); |
| CPPUNIT_TEST(set1); |
| CPPUNIT_TEST(set2); |
| CPPUNIT_TEST(erase); |
| CPPUNIT_TEST(insert); |
| CPPUNIT_TEST(find); |
| CPPUNIT_TEST(bounds); |
| CPPUNIT_TEST(specialized_less); |
| CPPUNIT_TEST(implementation_check); |
| CPPUNIT_TEST(allocator_with_state); |
| CPPUNIT_TEST(reverse_iterator_test); |
| #if !defined (STLPORT) || !defined (_STLP_USE_CONTAINERS_EXTENSION) |
| CPPUNIT_IGNORE; |
| #endif |
| CPPUNIT_TEST(template_methods); |
| CPPUNIT_TEST_SUITE_END(); |
| |
| protected: |
| void set1(); |
| void set2(); |
| void erase(); |
| void insert(); |
| void find(); |
| void bounds(); |
| void specialized_less(); |
| void implementation_check(); |
| void allocator_with_state(); |
| void reverse_iterator_test(); |
| void template_methods(); |
| }; |
| |
| CPPUNIT_TEST_SUITE_REGISTRATION(SetTest); |
| |
| |
| // |
| // tests implementation |
| // |
| void SetTest::set1() |
| { |
| set<int, less<int> > s; |
| CPPUNIT_ASSERT (s.count(42) == 0); |
| s.insert(42); |
| CPPUNIT_ASSERT (s.count(42) == 1); |
| s.insert(42); |
| CPPUNIT_ASSERT (s.count(42) == 1); |
| size_t count = s.erase(42); |
| CPPUNIT_ASSERT (count == 1); |
| } |
| |
| void SetTest::set2() |
| { |
| typedef set<int, less<int> > int_set; |
| int_set s; |
| pair<int_set::iterator, bool> p = s.insert(42); |
| CPPUNIT_ASSERT (p.second == true); |
| p = s.insert(42); |
| CPPUNIT_ASSERT (p.second == false); |
| |
| int array1 [] = { 1, 3, 6, 7 }; |
| s.insert(array1, array1 + 4); |
| CPPUNIT_ASSERT (distance(s.begin(), s.end()) == 5); |
| |
| int_set s2; |
| s2.swap(s); |
| CPPUNIT_ASSERT (distance(s2.begin(), s2.end()) == 5); |
| CPPUNIT_ASSERT (distance(s.begin(), s.end()) == 0); |
| |
| int_set s3; |
| s3.swap(s); |
| s3.swap(s2); |
| CPPUNIT_ASSERT (distance(s.begin(), s.end()) == 0); |
| CPPUNIT_ASSERT (distance(s2.begin(), s2.end()) == 0); |
| CPPUNIT_ASSERT (distance(s3.begin(), s3.end()) == 5); |
| } |
| |
| void SetTest::erase() |
| { |
| set<int, less<int> > s; |
| s.insert(1); |
| s.erase(s.begin()); |
| CPPUNIT_ASSERT( s.empty() ); |
| |
| size_t nb = s.erase(1); |
| CPPUNIT_ASSERT(nb == 0); |
| } |
| |
| void SetTest::insert() |
| { |
| set<int> s; |
| set<int>::iterator i = s.insert( s.end(), 0 ); |
| CPPUNIT_ASSERT( *i == 0 ); |
| } |
| |
| void SetTest::find() |
| { |
| set<int> s; |
| |
| CPPUNIT_ASSERT( s.find(0) == s.end() ); |
| |
| set<int> const& crs = s; |
| |
| CPPUNIT_ASSERT( crs.find(0) == crs.end() ); |
| } |
| |
| void SetTest::bounds() |
| { |
| int array1 [] = { 1, 3, 6, 7 }; |
| set<int> s(array1, array1 + sizeof(array1) / sizeof(array1[0])); |
| set<int> const& crs = s; |
| |
| set<int>::iterator sit; |
| set<int>::const_iterator scit; |
| pair<set<int>::iterator, set<int>::iterator> pit; |
| pair<set<int>::const_iterator, set<int>::const_iterator> pcit; |
| |
| //Check iterator on mutable set |
| sit = s.lower_bound(2); |
| CPPUNIT_ASSERT( sit != s.end() ); |
| CPPUNIT_ASSERT( *sit == 3 ); |
| |
| sit = s.upper_bound(5); |
| CPPUNIT_ASSERT( sit != s.end() ); |
| CPPUNIT_ASSERT( *sit == 6 ); |
| |
| pit = s.equal_range(6); |
| CPPUNIT_ASSERT( pit.first != pit.second ); |
| CPPUNIT_ASSERT( pit.first != s.end() ); |
| CPPUNIT_ASSERT( *pit.first == 6 ); |
| CPPUNIT_ASSERT( pit.second != s.end() ); |
| CPPUNIT_ASSERT( *pit.second == 7 ); |
| |
| pit = s.equal_range(4); |
| CPPUNIT_ASSERT( pit.first == pit.second ); |
| CPPUNIT_ASSERT( pit.first != s.end() ); |
| CPPUNIT_ASSERT( *pit.first == 6 ); |
| CPPUNIT_ASSERT( pit.second != s.end() ); |
| CPPUNIT_ASSERT( *pit.second == 6 ); |
| |
| //Check const_iterator on mutable set |
| scit = s.lower_bound(2); |
| CPPUNIT_ASSERT( scit != s.end() ); |
| CPPUNIT_ASSERT( *scit == 3 ); |
| |
| scit = s.upper_bound(5); |
| CPPUNIT_ASSERT( scit != s.end() ); |
| CPPUNIT_ASSERT( *scit == 6 ); |
| |
| #ifdef _STLP_MEMBER_TEMPLATES |
| pcit = s.equal_range(6); |
| CPPUNIT_ASSERT( pcit.first != pcit.second ); |
| CPPUNIT_ASSERT( pcit.first != s.end() ); |
| CPPUNIT_ASSERT( *pcit.first == 6 ); |
| CPPUNIT_ASSERT( pcit.second != s.end() ); |
| CPPUNIT_ASSERT( *pcit.second == 7 ); |
| #endif |
| |
| //Check const_iterator on const set |
| scit = crs.lower_bound(2); |
| CPPUNIT_ASSERT( scit != crs.end() ); |
| CPPUNIT_ASSERT( *scit == 3 ); |
| |
| scit = crs.upper_bound(5); |
| CPPUNIT_ASSERT( scit != crs.end() ); |
| CPPUNIT_ASSERT( *scit == 6 ); |
| |
| pcit = crs.equal_range(6); |
| CPPUNIT_ASSERT( pcit.first != pcit.second ); |
| CPPUNIT_ASSERT( pcit.first != crs.end() ); |
| CPPUNIT_ASSERT( *pcit.first == 6 ); |
| CPPUNIT_ASSERT( pcit.second != crs.end() ); |
| CPPUNIT_ASSERT( *pcit.second == 7 ); |
| } |
| |
| |
| class SetTestClass { |
| public: |
| SetTestClass (int data) : _data(data) |
| {} |
| |
| int data() const { |
| return _data; |
| } |
| |
| private: |
| int _data; |
| }; |
| |
| #if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES) |
| namespace std { |
| #endif |
| #if defined (STLPORT) |
| _STLP_TEMPLATE_NULL |
| #else |
| template <> |
| #endif |
| struct less<SetTestClass> { |
| bool operator () (SetTestClass const& lhs, SetTestClass const& rhs) const { |
| return lhs.data() < rhs.data(); |
| } |
| }; |
| #if !defined (STLPORT) || defined (_STLP_USE_NAMESPACES) |
| } |
| #endif |
| |
| void SetTest::specialized_less() |
| { |
| set<SetTestClass> s; |
| s.insert(SetTestClass(1)); |
| s.insert(SetTestClass(3)); |
| s.insert(SetTestClass(2)); |
| s.insert(SetTestClass(0)); |
| |
| set<SetTestClass>::iterator sit(s.begin()), sitEnd(s.end()); |
| int i = 0; |
| for (; sit != sitEnd; ++sit, ++i) { |
| CPPUNIT_ASSERT( sit->data() == i ); |
| } |
| } |
| |
| void SetTest::implementation_check() |
| { |
| set<int> tree; |
| tree.insert(1); |
| set<int>::iterator it = tree.begin(); |
| int const& int_ref = *it++; |
| CPPUNIT_ASSERT( int_ref == 1 ); |
| |
| CPPUNIT_ASSERT( it == tree.end() ); |
| CPPUNIT_ASSERT( it != tree.begin() ); |
| |
| set<int>::const_iterator cit = tree.begin(); |
| int const& int_cref = *cit++; |
| CPPUNIT_ASSERT( int_cref == 1 ); |
| } |
| |
| void SetTest::reverse_iterator_test() |
| { |
| set<int> tree; |
| tree.insert(1); |
| tree.insert(2); |
| |
| { |
| set<int>::reverse_iterator rit(tree.rbegin()); |
| CPPUNIT_ASSERT( *(rit++) == 2 ); |
| CPPUNIT_ASSERT( *(rit++) == 1 ); |
| CPPUNIT_ASSERT( rit == tree.rend() ); |
| } |
| |
| { |
| set<int> const& ctree = tree; |
| set<int>::const_reverse_iterator rit(ctree.rbegin()); |
| CPPUNIT_ASSERT( *(rit++) == 2 ); |
| CPPUNIT_ASSERT( *(rit++) == 1 ); |
| CPPUNIT_ASSERT( rit == ctree.rend() ); |
| } |
| } |
| |
| void SetTest::allocator_with_state() |
| { |
| char buf1[1024]; |
| StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1)); |
| |
| char buf2[1024]; |
| StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2)); |
| |
| int i; |
| typedef set<int, less<int>, StackAllocator<int> > SetInt; |
| less<int> intLess; |
| |
| { |
| SetInt sint1(intLess, stack1); |
| for (i = 0; i < 5; ++i) |
| sint1.insert(i); |
| SetInt sint1Cpy(sint1); |
| |
| SetInt sint2(intLess, stack2); |
| for (; i < 10; ++i) |
| sint2.insert(i); |
| SetInt sint2Cpy(sint2); |
| |
| sint1.swap(sint2); |
| |
| CPPUNIT_ASSERT( sint1.get_allocator().swaped() ); |
| CPPUNIT_ASSERT( sint2.get_allocator().swaped() ); |
| |
| CPPUNIT_ASSERT( sint1 == sint2Cpy ); |
| CPPUNIT_ASSERT( sint2 == sint1Cpy ); |
| CPPUNIT_ASSERT( sint1.get_allocator() == stack2 ); |
| CPPUNIT_ASSERT( sint2.get_allocator() == stack1 ); |
| } |
| CPPUNIT_ASSERT( stack1.ok() ); |
| CPPUNIT_ASSERT( stack2.ok() ); |
| stack1.reset(); stack2.reset(); |
| |
| { |
| SetInt sint1(intLess, stack1); |
| SetInt sint1Cpy(sint1); |
| |
| SetInt sint2(intLess, stack2); |
| for (i = 0; i < 10; ++i) |
| sint2.insert(i); |
| SetInt sint2Cpy(sint2); |
| |
| sint1.swap(sint2); |
| |
| CPPUNIT_ASSERT( sint1.get_allocator().swaped() ); |
| CPPUNIT_ASSERT( sint2.get_allocator().swaped() ); |
| |
| CPPUNIT_ASSERT( sint1 == sint2Cpy ); |
| CPPUNIT_ASSERT( sint2 == sint1Cpy ); |
| CPPUNIT_ASSERT( sint1.get_allocator() == stack2 ); |
| CPPUNIT_ASSERT( sint2.get_allocator() == stack1 ); |
| } |
| CPPUNIT_ASSERT( stack1.ok() ); |
| CPPUNIT_ASSERT( stack2.ok() ); |
| stack1.reset(); stack2.reset(); |
| |
| { |
| SetInt sint1(intLess, stack1); |
| for (i = 0; i < 10; ++i) |
| sint1.insert(i); |
| SetInt sint1Cpy(sint1); |
| |
| SetInt sint2(intLess, stack2); |
| SetInt sint2Cpy(sint2); |
| |
| sint1.swap(sint2); |
| |
| CPPUNIT_ASSERT( sint1.get_allocator().swaped() ); |
| CPPUNIT_ASSERT( sint2.get_allocator().swaped() ); |
| |
| CPPUNIT_ASSERT( sint1 == sint2Cpy ); |
| CPPUNIT_ASSERT( sint2 == sint1Cpy ); |
| CPPUNIT_ASSERT( sint1.get_allocator() == stack2 ); |
| CPPUNIT_ASSERT( sint2.get_allocator() == stack1 ); |
| } |
| CPPUNIT_ASSERT( stack1.ok() ); |
| CPPUNIT_ASSERT( stack2.ok() ); |
| stack1.reset(); stack2.reset(); |
| } |
| |
| struct Key |
| { |
| Key() : m_data(0) {} |
| explicit Key(int data) : m_data(data) {} |
| |
| int m_data; |
| }; |
| |
| struct KeyCmp |
| { |
| bool operator () (Key lhs, Key rhs) const |
| { return lhs.m_data < rhs.m_data; } |
| |
| bool operator () (Key lhs, int rhs) const |
| { return lhs.m_data < rhs; } |
| |
| bool operator () (int lhs, Key rhs) const |
| { return lhs < rhs.m_data; } |
| }; |
| |
| struct KeyCmpPtr |
| { |
| bool operator () (Key const volatile *lhs, Key const volatile *rhs) const |
| { return (*lhs).m_data < (*rhs).m_data; } |
| |
| bool operator () (Key const volatile *lhs, int rhs) const |
| { return (*lhs).m_data < rhs; } |
| |
| bool operator () (int lhs, Key const volatile *rhs) const |
| { return lhs < (*rhs).m_data; } |
| }; |
| |
| void SetTest::template_methods() |
| { |
| #if defined (STLPORT) && defined (_STLP_USE_CONTAINERS_EXTENSION) |
| { |
| typedef set<Key, KeyCmp> KeySet; |
| KeySet keySet; |
| keySet.insert(Key(1)); |
| keySet.insert(Key(2)); |
| keySet.insert(Key(3)); |
| keySet.insert(Key(4)); |
| |
| CPPUNIT_ASSERT( keySet.count(Key(1)) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(1) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(5) == 0 ); |
| |
| CPPUNIT_ASSERT( keySet.find(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.lower_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.upper_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.equal_range(2) != make_pair(keySet.begin(), keySet.end()) ); |
| |
| KeySet const& ckeySet = keySet; |
| CPPUNIT_ASSERT( ckeySet.find(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.lower_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.upper_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.equal_range(2) != make_pair(ckeySet.begin(), ckeySet.end()) ); |
| } |
| |
| { |
| typedef set<Key*, KeyCmpPtr> KeySet; |
| KeySet keySet; |
| Key key1(1), key2(2), key3(3), key4(4); |
| keySet.insert(&key1); |
| keySet.insert(&key2); |
| keySet.insert(&key3); |
| keySet.insert(&key4); |
| |
| CPPUNIT_ASSERT( keySet.count(1) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(5) == 0 ); |
| |
| CPPUNIT_ASSERT( keySet.find(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.lower_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.upper_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.equal_range(2) != make_pair(keySet.begin(), keySet.end()) ); |
| |
| KeySet const& ckeySet = keySet; |
| CPPUNIT_ASSERT( ckeySet.find(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.lower_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.upper_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.equal_range(2) != make_pair(ckeySet.begin(), ckeySet.end()) ); |
| } |
| { |
| typedef multiset<Key, KeyCmp> KeySet; |
| KeySet keySet; |
| keySet.insert(Key(1)); |
| keySet.insert(Key(2)); |
| keySet.insert(Key(3)); |
| keySet.insert(Key(4)); |
| |
| CPPUNIT_ASSERT( keySet.count(Key(1)) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(1) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(5) == 0 ); |
| |
| CPPUNIT_ASSERT( keySet.find(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.lower_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.upper_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.equal_range(2) != make_pair(keySet.begin(), keySet.end()) ); |
| |
| KeySet const& ckeySet = keySet; |
| CPPUNIT_ASSERT( ckeySet.find(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.lower_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.upper_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.equal_range(2) != make_pair(ckeySet.begin(), ckeySet.end()) ); |
| } |
| |
| { |
| typedef multiset<Key const volatile*, KeyCmpPtr> KeySet; |
| KeySet keySet; |
| Key key1(1), key2(2), key3(3), key4(4); |
| keySet.insert(&key1); |
| keySet.insert(&key2); |
| keySet.insert(&key3); |
| keySet.insert(&key4); |
| |
| CPPUNIT_ASSERT( keySet.count(1) == 1 ); |
| CPPUNIT_ASSERT( keySet.count(5) == 0 ); |
| |
| CPPUNIT_ASSERT( keySet.find(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.lower_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.upper_bound(2) != keySet.end() ); |
| CPPUNIT_ASSERT( keySet.equal_range(2) != make_pair(keySet.begin(), keySet.end()) ); |
| |
| KeySet const& ckeySet = keySet; |
| CPPUNIT_ASSERT( ckeySet.find(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.lower_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.upper_bound(2) != ckeySet.end() ); |
| CPPUNIT_ASSERT( ckeySet.equal_range(2) != make_pair(ckeySet.begin(), ckeySet.end()) ); |
| } |
| #endif |
| } |
| |
| #if !defined (STLPORT) || \ |
| !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 |
| { |
| set<IncompleteClass> instances; |
| typedef set<IncompleteClass>::iterator it; |
| multiset<IncompleteClass> minstances; |
| typedef multiset<IncompleteClass>::iterator mit; |
| }; |
| # endif |
| #endif |