OpenShot Audio Library | OpenShotAudio  0.3.1
juce_ScopedPointer.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 #ifndef DOXYGEN
24 
25 namespace juce
26 {
27 
28 //==============================================================================
32 template <class ObjectType>
34 {
35 public:
36  //==============================================================================
37  // ScopedPointer is deprecated! You should use std::unique_ptr instead.
38  JUCE_DEPRECATED_ATTRIBUTE inline ScopedPointer() = default;
39 
40  // ScopedPointer is deprecated! You should use std::unique_ptr instead.
41  JUCE_DEPRECATED_ATTRIBUTE inline ScopedPointer (decltype (nullptr)) noexcept {}
42 
43  // ScopedPointer is deprecated! You should use std::unique_ptr instead.
44  JUCE_DEPRECATED_ATTRIBUTE inline ScopedPointer (ObjectType* objectToTakePossessionOf) noexcept
45  : object (objectToTakePossessionOf)
46  {
47  }
48 
49  // ScopedPointer is deprecated! You should use std::unique_ptr instead.
50  ScopedPointer (ScopedPointer& objectToTransferFrom) noexcept
51  : object (objectToTransferFrom.release())
52  {
53  }
54 
55  // ScopedPointer is deprecated! You should use std::unique_ptr instead.
56  JUCE_DEPRECATED_ATTRIBUTE inline ~ScopedPointer() { reset(); }
57 
58  ScopedPointer& operator= (ScopedPointer& objectToTransferFrom)
59  {
60  if (this != objectToTransferFrom.getAddress())
61  {
62  // Two ScopedPointers should never be able to refer to the same object - if
63  // this happens, you must have done something dodgy!
64  jassert (object == nullptr || object != objectToTransferFrom.object);
65  reset (objectToTransferFrom.release());
66  }
67 
68  return *this;
69  }
70 
71  ScopedPointer& operator= (ObjectType* newObjectToTakePossessionOf)
72  {
73  reset (newObjectToTakePossessionOf);
74  return *this;
75  }
76 
77  ScopedPointer (ScopedPointer&& other) noexcept : object (other.object)
78  {
79  other.object = nullptr;
80  }
81 
82  ScopedPointer& operator= (ScopedPointer&& other) noexcept
83  {
84  reset (other.release());
85  return *this;
86  }
87 
88  //==============================================================================
89  inline operator ObjectType*() const noexcept { return object; }
90  inline ObjectType* get() const noexcept { return object; }
91  inline ObjectType& operator*() const noexcept { return *object; }
92  inline ObjectType* operator->() const noexcept { return object; }
93 
94  void reset()
95  {
96  auto* oldObject = object;
97  object = {};
99  }
100 
101  void reset (ObjectType* newObject)
102  {
103  if (object != newObject)
104  {
105  auto* oldObject = object;
106  object = newObject;
108  }
109  else
110  {
111  // You're trying to reset this ScopedPointer to itself! This will work here as ScopedPointer does an equality check
112  // but be aware that std::unique_ptr won't do this and you could end up with some nasty, subtle bugs!
113  jassert (newObject == nullptr);
114  }
115  }
116 
117  void reset (ScopedPointer& newObject)
118  {
119  reset (newObject.release());
120  }
121 
122  ObjectType* release() noexcept { auto* o = object; object = {}; return o; }
123 
124  //==============================================================================
125  void swapWith (ScopedPointer<ObjectType>& other) noexcept
126  {
127  // Two ScopedPointers should never be able to refer to the same object - if
128  // this happens, you must have done something dodgy!
129  jassert (object != other.object || this == other.getAddress() || object == nullptr);
130 
131  std::swap (object, other.object);
132  }
133 
134  inline ObjectType* createCopy() const { return createCopyIfNotNull (object); }
135 
136 private:
137  //==============================================================================
138  ObjectType* object = nullptr;
139 
140  const ScopedPointer* getAddress() const noexcept { return this; } // Used internally to avoid the & operator
141 
142  #if ! JUCE_MSVC // (MSVC can't deal with multiple copy constructors)
143  ScopedPointer (const ScopedPointer&) = delete;
144  ScopedPointer& operator= (const ScopedPointer&) = delete;
145  #endif
146 };
147 
148 //==============================================================================
149 template <typename ObjectType1, typename ObjectType2>
150 bool operator== (ObjectType1* pointer1, const ScopedPointer<ObjectType2>& pointer2) noexcept
151 {
152  return pointer1 == pointer2.get();
153 }
154 
155 template <typename ObjectType1, typename ObjectType2>
156 bool operator!= (ObjectType1* pointer1, const ScopedPointer<ObjectType2>& pointer2) noexcept
157 {
158  return pointer1 != pointer2.get();
159 }
160 
161 template <typename ObjectType1, typename ObjectType2>
162 bool operator== (const ScopedPointer<ObjectType1>& pointer1, ObjectType2* pointer2) noexcept
163 {
164  return pointer1.get() == pointer2;
165 }
166 
167 template <typename ObjectType1, typename ObjectType2>
168 bool operator!= (const ScopedPointer<ObjectType1>& pointer1, ObjectType2* pointer2) noexcept
169 {
170  return pointer1.get() != pointer2;
171 }
172 
173 template <typename ObjectType1, typename ObjectType2>
174 bool operator== (const ScopedPointer<ObjectType1>& pointer1, const ScopedPointer<ObjectType2>& pointer2) noexcept
175 {
176  return pointer1.get() == pointer2.get();
177 }
178 
179 template <typename ObjectType1, typename ObjectType2>
180 bool operator!= (const ScopedPointer<ObjectType1>& pointer1, const ScopedPointer<ObjectType2>& pointer2) noexcept
181 {
182  return pointer1.get() != pointer2.get();
183 }
184 
185 template <class ObjectType>
186 bool operator== (decltype (nullptr), const ScopedPointer<ObjectType>& pointer) noexcept
187 {
188  return pointer.get() == nullptr;
189 }
190 
191 template <class ObjectType>
192 bool operator!= (decltype (nullptr), const ScopedPointer<ObjectType>& pointer) noexcept
193 {
194  return pointer.get() != nullptr;
195 }
196 
197 template <class ObjectType>
198 bool operator== (const ScopedPointer<ObjectType>& pointer, decltype (nullptr)) noexcept
199 {
200  return pointer.get() == nullptr;
201 }
202 
203 template <class ObjectType>
204 bool operator!= (const ScopedPointer<ObjectType>& pointer, decltype (nullptr)) noexcept
205 {
206  return pointer.get() != nullptr;
207 }
208 
209 //==============================================================================
210 // NB: This is just here to prevent any silly attempts to call deleteAndZero() on a ScopedPointer.
211 template <typename Type>
212 void deleteAndZero (ScopedPointer<Type>&) { static_assert (sizeof (Type) == 12345,
213  "Attempt to call deleteAndZero() on a ScopedPointer"); }
214 
215 } // namespace juce
216 
217 #endif