aboutsummaryrefslogtreecommitdiffstats
path: root/util/generic
diff options
context:
space:
mode:
authorsskvor <sskvor@yandex-team.com>2022-08-24 11:41:27 +0300
committersskvor <sskvor@yandex-team.com>2022-08-24 11:41:27 +0300
commit30a75ad702329a4178784acc5bad610931c32382 (patch)
treed490edde5fe1700104ceecbcc8d443a33eb6168c /util/generic
parent26dcb3705729c807903c7c1d5757cb950e703c1a (diff)
downloadydb-30a75ad702329a4178784acc5bad610931c32382.tar.gz
[util] Add specializations for const / ref qualified member functions
Diffstat (limited to 'util/generic')
-rw-r--r--util/generic/function.h35
-rw-r--r--util/generic/function_ut.cpp69
2 files changed, 94 insertions, 10 deletions
diff --git a/util/generic/function.h b/util/generic/function.h
index 62fa84e0cb..859cc3f849 100644
--- a/util/generic/function.h
+++ b/util/generic/function.h
@@ -11,15 +11,23 @@ namespace NPrivate {
using TSignature = F;
};
- template <typename C, typename R, typename... Args>
- struct TRemoveClassImpl<R (C::*)(Args...)> {
- typedef R TSignature(Args...);
+#define Y_EMPTY_REF_QUALIFIER
+#define Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(XX) \
+ XX(Y_EMPTY_REF_QUALIFIER) \
+ XX(&) \
+ XX(&&) \
+ XX(const) \
+ XX(const&) \
+ XX(const&&)
+
+#define Y_DECLARE_REMOVE_CLASS_IMPL(qualifiers) \
+ template <typename C, typename R, typename... Args> \
+ struct TRemoveClassImpl<R (C::*)(Args...) qualifiers> { \
+ typedef R TSignature(Args...); \
};
- template <typename C, typename R, typename... Args>
- struct TRemoveClassImpl<R (C::*)(Args...) const> {
- typedef R TSignature(Args...);
- };
+ Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_CLASS_IMPL)
+#undef Y_DECLARE_REMOVE_CLASS_IMPL
template <class T>
struct TRemoveNoExceptImpl {
@@ -31,11 +39,18 @@ namespace NPrivate {
using Type = R(Args...);
};
- template <typename R, typename C, typename... Args>
- struct TRemoveNoExceptImpl<R (C::*)(Args...) noexcept> {
- using Type = R (C::*)(Args...);
+#define Y_DECLARE_REMOVE_NOEXCEPT_IMPL(qualifiers) \
+ template <typename R, typename C, typename... Args> \
+ struct TRemoveNoExceptImpl<R (C::*)(Args...) qualifiers noexcept> { \
+ using Type = R (C::*)(Args...); \
};
+ Y_FOR_EACH_REF_QUALIFIERS_COMBINATION(Y_DECLARE_REMOVE_NOEXCEPT_IMPL)
+#undef Y_DECLARE_REMOVE_NOEXCEPT_IMPL
+
+#undef Y_FOR_EACH_REF_QUALIFIERS_COMBINATION
+#undef Y_EMPTY_REF_QUALIFIER
+
template <class T>
using TRemoveNoExcept = typename TRemoveNoExceptImpl<T>::Type;
diff --git a/util/generic/function_ut.cpp b/util/generic/function_ut.cpp
index 3880295a9f..f46188aa2a 100644
--- a/util/generic/function_ut.cpp
+++ b/util/generic/function_ut.cpp
@@ -8,22 +8,70 @@ Y_UNIT_TEST_SUITE(TestFunctionSignature) {
return (int)x;
}
+ int FFN(double x) noexcept {
+ return (int)x;
+ }
+
int FFF(double x, char xx) {
return (int)x + (int)xx;
}
+ int FFFN(double x, char xx) noexcept {
+ return (int)x + (int)xx;
+ }
+
struct A {
int F(double x) {
return FF(x);
}
+
+ int FN(double x) noexcept {
+ return FFN(x);
+ }
+
+ int FC(double x) const {
+ return FF(x);
+ }
+
+ int FCN(double x) const noexcept {
+ return FFN(x);
+ }
+
+#define Y_FOR_EACH_REF_QUALIFIED_MEMBERS(XX) \
+ XX(AsMutLvalue, &, false) \
+ XX(AsMutLvalueN, &, true) \
+ XX(AsMutRvalue, &&, false) \
+ XX(AsMutRvalueN, &&, true) \
+ XX(AsConstLvalue, const&, false) \
+ XX(AsConstLvalueN, const&, true) \
+ XX(AsConstRvalue, const&&, false) \
+ XX(AsConstRvalueN, const&&, true)
+
+#define Y_ADD_MEMBER(name, qualifiers, isNoexcept) \
+ int name(double x) qualifiers noexcept(isNoexcept) { \
+ return FF(x); \
+ }
+
+ Y_FOR_EACH_REF_QUALIFIED_MEMBERS(Y_ADD_MEMBER)
+#undef Y_ADD_MEMBER
};
Y_UNIT_TEST(TestPlainFunc) {
UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(FF)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(FFN)>, decltype(FF));
}
Y_UNIT_TEST(TestMethod) {
UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::F)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FN)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FC)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::FCN)>, decltype(FF));
+
+#define Y_CHECK_MEMBER(name, qualifiers, isNoexcept) \
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(&A::name)>, decltype(FF));
+
+ Y_FOR_EACH_REF_QUALIFIED_MEMBERS(Y_CHECK_MEMBER)
+#undef Y_CHECK_MEMBER
}
Y_UNIT_TEST(TestLambda) {
@@ -31,7 +79,17 @@ Y_UNIT_TEST_SUITE(TestFunctionSignature) {
return FF(x);
};
+ auto fn = [](double x) mutable noexcept -> int {
+ return FFN(x);
+ };
+
+ auto fcn = [](double x) noexcept -> int {
+ return FFN(x);
+ };
+
UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(f)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(fn)>, decltype(FF));
+ UNIT_ASSERT_TYPES_EQUAL(TFunctionSignature<decltype(fcn)>, decltype(FF));
}
Y_UNIT_TEST(TestFunction) {
@@ -57,6 +115,7 @@ Y_UNIT_TEST_SUITE(TestFunctionSignature) {
Y_UNIT_TEST(TestPlainFunctionTraits) {
TestCT<decltype(FFF)>();
+ TestCT<decltype(FFFN)>();
}
Y_UNIT_TEST(TestLambdaTraits) {
@@ -64,6 +123,16 @@ Y_UNIT_TEST_SUITE(TestFunctionSignature) {
return FFF(xx, xxx);
};
+ auto fffn = [](double xx, char xxx) mutable noexcept -> int {
+ return FFFN(xx, xxx);
+ };
+
+ auto fffcn = [](double xx, char xxx) noexcept -> int {
+ return FFFN(xx, xxx);
+ };
+
TestCT<decltype(fff)>();
+ TestCT<decltype(fffn)>();
+ TestCT<decltype(fffcn)>();
}
}