Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
bind_overloads.hpp
Go to the documentation of this file.
1// parasoft-begin-suppress AUTOSAR-A2_8_1-a-2 "False positive: also defines arene::base::bind_overloads"
2
3// Copyright 2026, Toyota Motor Corporation
4//
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
7#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_FUNCTIONAL_BIND_OVERLOADS_HPP_
8#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_FUNCTIONAL_BIND_OVERLOADS_HPP_
9
10// IWYU pragma: private, include "arene/base/functional.hpp"
11// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
12
13// parasoft-begin-suppress AUTOSAR-A16_2_2-a "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
14#include "arene/base/stdlib_choice/decay.hpp"
15#include "arene/base/stdlib_choice/forward.hpp"
16#include "arene/base/stdlib_choice/is_constructible.hpp"
17#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
18#include "arene/base/stdlib_choice/is_move_constructible.hpp"
19#include "arene/base/stdlib_choice/move.hpp"
20// parasoft-end-suppress AUTOSAR-A16_2_2-a
21
22namespace arene {
23namespace base {
24
25namespace bind_overloads_detail {
26
27/// @brief Helper structure for creating an invocable that is the sum-type of N invocables.
28/// @tparam OverloadTs The set of invocables to combine.
29/// @note This has to be implemented as a recursive template because C++14 doesn't support argument pack expansion for
30/// @c using declarations.
31template <typename... OverloadTs>
32class bind_overloads_impl;
33
34/// @brief Specialization for a single invocable.
35///
36/// @tparam OverloadT The invocable to bind.
37template <typename OverloadT>
38class bind_overloads_impl<OverloadT> : OverloadT {
39 public:
40 /// @brief lvalue consuming ctor
41 /// @param overload The invocable to bind.
42 explicit bind_overloads_impl(OverloadT const& overload) noexcept(std::is_nothrow_copy_constructible<OverloadT>::value)
43 : OverloadT(overload) {}
44
45 /// @brief rvalue consuming ctor
46 /// @param overload The invocable to bind.
47 explicit bind_overloads_impl(OverloadT&& overload) noexcept(std::is_nothrow_move_constructible<OverloadT>::value)
48 : OverloadT(std::move(overload)) {}
49
50 /// @brief default destructor
51 ~bind_overloads_impl() = default;
52
53 /// @brief aliases in the underlying call operator.
54 using OverloadT::operator();
55
56 protected:
57 /// @brief default copy ctor
58 constexpr bind_overloads_impl(bind_overloads_impl const& copy) = default;
59 /// @brief default move ctor
60 constexpr bind_overloads_impl(bind_overloads_impl&& move) = default;
61 /// @brief default copy assignment operator
62 constexpr auto operator=(bind_overloads_impl const& copy) -> bind_overloads_impl& = default;
63 /// @brief default move assignment operator
64 constexpr auto operator=(bind_overloads_impl&& move) -> bind_overloads_impl& = default;
65};
66
67/// @brief Specialization for more than one invocable.
68///
69/// @tparam OverloadT The invocable to bind.
70/// @tparam OverloadTs The remaining invocables to bind.
71// parasoft-begin-suppress AUTOSAR-A10_1_1-a "Multiple base classes needed to implement semantics."
72template <typename OverloadT, typename... OverloadTs>
73class bind_overloads_impl<OverloadT, OverloadTs...>
74 : OverloadT
75 , bind_overloads_impl<OverloadTs...> {
76 public:
77 /// @brief copy ctor for current invocable.
78 /// @tparam UOverloads The types of the remaining invocables to bind.
79 /// @param overload The invocable to bind.
80 /// @param overloads The remaining invocables to bind.
81 template <typename... UOverloads>
82 constexpr explicit bind_overloads_impl(OverloadT const& overload, UOverloads&&... overloads) noexcept(
83 std::is_nothrow_copy_constructible<OverloadT>::value &&
84 std::is_nothrow_constructible<bind_overloads_impl<OverloadTs...>, UOverloads&&...>::value
85 )
86 : OverloadT(overload),
87 bind_overloads_impl<OverloadTs...>(std::forward<UOverloads>(overloads)...) {}
88
89 /// @brief move ctor for current invocable.
90 /// @tparam UOverloadTs The types of the remaining invocables to bind.
91 /// @param overload The invocable to bind.
92 /// @param overloads The remaining invocables to bind.
93 template <typename... UOverloadTs>
94 constexpr explicit bind_overloads_impl(OverloadT&& overload, UOverloadTs&&... overloads) noexcept(
95 std::is_nothrow_move_constructible<OverloadT>::value &&
96 std::is_nothrow_constructible<bind_overloads_impl<OverloadTs...>, UOverloadTs&&...>::value
97 )
98 : OverloadT(std::move(overload)),
99 bind_overloads_impl<OverloadTs...>(std::forward<UOverloadTs>(overloads)...) {}
100
101 /// @brief default destructor
102 ~bind_overloads_impl() = default;
103
104 /// @brief aliases in the underlying call operator.
105 using OverloadT::operator();
106 /// @brief aliases in the other underlying call operators.
107 using bind_overloads_impl<OverloadTs...>::operator();
108
109 protected:
110 /// @brief default copy ctor
111 constexpr bind_overloads_impl(bind_overloads_impl const& copy) = default;
112 /// @brief default move ctor
113 constexpr bind_overloads_impl(bind_overloads_impl&& move) = default;
114 /// @brief default copy assignment operator
115 constexpr auto operator=(bind_overloads_impl const& copy) -> bind_overloads_impl& = default;
116 /// @brief default move assignment operator
117 constexpr auto operator=(bind_overloads_impl&& move) -> bind_overloads_impl& = default;
118};
119// parasoft-begin-suppress AUTOSAR-A10_1_1-a "Multiple base classes needed to implement semantics."
120
121/// @brief A type which is the sum-type of all the input invocables.
122/// This indirection is needed to satisfy CppTestPro static analysis around slicing constructors while keeping a
123/// recursive template copyable/movable as they don't consider the visibility of inheritance of the base class.
124template <typename... OverloadTs>
125class bind_overloads_t : bind_overloads_impl<OverloadTs...> {
126 public:
127 /// @brief alias in underlying constructors.
128 using bind_overloads_impl<OverloadTs...>::bind_overloads_impl;
129 /// @brief alias in underlying call operator.
130 using bind_overloads_impl<OverloadTs...>::operator();
131};
132
133} // namespace bind_overloads_detail
134
135///
136/// @brief Given a sequence of invocables, creates a type which is the sum-type of all the input invocables.
137///
138/// Typically, @c bind_overloads is used to produce a variant-visitor inline from a sequence of lambdas, like so:
139///
140/// \snippet docs/examples/subpackages/variant_examples.cpp bind_overloads_usage
141///
142/// @tparam OverloadsT The types of the invocables to combine.
143/// @param overloads The invocables to combine. They will be perfect-forwarded into the resulting object.
144/// @return An implementation-defined type which is the summation of the input callables and can be invoked as if it
145/// were any of them.
146///
147// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive, this is not a member function and thus cannot be static."
148template <typename... OverloadsT>
156// parasoft-end-suppress AUTOSAR-M3_3_2-a "False positive, this is not a member function and thus cannot be static."
157
158} // namespace base
159} // namespace arene
160
161#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_FUNCTIONAL_BIND_OVERLOADS_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10