/home/ntakagi/work/STLport-5.1.5/stlport/stl/_move_construct_fwk.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 2003
00004  * François Dumont
00005  *
00006  * This material is provided "as is", with absolutely no warranty expressed
00007  * or implied. Any use is at your own risk.
00008  *
00009  * Permission to use or copy this software for any purpose is hereby granted
00010  * without fee, provided the above notices are retained on all copies.
00011  * Permission to modify the code and to distribute modified code is granted,
00012  * provided the above notices are retained, and a notice that the code was
00013  * modified is included with the above copyright notice.
00014  *
00015  */
00016 
00017 #ifndef _STLP_MOVE_CONSTRUCT_FWK_H
00018 #define _STLP_MOVE_CONSTRUCT_FWK_H
00019 
00020 #ifndef _STLP_TYPE_TRAITS_H
00021 #  include <stl/type_traits.h>
00022 #endif
00023 
00024 _STLP_BEGIN_NAMESPACE
00025 
00026 /*************************************************************
00027  * Move constructor framework
00028  *************************************************************/
00029 
00030 /*************************************************************
00031  *Partial move:
00032  *The source HAS to be a valid instance after the move!
00033  *************************************************************/
00034 template <class _Tp>
00035 class __move_source {
00036 public:
00037   explicit __move_source (_Tp &_src) : _M_data(_src)
00038   {}
00039 
00040   _Tp& get() const
00041   { return _M_data; }
00042 private:
00043   _Tp &_M_data;
00044 
00045   //We explicitely forbid assignment to avoid warning:
00046   typedef __move_source<_Tp> _Self;
00047   _Self& operator = (_Self const&);
00048 };
00049 
00050 //Class used to signal move constructor support, implementation and type.
00051 template <class _Tp>
00052 struct __move_traits {
00053   /*
00054    * implemented tells if a the special move constructor has to be called or the classic
00055    * copy constructor is just fine. Most of the time the copy constructor is fine only
00056    * if the following info is true.
00057    */
00058 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && \
00059    !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && \
00060    !defined (_STLP_NO_MOVE_SEMANTIC)
00061   typedef typename _IsSTLportClass<_Tp>::_Ret implemented;
00062 #else
00063   typedef __false_type implemented;
00064 #endif
00065   /*
00066    * complete tells if the move is complete or partial, that is to say, does the source
00067    * needs to be destroyed once it has been moved.
00068    */
00069   typedef typename __type_traits<_Tp>::has_trivial_destructor complete;
00070 };
00071 
00072 #if !defined (_STLP_NO_MOVE_SEMANTIC)
00073 typedef __true_type __stlp_movable;
00074 #else
00075 typedef __false_type __stlp_movable;
00076 #endif
00077 
00078 _STLP_MOVE_TO_PRIV_NAMESPACE
00079 
00080 /*
00081  * This struct should never be used if the user has not explicitely stipulated
00082  * that its class support the full move concept. To check that the return type
00083  * in such a case will be __invalid_source<_Tp> to generate a compile error
00084  * revealing the configuration problem.
00085  */
00086 template <class _Tp>
00087 struct _MoveSourceTraits {
00088   typedef typename __move_traits<_Tp>::implemented _MvImpRet;
00089 #if defined (__BORLANDC__)
00090   typedef typename __selectT<_MvImpRet,
00091 #else
00092   enum {_MvImp = __type2bool<_MvImpRet>::_Ret};
00093   typedef typename __select<_MvImp,
00094 #endif
00095                             __move_source<_Tp>,
00096                             _Tp const&>::_Ret _Type;
00097 };
00098 
00099 //The helper function
00100 template <class _Tp>
00101 inline _STLP_TYPENAME_ON_RETURN_TYPE _MoveSourceTraits<_Tp>::_Type
00102 _AsMoveSource (_Tp &src) {
00103   typedef typename _MoveSourceTraits<_Tp>::_Type _SrcType;
00104   return _SrcType(src);
00105 }
00106 
00107 //Helper structs used for many class.
00108 template <class _Tp>
00109 struct __move_traits_aux {
00110   typedef typename __move_traits<_Tp>::implemented implemented;
00111   typedef typename __move_traits<_Tp>::complete complete;
00112 };
00113 
00114 template <class _Tp1, class _Tp2>
00115 struct __move_traits_aux2 {
00116   typedef __move_traits<_Tp1> _MoveTraits1;
00117   typedef __move_traits<_Tp2> _MoveTraits2;
00118 
00119   typedef typename _Lor2<typename _MoveTraits1::implemented,
00120                          typename _MoveTraits2::implemented>::_Ret implemented;
00121   typedef typename _Land2<typename _MoveTraits1::complete,
00122                           typename _MoveTraits2::complete>::_Ret complete;
00123 };
00124 
00125 /*
00126  * Most of the time a class implement a move constructor but its use depends
00127  * on a third party, this is what the following struct are for.
00128  */
00129 template <class _Tp>
00130 struct __move_traits_help {
00131   typedef __true_type implemented;
00132   typedef typename __move_traits<_Tp>::complete complete;
00133 };
00134 
00135 template <class _Tp1, class _Tp2>
00136 struct __move_traits_help1 {
00137   typedef __move_traits<_Tp1> _MoveTraits1;
00138   typedef __move_traits<_Tp2> _MoveTraits2;
00139 
00140   typedef typename _Lor2<typename _MoveTraits1::implemented,
00141                          typename _MoveTraits2::implemented>::_Ret implemented;
00142   typedef typename _Land2<typename _MoveTraits1::complete,
00143                           typename _MoveTraits2::complete>::_Ret complete;
00144 };
00145 
00146 template <class _Tp1, class _Tp2>
00147 struct __move_traits_help2 {
00148   typedef __move_traits<_Tp1> _MoveTraits1;
00149   typedef __move_traits<_Tp2> _MoveTraits2;
00150 
00151   typedef __stlp_movable implemented;
00152   typedef typename _Land2<typename _MoveTraits1::complete,
00153                           typename _MoveTraits2::complete>::_Ret complete;
00154 };
00155 
00156 _STLP_MOVE_TO_STD_NAMESPACE
00157 
00158 _STLP_END_NAMESPACE
00159 
00160 #endif /* _STLP_MOVE_CONSTRUCT_FWK_H */



Generated on Mon Mar 10 15:32:31 2008 by  doxygen 1.5.1