OpenShot Audio Library | OpenShotAudio  0.3.3
juce_HeapBlock.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 namespace juce
24 {
25 
26 #if ! (defined (DOXYGEN) || JUCE_EXCEPTIONS_DISABLED)
27 namespace HeapBlockHelper
28 {
29  template <bool shouldThrow>
30  struct ThrowOnFail { static void checkPointer (void*) {} };
31 
32  template<>
33  struct ThrowOnFail<true> { static void checkPointer (void* data) { if (data == nullptr) throw std::bad_alloc(); } };
34 }
35 #endif
36 
37 //==============================================================================
85 template <class ElementType, bool throwOnFailure = false>
86 class HeapBlock
87 {
88 private:
89  template <class OtherElementType>
90  using AllowConversion = typename std::enable_if<std::is_base_of<typename std::remove_pointer<ElementType>::type,
91  typename std::remove_pointer<OtherElementType>::type>::value>::type;
92 
93 public:
94  //==============================================================================
100  HeapBlock() = default;
101 
110  template <typename SizeType>
111  explicit HeapBlock (SizeType numElements)
112  : data (static_cast<ElementType*> (std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType))))
113  {
114  throwOnAllocationFailure();
115  }
116 
122  template <typename SizeType>
123  HeapBlock (SizeType numElements, bool initialiseToZero)
124  : data (static_cast<ElementType*> (initialiseToZero
125  ? std::calloc (static_cast<size_t> (numElements), sizeof (ElementType))
126  : std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType))))
127  {
128  throwOnAllocationFailure();
129  }
130 
135  {
136  std::free (data);
137  }
138 
140  HeapBlock (HeapBlock&& other) noexcept
141  : data (other.data)
142  {
143  other.data = nullptr;
144  }
145 
147  HeapBlock& operator= (HeapBlock&& other) noexcept
148  {
149  std::swap (data, other.data);
150  return *this;
151  }
152 
157  template <class OtherElementType, bool otherThrowOnFailure, typename = AllowConversion<OtherElementType>>
159  : data (reinterpret_cast<ElementType*> (other.data))
160  {
161  other.data = nullptr;
162  }
163 
168  template <class OtherElementType, bool otherThrowOnFailure, typename = AllowConversion<OtherElementType>>
170  {
171  free();
172  data = reinterpret_cast<ElementType*> (other.data);
173  other.data = nullptr;
174  return *this;
175  }
176 
177  //==============================================================================
182  inline operator ElementType*() const noexcept { return data; }
183 
188  inline ElementType* get() const noexcept { return data; }
189 
194  inline ElementType* getData() const noexcept { return data; }
195 
200  inline operator void*() const noexcept { return static_cast<void*> (data); }
201 
206  inline operator const void*() const noexcept { return static_cast<const void*> (data); }
207 
212  inline ElementType* operator->() const noexcept { return data; }
213 
218  template <typename IndexType>
219  ElementType& operator[] (IndexType index) const noexcept { return data [index]; }
220 
224  template <typename IndexType>
225  ElementType* operator+ (IndexType index) const noexcept { return data + index; }
226 
227  //==============================================================================
231  inline bool operator== (const ElementType* otherPointer) const noexcept { return otherPointer == data; }
232 
236  inline bool operator!= (const ElementType* otherPointer) const noexcept { return otherPointer != data; }
237 
238  //==============================================================================
251  template <typename SizeType>
252  void malloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType))
253  {
254  std::free (data);
255  data = static_cast<ElementType*> (std::malloc (static_cast<size_t> (newNumElements) * elementSize));
256  throwOnAllocationFailure();
257  }
258 
262  template <typename SizeType>
263  void calloc (SizeType newNumElements, const size_t elementSize = sizeof (ElementType))
264  {
265  std::free (data);
266  data = static_cast<ElementType*> (std::calloc (static_cast<size_t> (newNumElements), elementSize));
267  throwOnAllocationFailure();
268  }
269 
274  template <typename SizeType>
275  void allocate (SizeType newNumElements, bool initialiseToZero)
276  {
277  std::free (data);
278  data = static_cast<ElementType*> (initialiseToZero
279  ? std::calloc (static_cast<size_t> (newNumElements), sizeof (ElementType))
280  : std::malloc (static_cast<size_t> (newNumElements) * sizeof (ElementType)));
281  throwOnAllocationFailure();
282  }
283 
289  template <typename SizeType>
290  void realloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType))
291  {
292  data = static_cast<ElementType*> (data == nullptr ? std::malloc (static_cast<size_t> (newNumElements) * elementSize)
293  : std::realloc (data, static_cast<size_t> (newNumElements) * elementSize));
294  throwOnAllocationFailure();
295  }
296 
300  void free() noexcept
301  {
302  std::free (data);
303  data = nullptr;
304  }
305 
309  template <bool otherBlockThrows>
311  {
312  std::swap (data, other.data);
313  }
314 
319  template <typename SizeType>
320  void clear (SizeType numElements) noexcept
321  {
322  zeromem (data, sizeof (ElementType) * static_cast<size_t> (numElements));
323  }
324 
326  using Type = ElementType;
327 
328 private:
329  //==============================================================================
330  ElementType* data = nullptr;
331 
332  void throwOnAllocationFailure() const
333  {
334  #if JUCE_EXCEPTIONS_DISABLED
335  jassert (data != nullptr); // without exceptions, you'll need to find a better way to handle this failure case.
336  #else
337  HeapBlockHelper::ThrowOnFail<throwOnFailure>::checkPointer (data);
338  #endif
339  }
340 
341  template <class OtherElementType, bool otherThrowOnFailure>
342  friend class HeapBlock;
343 
344  #if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD))
345  JUCE_DECLARE_NON_COPYABLE (HeapBlock)
346  JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point!
347  #endif
348 };
349 
350 } // namespace juce
HeapBlock & operator=(HeapBlock &&other) noexcept
HeapBlock(HeapBlock< OtherElementType, otherThrowOnFailure > &&other) noexcept
ElementType * get() const noexcept
ElementType Type
void clear(SizeType numElements) noexcept
void swapWith(HeapBlock< ElementType, otherBlockThrows > &other) noexcept
bool operator!=(const ElementType *otherPointer) const noexcept
HeapBlock(SizeType numElements, bool initialiseToZero)
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
ElementType * getData() const noexcept
HeapBlock(HeapBlock &&other) noexcept
ElementType * operator+(IndexType index) const noexcept
HeapBlock()=default
void allocate(SizeType newNumElements, bool initialiseToZero)
HeapBlock(SizeType numElements)
bool operator==(const ElementType *otherPointer) const noexcept
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
ElementType * operator->() const noexcept
void free() noexcept
ElementType & operator[](IndexType index) const noexcept
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))