Atlas 0.7.0
Networking protocol for the Worldforge system.
SmartPtr.h
1// This file may be redistributed and modified only under the terms of
2// the GNU Lesser General Public License (See COPYING for details).
3// Copyright (C) 2000 Aloril
4// Copyright (C) 2000-2005 Al Riddoch
5
6// $Id$
7
8#ifndef ATLAS_OBJECTS_SMARTPTR_H
9#define ATLAS_OBJECTS_SMARTPTR_H
10
11#include <Atlas/Exception.h>
12#include <cassert>
13
14namespace Atlas { namespace Objects {
15
16template <class T>
18{
19 public:
20 template<class U> friend
21 class SmartPtr;
22
23 typedef T DataT;
24
25 SmartPtr() noexcept : ptr(T::allocator.alloc()) {
26 }
27 SmartPtr(const SmartPtr<T>& a) noexcept : ptr(a.get()) {
28 incRef();
29 }
30 SmartPtr(SmartPtr<T>&& a) noexcept : ptr(a.get()) {
31 a.ptr = nullptr;
32 }
33 SmartPtr(T *a_ptr) noexcept : ptr(a_ptr)
34 {
35 incRef();
36 }
37 template<class oldType>
38 explicit SmartPtr(const SmartPtr<oldType>& a) noexcept : ptr(a.get()) {
39 incRef();
40 }
41 template<class oldType>
42 explicit SmartPtr(SmartPtr<oldType>&& a) noexcept : ptr(a.get()) {
43 a.ptr = nullptr;
44 }
45 ~SmartPtr() {
46 decRef();
47 }
48 SmartPtr& operator=(const SmartPtr<T>& a) noexcept {
49 if (a.get() != this->get()) {
50 decRef();
51 ptr = a.get();
52 incRef();
53 }
54 return *this;
55 }
56
57 SmartPtr& operator=(SmartPtr<T>&& a) noexcept {
58 if (a.get() != this->get()) {
59 //Do a dec-ref on the existing ptr (if any)
60 decRef();
61 //But don't do any increase on the new one, just move it over.
62 // The reference number on it will stay the same, which is what we want.
63 ptr = a.get();
64 a.ptr = nullptr;
65 }
66 return *this;
67 }
68
69 template<class newType>
70 operator SmartPtr<newType>() const noexcept {
71 return SmartPtr<newType>(ptr);
72 }
73 template<class newType>
74 operator SmartPtr<const newType>() const noexcept {
75 return SmartPtr<const newType>(ptr);
76 }
77 constexpr bool isValid() const noexcept {
78 return ptr != nullptr;
79 }
80 constexpr bool operator!() const noexcept {
81 return this->ptr == nullptr;
82 }
83
84 explicit constexpr operator bool () const noexcept
85 {
86 return !this->operator!();
87 }
88
89 constexpr T& operator*() const noexcept {
90 assert(ptr);
91 return *ptr;
92 }
93 constexpr T* operator->() const noexcept {
94 assert(ptr);
95 return ptr;
96 }
97 constexpr T* get() const noexcept {
98 return ptr;
99 }
100 SmartPtr<T> copy() const noexcept
101 {
102 return SmartPtr(ptr->copy());
103 }
104 // If you want to make these protected, please ensure that the
105 // destructor is made virtual to ensure your new class behaves
106 // correctly.
107 private:
108 void decRef() const noexcept {
109 if (ptr != nullptr) {
110 ptr->decRef();
111 }
112 }
113 void incRef() const noexcept {
114 if (ptr != nullptr) {
115 ptr->incRef();
116 }
117 }
118 T * ptr;
119};
120
121template<typename returnPtrType, class fromType>
122returnPtrType smart_dynamic_cast(const SmartPtr<fromType> & o)
123{
124 return returnPtrType(dynamic_cast<typename returnPtrType::DataT*>(o.get()));
125}
126
127template<typename returnPtrType, class fromType>
128returnPtrType smart_static_cast(const SmartPtr<fromType> & o)
129{
130 return returnPtrType((typename returnPtrType::DataT *)o.get());
131}
132
133} } // namespace Atlas::Objects
134
135#endif // ATLAS_OBJECTS_SMARTPTR_H
Definition: Bridge.h:20