@@ -100,6 +100,18 @@ I Reduce(std::function<I(I&&, I&&)> red, std::vector<I>&& vec) {
100
100
return res;
101
101
}
102
102
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
+
103
115
/*
104
116
* Return a copy of the vector that contains only those elements for which
105
117
* function "f" returns true.
@@ -108,8 +120,12 @@ I Reduce(std::function<I(I&&, I&&)> red, std::vector<I>&& vec) {
108
120
* functor) with signature <bool(T)>.
109
121
*
110
122
* 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.
113
129
*/
114
130
template <typename Func, typename T>
115
131
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) {
119
135
static_assert (
120
136
function_traits<Func>::n_args == 1 ,
121
137
" 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;
122
155
static_assert (
123
- std::is_same<typename function_traits<Func>::template arg<0 >::type, T>::
124
- value,
156
+ sameType || sameTypeRightMbConst || ptrToSameTypeRightMbConst,
125
157
" The argument of the filtering function must have the same type "
126
158
" as the element type of the collection being filtered" );
127
159
0 commit comments