| #include <vector> |
| #include <algorithm> |
| #include <string> |
| #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| # include <rope> |
| #endif |
| #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| # include <slist> |
| #endif |
| #include <list> |
| #include <deque> |
| #include <set> |
| #include <map> |
| #if defined (STLPORT) |
| # include <unordered_set> |
| # include <unordered_map> |
| #endif |
| #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| # include <hash_set> |
| # include <hash_map> |
| #endif |
| #include <queue> |
| #include <stack> |
| |
| #include "mvctor_test.h" |
| |
| #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) |
| using namespace std; |
| # if defined (STLPORT) |
| using namespace std::tr1; |
| # endif |
| #endif |
| |
| #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) |
| |
| # if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES) |
| // libstdc++ sometimes exposed its own __true_type in |
| // global namespace resulting in an ambiguity. |
| # define __true_type std::__true_type |
| # define __false_type std::__false_type |
| # endif |
| |
| static bool type_to_bool(__true_type) |
| { return true; } |
| static bool type_to_bool(__false_type) |
| { return false; } |
| |
| template <class _Tp> |
| static bool is_movable(const _Tp&) { |
| typedef typename __move_traits<_Tp>::implemented _MovableTp; |
| return type_to_bool(_MovableTp()); |
| } |
| |
| template <class _Tp> |
| static bool is_move_complete(const _Tp&) { |
| typedef __move_traits<_Tp> _TpMoveTraits; |
| typedef typename _TpMoveTraits::complete _TpMoveComplete; |
| return type_to_bool(_TpMoveComplete()); |
| } |
| |
| struct specially_allocated_struct { |
| bool operator < (const specially_allocated_struct&) const; |
| # if defined (__DMC__) // slist<_Tp,_Alloc>::remove error |
| bool operator==(const specially_allocated_struct&) const; |
| # endif |
| }; |
| |
| #if defined (__DMC__) |
| bool specially_allocated_struct::operator < (const specially_allocated_struct&) const |
| { return false; } |
| #endif |
| |
| struct struct_with_specialized_less {}; |
| |
| # if defined (_STLP_USE_NAMESPACES) |
| namespace std { |
| # endif |
| _STLP_TEMPLATE_NULL |
| class allocator<specially_allocated_struct> { |
| //This allocator just represent what a STLport could do and in this |
| //case the STL containers implemented with it should still be movable |
| //but not completely as we cannot do any hypothesis on what is in this |
| //allocator. |
| public: |
| typedef specially_allocated_struct value_type; |
| typedef value_type * pointer; |
| typedef const value_type* const_pointer; |
| typedef value_type& reference; |
| typedef const value_type& const_reference; |
| typedef size_t size_type; |
| typedef ptrdiff_t difference_type; |
| # if defined (_STLP_MEMBER_TEMPLATE_CLASSES) |
| template <class _Tp1> struct rebind { |
| typedef allocator<_Tp1> other; |
| }; |
| # endif |
| allocator() _STLP_NOTHROW {} |
| # if defined (_STLP_MEMBER_TEMPLATES) |
| template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {} |
| # endif |
| allocator(const allocator&) _STLP_NOTHROW {} |
| ~allocator() _STLP_NOTHROW {} |
| pointer address(reference __x) const { return &__x; } |
| const_pointer address(const_reference __x) const { return &__x; } |
| pointer allocate(size_type, const void* = 0) { return 0; } |
| void deallocate(pointer, size_type) {} |
| size_type max_size() const _STLP_NOTHROW { return 0; } |
| void construct(pointer, const_reference) {} |
| void destroy(pointer) {} |
| }; |
| |
| _STLP_TEMPLATE_NULL |
| struct less<struct_with_specialized_less> { |
| bool operator() (struct_with_specialized_less const&, |
| struct_with_specialized_less const&) const; |
| }; |
| |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| # if !defined (_STLP_NO_MOVE_SEMANTIC) |
| # if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564) |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<vector<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<deque<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<list<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<slist<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<less<struct_with_specialized_less> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<set<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| _STLP_TEMPLATE_NULL |
| struct __move_traits<multiset<specially_allocated_struct> > { |
| typedef __true_type implemented; |
| typedef __false_type complete; |
| }; |
| # endif |
| # endif |
| # endif |
| |
| # if defined (_STLP_USE_NAMESPACES) |
| } |
| # endif |
| #endif |
| |
| void MoveConstructorTest::movable_declaration() |
| { |
| #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \ |
| !defined (_STLP_NO_MOVE_SEMANTIC) |
| //This test purpose is to check correct detection of the STL movable |
| //traits declaration |
| { |
| //string, wstring: |
| CPPUNIT_ASSERT( is_movable(string()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(string()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(string()) ); |
| # endif |
| # if defined (_STLP_HAS_WCHAR_T) |
| CPPUNIT_ASSERT( is_movable(wstring()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(wstring()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(wstring()) ); |
| # endif |
| # endif |
| } |
| |
| # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| { |
| //crope, wrope: |
| CPPUNIT_ASSERT( is_movable(crope()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(crope()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(crope()) ); |
| # endif |
| # if defined (_STLP_HAS_WCHAR_T) |
| CPPUNIT_ASSERT( is_movable(wrope()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(wrope()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(wrope()) ); |
| # endif |
| # endif |
| } |
| # endif |
| |
| { |
| //vector: |
| CPPUNIT_ASSERT( is_movable(vector<char>()) ); |
| CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(vector<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(vector<char>()) ); |
| # endif |
| } |
| |
| { |
| //deque: |
| CPPUNIT_ASSERT( is_movable(deque<char>()) ); |
| CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(deque<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(deque<char>()) ); |
| # endif |
| } |
| |
| { |
| //list: |
| CPPUNIT_ASSERT( is_movable(list<char>()) ); |
| CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(list<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(list<char>()) ); |
| # endif |
| } |
| |
| # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| { |
| //slist: |
| CPPUNIT_ASSERT( is_movable(slist<char>()) ); |
| CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(slist<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(slist<char>()) ); |
| # endif |
| } |
| # endif |
| |
| { |
| //queue: |
| CPPUNIT_ASSERT( is_movable(queue<char>()) ); |
| CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(queue<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(queue<char>()) ); |
| # endif |
| } |
| |
| { |
| //stack: |
| CPPUNIT_ASSERT( is_movable(stack<char>()) ); |
| CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(stack<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(stack<char>()) ); |
| # endif |
| } |
| |
| #endif |
| } |
| |
| void MoveConstructorTest::movable_declaration_assoc() |
| { |
| #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \ |
| !defined (_STLP_NO_MOVE_SEMANTIC) |
| { |
| //associative containers, set multiset, map, multimap: |
| |
| //For associative containers it is important that less is correctly recognize as |
| //the STLport less or a user specialized less: |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(less<char>()) ); |
| # endif |
| CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) ); |
| |
| //set |
| CPPUNIT_ASSERT( is_movable(set<char>()) ); |
| CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(set<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(set<char>()) ); |
| # endif |
| |
| //multiset |
| CPPUNIT_ASSERT( is_movable(multiset<char>()) ); |
| CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(multiset<char>()) ); |
| CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) ); |
| # endif |
| |
| //map |
| CPPUNIT_ASSERT( is_movable(map<char, char>()) ); |
| CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(map<char, char>()) ); |
| //Here even if allocator has been specialized for specially_allocated_struct |
| //this pecialization won't be used in default map instanciation as the default |
| //allocator is allocator<pair<specially_allocated_struct, char> > |
| CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) ); |
| # endif |
| |
| //multimap |
| CPPUNIT_ASSERT( is_movable(multimap<char, char>()) ); |
| CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) ); |
| # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) |
| CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) ); |
| //Idem map remark |
| CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) ); |
| # else |
| CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) ); |
| # endif |
| } |
| #endif |
| } |
| |
| void MoveConstructorTest::movable_declaration_hash() |
| { |
| #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \ |
| !defined (_STLP_NO_MOVE_SEMANTIC) |
| { |
| //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap, |
| // hash_set, hash_multiset, hash_map, hash_multimap: |
| |
| //We only check that they are movable, completness is not yet supported |
| CPPUNIT_ASSERT( is_movable(unordered_set<char>()) ); |
| CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) ); |
| CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) ); |
| CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) ); |
| # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) |
| CPPUNIT_ASSERT( is_movable(hash_set<char>()) ); |
| CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) ); |
| CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) ); |
| CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) ); |
| # endif |
| } |
| #endif |
| } |
| |