30 #ifndef BPSTD_FUNCTIONAL_HPP
31 #define BPSTD_FUNCTIONAL_HPP
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
37 #include "detail/config.hpp"
40 #include "detail/invoke.hpp"
44 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
54 template <
typename Func,
typename... Args>
55 constexpr invoke_result_t<Func,Args...>
invoke(Func&&
function, Args&&... args)
56 noexcept(is_nothrow_invocable<Func,Args...>::value);
59 template <
typename Fn>
64 template <
typename...Args>
65 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
66 auto operator()(Args&&... args) &
67 noexcept(noexcept(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...)))
68 -> decltype(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...))
70 return !::bpstd::invoke(fn, bpstd::forward<Args>(args)...);
73 template <
typename...Args>
74 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
75 auto operator()(Args&&... args) &&
76 noexcept(noexcept(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...)))
77 -> decltype(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...))
79 return !::bpstd::invoke(std::move(fn), bpstd::forward<Args>(args)...);
82 template <
typename...Args>
83 inline BPSTD_INLINE_VISIBILITY constexpr
84 auto operator()(Args&&... args)
const&
85 noexcept(noexcept(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...)))
86 -> decltype(!::bpstd::invoke(fn, ::bpstd::forward<Args>(args)...))
88 return !::bpstd::invoke(fn, bpstd::forward<Args>(args)...);
91 template <
typename...Args>
92 inline BPSTD_INLINE_VISIBILITY constexpr
93 auto operator()(Args&&... args)
const&&
94 noexcept(noexcept(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...)))
95 -> decltype(!::bpstd::invoke(std::move(fn), ::bpstd::forward<Args>(args)...))
97 return !::bpstd::invoke(std::move(fn), bpstd::forward<Args>(args)...);
108 template <
typename Fn>
109 constexpr detail::not_fn_t<decay_t<Fn>>
not_fn(Fn&& fn);
115 template <
typename T =
void>
118 inline BPSTD_INLINE_VISIBILITY constexpr
119 T operator()(
const T& lhs,
const T& rhs)
129 using is_transparent = true_type;
131 template <
typename T,
typename U>
132 inline BPSTD_INLINE_VISIBILITY constexpr
133 auto operator()(T&& lhs, U&& rhs)
const
134 -> decltype(::bpstd::forward<T>(lhs) + ::bpstd::forward<U>(rhs))
136 return bpstd::forward<T>(lhs) + bpstd::forward<U>(rhs);
144 template <
typename T =
void>
147 inline BPSTD_INLINE_VISIBILITY constexpr
148 T operator()(
const T& lhs,
const T& rhs)
158 using is_transparent = true_type;
160 template <
typename T,
typename U>
161 inline BPSTD_INLINE_VISIBILITY constexpr
162 auto operator()(T&& lhs, U&& rhs)
const
163 -> decltype(::bpstd::forward<T>(lhs) - ::bpstd::forward<U>(rhs))
165 return bpstd::forward<T>(lhs) - bpstd::forward<U>(rhs);
173 template <
typename T =
void>
176 inline BPSTD_INLINE_VISIBILITY constexpr
177 T operator()(
const T& lhs,
const T& rhs)
187 using is_transparent = true_type;
189 template <
typename T,
typename U>
190 inline BPSTD_INLINE_VISIBILITY constexpr
191 auto operator()(T&& lhs, U&& rhs)
const
192 -> decltype(::bpstd::forward<T>(lhs) * ::bpstd::forward<U>(rhs))
194 return bpstd::forward<T>(lhs) * bpstd::forward<U>(rhs);
202 template <
typename T =
void>
205 inline BPSTD_INLINE_VISIBILITY constexpr
206 T operator()(
const T& lhs,
const T& rhs)
216 using is_transparent = true_type;
218 template <
typename T,
typename U>
219 inline BPSTD_INLINE_VISIBILITY constexpr
220 auto operator()(T&& lhs, U&& rhs)
const
221 -> decltype(::bpstd::forward<T>(lhs) / ::bpstd::forward<U>(rhs))
223 return bpstd::forward<T>(lhs) / bpstd::forward<U>(rhs);
231 template <
typename T =
void>
234 inline BPSTD_INLINE_VISIBILITY constexpr
235 T operator()(
const T& lhs,
const T& rhs)
245 using is_transparent = true_type;
247 template <
typename T,
typename U>
248 inline BPSTD_INLINE_VISIBILITY constexpr
249 auto operator()(T&& lhs, U&& rhs)
const
250 -> decltype(::bpstd::forward<T>(lhs) % ::bpstd::forward<U>(rhs))
252 return bpstd::forward<T>(lhs) % bpstd::forward<U>(rhs);
260 template <
typename T =
void>
263 inline BPSTD_INLINE_VISIBILITY constexpr
264 T operator()(
const T& arg)
274 using is_transparent = true_type;
276 template <
typename T>
277 inline BPSTD_INLINE_VISIBILITY constexpr
278 auto operator()(T&& arg)
const
279 -> decltype(-::bpstd::forward<T>(arg))
281 return -bpstd::forward<T>(arg);
289 template <
typename T =
void>
292 inline BPSTD_INLINE_VISIBILITY constexpr
293 bool operator()(
const T& lhs,
const T& rhs)
303 using is_transparent = true_type;
305 template <
typename T,
typename U>
306 inline BPSTD_INLINE_VISIBILITY constexpr
307 auto operator()(T&& lhs, U&& rhs)
const
308 -> decltype(::bpstd::forward<T>(lhs) == ::bpstd::forward<U>(rhs))
310 return bpstd::forward<T>(lhs) == bpstd::forward<U>(rhs);
318 template <
typename T =
void>
321 inline BPSTD_INLINE_VISIBILITY constexpr
322 bool operator()(
const T& lhs,
const T& rhs)
332 using is_transparent = true_type;
334 template <
typename T,
typename U>
335 inline BPSTD_INLINE_VISIBILITY constexpr
336 auto operator()(T&& lhs, U&& rhs)
const
337 -> decltype(::bpstd::forward<T>(lhs) != ::bpstd::forward<U>(rhs))
339 return bpstd::forward<T>(lhs) != bpstd::forward<U>(rhs);
347 template <
typename T =
void>
350 inline BPSTD_INLINE_VISIBILITY constexpr
351 bool operator()(
const T& lhs,
const T& rhs)
361 using is_transparent = true_type;
363 template <
typename T,
typename U>
364 inline BPSTD_INLINE_VISIBILITY constexpr
365 auto operator()(T&& lhs, U&& rhs)
const
366 -> decltype(::bpstd::forward<T>(lhs) > ::bpstd::forward<U>(rhs))
368 return bpstd::forward<T>(lhs) > bpstd::forward<U>(rhs);
376 template <
typename T =
void>
379 inline BPSTD_INLINE_VISIBILITY constexpr
380 bool operator()(
const T& lhs,
const T& rhs)
390 using is_transparent = true_type;
392 template <
typename T,
typename U>
393 inline BPSTD_INLINE_VISIBILITY constexpr
394 auto operator()(T&& lhs, U&& rhs)
const
395 -> decltype(::bpstd::forward<T>(lhs) >= ::bpstd::forward<U>(rhs))
397 return bpstd::forward<T>(lhs) >= bpstd::forward<U>(rhs);
405 template <
typename T =
void>
408 inline BPSTD_INLINE_VISIBILITY constexpr
409 bool operator()(
const T& lhs,
const T& rhs)
419 using is_transparent = true_type;
421 template <
typename T,
typename U>
422 inline BPSTD_INLINE_VISIBILITY constexpr
423 auto operator()(T&& lhs, U&& rhs)
const
424 -> decltype(::bpstd::forward<T>(lhs) < ::bpstd::forward<U>(rhs))
426 return bpstd::forward<T>(lhs) < bpstd::forward<U>(rhs);
434 template <
typename T =
void>
437 inline BPSTD_INLINE_VISIBILITY constexpr
438 bool operator()(
const T& lhs,
const T& rhs)
448 using is_transparent = true_type;
450 template <
typename T,
typename U>
451 inline BPSTD_INLINE_VISIBILITY constexpr
452 auto operator()(T&& lhs, U&& rhs)
const
453 -> decltype(::bpstd::forward<T>(lhs) <= ::bpstd::forward<U>(rhs))
455 return bpstd::forward<T>(lhs) <= bpstd::forward<U>(rhs);
463 template <
typename T =
void>
466 inline BPSTD_INLINE_VISIBILITY constexpr
467 bool operator()(
const T& lhs,
const T& rhs)
477 using is_transparent = true_type;
479 template <
typename T,
typename U>
480 inline BPSTD_INLINE_VISIBILITY constexpr
481 auto operator()(T&& lhs, U&& rhs)
const
482 -> decltype(::bpstd::forward<T>(lhs) && ::bpstd::forward<U>(rhs))
484 return bpstd::forward<T>(lhs) && bpstd::forward<U>(rhs);
492 template <
typename T =
void>
495 inline BPSTD_INLINE_VISIBILITY constexpr
496 bool operator()(
const T& lhs,
const T& rhs)
506 using is_transparent = true_type;
508 template <
typename T,
typename U>
509 inline BPSTD_INLINE_VISIBILITY constexpr
510 auto operator()(T&& lhs, U&& rhs)
const
511 -> decltype(::bpstd::forward<T>(lhs) || ::bpstd::forward<U>(rhs))
513 return bpstd::forward<T>(lhs) || bpstd::forward<U>(rhs);
521 template <
typename T =
void>
524 inline BPSTD_INLINE_VISIBILITY constexpr
525 bool operator()(
const T& arg)
535 using is_transparent = true_type;
537 template <
typename T>
538 inline BPSTD_INLINE_VISIBILITY constexpr
539 auto operator()(T&& arg)
const
540 -> decltype(!::bpstd::forward<T>(arg))
542 return !bpstd::forward<T>(arg);
550 template <
typename T =
void>
553 inline BPSTD_INLINE_VISIBILITY constexpr
554 T operator()(
const T& lhs,
const T& rhs)
564 using is_transparent = true_type;
566 template <
typename T,
typename U>
567 inline BPSTD_INLINE_VISIBILITY constexpr
568 auto operator()(T&& lhs, U&& rhs)
const
569 -> decltype(::bpstd::forward<T>(lhs) & ::bpstd::forward<U>(rhs))
571 return bpstd::forward<T>(lhs) & bpstd::forward<U>(rhs);
579 template <
typename T =
void>
582 inline BPSTD_INLINE_VISIBILITY constexpr
583 T operator()(
const T& lhs,
const T& rhs)
593 using is_transparent = true_type;
595 template <
typename T,
typename U>
596 inline BPSTD_INLINE_VISIBILITY constexpr
597 auto operator()(T&& lhs, U&& rhs)
const
598 -> decltype(::bpstd::forward<T>(lhs) | ::bpstd::forward<U>(rhs))
600 return bpstd::forward<T>(lhs) | bpstd::forward<U>(rhs);
608 template <
typename T =
void>
611 inline BPSTD_INLINE_VISIBILITY constexpr
612 T operator()(
const T& lhs,
const T& rhs)
622 using is_transparent = true_type;
624 template <
typename T,
typename U>
625 inline BPSTD_INLINE_VISIBILITY constexpr
626 auto operator()(T&& lhs, U&& rhs)
const
627 -> decltype(::bpstd::forward<T>(lhs) ^ ::bpstd::forward<U>(rhs))
629 return bpstd::forward<T>(lhs) ^ bpstd::forward<U>(rhs);
637 template <
typename T =
void>
640 inline BPSTD_INLINE_VISIBILITY constexpr
641 T operator()(
const T& arg)
651 using is_transparent = true_type;
653 template <
typename T>
654 inline BPSTD_INLINE_VISIBILITY constexpr
655 auto operator()(T&& arg)
const
656 -> decltype(~::bpstd::forward<T>(arg))
658 return ~bpstd::forward<T>(arg);
668 template <
typename Func,
typename... Args>
669 inline BPSTD_INLINE_VISIBILITY constexpr
670 bpstd::invoke_result_t<Func,Args...> bpstd::invoke(Func&&
function, Args&&... args)
671 noexcept(is_nothrow_invocable<Func,Args...>::value)
673 return detail::INVOKE(bpstd::forward<Func>(
function), bpstd::forward<Args>(args)...);
681 template <
typename Fn>
682 inline BPSTD_INLINE_VISIBILITY constexpr
683 bpstd::detail::not_fn_t<bpstd::decay_t<Fn>>
bpstd::not_fn(Fn&& fn)
686 is_move_constructible<Fn>::value,
687 "Fn must be move constructible"
690 is_constructible<decay_t<Fn>,Fn>::value,
691 "Fn must be constructible from an instance of fn"
694 return { bpstd::forward<Fn>(fn) };
697 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE