Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 2003
      4  * Francois Dumont
      5  *
      6  * This material is provided "as is", with absolutely no warranty expressed
      7  * or implied. Any use is at your own risk.
      8  *
      9  * Permission to use or copy this software for any purpose is hereby granted
     10  * without fee, provided the above notices are retained on all copies.
     11  * Permission to modify the code and to distribute modified code is granted,
     12  * provided the above notices are retained, and a notice that the code was
     13  * modified is included with the above copyright notice.
     14  *
     15  */
     16 
     17 #ifndef _STLP_MOVE_CONSTRUCT_FWK_H
     18 #define _STLP_MOVE_CONSTRUCT_FWK_H
     19 
     20 #ifndef _STLP_TYPE_TRAITS_H
     21 #  include <stl/type_traits.h>
     22 #endif
     23 
     24 _STLP_BEGIN_NAMESPACE
     25 
     26 /*************************************************************
     27  * Move constructor framework
     28  *************************************************************/
     29 
     30 /*************************************************************
     31  *Partial move:
     32  *The source HAS to be a valid instance after the move!
     33  *************************************************************/
     34 template <class _Tp>
     35 class __move_source {
     36 public:
     37   explicit __move_source (_Tp &_src) : _M_data(_src)
     38   {}
     39 
     40   _Tp& get() const
     41   { return _M_data; }
     42 private:
     43   _Tp &_M_data;
     44 
     45   //We explicitely forbid assignment to avoid warning:
     46   typedef __move_source<_Tp> _Self;
     47   _Self& operator = (_Self const&);
     48 };
     49 
     50 //Class used to signal move constructor support, implementation and type.
     51 template <class _Tp>
     52 struct __move_traits {
     53   /*
     54    * implemented tells if a the special move constructor has to be called or the classic
     55    * copy constructor is just fine. Most of the time the copy constructor is fine only
     56    * if the following info is true.
     57    */
     58 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && \
     59    !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && \
     60    !defined (_STLP_NO_MOVE_SEMANTIC)
     61   typedef typename _IsSTLportClass<_Tp>::_Ret implemented;
     62 #else
     63   typedef __false_type implemented;
     64 #endif
     65   /*
     66    * complete tells if the move is complete or partial, that is to say, does the source
     67    * needs to be destroyed once it has been moved.
     68    */
     69 #  if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564)
     70   typedef __type_traits<_Tp>::has_trivial_destructor _TpMoveComplete;
     71   typedef typename __bool2type<__type2bool<_TpMoveComplete>::_Ret>::_Ret complete;
     72 #  else
     73   typedef typename __type_traits<_Tp>::has_trivial_destructor complete;
     74 #  endif
     75 };
     76 
     77 _STLP_MOVE_TO_PRIV_NAMESPACE
     78 
     79 /*
     80  * This struct should never be used if the user has not explicitely stipulated
     81  * that its class support the full move concept. To check that the return type
     82  * in such a case will be __invalid_source<_Tp> to generate a compile error
     83  * revealing the configuration problem.
     84  */
     85 template <class _Tp>
     86 struct _MoveSourceTraits {
     87   typedef typename __move_traits<_Tp>::implemented _MvImpRet;
     88 #if defined (__BORLANDC__)
     89   typedef typename __selectT<_MvImpRet,
     90 #else
     91   enum {_MvImp = __type2bool<_MvImpRet>::_Ret};
     92   typedef typename __select<_MvImp,
     93 #endif
     94                             __move_source<_Tp>,
     95                             _Tp const&>::_Ret _Type;
     96 };
     97 
     98 //The helper function
     99 template <class _Tp>
    100 inline _STLP_TYPENAME_ON_RETURN_TYPE _MoveSourceTraits<_Tp>::_Type
    101 _AsMoveSource (_Tp &src) {
    102   typedef typename _MoveSourceTraits<_Tp>::_Type _SrcType;
    103   return _SrcType(src);
    104 }
    105 
    106 //Helper structs used for many class.
    107 template <class _Tp>
    108 struct __move_traits_aux {
    109   typedef typename __move_traits<_Tp>::implemented implemented;
    110   typedef typename __move_traits<_Tp>::complete complete;
    111 };
    112 
    113 template <class _Tp1, class _Tp2>
    114 struct __move_traits_aux2 {
    115   typedef __move_traits<_Tp1> _MoveTraits1;
    116   typedef __move_traits<_Tp2> _MoveTraits2;
    117 
    118   typedef typename _Lor2<typename _MoveTraits1::implemented,
    119                          typename _MoveTraits2::implemented>::_Ret implemented;
    120   typedef typename _Land2<typename _MoveTraits1::complete,
    121                           typename _MoveTraits2::complete>::_Ret complete;
    122 };
    123 
    124 /*
    125  * Most of the time a class implement a move constructor but its use depends
    126  * on a third party, this is what the following struct are for.
    127  */
    128 template <class _Tp>
    129 struct __move_traits_help {
    130   typedef __true_type implemented;
    131   typedef typename __move_traits<_Tp>::complete complete;
    132 };
    133 
    134 template <class _Tp1, class _Tp2>
    135 struct __move_traits_help1 {
    136   typedef __move_traits<_Tp1> _MoveTraits1;
    137   typedef __move_traits<_Tp2> _MoveTraits2;
    138 
    139   typedef typename _Lor2<typename _MoveTraits1::implemented,
    140                          typename _MoveTraits2::implemented>::_Ret implemented;
    141   typedef typename _Land2<typename _MoveTraits1::complete,
    142                           typename _MoveTraits2::complete>::_Ret complete;
    143 };
    144 
    145 template <class _Tp1, class _Tp2>
    146 struct __move_traits_help2 {
    147   typedef __move_traits<_Tp1> _MoveTraits1;
    148   typedef __move_traits<_Tp2> _MoveTraits2;
    149 
    150   typedef __true_type implemented;
    151   typedef typename _Land2<typename _MoveTraits1::complete,
    152                           typename _MoveTraits2::complete>::_Ret complete;
    153 };
    154 
    155 _STLP_MOVE_TO_STD_NAMESPACE
    156 
    157 _STLP_END_NAMESPACE
    158 
    159 #endif /* _STLP_MOVE_CONSTRUCT_FWK_H */
    160