function_ut.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "function.h"
  2. #include "typetraits.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. Y_UNIT_TEST_SUITE(TestFunctionSignature) {
  5. int FF(double x) {
  6. return (int)x;
  7. }
  8. int FFN(double x) noexcept {
  9. return (int)x;
  10. }
  11. int FFF(double x, char xx) {
  12. return (int)x + (int)xx;
  13. }
  14. int FFFN(double x, char xx) noexcept {
  15. return (int)x + (int)xx;
  16. }
  17. struct A {
  18. int F(double x) {
  19. return FF(x);
  20. }
  21. int FN(double x) noexcept {
  22. return FFN(x);
  23. }
  24. int FC(double x) const {
  25. return FF(x);
  26. }
  27. int FCN(double x) const noexcept {
  28. return FFN(x);
  29. }
  30. #define Y_FOR_EACH_REF_QUALIFIED_MEMBERS(XX) \
  31. XX(AsMutLvalue, &, false) \
  32. XX(AsMutLvalueN, &, true) \
  33. XX(AsMutRvalue, &&, false) \
  34. XX(AsMutRvalueN, &&, true) \
  35. XX(AsConstLvalue, const&, false) \
  36. XX(AsConstLvalueN, const&, true) \
  37. XX(AsConstRvalue, const&&, false) \
  38. XX(AsConstRvalueN, const&&, true)
  39. #define Y_ADD_MEMBER(name, qualifiers, isNoexcept) \
  40. int name(double x) qualifiers noexcept(isNoexcept) { \
  41. return FF(x); \
  42. }
  43. Y_FOR_EACH_REF_QUALIFIED_MEMBERS(Y_ADD_MEMBER)
  44. #undef Y_ADD_MEMBER
  45. };
  46. Y_UNIT_TEST(TestPlainFunc) {
  47. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(FF)>, decltype(FF));
  48. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(FFN)>, decltype(FF));
  49. }
  50. Y_UNIT_TEST(TestMethod) {
  51. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::F)>, decltype(FF));
  52. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FN)>, decltype(FF));
  53. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FC)>, decltype(FF));
  54. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FCN)>, decltype(FF));
  55. #define Y_CHECK_MEMBER(name, qualifiers, isNoexcept) \
  56. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::name)>, decltype(FF));
  57. Y_FOR_EACH_REF_QUALIFIED_MEMBERS(Y_CHECK_MEMBER)
  58. #undef Y_CHECK_MEMBER
  59. }
  60. Y_UNIT_TEST(TestLambda) {
  61. auto f = [](double x) -> int {
  62. return FF(x);
  63. };
  64. auto fn = [](double x) mutable noexcept -> int {
  65. return FFN(x);
  66. };
  67. auto fcn = [](double x) noexcept -> int {
  68. return FFN(x);
  69. };
  70. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(f)>, decltype(FF));
  71. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(fn)>, decltype(FF));
  72. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(fcn)>, decltype(FF));
  73. }
  74. Y_UNIT_TEST(TestFunction) {
  75. std::function<int(double)> f(FF);
  76. UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(f)>, decltype(FF));
  77. }
  78. template <class F>
  79. void TestCT() {
  80. #define FA(x) TFunctionArg<F, x>
  81. UNIT_ASSERT_TYPES_EQUAL(FA(0), double);
  82. UNIT_ASSERT_TYPES_EQUAL(FA(1), char);
  83. UNIT_ASSERT_TYPES_EQUAL(TFunctionResult<F>, int);
  84. #undef FA
  85. }
  86. Y_UNIT_TEST(TestTypeErasureTraits) {
  87. TestCT<std::function<int(double, char)>>();
  88. }
  89. Y_UNIT_TEST(TestPlainFunctionTraits) {
  90. TestCT<decltype(FFF)>();
  91. TestCT<decltype(FFFN)>();
  92. }
  93. Y_UNIT_TEST(TestLambdaTraits) {
  94. auto fff = [](double xx, char xxx) -> int {
  95. return FFF(xx, xxx);
  96. };
  97. auto fffn = [](double xx, char xxx) mutable noexcept -> int {
  98. return FFFN(xx, xxx);
  99. };
  100. auto fffcn = [](double xx, char xxx) noexcept -> int {
  101. return FFFN(xx, xxx);
  102. };
  103. TestCT<decltype(fff)>();
  104. TestCT<decltype(fffn)>();
  105. TestCT<decltype(fffcn)>();
  106. }
  107. } // Y_UNIT_TEST_SUITE(TestFunctionSignature)