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.

274 lines
6.1KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_CPP_COMPAT_HPP_INCLUDED
  18. #define CARLA_CPP_COMPAT_HPP_INCLUDED
  19. #include "CarlaDefines.h"
  20. #ifdef CARLA_PROPER_CPP11_SUPPORT
  21. # include <memory>
  22. #else
  23. # include <algorithm>
  24. # include "CarlaUtils.hpp"
  25. #endif
  26. // -----------------------------------------------------------------------
  27. #ifndef CARLA_PROPER_CPP11_SUPPORT
  28. namespace std {
  29. /* This code is part of shared_ptr.hpp:
  30. * minimal implementation of smart pointer, a subset of the C++11 std::shared_ptr or boost::shared_ptr.
  31. * Copyright (c) 2013-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
  32. * Distributed under the MIT License (MIT)
  33. */
  34. class shared_ptr_count
  35. {
  36. public:
  37. shared_ptr_count() : pn(nullptr) {}
  38. shared_ptr_count(const shared_ptr_count& count) : pn(count.pn) {}
  39. void swap(shared_ptr_count& lhs) noexcept { std::swap(pn, lhs.pn); }
  40. long use_count(void) const noexcept
  41. {
  42. long count = 0;
  43. if (nullptr != pn)
  44. {
  45. count = *pn;
  46. }
  47. return count;
  48. }
  49. template<class U>
  50. void acquire(U* p)
  51. {
  52. if (nullptr != p)
  53. {
  54. if (nullptr == pn)
  55. {
  56. try
  57. {
  58. pn = new volatile long(1);
  59. }
  60. catch (std::bad_alloc&)
  61. {
  62. delete p;
  63. throw;
  64. }
  65. }
  66. else
  67. {
  68. ++(*pn);
  69. }
  70. }
  71. }
  72. template<class U>
  73. void release(U* p) noexcept
  74. {
  75. if (nullptr != pn)
  76. {
  77. --(*pn);
  78. if (0 == *pn)
  79. {
  80. delete p;
  81. delete pn;
  82. }
  83. pn = nullptr;
  84. }
  85. }
  86. public:
  87. volatile long* pn;
  88. };
  89. template<class T>
  90. class shared_ptr
  91. {
  92. public:
  93. typedef T element_type;
  94. shared_ptr(void) noexcept
  95. : px(nullptr),
  96. pn() {}
  97. /*explicit*/ shared_ptr(T* p)
  98. : px(nullptr),
  99. pn()
  100. {
  101. acquire(p);
  102. }
  103. template <class U>
  104. shared_ptr(const shared_ptr<U>& ptr, T* p) :
  105. px(nullptr),
  106. pn(ptr.pn)
  107. {
  108. acquire(p);
  109. }
  110. template <class U>
  111. shared_ptr(const shared_ptr<U>& ptr) noexcept :
  112. px(nullptr),
  113. pn(ptr.pn)
  114. {
  115. CARLA_SAFE_ASSERT_RETURN(nullptr == ptr.px || 0 != ptr.pn.use_count(),);
  116. acquire(static_cast<typename shared_ptr<T>::element_type*>(ptr.px));
  117. }
  118. shared_ptr(const shared_ptr& ptr) noexcept :
  119. px(nullptr),
  120. pn(ptr.pn)
  121. {
  122. CARLA_SAFE_ASSERT_RETURN(nullptr == ptr.px || 0 != ptr.pn.use_count(),);
  123. acquire(ptr.px);
  124. }
  125. shared_ptr& operator=(shared_ptr ptr) noexcept
  126. {
  127. swap(ptr);
  128. return *this;
  129. }
  130. ~shared_ptr(void) noexcept
  131. {
  132. release();
  133. }
  134. void reset(void) noexcept
  135. {
  136. release();
  137. }
  138. void swap(shared_ptr& lhs) noexcept
  139. {
  140. std::swap(px, lhs.px);
  141. pn.swap(lhs.pn);
  142. }
  143. operator bool() const noexcept
  144. {
  145. return (0 < pn.use_count());
  146. }
  147. long use_count(void) const noexcept
  148. {
  149. return pn.use_count();
  150. }
  151. // underlying pointer operations :
  152. T& operator*() const noexcept
  153. {
  154. return *px;
  155. }
  156. T* operator->() const noexcept
  157. {
  158. return px;
  159. }
  160. T* get(void) const noexcept
  161. {
  162. return px;
  163. }
  164. private:
  165. void acquire(T* p)
  166. {
  167. pn.acquire(p);
  168. px = p;
  169. }
  170. void release(void) noexcept
  171. {
  172. pn.release(px);
  173. px = nullptr;
  174. }
  175. private:
  176. template<class U>
  177. friend class shared_ptr;
  178. private:
  179. T* px;
  180. shared_ptr_count pn;
  181. };
  182. template<class T, class U> bool operator==(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  183. {
  184. return (l.get() == r.get());
  185. }
  186. template<class T, class U> bool operator!=(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  187. {
  188. return (l.get() != r.get());
  189. }
  190. template<class T, class U> bool operator<=(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  191. {
  192. return (l.get() <= r.get());
  193. }
  194. template<class T, class U> bool operator<(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  195. {
  196. return (l.get() < r.get());
  197. }
  198. template<class T, class U> bool operator>=(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  199. {
  200. return (l.get() >= r.get());
  201. }
  202. template<class T, class U> bool operator>(const shared_ptr<T>& l, const shared_ptr<U>& r) noexcept
  203. {
  204. return (l.get() > r.get());
  205. }
  206. template<class T, class U>
  207. shared_ptr<T> static_pointer_cast(const shared_ptr<U>& ptr)
  208. {
  209. return shared_ptr<T>(ptr, static_cast<typename shared_ptr<T>::element_type*>(ptr.get()));
  210. }
  211. template<class T, class U>
  212. shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& ptr)
  213. {
  214. T* p = dynamic_cast<typename shared_ptr<T>::element_type*>(ptr.get());
  215. if (nullptr != p)
  216. {
  217. return shared_ptr<T>(ptr, p);
  218. }
  219. else
  220. {
  221. return shared_ptr<T>();
  222. }
  223. }
  224. template<class T>
  225. bool operator==(const shared_ptr<T>& pointer1, T* const pointer2) noexcept
  226. {
  227. return static_cast<T*>(pointer1) == pointer2;
  228. }
  229. template<class T>
  230. bool operator!=(const shared_ptr<T>& pointer1, T* const pointer2) noexcept
  231. {
  232. return static_cast<T*>(pointer1) != pointer2;
  233. }
  234. } // namespace std
  235. #endif // CARLA_PROPER_CPP11_SUPPORT
  236. CARLA_BACKEND_START_NAMESPACE
  237. typedef std::shared_ptr<CarlaPlugin> CarlaPluginPtr;
  238. CARLA_BACKEND_END_NAMESPACE
  239. // -----------------------------------------------------------------------
  240. #endif // CARLA_CPP_COMPAT_HPP_INCLUDED