Skip to content
This repository was archived by the owner on Apr 28, 2023. It is now read-only.

Commit eb39d2c

Browse files
committed
functional::Filter: allow functions with const argument for non-const list
Relax static_asserts in functional::Filter to accept filtering function with the argument of type "const T" or "const T*" for vectors of type "T" or "T *". These are regular C++ type conversion rules and they should be supported.
1 parent 74c76ca commit eb39d2c

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

tc/core/polyhedral/functional.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ I Reduce(std::function<I(I&&, I&&)> red, std::vector<I>&& vec) {
100100
return res;
101101
}
102102

103+
namespace {
104+
// Allow combinations:
105+
// LHS RHS
106+
// const T and T
107+
// const T and const T
108+
template <typename LHS, typename RHS>
109+
struct is_same_allow_rhs_non_const {
110+
const static bool value =
111+
std::is_same<LHS, typename std::add_const<RHS>::type>::value;
112+
};
113+
} // namespace
114+
103115
/*
104116
* Return a copy of the vector that contains only those elements for which
105117
* function "f" returns true.
@@ -108,8 +120,12 @@ I Reduce(std::function<I(I&&, I&&)> red, std::vector<I>&& vec) {
108120
* functor) with signature <bool(T)>.
109121
*
110122
* Template argument deduction takes care of vector<const T> cases
111-
* automatically. Note that the signature of "f" must use the same type, that
112-
* is "const T".
123+
* automatically. Additionally, accept vectors of (pointers to) non-const
124+
* elements and a function with (a pointer to) a const argument.
125+
* Note that the function type is a template argument guarded by static asserts
126+
* rather than an std::function because template argument deduction fails on
127+
* lambdas in the latter case; lambdas are convertible to std::function but are
128+
* not an instance of std::function.
113129
*/
114130
template <typename Func, typename T>
115131
std::vector<T> Filter(Func f, const std::vector<T>& input) {
@@ -119,9 +135,25 @@ std::vector<T> Filter(Func f, const std::vector<T>& input) {
119135
static_assert(
120136
function_traits<Func>::n_args == 1,
121137
"Filtering function must take one argument");
138+
139+
// Allow combinations:
140+
// Function arg Vector element
141+
// T and T
142+
// const T and T
143+
// const T and const T
144+
// T* and T*
145+
// const T* and T*
146+
// const T* and const T*
147+
using arg0 = typename function_traits<Func>::template arg<0>::type;
148+
constexpr bool sameType = std::is_same<arg0, T>::value;
149+
constexpr bool sameTypeRightMbConst =
150+
is_same_allow_rhs_non_const<arg0, T>::value;
151+
constexpr bool ptrToSameTypeRightMbConst = std::is_pointer<arg0>::value &&
152+
std::is_pointer<T>::value &&
153+
is_same_allow_rhs_non_const<typename std::remove_pointer<arg0>::type,
154+
typename std::remove_pointer<T>::type>::value;
122155
static_assert(
123-
std::is_same<typename function_traits<Func>::template arg<0>::type, T>::
124-
value,
156+
sameType || sameTypeRightMbConst || ptrToSameTypeRightMbConst,
125157
"The argument of the filtering function must have the same type "
126158
"as the element type of the collection being filtered");
127159

0 commit comments

Comments
 (0)