CopiedPtr.hpp
Go to the documentation of this file.
1 //
3 // Aurora C++ Library
4 // Copyright (c) 2012-2016 Jan Haller
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not be
20 // misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
25 
28 
29 #ifndef AURORA_COPIEDPTR_HPP
30 #define AURORA_COPIEDPTR_HPP
31 
33 #include <Aurora/SmartPtr/Detail/PtrOwner.hpp>
35 #include <Aurora/Tools/Swap.hpp>
36 #include <Aurora/Config.hpp>
37 
38 #include <algorithm>
39 #include <type_traits>
40 #include <utility>
41 
42 
43 namespace aurora
44 {
45 
48 
60 template <typename T>
61 class CopiedPtr
62 {
63  // ---------------------------------------------------------------------------------------------------------------------------
64  // Public member functions
65  public:
69  : mOwner(nullptr)
70  , mPointer(nullptr)
71  {
72  }
73 
76  CopiedPtr(std::nullptr_t)
77  : mOwner(nullptr)
78  , mPointer(nullptr)
79  {
80  }
81 
84  template <typename U>
85  explicit CopiedPtr(U* pointer)
86  : mOwner( detail::newPtrOwner<T>(pointer, OperatorNewCopy<U>(), OperatorDelete<U>()) )
87  , mPointer(pointer)
88  {
89  }
90 
96  template <typename U, typename C>
97  CopiedPtr(U* pointer, C cloner)
98  : mOwner( detail::newPtrOwner<T>(pointer, cloner, OperatorDelete<U>()) )
99  , mPointer(pointer)
100  {
101  }
102 
108  template <typename U, typename C, typename D>
109  CopiedPtr(U* pointer, C cloner, D deleter)
110  : mOwner( detail::newPtrOwner<T>(pointer, cloner, deleter) )
111  , mPointer(pointer)
112  {
113  }
114 
119  CopiedPtr(const CopiedPtr& origin)
120  : mOwner(origin ? origin.mOwner->clone() : nullptr)
121  , mPointer(origin ? mOwner->getPointer() : nullptr)
122  {
123  }
124 
129  template <typename U>
130  CopiedPtr(const CopiedPtr<U>& origin)
131  : mOwner(origin ? new detail::PtrIndirection<T, U>(origin.mOwner, detail::CopyTag()) : nullptr)
132  , mPointer(origin ? mOwner->getPointer() : nullptr)
133  {
134  }
135 
139  : mOwner(source.mOwner)
140  , mPointer(source.mPointer)
141  {
142  source.mOwner = nullptr;
143  source.mPointer = nullptr;
144  }
145 
150  template <typename U>
152  : mOwner(source ? new detail::PtrIndirection<T, U>(source.mOwner, detail::MoveTag()) : nullptr)
153  , mPointer(source.mPointer)
154  {
155  source.mOwner = nullptr;
156  source.mPointer = nullptr;
157  }
158 
159 #ifdef AURORA_HAS_VARIADIC_TEMPLATES
160 
161  // [Implementation detail]
162  // Emplacement constructor: Used to implement makeCopied<T>(args)
163  template <typename... Args>
164  CopiedPtr(detail::EmplaceTag, Args&&... args)
165  : mOwner(new detail::CompactOwner<T>(detail::EmplaceTag(), std::forward<Args>(args)...))
166  , mPointer(mOwner->getPointer())
167  {
168  }
169 
170 #endif // AURORA_HAS_VARIADIC_TEMPLATES
171 
176  {
177  CopiedPtr(origin).swap(*this);
178  return *this;
179  }
180 
184  template <typename U>
186  {
187  CopiedPtr(origin).swap(*this);
188  return *this;
189  }
190 
194  {
195  CopiedPtr(std::move(source)).swap(*this);
196  return *this;
197  }
198 
203  template <typename U>
205  {
206  CopiedPtr(std::move(source)).swap(*this);
207  return *this;
208  }
209 
213  {
214  // Destroy owner, whose destructor also deletes the pointer
215  delete mOwner;
216  }
217 
220  void swap(CopiedPtr& other)
221  {
222  adlSwap(mOwner, other.mOwner);
223  adlSwap(mPointer, other.mPointer);
224  }
225 
228  AURORA_FAKE_DOC(typename std::add_lvalue_reference<T>::type, T&) operator* () const
229  {
230  assert(mPointer);
231  return *mPointer;
232  }
233 
236  T* operator-> () const
237  {
238  assert(mPointer);
239  return mPointer;
240  }
241 
245  operator SafeBool() const
246  {
247  return toSafeBool(mPointer != nullptr);
248  }
249 
252  T* get() const
253  {
254  return mPointer;
255  }
256 
259  void reset()
260  {
261  CopiedPtr().swap(*this);
262  }
263 
267  template <typename U>
268  void reset(U* pointer)
269  {
270  CopiedPtr(pointer).swap(*this);
271  }
272 
279  template <typename U, typename C>
280  void reset(U* pointer, C cloner)
281  {
282  CopiedPtr(pointer, cloner).swap(*this);
283  }
284 
291  template <typename U, typename C, typename D>
292  void reset(U* pointer, C cloner, D deleter)
293  {
294  CopiedPtr(pointer, cloner, deleter).swap(*this);
295  }
296 
297 
298  // ---------------------------------------------------------------------------------------------------------------------------
299  // Private variables
300  private:
301  detail::PtrOwnerBase<T>* mOwner;
302  T* mPointer;
303 
304  template <typename T2>
305  friend class CopiedPtr;
306 };
307 
308 
311 template <typename T>
313 {
314  return lhs.swap(rhs);
315 }
316 
317 
318 // For documentation and modern compilers
319 #ifdef AURORA_HAS_VARIADIC_TEMPLATES
320 
335 template <typename T, typename... Args>
336 CopiedPtr<T> makeCopied(Args&&... args)
337 {
338  return CopiedPtr<T>(detail::EmplaceTag(), std::forward<Args>(args)...);
339 }
340 
341 // Unoptimized fallback for compilers that don't support variadic templates, emulated by preprocessor metaprogramming
342 #else // AURORA_HAS_VARIADIC_TEMPLATES
343 
344 #include <Aurora/SmartPtr/Detail/Factories.hpp>
345 
346 // Define metafunction to generate overloads for aurora::CopiedPtr
347 #define AURORA_DETAIL_COPIEDPTR_FACTORY(n) AURORA_DETAIL_SMARTPTR_FACTORY(CopiedPtr, makeCopied, n)
348 
349 // Generate code
350 AURORA_PP_ENUMERATE(AURORA_PP_LIMIT, AURORA_DETAIL_COPIEDPTR_FACTORY)
351 
352 #endif // AURORA_HAS_VARIADIC_TEMPLATES
353 
355 
356 } // namespace aurora
357 
358 #endif // AURORA_COPIEDPTR_HPP
CopiedPtr(std::nullptr_t)
Construct from nullptr.
Definition: CopiedPtr.hpp:76
CopiedPtr(U *pointer, C cloner, D deleter)
Construct from raw pointer with cloner and deleter.
Definition: CopiedPtr.hpp:109
#define AURORA_PP_ENUMERATE(n, macro)
Apply a macro repeated times.
Definition: Preprocessor.hpp:155
void reset()
Reset to null pointer.
Definition: CopiedPtr.hpp:259
#define AURORA_PP_LIMIT
Limit for preprocessor metaprogramming arguments.
Definition: Preprocessor.hpp:58
void(detail::SafeBoolHolder::* SafeBool)()
SafeBool type.
Definition: SafeBool.hpp:55
CopiedPtr()
Default constructor.
Definition: CopiedPtr.hpp:68
void swap(CopiedPtr &other)
Exchanges the values of *this and other.
Definition: CopiedPtr.hpp:220
CopiedPtr(CopiedPtr< U > &&source)
Move from different CopiedPtr.
Definition: CopiedPtr.hpp:151
Configuration header of the library.
Cloner and deleter functors for smart pointers.
CopiedPtr(U *pointer)
Construct from raw pointer.
Definition: CopiedPtr.hpp:85
~CopiedPtr()
Destructor.
Definition: CopiedPtr.hpp:212
CopiedPtr< T > makeCopied(Args &&...args)
Emplaces an object directly inside the copied pointer.
Definition: CopiedPtr.hpp:336
void swap(CopiedPtr< T > &lhs, CopiedPtr< T > &rhs)
Swaps the contents of two CopiedPtr instances.
Definition: CopiedPtr.hpp:312
CopiedPtr(const CopiedPtr &origin)
Copy constructor.
Definition: CopiedPtr.hpp:119
CopiedPtr & operator=(const CopiedPtr &origin)
Copy assignment operator.
Definition: CopiedPtr.hpp:175
void reset(U *pointer, C cloner)
Reset to raw pointer with cloner.
Definition: CopiedPtr.hpp:280
Type aurora::SafeBool and corresponding functionality.
CopiedPtr(U *pointer, C cloner)
Construct from raw pointer with cloner.
Definition: CopiedPtr.hpp:97
void reset(U *pointer, C cloner, D deleter)
Reset to raw pointer with cloner and deleter.
Definition: CopiedPtr.hpp:292
Helpers to declare and invoke swap() functions.
Cloner that invokes the copy constructor and new operator.
Definition: ClonersAndDeleters.hpp:45
Deleter that invokes the delete operator.
Definition: ClonersAndDeleters.hpp:70
SafeBool toSafeBool(bool condition)
Conversion function from bool to SafeBool.
Definition: SafeBool.hpp:67
Copyable smart pointer template.
Definition: CopiedPtr.hpp:61
void reset(U *pointer)
Reset to raw pointer.
Definition: CopiedPtr.hpp:268
CopiedPtr(CopiedPtr &&source)
Move constructor.
Definition: CopiedPtr.hpp:138
void adlSwap(T &lhs, T &rhs)
swap() function with argument-dependent lookup
Definition: Swap.hpp:49
T * operator->() const
Dereferences the pointer for member access.
Definition: CopiedPtr.hpp:236
Definition: DispatchTraits.hpp:39
CopiedPtr(const CopiedPtr< U > &origin)
Construct from different CopiedPtr.
Definition: CopiedPtr.hpp:130