paramspec.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #ifndef GI_PARAMSPEC_HPP
  2. #define GI_PARAMSPEC_HPP
  3. #include "objectbase.hpp"
  4. #include "value.hpp"
  5. namespace gi
  6. {
  7. // slightly nasty; will be generated
  8. namespace repository
  9. {
  10. namespace GObject
  11. {
  12. enum class ParamFlags : std::underlying_type<::GParamFlags>::type;
  13. }
  14. } // namespace repository
  15. namespace detail
  16. {
  17. struct GParamSpecFuncs
  18. {
  19. static void *ref(void *data) { return g_param_spec_ref((GParamSpec *)data); }
  20. static void *sink(void *data)
  21. {
  22. return g_param_spec_ref_sink((GParamSpec *)data);
  23. }
  24. static void free(void *data) { g_param_spec_unref((GParamSpec *)data); }
  25. static void *float_(void *data) { return data; }
  26. };
  27. using ParamFlags = repository::GObject::ParamFlags;
  28. // helper paramspec type
  29. template<typename T>
  30. struct param_spec_constructor;
  31. #define GI_DECLARE_PARAM_SPEC(cpptype, suffix) \
  32. template<> \
  33. struct param_spec_constructor<cpptype> \
  34. { \
  35. typedef std::true_type range_type; \
  36. static const constexpr decltype(&g_param_spec_##suffix) new_ = \
  37. g_param_spec_##suffix; \
  38. };
  39. GI_DECLARE_PARAM_SPEC(char, char)
  40. GI_DECLARE_PARAM_SPEC(unsigned char, uchar)
  41. GI_DECLARE_PARAM_SPEC(int, int)
  42. GI_DECLARE_PARAM_SPEC(unsigned int, uint)
  43. GI_DECLARE_PARAM_SPEC(long, long)
  44. GI_DECLARE_PARAM_SPEC(unsigned long, ulong)
  45. GI_DECLARE_PARAM_SPEC(long long, int64)
  46. GI_DECLARE_PARAM_SPEC(unsigned long long, uint64)
  47. GI_DECLARE_PARAM_SPEC(float, float)
  48. GI_DECLARE_PARAM_SPEC(double, double)
  49. #undef GI_DECLARE_PARAM_SPEC
  50. // specialize appropriately with static new_ member
  51. template<typename T, typename Enable = void>
  52. struct ParamSpecFactory;
  53. template<typename T>
  54. struct ParamSpecFactory<T,
  55. typename std::enable_if<param_spec_constructor<T>::range_type::value>::type>
  56. {
  57. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  58. const gi::cstring_v blurb, T min, T max, T _default,
  59. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  60. {
  61. return param_spec_constructor<T>::new_(name.c_str(), nick.c_str(),
  62. blurb.c_str(), min, max, _default, (GParamFlags)flags);
  63. }
  64. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  65. const gi::cstring_v blurb, T min, T max,
  66. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  67. {
  68. return new_(name, nick, blurb, min, max, T{}, flags);
  69. }
  70. };
  71. template<>
  72. struct ParamSpecFactory<bool>
  73. {
  74. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  75. const gi::cstring_v blurb, bool _default,
  76. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  77. {
  78. return g_param_spec_boolean(name.c_str(), nick.c_str(), blurb.c_str(),
  79. _default, (GParamFlags)flags);
  80. }
  81. };
  82. template<>
  83. struct ParamSpecFactory<gpointer>
  84. {
  85. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  86. const gi::cstring_v blurb,
  87. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  88. {
  89. return g_param_spec_pointer(
  90. name.c_str(), nick.c_str(), blurb.c_str(), (GParamFlags)flags);
  91. }
  92. };
  93. template<>
  94. struct ParamSpecFactory<std::string>
  95. {
  96. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  97. const gi::cstring_v blurb, const gi::cstring_v _default,
  98. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  99. {
  100. return g_param_spec_string(name.c_str(), nick.c_str(), blurb.c_str(),
  101. _default.c_str(), (GParamFlags)flags);
  102. }
  103. };
  104. template<>
  105. struct ParamSpecFactory<gi::cstring> : public ParamSpecFactory<std::string>
  106. {};
  107. template<typename T>
  108. struct ParamSpecFactory<T,
  109. typename std::enable_if<traits::is_object<T>::value>::type>
  110. {
  111. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  112. const gi::cstring_v blurb,
  113. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  114. {
  115. return g_param_spec_object(name.c_str(), nick.c_str(), blurb.c_str(),
  116. traits::gtype<T>::get_type(), (GParamFlags)flags);
  117. }
  118. };
  119. template<typename T>
  120. struct ParamSpecFactory<T,
  121. typename std::enable_if<traits::is_boxed<T>::value>::type>
  122. {
  123. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  124. const gi::cstring_v blurb,
  125. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  126. {
  127. return g_param_spec_boxed(name.c_str(), nick.c_str(), blurb.c_str(),
  128. traits::gtype<T>::get_type(), (GParamFlags)flags);
  129. }
  130. };
  131. template<typename T>
  132. struct ParamSpecFactory<T,
  133. typename std::enable_if<traits::is_enum_or_bitfield<T>::value>::type>
  134. {
  135. static GParamSpec *new_(const gi::cstring_v name, const gi::cstring_v nick,
  136. const gi::cstring_v blurb, guint _default = 0,
  137. ParamFlags flags = (ParamFlags)G_PARAM_READWRITE)
  138. {
  139. GType t = traits::gtype<T>::get_type();
  140. // FIXME compile-time determination rather than dynamic ??
  141. return G_TYPE_IS_FLAGS(t)
  142. ? g_param_spec_flags(name.c_str(), nick.c_str(), blurb.c_str(),
  143. t, _default, (GParamFlags)flags)
  144. : g_param_spec_enum(name.c_str(), nick.c_str(), blurb.c_str(), t,
  145. _default, (GParamFlags)flags);
  146. }
  147. };
  148. } // namespace detail
  149. namespace repository
  150. {
  151. // slightly nasty
  152. namespace GObject
  153. {
  154. class ParamSpec;
  155. }
  156. template<>
  157. struct declare_cpptype_of<GParamSpec>
  158. {
  159. typedef GObject::ParamSpec type;
  160. };
  161. namespace GObject
  162. {
  163. class ParamSpec : public detail::WrapperBase<GParamSpec,
  164. detail::GParamSpecFuncs, G_TYPE_PARAM>
  165. {
  166. typedef WrapperBase<GParamSpec, detail::GParamSpecFuncs, G_TYPE_PARAM> super;
  167. public:
  168. ParamSpec(std::nullptr_t = nullptr) {}
  169. template<typename T, typename... Args>
  170. static ParamSpec new_(Args &&...args)
  171. {
  172. return static_cast<ParamSpec &&>(
  173. super(detail::ParamSpecFactory<T>::new_(std::forward<Args>(args)...)));
  174. }
  175. // special override case
  176. static ParamSpec new_(const gi::cstring_v name, ParamSpec overridden)
  177. {
  178. return static_cast<ParamSpec &&>(
  179. super(g_param_spec_override(name.c_str(), overridden.gobj_())));
  180. }
  181. gi::cstring_v get_blurb() { return g_param_spec_get_blurb(gobj_()); }
  182. gi::cstring_v get_nick() { return g_param_spec_get_nick(gobj_()); }
  183. gi::cstring_v get_name() { return g_param_spec_get_name(gobj_()); }
  184. GQuark get_name_quark() { return g_param_spec_get_name_quark(gobj_()); }
  185. repository::GObject::Value get_default_value()
  186. {
  187. return gi::wrap(g_param_spec_get_default_value(gobj_()), transfer_none);
  188. }
  189. ParamSpec get_redirect_target()
  190. {
  191. return gi::wrap(g_param_spec_get_redirect_target(gobj_()), transfer_none);
  192. }
  193. // struct fields
  194. const gchar *name_() const { return gobj_()->name; }
  195. ParamFlags value_type() const { return (ParamFlags)gobj_()->flags; }
  196. GType value_type_() const { return gobj_()->value_type; }
  197. GType owner_type_() const { return gobj_()->owner_type; }
  198. };
  199. } // namespace GObject
  200. } // namespace repository
  201. } // namespace gi
  202. #endif // GI_PARAMSPEC_HPP