builderutils.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (C) 2020 The Qt Company Ltd.
  2. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
  3. #pragma once
  4. #include <functional>
  5. #if defined(UTILS_LIBRARY)
  6. # define QTCREATOR_UTILS_EXPORT Q_DECL_EXPORT
  7. #elif defined(UTILS_STATIC_LIBRARY)
  8. # define QTCREATOR_UTILS_EXPORT
  9. #else
  10. # define QTCREATOR_UTILS_EXPORT Q_DECL_IMPORT
  11. #endif
  12. namespace Building {
  13. class Widget;
  14. class NestId {};
  15. template <typename Id, typename Arg>
  16. class IdAndArg
  17. {
  18. public:
  19. IdAndArg(Id, const Arg &arg) : arg(arg) {}
  20. const Arg arg; // FIXME: Could be const &, but this would currently break bindTo().
  21. };
  22. template<typename T1, typename T2>
  23. struct Arg2
  24. {
  25. Arg2(const T1 &a1, const T2 &a2)
  26. : p1(a1)
  27. , p2(a2)
  28. {}
  29. const T1 p1;
  30. const T2 p2;
  31. };
  32. template<typename T1, typename T2, typename T3>
  33. struct Arg3
  34. {
  35. Arg3(const T1 &a1, const T2 &a2, const T3 &a3)
  36. : p1(a1)
  37. , p2(a2)
  38. , p3(a3)
  39. {}
  40. const T1 p1;
  41. const T2 p2;
  42. const T3 p3;
  43. };
  44. template<typename T1, typename T2, typename T3, typename T4>
  45. struct Arg4
  46. {
  47. Arg4(const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4)
  48. : p1(a1)
  49. , p2(a2)
  50. , p3(a3)
  51. , p4(a4)
  52. {}
  53. const T1 p1;
  54. const T2 p2;
  55. const T3 p3;
  56. const T4 p4;
  57. };
  58. // The main dispatcher
  59. // void doit(Widget *x, Building::NestId id, auto p);
  60. template<typename X>
  61. class BuilderItem
  62. {
  63. public:
  64. // Property setter
  65. template <typename Id, typename Arg>
  66. BuilderItem(IdAndArg<Id, Arg> && idarg)
  67. {
  68. apply = [&idarg](X *x) { doit(x, Id{}, idarg.arg); };
  69. }
  70. // Nested child object
  71. template <typename Inner>
  72. BuilderItem(Inner && p)
  73. {
  74. apply = [&p](X *x) { doit(x, NestId{}, std::forward<Inner>(p)); };
  75. }
  76. std::function<void(X *)> apply;
  77. };
  78. #define QTC_DEFINE_BUILDER_SETTER(name, setter) \
  79. class name##_TAG {}; \
  80. inline auto name(auto p) { return Building::IdAndArg{name##_TAG{}, p}; } \
  81. inline void doit(auto x, name##_TAG, auto p) { x->setter(p); }
  82. #define QTC_DEFINE_BUILDER_SETTER2(name, setter) \
  83. class name##_TAG {}; \
  84. inline auto name(auto p1, auto p2) { return Building::IdAndArg{name##_TAG{}, Building::Arg2{p1, p2}}; } \
  85. inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2); }
  86. #define QTC_DEFINE_BUILDER_SETTER3(name, setter) \
  87. class name##_TAG {}; \
  88. inline auto name(auto p1, auto p2, auto p3) { return Building::IdAndArg{name##_TAG{}, Building::Arg3{p1, p2, p3}}; } \
  89. inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3); }
  90. #define QTC_DEFINE_BUILDER_SETTER4(name, setter) \
  91. class name##_TAG {}; \
  92. inline auto name(auto p1, auto p2, auto p3, auto p4) { return Building::IdAndArg{name##_TAG{}, Building::Arg4{p1, p2, p3, p4}}; } \
  93. inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3, p.p4); }
  94. } // Building