blob: 4a85fe32de5f9ea1915d2f4aad64e80c7e576ef7 [file] [log] [blame]
/*
*
* Copyright (c) 2003
* Francois Dumont
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#ifndef _STLP_MOVE_CONSTRUCT_FWK_H
#define _STLP_MOVE_CONSTRUCT_FWK_H
#ifndef _STLP_TYPE_TRAITS_H
# include <stl/type_traits.h>
#endif
_STLP_BEGIN_NAMESPACE
/*************************************************************
* Move constructor framework
*************************************************************/
/*************************************************************
*Partial move:
*The source HAS to be a valid instance after the move!
*************************************************************/
template <class _Tp>
class __move_source {
public:
explicit __move_source (_Tp &_src) : _M_data(_src)
{}
_Tp& get() const
{ return _M_data; }
private:
_Tp &_M_data;
//We explicitely forbid assignment to avoid warning:
typedef __move_source<_Tp> _Self;
_Self& operator = (_Self const&);
};
//Class used to signal move constructor support, implementation and type.
template <class _Tp>
struct __move_traits {
/*
* implemented tells if a the special move constructor has to be called or the classic
* copy constructor is just fine. Most of the time the copy constructor is fine only
* if the following info is true.
*/
#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && \
!defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && \
!defined (_STLP_NO_MOVE_SEMANTIC)
typedef typename _IsSTLportClass<_Tp>::_Ret implemented;
#else
typedef __false_type implemented;
#endif
/*
* complete tells if the move is complete or partial, that is to say, does the source
* needs to be destroyed once it has been moved.
*/
# if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564)
typedef __type_traits<_Tp>::has_trivial_destructor _TpMoveComplete;
typedef typename __bool2type<__type2bool<_TpMoveComplete>::_Ret>::_Ret complete;
# else
typedef typename __type_traits<_Tp>::has_trivial_destructor complete;
# endif
};
_STLP_MOVE_TO_PRIV_NAMESPACE
/*
* This struct should never be used if the user has not explicitely stipulated
* that its class support the full move concept. To check that the return type
* in such a case will be __invalid_source<_Tp> to generate a compile error
* revealing the configuration problem.
*/
template <class _Tp>
struct _MoveSourceTraits {
typedef typename __move_traits<_Tp>::implemented _MvImpRet;
#if defined (__BORLANDC__)
typedef typename __selectT<_MvImpRet,
#else
enum {_MvImp = __type2bool<_MvImpRet>::_Ret};
typedef typename __select<_MvImp,
#endif
__move_source<_Tp>,
_Tp const&>::_Ret _Type;
};
//The helper function
template <class _Tp>
inline _STLP_TYPENAME_ON_RETURN_TYPE _MoveSourceTraits<_Tp>::_Type
_AsMoveSource (_Tp &src) {
typedef typename _MoveSourceTraits<_Tp>::_Type _SrcType;
return _SrcType(src);
}
//Helper structs used for many class.
template <class _Tp>
struct __move_traits_aux {
typedef typename __move_traits<_Tp>::implemented implemented;
typedef typename __move_traits<_Tp>::complete complete;
};
template <class _Tp1, class _Tp2>
struct __move_traits_aux2 {
typedef __move_traits<_Tp1> _MoveTraits1;
typedef __move_traits<_Tp2> _MoveTraits2;
typedef typename _Lor2<typename _MoveTraits1::implemented,
typename _MoveTraits2::implemented>::_Ret implemented;
typedef typename _Land2<typename _MoveTraits1::complete,
typename _MoveTraits2::complete>::_Ret complete;
};
/*
* Most of the time a class implement a move constructor but its use depends
* on a third party, this is what the following struct are for.
*/
template <class _Tp>
struct __move_traits_help {
typedef __true_type implemented;
typedef typename __move_traits<_Tp>::complete complete;
};
template <class _Tp1, class _Tp2>
struct __move_traits_help1 {
typedef __move_traits<_Tp1> _MoveTraits1;
typedef __move_traits<_Tp2> _MoveTraits2;
typedef typename _Lor2<typename _MoveTraits1::implemented,
typename _MoveTraits2::implemented>::_Ret implemented;
typedef typename _Land2<typename _MoveTraits1::complete,
typename _MoveTraits2::complete>::_Ret complete;
};
template <class _Tp1, class _Tp2>
struct __move_traits_help2 {
typedef __move_traits<_Tp1> _MoveTraits1;
typedef __move_traits<_Tp2> _MoveTraits2;
typedef __true_type implemented;
typedef typename _Land2<typename _MoveTraits1::complete,
typename _MoveTraits2::complete>::_Ret complete;
};
_STLP_MOVE_TO_STD_NAMESPACE
_STLP_END_NAMESPACE
#endif /* _STLP_MOVE_CONSTRUCT_FWK_H */