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