unique_ptr.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 The FLWOR Foundation.
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef ZORBA_UNIQUE_PTR_H
00018 #define ZORBA_UNIQUE_PTR_H
00019 
00020 #include <zorba/config.h>
00021 
00022 #ifdef ZORBA_CXX_UNIQUE_PTR
00023 # include <memory>                      /* for unique_ptr */
00024 # include <utility>                     /* for forward, move */
00025 #else
00026 
00027 #include <algorithm>                    /* for swap() */
00028 #include "type_traits.h"
00029 
00030 namespace std {
00031 
00032 ///////////////////////////////////////////////////////////////////////////////
00033 
00034 template<typename T> inline
00035 typename enable_if<!zorba::internal::is_movable<T>::value,T&>::type
00036 move( T &t ) {
00037    return t;
00038 }
00039 
00040 template<typename T> inline
00041 typename enable_if<zorba::internal::is_movable<T>::value,
00042                    zorba::internal::rv<T>&>::type
00043 move( T const &t ) {
00044    return *static_cast<zorba::internal::rv<T>*>( const_cast<T*>( &t ) );
00045 }
00046 
00047 template<typename T> inline
00048 typename enable_if<zorba::internal::is_movable<T>::value,
00049                    zorba::internal::rv<T>&>::type
00050 move( zorba::internal::rv<T> &t ) {
00051   return t;
00052 }
00053 
00054 ///////////////////////////////////////////////////////////////////////////////
00055 
00056 /**
00057  * \internal
00058  * Storage for unique_ptr's pointer and deleter.
00059  *
00060  * @tparam T The pointed-to type.
00061  * @tparam D The deleter type.
00062  */
00063 template<typename T,typename D,bool = ZORBA_TR1_NS::is_empty<D>::value>
00064 class unique_ptr_storage {
00065   typedef typename ZORBA_TR1_NS::add_reference<D>::type deleter_reference;
00066   typedef zorba::internal::rv<unique_ptr_storage> rvalue_type;
00067 public:
00068   T *ptr_;
00069 
00070   unique_ptr_storage( T *p ) throw() : ptr_( p ) {
00071   }
00072 
00073   unique_ptr_storage( T *p, deleter_reference d ) :
00074     ptr_( p ), deleter_( d )
00075   {
00076   }
00077 
00078   operator rvalue_type() throw() {
00079     return rvalue_type( *this );
00080   }
00081 
00082   deleter_reference deleter() throw() {
00083     return deleter_;
00084   }
00085 
00086 private:
00087   D deleter_;
00088   // forbid
00089   unique_ptr_storage( unique_ptr_storage const& );
00090   unique_ptr_storage& operator=( unique_ptr_storage const& );
00091 };
00092 
00093 /**
00094  * \internal
00095  * Specialization of %unique_ptr_storage when the \c D is empty.
00096  *
00097  * @tparam T The pointed-to type.
00098  * @tparam D The deleter type.
00099  */
00100 template<typename T,typename D>
00101 class unique_ptr_storage<T,D,true> : private D {
00102   typedef zorba::internal::rv<unique_ptr_storage> rvalue_type;
00103 public:
00104   T *ptr_;
00105 
00106   unique_ptr_storage( T *p ) throw() : ptr_( p ) {
00107   }
00108 
00109   unique_ptr_storage( T *p, D &d ) : D( d ), ptr_( p ) {
00110   }
00111 
00112   operator rvalue_type() throw() {
00113     return rvalue_type( *this );
00114   }
00115 
00116   D& deleter() throw() {
00117     return *this;
00118   }
00119 
00120 private:
00121   // forbid
00122   unique_ptr_storage( unique_ptr_storage const& );
00123   unique_ptr_storage& operator=( unique_ptr_storage const& );
00124 };
00125 
00126 ///////////////////////////////////////////////////////////////////////////////
00127 
00128 /**
00129  * \internal
00130  * Swaps two unique_ptr objects.
00131  *
00132  * @param a The first object to swap.
00133  * @param b The second object to swap.
00134  */
00135 template<typename T,typename D,bool IsEmpty> inline
00136 void swap( unique_ptr_storage<T,D,IsEmpty> &a,
00137            unique_ptr_storage<T,D,IsEmpty> &b ) {
00138   std::swap( a.ptr_, b.ptr_ );
00139   std::swap( a.deleter(), b.deleter() );
00140 }
00141 
00142 ///////////////////////////////////////////////////////////////////////////////
00143 
00144 /**
00145  * \internal
00146  * The default deleter class used by unique_ptr.  It simply calls \c delete on
00147  * the pointed-to object.
00148  */
00149 template<typename T>
00150 struct default_delete {
00151   default_delete() { }
00152 
00153   /**
00154    * Copy constructor.
00155    *
00156    * @tparam U The type of the deleter to copy-construct from such that \c U*
00157    * is convertible to \c T*.
00158    */
00159   template<typename U>
00160   default_delete( default_delete<U> const&,
00161     typename enable_if<ZORBA_TR1_NS::is_convertible<U*,T*>::value>::type* = 0 )
00162   {
00163   }
00164 
00165   /**
00166    * Deletes the pointed-to object using \c delete.
00167    *
00168    * @param p A pointer to the object to delete.
00169    */
00170   void operator()( T *p ) const {
00171     delete p;
00172   }
00173 };
00174 
00175 /**
00176  * \internal
00177  * Specialization of default_delete for arrays.  It simply calls \c delete[] on
00178  * the pointed-to array.
00179  */
00180 template<typename T>
00181 struct default_delete<T[]> {
00182   default_delete() { }
00183   void operator()( T *p ) const {
00184     delete[] p;
00185   }
00186 };
00187 
00188 ///////////////////////////////////////////////////////////////////////////////
00189 
00190 /**
00191  * \internal
00192  * Emulation of the C++11 std::unique_ptr.
00193  *
00194  * @tparam T The pointed-to type.
00195  * @tparam D The deleter to use, if any.  It must be either a function pointer
00196  * or a functor such that if \c d is of type \a D and \c p is of type \a T*,
00197  * then \c d(p) is valid and deletes the pointed-to object.  The deleter must
00198  * handle null pointers.  Note that \a D may be a reference type.
00199  */
00200 template<typename T,class D = default_delete<T> >
00201 class unique_ptr {
00202   typedef typename ZORBA_TR1_NS::add_reference<D>::type
00203           deleter_reference;
00204 
00205   typedef typename ZORBA_TR1_NS::add_reference<D const>::type
00206           deleter_const_reference;
00207 
00208   // see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2333.html
00209   struct pointer_conversion { int valid; };
00210   typedef int pointer_conversion::*explicit_bool;
00211 
00212 public:
00213   typedef T element_type;
00214   typedef T* pointer;
00215   typedef D deleter_type;
00216 
00217   /**
00218    * Default constructor.
00219    *
00220    * @param p A pointer to the object to point to, if any.
00221    */
00222   explicit unique_ptr( pointer p = 0 ) throw() : storage_( p ) {
00223   }
00224 
00225   /**
00226    * Constructs a %unique_ptr using a specific deleter.  This %unique_ptr now
00227    * has ownership of the pointed-to object.
00228    *
00229    * @param p A pointer to the object to own.
00230    * @param d The deleter to use.
00231    */
00232   unique_ptr( pointer p, deleter_reference d ) : storage_( p, d ) {
00233   }
00234 
00235   /**
00236    * Constructs a %unique_ptr from an existing %unique_ptr.  Note that:
00237    * \code
00238    *  unique_ptr<int> a( new int(1) );
00239    *  unique_ptr<int> b( a );           // compile-time error
00240    * \endcode
00241    * Instead, you must use the \c move() function:
00242    * \code
00243    *  unique_ptr<int> a( new int(1) );
00244    *  unique_ptr<int> b( move(a) );     // ok now
00245    * \endcode
00246    *
00247    * @param p The %unique_ptr to move from.
00248    */
00249   unique_ptr( zorba::internal::rv<unique_ptr> &p ) :
00250     storage_( p.release(), p.get_deleter() )
00251   {
00252   }
00253 
00254   /**
00255    * Constructs a %unique_ptr from an existing %unique_ptr 
00256    *
00257    * @tparam U The pointed-to type such that \c U* is convertible to \c T*.
00258    * @tparam E The deleter such that \c E is convertible to \c D.
00259    * @param p The %unique_ptr to move from.
00260    */
00261   template<typename U,typename E>
00262   unique_ptr( zorba::internal::rv<unique_ptr<U,E> > &p,
00263     typename enable_if<
00264       ZORBA_TR1_NS::is_convertible<typename unique_ptr<U>::pointer,
00265                                    pointer>::value &&
00266       ZORBA_TR1_NS::is_convertible<E,D>::value && (
00267         !ZORBA_TR1_NS::is_reference<D>::value ||
00268          ZORBA_TR1_NS::is_same<D,E>::value
00269       )
00270     >::type* = 0
00271   ) :
00272     storage_( p.release(), move<D>( p.get_deleter() ) )
00273   {
00274   }
00275 
00276   /**
00277    * Destroys the pointed-to object by calling the deleter (if the pointer is
00278    * not null).
00279    */
00280   ~unique_ptr() {
00281     call_deleter();
00282   }
00283 
00284   /**
00285    * Destructive assignment: moves ownership of the object pointed-to by \a p
00286    * to this %unique_ptr.  The object pointed-to by this %unique_ptr, if any,
00287    * is deleted.
00288    *
00289    * @param p The %unique_ptr to move from.
00290    * @return Returns \c *this.
00291    */
00292   unique_ptr& operator=( zorba::internal::rv<unique_ptr> &p ) {
00293     reset( p.release() );
00294     storage_.deleter() = move( p.get_deleter() );
00295     return *this;
00296   }
00297 
00298   /**
00299    * Destructive assignment: moves ownership of the object pointed-to by \a p
00300    * to this %unique_ptr.  The object pointed-to by this %unique_ptr, if any,
00301    * is deleted.
00302    *
00303    * @tparam U The pointed-to type such that \c U* is convertible to \c T*.
00304    * @tparam E The deleter of \a p.
00305    * @param p The %unique_ptr to move from.
00306    * @return Returns \c *this.
00307    */
00308   template<typename U,typename E>
00309   unique_ptr& operator=( zorba::internal::rv<unique_ptr<U,E> > &p ) {
00310     reset( p.release() );
00311     storage_.deleter() = move( p.get_deleter() );
00312     return *this;
00313   }
00314 
00315   /**
00316    * Assignment from null: equivalent to \c reset().
00317    *
00318    * @return Returns \c *this.
00319    */
00320   unique_ptr& operator=( int ) {
00321     reset();
00322     return *this;
00323   }
00324 
00325   /**
00326    * Dereferences the pointer.
00327    *
00328    * @return Returns a reference to the pointed-to object.
00329    */
00330   element_type& operator*() const throw() {
00331     return *get();
00332   }
00333 
00334   /**
00335    * Gets the pointer.
00336    *
00337    * @return Returns said pointer.
00338    */
00339   pointer operator->() const throw() {
00340     return get();
00341   }
00342 
00343   /**
00344    * Gets the pointer.
00345    *
00346    * @return Returns said pointer.
00347    */
00348   pointer get() const throw() {
00349     return storage_.ptr_;
00350   }
00351 
00352   /**
00353    * Gets the deleter in use.
00354    *
00355    * @return Returns said deleter.
00356    */
00357   deleter_reference get_deleter() throw() {
00358     return storage_.deleter();
00359   }
00360 
00361   /**
00362    * Gets the deleter in use.
00363    *
00364    * @return Returns said deleter.
00365    */
00366   deleter_const_reference get_deleter() const throw() {
00367     return storage_.deleter();
00368   }
00369 
00370   /**
00371    * Releases ownership of the pointed-to object.  Said object will now be the
00372    * responsibility of the caller.
00373    *
00374    * @return Returns a pointer to the object.
00375    */
00376   pointer release() throw() {
00377     pointer const temp = get();
00378     storage_.ptr_ = 0;
00379     return temp;
00380   }
00381 
00382   /**
00383    * Sets the pointer to the given value or null if none.  The previosly
00384    * pointed-to object, if any, is deleted.  However, if \a p equals the
00385    * current pointer value, then this function does nothing.
00386    *
00387    * @param p The new pointer value, if any.
00388    */
00389   void reset( pointer p = 0 ) throw() {
00390     if ( p != storage_.ptr_ ) {
00391       call_deleter();
00392       storage_.ptr_ = p;
00393     }
00394   }
00395 
00396   /**
00397    * Swaps the pointer and deleter with that of another %unique_ptr.
00398    *
00399    * @param p The %unique_ptr to swap with.
00400    */
00401   void swap( unique_ptr &p ) {
00402     std::swap( storage_, p.storage_ );
00403   }
00404 
00405   /**
00406    * Conversion to \c bool.
00407    *
00408    * @return Returns \c true only if the pointer is not null; \c false only if
00409    * the pointer is null.
00410    */
00411   operator explicit_bool() const throw() {
00412     return get() ? &pointer_conversion::valid : 0;
00413   }
00414 
00415 private:
00416   unique_ptr_storage<T,D> storage_;
00417 
00418   void call_deleter() {
00419     if ( storage_.ptr_ )
00420       get_deleter()( storage_.ptr_ );
00421   }
00422 
00423   // forbid
00424   unique_ptr( unique_ptr& );
00425   unique_ptr& operator=( unique_ptr& );
00426   template<typename U,typename E> unique_ptr( unique_ptr<U,E>& );
00427   template<typename U,typename E> unique_ptr& operator=( unique_ptr<U,E>& );
00428 
00429 public:
00430   operator ::zorba::internal::rv<unique_ptr>&() throw() {
00431     return *static_cast<zorba::internal::rv<unique_ptr>*>( this ); 
00432   }
00433 
00434   operator ::zorba::internal::rv<unique_ptr> const&() const throw() {
00435     return *static_cast<zorba::internal::rv<unique_ptr> const*>( this ); 
00436   }
00437 };
00438 
00439 ///////////////////////////////////////////////////////////////////////////////
00440 
00441 /**
00442  * \internal
00443  * Specialization of %unique_ptr for arrays.
00444  *
00445  * @tparam T The pointed-to array type.
00446  * @tparam D The deleter to use, if any.  It must be either a function pointer
00447  * or a functor such that if \c d is of type \a D and \c p is of type \a T*,
00448  * then \c d(p) is valid and deletes the pointed-to object.  The deleter must
00449  * handle null pointers.  Note that \a D may be a reference type.
00450  */
00451 template<typename T,typename D>
00452 class unique_ptr<T[],D> {
00453   typedef typename ZORBA_TR1_NS::add_reference<D>::type
00454           deleter_reference;
00455 
00456   typedef typename ZORBA_TR1_NS::add_reference<D const>::type
00457           deleter_const_reference;
00458 
00459   struct pointer_conversion { int valid; };
00460   typedef int pointer_conversion::*explicit_bool;
00461 
00462 public:
00463   typedef T element_type;
00464   typedef T* pointer;
00465   typedef D deleter_type;
00466 
00467   explicit unique_ptr( pointer p = 0 ) throw() : storage_( p ) {
00468   }
00469 
00470   unique_ptr( pointer p, deleter_reference d ) : storage_( p, d ) {
00471   }
00472 
00473   ~unique_ptr() {
00474     call_deleter();
00475   }
00476 
00477   unique_ptr& operator=( zorba::internal::rv<unique_ptr> &p ) {
00478     reset( p.release() );
00479     storage_.deleter() = move( p.get_deleter() );
00480     return *this;
00481   }
00482 
00483   pointer get() const throw() {
00484     return storage_.ptr_;
00485   }
00486 
00487   T& operator[]( size_t i ) const {
00488     return get()[i];
00489   }
00490 
00491   deleter_reference get_deleter() throw() {
00492     return storage_.deleter();
00493   }
00494 
00495   deleter_const_reference get_deleter() const throw() {
00496     return storage_.deleter();
00497   }
00498 
00499   pointer release() throw() {
00500     pointer const temp = get();
00501     storage_.ptr_ = 0;
00502     return temp;
00503   }
00504 
00505   void reset( pointer p = 0 ) throw() {
00506     if ( p != storage_.ptr_ ) {
00507       call_deleter();
00508       storage_.ptr_ = p;
00509     }
00510   }
00511 
00512   void swap( unique_ptr &p ) {
00513     std::swap( storage_, p.storage_ );
00514   }
00515 
00516   operator explicit_bool() const throw() {
00517     return get() ? &pointer_conversion::valid : 0;
00518   }
00519 
00520 private:
00521   unique_ptr_storage<T,D> storage_;
00522 
00523   void call_deleter() {
00524     if ( storage_.ptr_ )
00525       get_deleter()( storage_.ptr_ );
00526   }
00527 
00528   // forbid
00529   unique_ptr( unique_ptr& );
00530   unique_ptr& operator=( unique_ptr& );
00531   template<typename U,typename E> unique_ptr( unique_ptr<U,E>& );
00532   template<typename U,typename E> unique_ptr& operator=( unique_ptr<U,E>& );
00533 
00534 public:
00535   operator ::zorba::internal::rv<unique_ptr>&() throw() {
00536     return *static_cast<zorba::internal::rv<unique_ptr>*>( this ); 
00537   }
00538 
00539   operator ::zorba::internal::rv<unique_ptr> const&() const throw() {
00540     return *static_cast<zorba::internal::rv<unique_ptr> const*>( this ); 
00541   }
00542 };
00543 
00544 ///////////////////////////////////////////////////////////////////////////////
00545 
00546 #define ZORBA_UNIQUE_PTR_RELOP(OP) \
00547   template<typename T1,typename D1,typename T2,typename D2> inline             \
00548   bool operator OP( unique_ptr<T1,D1> const &a, unique_ptr<T2,D2> const &b ) { \
00549     return a.get() OP b.get();                                                 \
00550   }
00551 
00552 ZORBA_UNIQUE_PTR_RELOP(==)
00553 ZORBA_UNIQUE_PTR_RELOP(!=)
00554 ZORBA_UNIQUE_PTR_RELOP(< )
00555 ZORBA_UNIQUE_PTR_RELOP(<=)
00556 ZORBA_UNIQUE_PTR_RELOP(> )
00557 ZORBA_UNIQUE_PTR_RELOP(>=)
00558 
00559 #undef ZORBA_UNIQUE_PTR_RELOP
00560 
00561 ///////////////////////////////////////////////////////////////////////////////
00562 
00563 /**
00564  * \internal
00565  * Swaps the pointed-to object and deleter of one unique_ptr with that of
00566  * another.
00567  *
00568  * @param a The first unique_ptr.
00569  * @param b The second unique_ptr.
00570  */
00571 template<typename T,typename D> inline
00572 void swap( unique_ptr<T,D> &a, unique_ptr<T,D> &b ) {
00573   a.swap( b );
00574 }
00575 
00576 ///////////////////////////////////////////////////////////////////////////////
00577 
00578 } // namespace std
00579 
00580 #endif /* ZORBA_CXX_UNIQUE_PTR */
00581 #endif /* ZORBA_UNIQUE_PTR_H */
00582 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus