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.

255 lines
4.3KB

  1. /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * If you would like to incorporate Link into a proprietary software application,
  17. * please contact <link-devs@ableton.com>.
  18. */
  19. #pragma once
  20. #include <memory>
  21. namespace ableton
  22. {
  23. namespace util
  24. {
  25. // Utility type for aiding in dependency injection.
  26. // Base template and implementation for injected valued
  27. template <typename T>
  28. struct Injected
  29. {
  30. using type = T;
  31. Injected() = default;
  32. explicit Injected(T t)
  33. : val(std::move(t))
  34. {
  35. }
  36. Injected(const Injected&) = default;
  37. Injected& operator=(const Injected&) = default;
  38. Injected(Injected&& rhs)
  39. : val(std::move(rhs.val))
  40. {
  41. }
  42. Injected& operator=(Injected&& rhs)
  43. {
  44. val = std::move(rhs.val);
  45. return *this;
  46. }
  47. T* operator->()
  48. {
  49. return &val;
  50. }
  51. const T* operator->() const
  52. {
  53. return &val;
  54. }
  55. T& operator*()
  56. {
  57. return val;
  58. }
  59. const T& operator*() const
  60. {
  61. return val;
  62. }
  63. T val;
  64. };
  65. // Utility function for injecting values
  66. template <typename T>
  67. Injected<T> injectVal(T t)
  68. {
  69. return Injected<T>(std::move(t));
  70. }
  71. // Specialization for injected references
  72. template <typename T>
  73. struct Injected<T&>
  74. {
  75. using type = T;
  76. explicit Injected(T& t)
  77. : ref(std::ref(t))
  78. {
  79. }
  80. Injected(const Injected&) = default;
  81. Injected& operator=(const Injected&) = default;
  82. Injected(Injected&& rhs)
  83. : ref(std::move(rhs.ref))
  84. {
  85. }
  86. Injected& operator=(Injected&& rhs)
  87. {
  88. ref = std::move(rhs.ref);
  89. return *this;
  90. }
  91. T* operator->()
  92. {
  93. return &ref.get();
  94. }
  95. const T* operator->() const
  96. {
  97. return &ref.get();
  98. }
  99. T& operator*()
  100. {
  101. return ref;
  102. }
  103. const T& operator*() const
  104. {
  105. return ref;
  106. }
  107. std::reference_wrapper<T> ref;
  108. };
  109. // Utility function for injecting references
  110. template <typename T>
  111. Injected<T&> injectRef(T& t)
  112. {
  113. return Injected<T&>(t);
  114. }
  115. // Specialization for injected shared_ptr
  116. template <typename T>
  117. struct Injected<std::shared_ptr<T>>
  118. {
  119. using type = T;
  120. explicit Injected(std::shared_ptr<T> pT)
  121. : shared(std::move(pT))
  122. {
  123. }
  124. Injected(const Injected&) = default;
  125. Injected& operator=(const Injected&) = default;
  126. Injected(Injected&& rhs)
  127. : shared(std::move(rhs.shared))
  128. {
  129. }
  130. Injected& operator=(Injected&& rhs)
  131. {
  132. shared = std::move(rhs.shared);
  133. return *this;
  134. }
  135. T* operator->()
  136. {
  137. return shared.get();
  138. }
  139. const T* operator->() const
  140. {
  141. return shared.get();
  142. }
  143. T& operator*()
  144. {
  145. return *shared;
  146. }
  147. const T& operator*() const
  148. {
  149. return *shared;
  150. }
  151. std::shared_ptr<T> shared;
  152. };
  153. // Utility function for injected shared_ptr
  154. template <typename T>
  155. Injected<std::shared_ptr<T>> injectShared(std::shared_ptr<T> shared)
  156. {
  157. return Injected<std::shared_ptr<T>>(std::move(shared));
  158. }
  159. // Specialization for injected unique_ptr
  160. template <typename T>
  161. struct Injected<std::unique_ptr<T>>
  162. {
  163. using type = T;
  164. explicit Injected(std::unique_ptr<T> pT)
  165. : unique(std::move(pT))
  166. {
  167. }
  168. Injected(const Injected&) = default;
  169. Injected& operator=(const Injected&) = default;
  170. Injected(Injected&& rhs)
  171. : unique(std::move(rhs.unique))
  172. {
  173. }
  174. Injected& operator=(Injected&& rhs)
  175. {
  176. unique = std::move(rhs.unique);
  177. return *this;
  178. }
  179. T* operator->()
  180. {
  181. return unique.get();
  182. }
  183. const T* operator->() const
  184. {
  185. return unique.get();
  186. }
  187. T& operator*()
  188. {
  189. return *unique;
  190. }
  191. const T& operator*() const
  192. {
  193. return *unique;
  194. }
  195. std::unique_ptr<T> unique;
  196. };
  197. // Utility function for injected unique_ptr
  198. template <typename T>
  199. Injected<std::unique_ptr<T>> injectUnique(std::unique_ptr<T> unique)
  200. {
  201. return Injected<std::unique_ptr<T>>(std::move(unique));
  202. }
  203. } // namespace util
  204. } // namespace ableton