#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
}