unique_ptr.h
Go to the documentation of this file.
1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ZORBA_UNIQUE_PTR_H
18 #define ZORBA_UNIQUE_PTR_H
19 
20 #include <zorba/config.h>
21 
22 #ifdef ZORBA_HAVE_UNIQUE_PTR
23 # include <memory> /* for unique_ptr */
24 # include <utility> /* for forward, move */
25 #else
26 
27 #include <algorithm> /* for swap() */
28 #include "type_traits.h"
29 #include "ztd.h"
30 
31 namespace std {
32 
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 template<typename T> inline
36 typename enable_if<!zorba::internal::is_movable<T>::value,T&>::type
37 move( T &t ) {
38  return t;
39 }
40 
41 template<typename T> inline
42 typename enable_if<zorba::internal::is_movable<T>::value,
44 move( T const &t ) {
45  return *static_cast<zorba::internal::rv<T>*>( const_cast<T*>( &t ) );
46 }
47 
48 template<typename T> inline
49 typename enable_if<zorba::internal::is_movable<T>::value,
52  return t;
53 }
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 
57 /**
58  * \internal
59  * Storage for unique_ptr's pointer and deleter.
60  *
61  * @tparam T The pointed-to type.
62  * @tparam D The deleter type.
63  */
64 template<typename T,typename D,bool = ZORBA_TR1_NS::is_empty<D>::value>
66  typedef typename ZORBA_TR1_NS::add_reference<D>::type deleter_reference;
68 public:
69  T *ptr_;
70 
71  unique_ptr_storage( T *p ) throw() : ptr_( p ) {
72  }
73 
74  unique_ptr_storage( T *p, deleter_reference d ) :
75  ptr_( p ), deleter_( d )
76  {
77  }
78 
79  operator rvalue_type() throw() {
80  return rvalue_type( *this );
81  }
82 
83  deleter_reference deleter() throw() {
84  return deleter_;
85  }
86 
87 private:
88  D deleter_;
89  // forbid
91  unique_ptr_storage& operator=( unique_ptr_storage const& );
92 };
93 
94 /**
95  * \internal
96  * Specialization of %unique_ptr_storage when the \c D is empty.
97  *
98  * @tparam T The pointed-to type.
99  * @tparam D The deleter type.
100  */
101 template<typename T,typename D>
102 class unique_ptr_storage<T,D,true> : private D {
104 public:
105  T *ptr_;
106 
107  unique_ptr_storage( T *p ) throw() : ptr_( p ) {
108  }
109 
110  unique_ptr_storage( T *p, D &d ) : D( d ), ptr_( p ) {
111  }
112 
113  operator rvalue_type() throw() {
114  return rvalue_type( *this );
115  }
116 
117  D& deleter() throw() {
118  return *this;
119  }
120 
121 private:
122  // forbid
124  unique_ptr_storage& operator=( unique_ptr_storage const& );
125 };
126 
127 ///////////////////////////////////////////////////////////////////////////////
128 
129 /**
130  * \internal
131  * Swaps two unique_ptr objects.
132  *
133  * @param a The first object to swap.
134  * @param b The second object to swap.
135  */
136 template<typename T,typename D,bool IsEmpty> inline
139  std::swap( a.ptr_, b.ptr_ );
140  std::swap( a.deleter(), b.deleter() );
141 }
142 
143 ///////////////////////////////////////////////////////////////////////////////
144 
145 /**
146  * \internal
147  * The default deleter class used by unique_ptr. It simply calls \c delete on
148  * the pointed-to object.
149  */
150 template<typename T>
153 
154  /**
155  * Copy constructor.
156  *
157  * @tparam U The type of the deleter to copy-construct from such that \c U*
158  * is convertible to \c T*.
159  */
160  template<typename U>
162  typename enable_if<ZORBA_TR1_NS::is_convertible<U*,T*>::value>::type* = 0 )
163  {
164  }
165 
166  /**
167  * Deletes the pointed-to object using \c delete.
168  *
169  * @param p A pointer to the object to delete.
170  */
171  void operator()( T *p ) const {
172  delete p;
173  }
174 };
175 
176 /**
177  * \internal
178  * Specialization of default_delete for arrays. It simply calls \c delete[] on
179  * the pointed-to array.
180  */
181 template<typename T>
182 struct default_delete<T[]> {
184  void operator()( T *p ) const {
185  delete[] p;
186  }
187 };
188 
189 ///////////////////////////////////////////////////////////////////////////////
190 
191 /**
192  * \internal
193  * Emulation of the C++11 std::unique_ptr.
194  *
195  * @tparam T The pointed-to type.
196  * @tparam D The deleter to use, if any. It must be either a function pointer
197  * or a functor such that if \c d is of type \a D and \c p is of type \a T*,
198  * then \c d(p) is valid and deletes the pointed-to object. The deleter must
199  * handle null pointers. Note that \a D may be a reference type.
200  */
201 template<typename T,class D = default_delete<T> >
202 class unique_ptr {
203  typedef typename ZORBA_TR1_NS::add_reference<D>::type
204  deleter_reference;
205 
207  deleter_const_reference;
208 
210 
211 public:
212  typedef T element_type;
213  typedef T* pointer;
214  typedef D deleter_type;
215 
216  /**
217  * Default constructor.
218  *
219  * @param p A pointer to the object to point to, if any.
220  */
221  explicit unique_ptr( pointer p = 0 ) throw() : storage_( p ) {
222  }
223 
224  /**
225  * Constructs a %unique_ptr using a specific deleter. This %unique_ptr now
226  * has ownership of the pointed-to object.
227  *
228  * @param p A pointer to the object to own.
229  * @param d The deleter to use.
230  */
231  unique_ptr( pointer p, deleter_reference d ) : storage_( p, d ) {
232  }
233 
234  /**
235  * Constructs a %unique_ptr from an existing %unique_ptr. Note that:
236  * \code
237  * unique_ptr<int> a( new int(1) );
238  * unique_ptr<int> b( a ); // compile-time error
239  * \endcode
240  * Instead, you must use the \c move() function:
241  * \code
242  * unique_ptr<int> a( new int(1) );
243  * unique_ptr<int> b( move(a) ); // ok now
244  * \endcode
245  *
246  * @param p The %unique_ptr to move from.
247  */
249  storage_( p.release(), p.get_deleter() )
250  {
251  }
252 
253  /**
254  * Constructs a %unique_ptr from an existing %unique_ptr
255  *
256  * @tparam U The pointed-to type such that \c U* is convertible to \c T*.
257  * @tparam E The deleter such that \c E is convertible to \c D.
258  * @param p The %unique_ptr to move from.
259  */
260  template<typename U,typename E>
262  typename enable_if<
263  ZORBA_TR1_NS::is_convertible<typename unique_ptr<U>::pointer,
264  pointer>::value &&
265  ZORBA_TR1_NS::is_convertible<E,D>::value && (
266  !ZORBA_TR1_NS::is_reference<D>::value ||
267  ZORBA_TR1_NS::is_same<D,E>::value
268  )
269  >::type* = 0
270  ) :
271  storage_( p.release(), move<D>( p.get_deleter() ) )
272  {
273  }
274 
275  /**
276  * Destroys the pointed-to object by calling the deleter (if the pointer is
277  * not null).
278  */
280  call_deleter();
281  }
282 
283  /**
284  * Destructive assignment: moves ownership of the object pointed-to by \a p
285  * to this %unique_ptr. The object pointed-to by this %unique_ptr, if any,
286  * is deleted.
287  *
288  * @param p The %unique_ptr to move from.
289  * @return Returns \c *this.
290  */
292  reset( p.release() );
293  storage_.deleter() = move( p.get_deleter() );
294  return *this;
295  }
296 
297  /**
298  * Destructive assignment: moves ownership of the object pointed-to by \a p
299  * to this %unique_ptr. The object pointed-to by this %unique_ptr, if any,
300  * is deleted.
301  *
302  * @tparam U The pointed-to type such that \c U* is convertible to \c T*.
303  * @tparam E The deleter of \a p.
304  * @param p The %unique_ptr to move from.
305  * @return Returns \c *this.
306  */
307  template<typename U,typename E>
309  reset( p.release() );
310  storage_.deleter() = move( p.get_deleter() );
311  return *this;
312  }
313 
314  /**
315  * Assignment from null: equivalent to \c reset().
316  *
317  * @return Returns \c *this.
318  */
320  reset();
321  return *this;
322  }
323 
324  /**
325  * Dereferences the pointer.
326  *
327  * @return Returns a reference to the pointed-to object.
328  */
329  element_type& operator*() const throw() {
330  return *get();
331  }
332 
333  /**
334  * Gets the pointer.
335  *
336  * @return Returns said pointer.
337  */
338  pointer operator->() const throw() {
339  return get();
340  }
341 
342  /**
343  * Gets the pointer.
344  *
345  * @return Returns said pointer.
346  */
347  pointer get() const throw() {
348  return storage_.ptr_;
349  }
350 
351  /**
352  * Gets the deleter in use.
353  *
354  * @return Returns said deleter.
355  */
356  deleter_reference get_deleter() throw() {
357  return storage_.deleter();
358  }
359 
360  /**
361  * Gets the deleter in use.
362  *
363  * @return Returns said deleter.
364  */
365  deleter_const_reference get_deleter() const throw() {
366  return storage_.deleter();
367  }
368 
369  /**
370  * Releases ownership of the pointed-to object. Said object will now be the
371  * responsibility of the caller.
372  *
373  * @return Returns a pointer to the object.
374  */
375  pointer release() throw() {
376  pointer const temp = get();
377  storage_.ptr_ = 0;
378  return temp;
379  }
380 
381  /**
382  * Sets the pointer to the given value or null if none. The previosly
383  * pointed-to object, if any, is deleted. However, if \a p equals the
384  * current pointer value, then this function does nothing.
385  *
386  * @param p The new pointer value, if any.
387  */
388  void reset( pointer p = 0 ) throw() {
389  if ( p != storage_.ptr_ ) {
390  call_deleter();
391  storage_.ptr_ = p;
392  }
393  }
394 
395  /**
396  * Swaps the pointer and deleter with that of another %unique_ptr.
397  *
398  * @param p The %unique_ptr to swap with.
399  */
400  void swap( unique_ptr &p ) {
401  std::swap( storage_, p.storage_ );
402  }
403 
404  /**
405  * Conversion to \c bool.
406  *
407  * @return Returns \c true only if the pointer is not null; \c false only if
408  * the pointer is null.
409  */
410  operator explicit_bool::type() const throw() {
411  return explicit_bool::value_of( get() );
412  }
413 
414 private:
415  unique_ptr_storage<T,D> storage_;
416 
417  void call_deleter() {
418  if ( storage_.ptr_ )
419  get_deleter()( storage_.ptr_ );
420  }
421 
422  // forbid
423  unique_ptr( unique_ptr& );
424  unique_ptr& operator=( unique_ptr& );
425  template<typename U,typename E> unique_ptr( unique_ptr<U,E>& );
426  template<typename U,typename E> unique_ptr& operator=( unique_ptr<U,E>& );
427 
428 public:
429  operator ::zorba::internal::rv<unique_ptr>&() throw() {
430  return *static_cast<zorba::internal::rv<unique_ptr>*>( this );
431  }
432 
433  operator ::zorba::internal::rv<unique_ptr> const&() const throw() {
434  return *static_cast<zorba::internal::rv<unique_ptr> const*>( this );
435  }
436 };
437 
438 ///////////////////////////////////////////////////////////////////////////////
439 
440 /**
441  * \internal
442  * Specialization of %unique_ptr for arrays.
443  *
444  * @tparam T The pointed-to array type.
445  * @tparam D The deleter to use, if any. It must be either a function pointer
446  * or a functor such that if \c d is of type \a D and \c p is of type \a T*,
447  * then \c d(p) is valid and deletes the pointed-to object. The deleter must
448  * handle null pointers. Note that \a D may be a reference type.
449  */
450 template<typename T,typename D>
451 class unique_ptr<T[],D> {
452  typedef typename ZORBA_TR1_NS::add_reference<D>::type
453  deleter_reference;
454 
456  deleter_const_reference;
457 
459 
460 public:
461  typedef T element_type;
462  typedef T* pointer;
463  typedef D deleter_type;
464 
465  explicit unique_ptr( pointer p = 0 ) throw() : storage_( p ) {
466  }
467 
468  unique_ptr( pointer p, deleter_reference d ) : storage_( p, d ) {
469  }
470 
472  call_deleter();
473  }
474 
476  reset( p.release() );
477  storage_.deleter() = move( p.get_deleter() );
478  return *this;
479  }
480 
481  pointer get() const throw() {
482  return storage_.ptr_;
483  }
484 
485  T& operator[]( size_t i ) const {
486  return get()[i];
487  }
488 
489  deleter_reference get_deleter() throw() {
490  return storage_.deleter();
491  }
492 
493  deleter_const_reference get_deleter() const throw() {
494  return storage_.deleter();
495  }
496 
497  pointer release() throw() {
498  pointer const temp = get();
499  storage_.ptr_ = 0;
500  return temp;
501  }
502 
503  void reset( pointer p = 0 ) throw() {
504  if ( p != storage_.ptr_ ) {
505  call_deleter();
506  storage_.ptr_ = p;
507  }
508  }
509 
510  void swap( unique_ptr &p ) {
511  std::swap( storage_, p.storage_ );
512  }
513 
514  operator explicit_bool::type() const throw() {
515  return explicit_bool::value_of( get() );
516  }
517 
518 private:
519  unique_ptr_storage<T,D> storage_;
520 
521  void call_deleter() {
522  if ( storage_.ptr_ )
523  get_deleter()( storage_.ptr_ );
524  }
525 
526  // forbid
527  unique_ptr( unique_ptr& );
528  unique_ptr& operator=( unique_ptr& );
529  template<typename U,typename E> unique_ptr( unique_ptr<U,E>& );
530  template<typename U,typename E> unique_ptr& operator=( unique_ptr<U,E>& );
531 
532 public:
533  operator ::zorba::internal::rv<unique_ptr>&() throw() {
534  return *static_cast<zorba::internal::rv<unique_ptr>*>( this );
535  }
536 
537  operator ::zorba::internal::rv<unique_ptr> const&() const throw() {
538  return *static_cast<zorba::internal::rv<unique_ptr> const*>( this );
539  }
540 };
541 
542 ///////////////////////////////////////////////////////////////////////////////
543 
544 #define ZORBA_UNIQUE_PTR_RELOP(OP) \
545  template<typename T1,typename D1,typename T2,typename D2> inline \
546  bool operator OP( unique_ptr<T1,D1> const &a, unique_ptr<T2,D2> const &b ) { \
547  return a.get() OP b.get(); \
548  }
549 
556 
557 #undef ZORBA_UNIQUE_PTR_RELOP
558 
559 ///////////////////////////////////////////////////////////////////////////////
560 
561 /**
562  * \internal
563  * Swaps the pointed-to object and deleter of one unique_ptr with that of
564  * another.
565  *
566  * @param a The first unique_ptr.
567  * @param b The second unique_ptr.
568  */
569 template<typename T,typename D> inline
571  a.swap( b );
572 }
573 
574 ///////////////////////////////////////////////////////////////////////////////
575 
576 } // namespace std
577 
578 #endif /* ZORBA_HAVE_UNIQUE_PTR */
579 #endif /* ZORBA_UNIQUE_PTR_H */
580 /* vim:set et sw=2 ts=2: */