Evo C++ Library v0.5.1
ptr.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_ptr_h
9 #define INCL_evo_ptr_h
10 
11 #include "type.h"
12 
13 namespace evo {
16 
18 
92 template<class T>
93 class SmartPtr : public PtrBase<T> {
94 protected:
95  using PtrBase<T>::ptr_;
96 
97 public:
98  typedef SmartPtr<T> This;
99  typedef T Item;
100 
104  SmartPtr(T* ptr=NULL) {
105  ptr_ = ptr;
106  }
107 
114  SmartPtr(const This& src) {
115  ptr_ = new T(*src.ptr_);
116  }
117 
120  free();
121  }
122 
130  This& operator=(const This& src) {
131  free();
132  ptr_ = new T(*src.ptr_);
133  return *this;
134  }
135 
140  This& operator=(T* ptr) {
141  free();
142  ptr_ = ptr;
143  return *this;
144  }
145 
146 #if defined(EVO_CPP11)
147 
150  SmartPtr(This&& src) {
151  ptr_ = src.ptr_;
152  src.ptr_ = NULL;
153  }
154 
159  This& operator=(This&& src) {
160  free();
161  ptr_ = src.ptr_;
162  src.ptr_ = NULL;
163  return *this;
164  }
165 #endif
166 
170  This& clear() {
171  free();
172  ptr_ = NULL;
173  return *this;
174  }
175 
179  This& set() {
180  free();
181  ptr_ = NULL;
182  return *this;
183  }
184 
190  T* detach() {
191  T* result = ptr_;
192  ptr_ = NULL;
193  return result;
194  }
195 
196 protected:
197  void free() {
198  if (ptr_ != NULL)
199  delete ptr_;
200  }
201 };
202 
240 template<class T>
241 class SmartPtr<T[]> : public PtrBase<T> {
242 protected:
243  using PtrBase<T>::ptr_;
244 
245 public:
247  typedef T Item;
248 
252  SmartPtr(T* ptr=NULL) {
253  ptr_ = ptr;
254  }
255 
258  free();
259  }
260 
265  This& operator=(T* ptr) {
266  free();
267  ptr_ = ptr;
268  return *this;
269  }
270 
271 #if defined(EVO_CPP11)
272 
275  SmartPtr(This&& src) {
276  ptr_ = src.ptr_;
277  src.ptr_ = NULL;
278  }
279 
284  This& operator=(This&& src) {
285  free();
286  ptr_ = src.ptr_;
287  src.ptr_ = NULL;
288  return *this;
289  }
290 #endif
291 
295  This& clear() {
296  free();
297  ptr_ = NULL;
298  return *this;
299  }
300 
304  This& set() {
305  free();
306  ptr_ = NULL;
307  return *this;
308  }
309 
315  T* detach() {
316  T* result = ptr_;
317  ptr_ = NULL;
318  return result;
319  }
320 
321 protected:
322  void free() {
323  if (ptr_ != NULL)
324  delete [] ptr_;
325  }
326 
327 private:
328  // Disable copying
329  explicit SmartPtr(const This&) EVO_ONCPP11(= delete);
330  This& operator=(const This&) EVO_ONCPP11(= delete);
331 };
332 
334 
398 template<class T,class TSize=SizeT>
399 class SharedPtr : public PtrBase<T> {
400 protected:
401  using PtrBase<T>::ptr_;
402 
403 public:
405  typedef T Item;
406 
409  { ptr_ = NULL; refs_ = NULL; }
410 
417  if (ptr != NULL)
418  { ptr_ = ptr; refs_ = new TSize; *refs_ = 1; }
419  else
420  { ptr_ = NULL; refs_ = NULL; }
421  }
422 
428  SharedPtr(const This& src) {
429  if (src.ptr_ != NULL)
430  { ptr_ = src.ptr_; refs_ = src.refs_; ++(*refs_); }
431  else
432  { ptr_ = NULL; refs_ = NULL; }
433  }
434 
437  { free(); }
438 
446  This& operator=(const This& src) {
447  free();
448  if (src.ptr_ != NULL)
449  { ptr_ = src.ptr_; refs_ = src.refs_; ++(*refs_); }
450  else
451  { ptr_ = NULL; refs_ = NULL; }
452  return *this;
453  }
454 
462  This& operator=(T* ptr) {
463  clear();
464  if (ptr != NULL) {
465  ptr_ = ptr;
466  if (refs_ == NULL)
467  refs_ = new TSize;
468  *refs_ = 1;
469  }
470  return *this;
471  }
472 
473 #if defined(EVO_CPP11)
474 
477  SharedPtr(This&& src) {
478  ptr_ = src.ptr_;
479  refs_ = src.refs_;
480  src.ptr_ = NULL;
481  src.refs_ = NULL;
482  }
483 
488  This& operator=(This&& src) {
489  free();
490  ptr_ = src.ptr_;
491  refs_ = src.refs_;
492  src.ptr_ = NULL;
493  src.refs_ = NULL;
494  return *this;
495  }
496 #endif
497 
503  This& clear() {
504  if (ptr_ != NULL) {
505  if (--(*refs_) == 0)
506  delete ptr_; // leave refs_ allocated for later
507  else
508  refs_ = NULL; // detach from shared
509  ptr_ = NULL;
510  }
511  return *this;
512  }
513 
517  This& set()
518  { return clear(); }
519 
525  This& unshare() {
526  if (ptr_ != NULL && *refs_ > 1) {
527  ptr_ = new T(*ptr_);
528  --(*refs_);
529  refs_ = new TSize;
530  *refs_ = 1;
531  }
532  return *this;
533  }
534 
538  bool shared() const
539  { return (ptr_ != NULL && *refs_ > 1); }
540 
541 protected:
542  TSize* refs_;
543 
544  void free() {
545  if (ptr_ != NULL) {
546  if (--(*refs_) == 0)
547  { delete ptr_; delete refs_; }
548  } else if (refs_ != NULL)
549  delete refs_;
550  }
551 };
552 
609 template<class T,class TSize>
610 class SharedPtr<T[],TSize> : public PtrBase<T> {
611 protected:
612  using PtrBase<T>::ptr_;
613 
614 public:
616  typedef T Item;
617 
620  { ptr_ = NULL; refs_ = NULL; }
621 
628  if (ptr != NULL)
629  { ptr_ = ptr; refs_ = new TSize; *refs_ = 1; }
630  else
631  { ptr_ = NULL; refs_ = NULL; }
632  }
633 
639  SharedPtr(const This& src) {
640  if (src.ptr_ != NULL)
641  { ptr_ = src.ptr_; refs_ = src.refs_; ++(*refs_); }
642  else
643  { ptr_ = NULL; refs_ = NULL; }
644  }
645 
648  { free(); }
649 
657  This& operator=(const This& src) {
658  free();
659  if (src.ptr_ != NULL)
660  { ptr_ = src.ptr_; refs_ = src.refs_; ++(*refs_); }
661  else
662  { ptr_ = NULL; refs_ = NULL; }
663  return *this;
664  }
665 
673  This& operator=(T* ptr) {
674  clear();
675  if (ptr != NULL) {
676  ptr_ = ptr;
677  if (refs_ == NULL)
678  refs_ = new TSize;
679  *refs_ = 1;
680  }
681  return *this;
682  }
683 
684 #if defined(EVO_CPP11)
685 
688  SharedPtr(This&& src) {
689  ptr_ = src.ptr_;
690  refs_ = src.refs_;
691  src.ptr_ = NULL;
692  src.refs_ = NULL;
693  }
694 
699  This& operator=(This&& src) {
700  free();
701  ptr_ = src.ptr_;
702  refs_ = src.refs_;
703  src.ptr_ = NULL;
704  src.refs_ = NULL;
705  return *this;
706  }
707 #endif
708 
714  This& clear() {
715  if (ptr_ != NULL) {
716  if (--(*refs_) == 0) {
717  delete [] ptr_; // leave refs_ allocated for later
718  ptr_ = NULL;
719  } else
720  refs_ = NULL; // detach from shared
721  }
722  return *this;
723  }
724 
728  This& set()
729  { return clear(); }
730 
734  bool shared() const
735  { return (ptr_ != NULL && *refs_ > 1); }
736 
737 protected:
738  TSize* refs_;
739 
740  void free() {
741  if (ptr_ != NULL) {
742  if (--(*refs_) == 0)
743  { delete [] ptr_; delete refs_; }
744  } else if (refs_ != NULL)
745  delete refs_;
746  }
747 
748 private:
749  // Disabled if array
750  This& unshare();
751 };
752 
754 
796 template<class T>
797 class Ptr : public PtrBase<T> {
798 protected:
799  using PtrBase<T>::ptr_;
800 
801 public:
802  typedef Ptr<T> This;
803  typedef PtrBase<T> Base;
804  typedef T Item;
805 
807  Ptr()
808  { ptr_ = NULL; }
809 
813  Ptr(T* ptr)
814  { ptr_ = ptr; }
815 
819  Ptr(const T* ptr)
820  { ptr_ = (T*)ptr; }
821 
825  Ptr(const This& src)
826  { ptr_ = src.ptr_; }
827 
831  Ptr(const Base& src)
832  { ptr_ = src.ptr_; }
833 
838  This& operator=(const This& src) {
839  ptr_ = src.ptr_;
840  return *this;
841  }
842 
847  This& operator=(const Base& src) {
848  ptr_ = src.ptr_;
849  return *this;
850  }
851 
856  This& operator=(T* ptr) {
857  ptr_ = ptr;
858  return *this;
859  }
860 
865  This& operator=(const T* ptr) {
866  ptr_ = (T*)ptr;
867  return *this;
868  }
869 
870 #if defined(EVO_CPP11)
871 
874  Ptr(This&& src) {
875  ptr_ = src.ptr_;
876  src.ptr_ = NULL;
877  }
878 
883  This& operator=(This&& src) {
884  ptr_ = src.ptr_;
885  src.ptr_ = NULL;
886  return *this;
887  }
888 #endif
889 
893  This& clear() {
894  ptr_ = NULL;
895  return *this;
896  }
897 
901  This& set() {
902  ptr_ = NULL;
903  return *this;
904  }
905 
911  T* detach() {
912  T* result = ptr_;
913  ptr_ = NULL;
914  return result;
915  }
916 };
917 
961 template<class T>
962 class Ptr<T[]> : public PtrBase<T> {
963 protected:
964  using PtrBase<T>::ptr_;
965 
966 public:
967  typedef Ptr<T[]> This;
968  typedef PtrBase<T> Base;
969  typedef T Item;
970 
971 
973  Ptr()
974  { ptr_ = NULL; }
975 
979  Ptr(T* ptr)
980  { ptr_ = ptr; }
981 
985  Ptr(const T* ptr)
986  { ptr_ = (T*)ptr; }
987 
991  Ptr(const This& src)
992  { ptr_ = src.ptr_; }
993 
997  Ptr(const Base& src)
998  { ptr_ = src.ptr_; }
999 
1004  This& operator=(const This& src)
1005  { ptr_ = src.ptr_; return *this; }
1006 
1011  This& operator=(const Base& src)
1012  { ptr_ = src.ptr_; return *this; }
1013 
1018  This& operator=(T* ptr)
1019  { ptr_ = ptr; return *this; }
1020 
1025  This& operator=(const T* ptr)
1026  { ptr_ = (T*)ptr; return *this; }
1027 
1028 #if defined(EVO_CPP11)
1029 
1032  Ptr(This&& src) {
1033  ptr_ = src.ptr_;
1034  src.ptr_ = NULL;
1035  }
1036 
1041  This& operator=(This&& src) {
1042  ptr_ = src.ptr_;
1043  src.ptr_ = NULL;
1044  return *this;
1045  }
1046 #endif
1047 
1051  This& clear()
1052  { ptr_ = NULL; return *this; }
1053 
1057  This& set()
1058  { ptr_ = NULL; return *this; }
1059 
1065  T* detach() {
1066  T* result = ptr_;
1067  ptr_ = NULL;
1068  return result;
1069  }
1070 };
1071 
1073 
1093 template<class T> struct IsSmartPtr : public StaticBoolF { };
1095 template<class T> struct IsSmartPtr<SmartPtr<T> > : public StaticBoolT { };
1096 template<class T> struct IsSmartPtr<SmartPtr<T[]> > : public StaticBoolT { };
1097 template<class T> struct IsSmartPtr<SharedPtr<T> > : public StaticBoolT { };
1098 template<class T> struct IsSmartPtr<SharedPtr<T[]> > : public StaticBoolT { };
1101 
1103 }
1104 #endif
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:699
SmartPtr(const This &src)
Copy constructor.
Definition: ptr.h:114
Check if type is a SmartPtr or SharedPtr.
Definition: ptr.h:1093
This & clear()
Clear (free) pointer and set as null.
Definition: ptr.h:295
Ptr(const T *ptr)
Constructor.
Definition: ptr.h:985
T Item
Item type dereferenced to.
Definition: ptr.h:99
This & operator=(const Base &src)
Assignment operator to reference pointer.
Definition: ptr.h:847
This & operator=(T *ptr)
Assignment operator for new pointer.
Definition: ptr.h:265
Ptr< T[]> This
This pointer type.
Definition: ptr.h:967
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:883
Ptr(T *ptr)
Constructor.
Definition: ptr.h:979
Static bool value.
Definition: meta.h:111
T * detach()
Detach and return pointer.
Definition: ptr.h:911
This & operator=(T *ptr)
Assignment operator for new pointer.
Definition: ptr.h:140
TSize * refs_
Definition: ptr.h:542
SharedPtr(const This &src)
Copy constructor.
Definition: ptr.h:428
This & operator=(const T *ptr)
Assignment operator for raw pointer.
Definition: ptr.h:1025
SharedPtr(T *ptr)
Constructor.
Definition: ptr.h:416
This & operator=(const This &src)
Copy/Assignment operator.
Definition: ptr.h:657
SmartPtr< T[]> This
Definition: ptr.h:246
T Item
Definition: ptr.h:616
SmartPtr(T *ptr=NULL)
Constructor.
Definition: ptr.h:104
TSize * refs_
Definition: ptr.h:738
Ptr(T *ptr)
Constructor.
Definition: ptr.h:813
This & operator=(T *ptr)
Assignment operator for new pointer.
Definition: ptr.h:462
PtrBase< T > Base
Base type.
Definition: ptr.h:803
T * detach()
Detach and return pointer.
Definition: ptr.h:1065
#define EVO_ONCPP11(EXPR)
Compile EXPR only if C++11 support is detected, otherwise this is a no-op.
Definition: sys.h:259
Shared smart pointer to array.
Definition: ptr.h:610
SharedPtr(T *ptr)
Constructor.
Definition: ptr.h:627
const T * ptr() const
Get current pointer (const).
Definition: type.h:1735
Ptr(This &&src)
Move constructor (C++11).
Definition: ptr.h:874
This & clear()
Clear pointer, setting as null.
Definition: ptr.h:893
This & operator=(T *ptr)
Assignment operator for new pointer.
Definition: ptr.h:673
Smart pointer to array.
Definition: ptr.h:241
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:284
T Item
Definition: ptr.h:247
void free()
Definition: ptr.h:544
This & clear()
Clear (free) pointer and set as null.
Definition: ptr.h:170
This & clear()
Release pointer and set as null.
Definition: ptr.h:714
SharedPtr()
Constructor to start with null pointer.
Definition: ptr.h:619
Ptr()
Default constructor sets as NULL.
Definition: ptr.h:807
SmartPtr(T *ptr=NULL)
Constructor.
Definition: ptr.h:252
Ptr(const Base &src)
Copy constructor to reference pointer.
Definition: ptr.h:997
T * detach()
Detach and return pointer.
Definition: ptr.h:190
SharedPtr(This &&src)
Move constructor (C++11).
Definition: ptr.h:477
~SharedPtr()
Destructor.
Definition: ptr.h:647
T Item
Item type dereferenced to.
Definition: ptr.h:804
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:1041
T Item
Item type dereferenced to.
Definition: ptr.h:969
Ptr< T > This
This pointer type.
Definition: ptr.h:802
SmartPtr(This &&src)
Move constructor (C++11).
Definition: ptr.h:275
bool shared() const
Get whether pointer is shared (reference count > 1).
Definition: ptr.h:538
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:159
~SharedPtr()
Destructor.
Definition: ptr.h:436
void free()
Definition: ptr.h:740
This & operator=(This &&src)
Move assignment operator (C++11).
Definition: ptr.h:488
~SmartPtr()
Destructor.
Definition: ptr.h:119
This & operator=(const This &src)
Copy/Assignment operator.
Definition: ptr.h:446
This & operator=(const This &src)
Copy/Assignment operator.
Definition: ptr.h:130
This & operator=(const This &src)
Copy/Assignment operator.
Definition: ptr.h:838
SharedPtr(This &&src)
Move constructor (C++11).
Definition: ptr.h:688
This & clear()
Release pointer and set as null.
Definition: ptr.h:503
Dumb pointer to array.
Definition: ptr.h:962
SmartPtr(This &&src)
Move constructor (C++11).
Definition: ptr.h:150
T Item
Item type dereferenced to.
Definition: ptr.h:405
SharedPtr< T, TSize > This
This pointer type.
Definition: ptr.h:404
This & operator=(const This &src)
Copy/Assignment operator.
Definition: ptr.h:1004
bool shared() const
Get whether pointer is shared (reference count > 1).
Definition: ptr.h:734
Evo C++ Library namespace.
Definition: alg.h:11
Ptr(const This &src)
Copy constructor.
Definition: ptr.h:825
Ptr()
Default constructor sets as NULL.
Definition: ptr.h:973
This & clear()
Clear pointer, setting as null.
Definition: ptr.h:1051
Ptr(const This &src)
Copy constructor.
Definition: ptr.h:991
SharedPtr(const This &src)
Copy constructor.
Definition: ptr.h:639
This & unshare()
Unshare pointer by setting as a new copy, if shared.
Definition: ptr.h:525
Ptr(const T *ptr)
Constructor.
Definition: ptr.h:819
This & operator=(T *ptr)
Assignment operator for raw pointer.
Definition: ptr.h:856
SharedPtr()
Constructor to start with null pointer.
Definition: ptr.h:408
T * ptr_
Pointer.
Definition: type.h:1566
Smart pointer to single object.
Definition: ptr.h:93
Shared smart pointer to single object.
Definition: ptr.h:399
PtrBase< T > Base
Base type.
Definition: ptr.h:968
void free()
Definition: ptr.h:322
SmartPtr< T > This
This pointer type.
Definition: ptr.h:98
SharedPtr< T[], TSize > This
Definition: ptr.h:615
This & operator=(T *ptr)
Assignment operator for raw pointer.
Definition: ptr.h:1018
void free()
Definition: ptr.h:197
Base managed pointer.
Definition: type.h:1562
~SmartPtr()
Destructor.
Definition: ptr.h:257
T * detach()
Detach and return pointer.
Definition: ptr.h:315
Ptr(const Base &src)
Copy constructor to reference pointer.
Definition: ptr.h:831
This & operator=(const T *ptr)
Assignment operator for raw pointer.
Definition: ptr.h:865
Evo basic types and traits.
This & operator=(const Base &src)
Assignment operator to reference pointer.
Definition: ptr.h:1011
Ptr(This &&src)
Move constructor (C++11).
Definition: ptr.h:1032
Dumb pointer to single object.
Definition: ptr.h:797