Adobe Source Libraries 1.49.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
functional.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6/**************************************************************************************************/
7
8#ifndef ADOBE_FUNCTIONAL_HPP
9#define ADOBE_FUNCTIONAL_HPP
10
11#include <adobe/config.hpp>
12
13#include <functional>
14#include <tuple>
15#include <type_traits>
16#include <utility>
17
18#include <boost/compressed_pair.hpp>
19
23
24/**************************************************************************************************/
25
26namespace adobe {
27
28/**************************************************************************************************/
29
34
35/*
36 REVISIT (sparent) : Documentation for delete_ptr moved to adobe/functional.hpp because doxygen
37 1.4.3 cannot handle the template specializations.
38*/
39
46
53
61
68
80
93
101
114
127
128
132
133template <typename F, // models UnaryFunction
134 typename G> // models UnaryFunction -> argument_type(F)
137 unary_compose(F f, G g) : data_m(f, g) {}
138
139 template <typename U> // U models Regular
140 auto operator()(const U& x) const {
141 return data_m.first()(data_m.second()(x));
142 }
143
144 template <typename U> // U models Regular
145 auto operator()(U& x) const {
146 return data_m.first()(data_m.second()(x));
147 }
148
149private:
150 boost::compressed_pair<F, G> data_m;
151};
152
153/**************************************************************************************************/
154
155template <typename F, // models UnaryFunction
156 typename G>
157// models UnaryFunction -> argument_type(F)
159 return unary_compose<F, G>(f, g);
160}
161
162/**************************************************************************************************/
163
164template <typename F, // models BinaryFunction
165 typename G, // models UnaryFunction -> argument_type(F, 0);
166 typename H = G> // models UnaryFunction -> argument_type(F, 1);
168 typedef typename F::result_type result_type;
169
170 template <typename T, typename U> // models Regular
171 result_type operator()(const T& x, const U& y) const {
172 return f(g(x), h(y));
173 }
174
175 template <typename T, typename U> // models Regular
176 result_type operator()(T& x, U& y) const {
177 return f(g(x), h(y));
178 }
179
181 G g;
182 H h;
183};
184
185/**************************************************************************************************/
186
188template <std::size_t I, class T>
189using element = std::tuple_element<I, T>;
190
191/**************************************************************************************************/
192
193template <std::size_t I, class T = void>
195 auto operator()(T& x) const -> std::tuple_element_t<I, T>& {
196 return std::get<I>(x);
197 }
198
199 auto operator()(const T& x) const -> const std::tuple_element_t<I, T>& {
200 return std::get<I>(x);
201 }
202};
203
204template <std::size_t I>
205struct get_element<I, void> {
206 template <class T>
207 auto operator()(T& x) const -> std::tuple_element_t<I, T>& {
208 return std::get<I>(x);
209 }
210
211 template <class T>
212 auto operator()(const T& x) const -> const std::tuple_element_t<I, T>& {
213 return std::get<I>(x);
214 }
215};
216
217/**************************************************************************************************/
218
219template <typename T>
221 bool operator()(const T&) const { return true; }
222};
223
224/**************************************************************************************************/
225
226template <class Result>
228 typedef Result result_type;
229};
230
231/**************************************************************************************************/
232
233
234template <typename T>
236#if !defined(ADOBE_NO_DOCUMENTATION)
237 : generator_t<T>
238#endif
239{
240 explicit sequence_t(const T& x) : data_m(x) {}
241 T operator()() { return data_m++; }
242
243private:
244 T data_m;
245};
246
247/**************************************************************************************************/
248
249template <class T, typename R, class Compare>
251 compare_members_t(R T::* member, Compare compare) : compare_m(compare), member_m(member) {}
252
253 bool operator()(const T& x, const T& y) const { return compare_m(x.*member_m, y.*member_m); }
254
255 bool operator()(const T& x, const R& y) const { return compare_m(x.*member_m, y); }
256
257 bool operator()(const R& x, const T& y) const { return compare_m(x, y.*member_m); }
258
259private:
260 /*
261 REVISIT (sparent) : This could probably use an empty member optimization.
262 */
263
264 Compare compare_m;
265 R T::* member_m;
266};
267
268template <class T, typename R>
270 return compare_members_t<T, R, std::less<R>>(member, std::less<R>());
271}
272
273template <class T, typename R, class Compare>
274compare_members_t<T, R, Compare> compare_members(R T::* member, Compare compare) {
275 return compare_members_t<T, R, Compare>(member, compare);
276}
277
278/**************************************************************************************************/
279
280template <class T, typename R>
283
284 explicit mem_data_t(R T::* member) : member_m(member) {}
285
286 R& operator()(T& x) const { return x.*member_m; }
287
288 const R& operator()(const T& x) const { return x.*member_m; }
289
290private:
291 R T::* member_m;
292};
293
294template <class T, typename R>
295struct mem_data_t<const T, R> {
296 explicit mem_data_t(R T::* member) : member_m(member) {}
297
298 const R& operator()(const T& x) const { return x.*member_m; }
299
300private:
301 R T::* member_m;
302};
303
304template <class T, typename R>
306 return mem_data_t<T, R>(member);
307}
308
309/**************************************************************************************************/
310
311template <typename O> // O models StrictWeakOrdering
313public:
314 explicit equivalent(const O& x) : o_m(x) {}
315
316 bool operator()(const typename O::first_argument_type& x,
317 const typename O::second_argument_type& y) const {
318 return !o_m(x, y) && !o_m(y, x);
319 }
320
321private:
322 O o_m;
323};
324
325/**************************************************************************************************/
326
329template <class F> // F models a BinaryFunction
330struct transpose {
332
333 transpose() = default;
334 explicit transpose(F&& f) noexcept : function(std::move(f)) {}
335 explicit transpose(const F& f) : function(f) {}
336
337 transpose(const transpose& x) = default;
338 transpose(transpose&& x) noexcept = default;
339
340 transpose& operator=(const transpose& x) = default;
341 transpose& operator=(transpose&& x) noexcept = default;
342
343 template <class T1, class T2>
344 auto operator()(T1&& x, T2&& y) const& noexcept(std::is_nothrow_invocable_v<const F&, T2, T1>) {
345 return function(std::forward<T2>(y), std::forward<T1>(x));
346 }
347
348 template <class T1, class T2>
349 auto operator()(T1&& x, T2&& y) & noexcept(std::is_nothrow_invocable_v<F&, T2, T1>) {
350 return function(std::forward<T2>(y), std::forward<T1>(x));
351 }
352
353 template <class T1, class T2>
354 auto operator()(T1&& x, T2&& y) && noexcept(std::is_nothrow_invocable_v<F&&, T2, T1>) {
355 return std::move(function)(std::forward<T2>(y), std::forward<T1>(x));
356 }
357};
358
359template <class F> // F models a BinaryFunction
360using transposer [[deprecated("Use `adobe::transpose` instead.")]] = transpose<F>;
361
362
363template <typename F> // F models BinaryFunction
364inline auto f_transpose [[deprecated("Use `adobe::transpose` instead.")]] (F f) -> transpose<F> {
365 return transpose<F>(f);
366}
367
369
370/**************************************************************************************************/
371
372} // namespace adobe
373
374/**************************************************************************************************/
375
376#endif
377
378/**************************************************************************************************/
unary_compose< F, G > compose(F f, G g)
auto f_transpose(F f) -> transpose< F >
mem_data_t< T, R > mem_data(R T::*member)
std::tuple_element< I, T > element
Deprecated, use std::tuple_element instead.
compare_members_t< T, R, std::less< R > > compare_members(R T::*member)
bool operator()(const T &) const
result_type operator()(T &x, U &y) const
F::result_type result_type
result_type operator()(const T &x, const U &y) const
Utility class for adobe::compare_members.
bool operator()(const R &x, const T &y) const
bool operator()(const T &x, const T &y) const
compare_members_t(R T::*member, Compare compare)
bool operator()(const T &x, const R &y) const
equivalent(const O &x)
bool operator()(const typename O::first_argument_type &x, const typename O::second_argument_type &y) const
A function object for value generation within a domain.
auto operator()(T &x) const -> std::tuple_element_t< I, T > &
auto operator()(const T &x) const -> const std::tuple_element_t< I, T > &
auto operator()(const T &x) const -> const std::tuple_element_t< I, T > &
auto operator()(T &x) const -> std::tuple_element_t< I, T > &
const R & operator()(const T &x) const
Adaptor similar to boost::mem_fn() used by std::bind.
mem_data_t(R T::*member)
const R & operator()(const T &x) const
R & operator()(T &x) const
sequence_t(const T &x)
auto operator()(T1 &&x, T2 &&y) &noexcept(std::is_nothrow_invocable_v< F &, T2, T1 >)
transpose & operator=(transpose &&x) noexcept=default
transpose()=default
transpose(F &&f) noexcept
transpose(const F &f)
transpose & operator=(const transpose &x)=default
auto operator()(T1 &&x, T2 &&y) const &noexcept(std::is_nothrow_invocable_v< const F &, T2, T1 >)
transpose(const transpose &x)=default
transpose(transpose &&x) noexcept=default
auto operator()(T1 &&x, T2 &&y) &&noexcept(std::is_nothrow_invocable_v< F &&, T2, T1 >)
auto operator()(const U &x) const
auto operator()(U &x) const