Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
12KB

  1. //------------------------------------------------------------------------
  2. // Project : SDK Base
  3. // Version : 1.0
  4. //
  5. // Category : Helpers
  6. // Filename : base/source/fcleanup.h
  7. // Created by : Steinberg, 2008
  8. // Description : Template classes for automatic resource cleanup
  9. //
  10. //-----------------------------------------------------------------------------
  11. // LICENSE
  12. // (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
  13. //-----------------------------------------------------------------------------
  14. // Redistribution and use in source and binary forms, with or without modification,
  15. // are permitted provided that the following conditions are met:
  16. //
  17. // * Redistributions of source code must retain the above copyright notice,
  18. // this list of conditions and the following disclaimer.
  19. // * Redistributions in binary form must reproduce the above copyright notice,
  20. // this list of conditions and the following disclaimer in the documentation
  21. // and/or other materials provided with the distribution.
  22. // * Neither the name of the Steinberg Media Technologies nor the names of its
  23. // contributors may be used to endorse or promote products derived from this
  24. // software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  29. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  30. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  31. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  33. // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  34. // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  35. // OF THE POSSIBILITY OF SUCH DAMAGE.
  36. //-----------------------------------------------------------------------------
  37. #pragma once
  38. #include <stdlib.h>
  39. namespace Steinberg {
  40. /** Template definition for classes that help guarding against memory leaks.
  41. A stack allocated object of this type automatically deletes an at construction time passed
  42. dynamically allocated single object when it reaches the end of its scope. \n\n
  43. Intended usage:
  44. \code
  45. {
  46. int* pointerToInt = new int;
  47. Steinberg::FDeleter<int> deleter (pointerToInt);
  48. // Do something with the variable behind pointerToInt.
  49. } // No memory leak here, destructor of deleter cleans up the integer.
  50. \endcode
  51. */
  52. //------------------------------------------------------------------------
  53. template <class T>
  54. struct FDeleter
  55. {
  56. /// Constructor. _toDelete is a pointer to the dynamically allocated object that is to be
  57. /// deleted when this FDeleter object's destructor is executed.
  58. FDeleter (T* _toDelete) : toDelete (_toDelete) {}
  59. /// Destructor. Calls delete on the at construction time passed pointer.
  60. ~FDeleter ()
  61. {
  62. if (toDelete)
  63. delete toDelete;
  64. }
  65. T* toDelete; ///< Remembers the object that is to be deleted during destruction.
  66. };
  67. /** Template definition for classes that help guarding against memory leaks.
  68. A stack allocated object of this type automatically deletes an at construction time passed
  69. dynamically allocated array of objects when it reaches the end of its scope. \n\n
  70. Intended usage:
  71. \code
  72. {
  73. int* pointerToIntArray = new int[10];
  74. Steinberg::FArrayDeleter<int> deleter (pointerToIntArray);
  75. // Do something with the array behind pointerToIntArray.
  76. } // No memory leak here, destructor of deleter cleans up the integer array.
  77. \endcode
  78. */
  79. //------------------------------------------------------------------------
  80. template <class T>
  81. struct FArrayDeleter
  82. {
  83. /// Constructor. _arrayToDelete is a pointer to the dynamically allocated array of objects that
  84. /// is to be deleted when this FArrayDeleter object's destructor is executed.
  85. FArrayDeleter (T* _arrayToDelete) : arrayToDelete (_arrayToDelete) {}
  86. /// Destructor. Calls delete[] on the at construction time passed pointer.
  87. ~FArrayDeleter ()
  88. {
  89. if (arrayToDelete)
  90. delete[] arrayToDelete;
  91. }
  92. T* arrayToDelete; ///< Remembers the array of objects that is to be deleted during destruction.
  93. };
  94. /** Template definition for classes that help guarding against dangling pointers.
  95. A stack allocated object of this type automatically resets an at construction time passed
  96. pointer to null when it reaches the end of its scope. \n\n
  97. Intended usage:
  98. \code
  99. int* pointerToInt = 0;
  100. {
  101. int i = 1;
  102. pointerToInt = &i;
  103. Steinberg::FPtrNuller<int> ptrNuller (pointerToInt);
  104. // Do something with pointerToInt.
  105. } // No dangling pointer here, pointerToInt is reset to 0 by destructor of ptrNuller.
  106. \endcode
  107. */
  108. //------------------------------------------------------------------------
  109. template <class T>
  110. struct FPtrNuller
  111. {
  112. /// Constructor. _toNull is a reference to the pointer that is to be reset to NULL when this
  113. /// FPtrNuller object's destructor is executed.
  114. FPtrNuller (T*& _toNull) : toNull (_toNull) {}
  115. /// Destructor. Calls delete[] on the at construction time passed pointer.
  116. ~FPtrNuller () { toNull = 0; }
  117. T*& toNull; ///< Remembers the pointer that is to be set to NULL during destruction.
  118. };
  119. /** Template definition for classes that help resetting an object's value.
  120. A stack allocated object of this type automatically resets the value of an at construction time
  121. passed object to null when it reaches the end of its scope. \n\n Intended usage: \code int theObject
  122. = 0;
  123. {
  124. Steinberg::FNuller<int> theNuller (theObject);
  125. theObject = 1;
  126. } // Here the destructor of theNuller resets the value of theObject to 0.
  127. \endcode
  128. */
  129. //------------------------------------------------------------------------
  130. template <class T>
  131. struct FNuller
  132. {
  133. /// Constructor. _toNull is a reference to the object that is to be assigned 0 when this FNuller
  134. /// object's destructor is executed.
  135. FNuller (T& _toNull) : toNull (_toNull) {}
  136. /// Destructor. Assigns 0 to the at construction time passed object reference.
  137. ~FNuller () { toNull = 0; }
  138. T& toNull; ///< Remembers the object that is to be assigned 0 during destruction.
  139. };
  140. /** Class definition for objects that help resetting boolean variables.
  141. A stack allocated object of this type automatically sets an at construction time passed
  142. boolean variable immediately to TRUE and resets the same variable to FALSE when it
  143. reaches the end of its own scope. \n\n
  144. Intended usage:
  145. \code
  146. bool theBoolean = false;
  147. {
  148. Steinberg::FBoolSetter theBoolSetter (theBoolean);
  149. // Here the constructor of theBoolSetter sets theBoolean to TRUE.
  150. // Do something.
  151. } // Here the destructor of theBoolSetter resets theBoolean to FALSE.
  152. \endcode
  153. */
  154. //------------------------------------------------------------------------
  155. template <class T>
  156. struct FBooleanSetter
  157. {
  158. /// Constructor. _toSet is a reference to the boolean that is set to TRUE immediately in this
  159. /// constructor call and gets reset to FALSE when this FBoolSetter object's destructor is
  160. /// executed.
  161. FBooleanSetter (T& _toSet) : toSet (_toSet) { toSet = true; }
  162. /// Destructor. Resets the at construction time passed boolean to FALSE.
  163. ~FBooleanSetter () { toSet = false; }
  164. T& toSet; ///< Remembers the boolean that is to be reset during destruction.
  165. };
  166. typedef FBooleanSetter<bool> FBoolSetter;
  167. /** Class definition for objects that help setting boolean variables.
  168. A stack allocated object of this type automatically sets an at construction time passed
  169. boolean variable to TRUE if the given condition is met. At the end of its own scope the
  170. stack object will reset the same boolean variable to FALSE, if it wasn't set so already. \n\n
  171. Intended usage:
  172. \code
  173. bool theBoolean = false;
  174. {
  175. bool creativityFirst = true;
  176. Steinberg::FConditionalBoolSetter theCBSetter (theBoolean, creativityFirst);
  177. // Here the constructor of theCBSetter sets theBoolean to the value of creativityFirst.
  178. // Do something.
  179. } // Here the destructor of theCBSetter resets theBoolean to FALSE.
  180. \endcode
  181. */
  182. //------------------------------------------------------------------------
  183. struct FConditionalBoolSetter
  184. {
  185. /// Constructor. _toSet is a reference to the boolean that is to be set. If the in the second
  186. /// parameter given condition is TRUE then also _toSet is set to TRUE immediately.
  187. FConditionalBoolSetter (bool& _toSet, bool condition) : toSet (_toSet)
  188. {
  189. if (condition)
  190. toSet = true;
  191. }
  192. /// Destructor. Resets the at construction time passed boolean to FALSE.
  193. ~FConditionalBoolSetter () { toSet = false; }
  194. bool& toSet; ///< Remembers the boolean that is to be reset during destruction.
  195. };
  196. /** Template definition for classes that help closing resources.
  197. A stack allocated object of this type automatically calls the close method of an at
  198. construction time passed object when it reaches the end of its scope.
  199. It goes without saying that the given type needs to have a close method. \n\n
  200. Intended usage:
  201. \code
  202. struct CloseableObject
  203. {
  204. void close() {};
  205. };
  206. {
  207. CloseableObject theObject;
  208. Steinberg::FCloser<CloseableObject> theCloser (&theObject);
  209. // Do something.
  210. } // Here the destructor of theCloser calls the close method of theObject.
  211. \endcode
  212. */
  213. template <class T>
  214. struct FCloser
  215. {
  216. /// Constructor. _obj is the pointer on which close is to be called when this FCloser object's
  217. /// destructor is executed.
  218. FCloser (T* _obj) : obj (_obj) {}
  219. /// Destructor. Calls the close function on the at construction time passed pointer.
  220. ~FCloser ()
  221. {
  222. if (obj)
  223. obj->close ();
  224. }
  225. T* obj; ///< Remembers the pointer on which close is to be called during destruction.
  226. };
  227. /** Class definition for objects that help guarding against memory leaks.
  228. A stack allocated object of this type automatically frees the "malloced" memory behind an at
  229. construction time passed pointer when it reaches the end of its scope.
  230. */
  231. //------------------------------------------------------------------------
  232. /*! \class FMallocReleaser
  233. */
  234. //------------------------------------------------------------------------
  235. class FMallocReleaser
  236. {
  237. public:
  238. /// Constructor. _data is the pointer to the memory on which free is to be called when this
  239. /// FMallocReleaser object's destructor is executed.
  240. FMallocReleaser (void* _data) : data (_data) {}
  241. /// Destructor. Calls the free function on the at construction time passed pointer.
  242. ~FMallocReleaser ()
  243. {
  244. if (data)
  245. free (data);
  246. }
  247. //------------------------------------------------------------------------
  248. protected:
  249. void* data; ///< Remembers the pointer on which free is to be called during destruction.
  250. };
  251. //------------------------------------------------------------------------
  252. } // namespace Steinberg
  253. #if MAC
  254. typedef const void* CFTypeRef;
  255. extern "C" {
  256. extern void CFRelease (CFTypeRef cf);
  257. }
  258. namespace Steinberg {
  259. /** Class definition for objects that helps releasing CoreFoundation objects.
  260. A stack allocated object of this type automatically releases an at construction time
  261. passed CoreFoundation object when it reaches the end of its scope.
  262. Only available on Macintosh platform.
  263. */
  264. //------------------------------------------------------------------------
  265. /*! \class CFReleaser
  266. */
  267. //------------------------------------------------------------------------
  268. class CFReleaser
  269. {
  270. public:
  271. /// Constructor. _obj is the reference to an CoreFoundation object which is to be released when this CFReleaser object's destructor is executed.
  272. CFReleaser (CFTypeRef _obj) : obj (_obj) {}
  273. /// Destructor. Releases the at construction time passed object.
  274. ~CFReleaser () { if (obj) CFRelease (obj); }
  275. protected:
  276. CFTypeRef obj; ///< Remembers the object which is to be released during destruction.
  277. };
  278. //------------------------------------------------------------------------
  279. } // namespace Steinberg
  280. #endif // MAC