Newton Dynamics  4.00
ndSharedPtr.h
1 /* Copyright (c) <2003-2021> <Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely
10 */
11 
12 #ifndef _ND_SHARED_PTR_H_
13 #define _ND_SHARED_PTR_H_
14 
15 template <typename T>
17 {
18  public:
19  ndSharedPtr();
20  ndSharedPtr(T* const ptr);
21  ndSharedPtr(const ndSharedPtr<T>& sp);
22  ~ndSharedPtr();
23  ndSharedPtr<T>& operator = (const ndSharedPtr<T>& sp);
24 
25  void Swap(ndSharedPtr& src);
26 
27  T* operator->();
28 
29  T* operator* ();
30  const T* operator* () const;
31 
32  private:
33  class ndRefCounter : public ndAtomic<ndInt32>, public ndContainersFreeListAlloc<ndRefCounter>
34  {
35  public:
36  ndRefCounter();
37  void AddRef();
38  ndInt32 Release();
39  };
40 
41  T* m_ptr;
42  ndRefCounter* m_references;
43 };
44 
45 template <typename T>
47  :ndAtomic<ndInt32>(0)
48  ,ndContainersFreeListAlloc<ndRefCounter>()
49 {
50 }
51 
52 template <typename T>
54 {
55  fetch_add(1);
56 }
57 
58 template <typename T>
60 {
61  int ref = fetch_add(-1);
62  return ref - 1;
63 }
64 
65 template <typename T>
67  :m_ptr(nullptr)
68  ,m_references(new ndRefCounter)
69 {
70  m_references->AddRef();
71 }
72 
73 template <typename T>
74 ndSharedPtr<T>::ndSharedPtr(T* const ptr)
75  :m_ptr(ptr)
76  ,m_references(new ndRefCounter)
77 {
78  m_references->AddRef();
79 }
80 
81 template <typename T>
83  :m_ptr(sp.m_ptr)
84  ,m_references(sp.m_references)
85 {
86  m_references->AddRef();
87 }
88 
89 template <typename T>
91 {
92  int ref = m_references->Release();
93  if (ref == 0)
94  {
95  if (m_ptr)
96  {
97  delete m_ptr;
98  }
99  delete m_references;
100  }
101 }
102 
103 template <typename T>
105 {
106  if (this != &src)
107  {
108  if (m_references->Release() == 0)
109  {
110  if (m_ptr)
111  {
112  delete m_ptr;
113  }
114  delete m_references;
115  }
116 
117  m_ptr = src.m_ptr;
118  m_references = src.m_references;
119  m_references->AddRef();
120  }
121  return *this;
122 }
123 
124 template <typename T>
126 {
127  ndSwap(m_ptr, src.m_ptr);
128  ndSwap(m_references, src.m_references);
129 }
130 
131 template <typename T>
133 {
134  return m_ptr;
135 }
136 
137 template <typename T>
138 const T* ndSharedPtr<T>::operator* () const
139 {
140  return m_ptr;
141 }
142 
143 template <typename T>
145 {
146  return m_ptr;
147 }
148 
149 #endif
150 
ndSharedPtr
Definition: ndSharedPtr.h:17
ndContainersFreeListAlloc
Definition: ndContainersAlloc.h:60
ndAtomic
wrapper over standard atomic operations
Definition: ndTypes.h:381