tune.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #pragma once
  2. /*
  3. Motivation: consider you have a template class with many parameters
  4. with default associations
  5. template <typename A = TDefA,
  6. typename B = TDefB,
  7. typename C = TDefC,
  8. typename D = TDefD>
  9. class TExample {
  10. };
  11. consider you would like to provide easy to use interface to tune all
  12. these parameters in position independed manner,
  13. In that case TTune would be helpful for you.
  14. How to use:
  15. First step: declare a struct with all default associations
  16. struct TDefaultTune {
  17. using TStructA = TDefA;
  18. using TStructB = TDefB;
  19. using TStructC = TDefC;
  20. using TStructD = TDefD;
  21. };
  22. Second step: declare helper names visible to a user
  23. DeclareTuneTypeParam(TTuneParamA, TStructA);
  24. DeclareTuneTypeParam(TTuneParamB, TStructB);
  25. DeclareTuneTypeParam(TTuneParamC, TStructC);
  26. DeclareTuneTypeParam(TTuneParamD, TStructD);
  27. Third step: declare TExample this way:
  28. template <typename...TParams>
  29. class TExample {
  30. using TMyParams = TTune<TDefaultTune, TParams...>;
  31. using TActualA = TMyParams::TStructA;
  32. using TActualB = TMyParams::TStructB;
  33. ...
  34. };
  35. TTune<TDefaultTune, TParams...> is a struct with the default parameteres
  36. taken from TDefaultTune and overridden from "TParams...".
  37. for example: "TTune<TDefaultTune, TTuneParamC<TUserClass>>"
  38. will be virtually the same as:
  39. struct TTunedClass {
  40. using TStructA = TDefA;
  41. using TStructB = TDefB;
  42. using TStructC = TUserClass;
  43. using TStructD = TDefD;
  44. };
  45. From now on you can tune your TExample in the following manner:
  46. using TCustomClass =
  47. TExample <TTuneParamA<TUserStruct1>, TTuneParamD<TUserStruct2>>;
  48. You can also tweak constant expressions in your TDefaultTune.
  49. Consider you have:
  50. struct TDefaultTune {
  51. static constexpr ui32 MySize = 42;
  52. };
  53. declare an interface to modify the parameter this way:
  54. DeclareTuneValueParam(TStructSize, ui32, MySize);
  55. and tweak your class:
  56. using TTwiceBigger = TExample<TStructSize<84>>;
  57. */
  58. #define DeclareTuneTypeParam(TParamName, InternalName) \
  59. template <typename TNewType> \
  60. struct TParamName { \
  61. template <typename TBase> \
  62. struct TApply: public TBase { \
  63. using InternalName = TNewType; \
  64. }; \
  65. }
  66. #define DeclareTuneValueParam(TParamName, TValueType, InternalName) \
  67. template <TValueType NewValue> \
  68. struct TParamName { \
  69. template <typename TBase> \
  70. struct TApply: public TBase { \
  71. static constexpr TValueType InternalName = NewValue; \
  72. }; \
  73. }
  74. #define DeclareTuneContainer(TParamName, InternalName) \
  75. template <template <typename, typename...> class TNewContainer> \
  76. struct TParamName { \
  77. template <typename TBase> \
  78. struct TApply: public TBase { \
  79. template <typename TElem, typename... TRest> \
  80. using InternalName = TNewContainer<TElem, TRest...>; \
  81. }; \
  82. }
  83. namespace NTunePrivate {
  84. template <typename TBase, typename... TParams>
  85. struct TFold;
  86. template <typename TBase>
  87. struct TFold<TBase>: public TBase {
  88. };
  89. template <typename TBase, typename TFirstArg, typename... TRest>
  90. struct TFold<TBase, TFirstArg, TRest...>
  91. : public TFold<typename TFirstArg::template TApply<TBase>, TRest...> {
  92. };
  93. }
  94. template <typename TDefault, typename... TParams>
  95. struct TTune: public NTunePrivate::TFold<TDefault, TParams...> {
  96. };