alpaqa develop
Nonconvex constrained optimization
Loading...
Searching...
No Matches
tag-invoke.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4#include <utility>
5
6/// @file
7/// @see https://wg21.link/P1895R0
8/// @see https://wg21.link/P2547R0
9
10namespace alpaqa {
11
12namespace tag_invoke_fn_ns {
13
14/// Poison pill to hide overloads of foo() that might be found in parent
15/// namespace.
16/// We want to limit to only finding overloads by ADL.
17#if defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 12 && !defined(__clang__))
18void alpaqa_tag_invoke() /* = delete */;
19#else
20void alpaqa_tag_invoke() = delete;
21#endif
22
24 template <typename Tag, typename... Args>
25 requires requires(Tag tag, Args &&...args) {
26 alpaqa_tag_invoke(std::move(tag), std::forward<Args>(args)...);
27 }
28 constexpr auto operator()(Tag tag, Args &&...args) const
29 noexcept(noexcept(alpaqa_tag_invoke(std::move(tag),
30 std::forward<Args>(args)...)))
31 -> decltype(alpaqa_tag_invoke(std::move(tag),
32 std::forward<Args>(args)...)) {
33 return alpaqa_tag_invoke(std::move(tag), std::forward<Args>(args)...);
34 }
35};
36} // namespace tag_invoke_fn_ns
37
38// Function object needs to be in a separate namespace to avoid conflicts with
39// hidden-friend customizations defined for types in the alpaqa namespace.
40inline namespace tag_invoke_ns {
42}
43
44template <typename Tag, typename... Args>
45concept tag_invocable = requires(Tag tag, Args... args) {
46 alpaqa_tag_invoke(std::forward<Tag>(tag), std::forward<Args>(args)...);
47};
48
49template <typename Tag, typename... Args>
51 tag_invocable<Tag, Args...> && requires(Tag tag, Args... args) {
52 {
53 alpaqa_tag_invoke(std::forward<Tag>(tag),
54 std::forward<Args>(args)...)
55 } noexcept;
56 };
57
58template <typename Tag, typename... Args>
59inline constexpr bool is_tag_invocable_v = tag_invocable<Tag, Args...>;
60
61template <typename Tag, typename... Args>
62inline constexpr bool is_nothrow_tag_invocable_v =
64
65template <typename Tag, typename... Args>
67 std::invoke_result<decltype(::alpaqa::alpaqa_tag_invoke), Tag, Args...>;
68
69template <typename Tag, typename... Args>
71 std::invoke_result_t<decltype(::alpaqa::alpaqa_tag_invoke), Tag, Args...>;
72
73template <auto &Tag>
74using tag_t = std::decay_t<decltype(Tag)>;
75
76} // namespace alpaqa
void alpaqa_tag_invoke()=delete
Poison pill to hide overloads of foo() that might be found in parent namespace.
constexpr tag_invoke_fn_ns::tag_invoke_fn alpaqa_tag_invoke
std::decay_t< decltype(Tag)> tag_t
std::invoke_result_t< decltype(::alpaqa::alpaqa_tag_invoke), Tag, Args... > tag_invoke_result_t
constexpr bool is_tag_invocable_v
constexpr const auto inf
Definition config.hpp:112
constexpr bool is_nothrow_tag_invocable_v
std::invoke_result< decltype(::alpaqa::alpaqa_tag_invoke), Tag, Args... > tag_invoke_result
constexpr auto operator()(Tag tag, Args &&...args) const noexcept(noexcept(alpaqa_tag_invoke(std::move(tag), std::forward< Args >(args)...))) -> decltype(alpaqa_tag_invoke(std::move(tag), std::forward< Args >(args)...))