ProxyImpl.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. ///
  2. /// \file Proxy/ProxyImpl.hpp
  3. ///
  4. /// Proxy template method implementations.
  5. ///
  6. /// \copyright
  7. /// Copyright (c) 2013-2017 Josh Blum
  8. /// 2021 Nicholas Corgan
  9. /// SPDX-License-Identifier: BSL-1.0
  10. ///
  11. #pragma once
  12. #include <Pothos/Config.hpp>
  13. #include <Pothos/Object/ObjectImpl.hpp>
  14. #include <Pothos/Proxy/Proxy.hpp>
  15. #include <Pothos/Proxy/Handle.hpp>
  16. #include <Pothos/Proxy/Environment.hpp>
  17. #include <type_traits> //enable_if
  18. #include <utility> //std::forward
  19. #include <cassert>
  20. #include <array>
  21. namespace Pothos {
  22. template <typename ValueType>
  23. ValueType Proxy::convert(void) const
  24. {
  25. return this->getEnvironment()->convertProxyToObject(*this).convert<ValueType>();
  26. }
  27. namespace Detail {
  28. /***********************************************************************
  29. * convertProxy either converts a proxy to a desired type
  30. * or returns a proxy if the requested type was a proxy
  31. **********************************************************************/
  32. template <typename T>
  33. typename std::enable_if<!std::is_same<T, Proxy>::value, T>::type
  34. convertProxy(const Proxy &p)
  35. {
  36. return p.convert<T>();
  37. }
  38. template <typename T>
  39. typename std::enable_if<std::is_same<T, Proxy>::value, T>::type
  40. convertProxy(const Proxy &p)
  41. {
  42. return p;
  43. }
  44. /***********************************************************************
  45. * makeProxy either makes a proxy from an arbitrary type
  46. * or returns a proxy if the type is already a proxy
  47. **********************************************************************/
  48. template <typename T>
  49. typename std::enable_if<!std::is_same<typename std::decay<T>::type, Proxy>::value, Proxy>::type
  50. makeProxy(const ProxyEnvironment::Sptr &env, T &&value)
  51. {
  52. return env->makeProxy(std::forward<T>(value));
  53. }
  54. template <typename T>
  55. typename std::enable_if<std::is_same<typename std::decay<T>::type, Proxy>::value, Proxy>::type
  56. makeProxy(const ProxyEnvironment::Sptr &, T &&value)
  57. {
  58. // Explicitly copy the input proxy. This removes a Clang warning that says
  59. // that this happens anyway. Since the proxy class only stores a shared_ptr
  60. // to the implementation, this operation is cheap.
  61. return T(value);
  62. }
  63. } //namespace Detail
  64. template <typename ValueType>
  65. Proxy::operator ValueType(void) const
  66. {
  67. return this->convert<ValueType>();
  68. }
  69. template <typename ReturnType, typename... ArgsType>
  70. ReturnType Proxy::call(const std::string &name, ArgsType&&... args) const
  71. {
  72. Proxy ret = this->call(name, std::forward<ArgsType>(args)...);
  73. return Detail::convertProxy<ReturnType>(ret);
  74. }
  75. template <typename... ArgsType>
  76. Proxy Proxy::call(const std::string &name, ArgsType&&... args) const
  77. {
  78. const std::array<Proxy, sizeof...(ArgsType)> proxyArgs{{Detail::makeProxy(this->getEnvironment(), std::forward<ArgsType>(args))...}};
  79. auto handle = this->getHandle();
  80. assert(handle);
  81. return handle->call(name, proxyArgs.data(), sizeof...(args));
  82. }
  83. template <typename... ArgsType>
  84. Proxy Proxy::callProxy(const std::string &name, ArgsType&&... args) const
  85. {
  86. return this->call(name, std::forward<ArgsType>(args)...);
  87. }
  88. template <typename... ArgsType>
  89. void Proxy::callVoid(const std::string &name, ArgsType&&... args) const
  90. {
  91. this->call(name, std::forward<ArgsType>(args)...);
  92. }
  93. template <typename ReturnType>
  94. ReturnType Proxy::get(const std::string &name) const
  95. {
  96. return this->call<ReturnType>("get:"+name);
  97. }
  98. template <typename ValueType>
  99. void Proxy::set(const std::string &name, ValueType&& value) const
  100. {
  101. this->call("set:"+name, std::forward<ValueType>(value));
  102. }
  103. template <typename... ArgsType>
  104. Proxy Proxy::operator()(ArgsType&&... args) const
  105. {
  106. return this->call("()", std::forward<ArgsType>(args)...);
  107. }
  108. } //namespace Pothos