tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
reference_wrapper.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_FUNCTIONAL_REFERENCE_WRAPPER_HPP
5#define TETL_FUNCTIONAL_REFERENCE_WRAPPER_HPP
6
7#include <etl/_functional/invoke.hpp>
8#include <etl/_memory/addressof.hpp>
9#include <etl/_type_traits/declval.hpp>
10#include <etl/_type_traits/enable_if.hpp>
11#include <etl/_type_traits/invoke_result.hpp>
12#include <etl/_type_traits/is_same.hpp>
13#include <etl/_type_traits/remove_cvref.hpp>
14#include <etl/_utility/forward.hpp>
15
16namespace etl {
17
18namespace detail {
19template <typename T>
20constexpr auto FUN(T& t) noexcept -> T&
21{
22 return t; // NOLINT(bugprone-return-const-ref-from-parameter)
23}
24
25template <typename T>
26void FUN(T&&) = delete;
27
28} // namespace detail
29
30/// \brief reference_wrapper is a class template that wraps a reference in a
31/// copyable, assignable object. It is frequently used as a mechanism to store
32/// references inside standard containers (like etl::static_vector) which cannot
33/// normally hold references. Specifically, reference_wrapper is a
34/// CopyConstructible and CopyAssignable wrapper around a reference to object or
35/// reference to function of type T. Instances of reference_wrapper are objects
36/// (they can be copied or stored in containers) but they are implicitly
37/// convertible to T&, so that they can be used as arguments with the functions
38/// that take the underlying type by reference. If the stored reference is
39/// Callable, reference_wrapper is callable with the same arguments.
40template <typename T>
42 using type = T;
43
44 /// \brief Constructs a new reference wrapper. Converts x to T& as if by T&
45 /// t = etl::forward(x);, then stores a reference to t. This overload only
46 /// participates in overload resolution if `decay_t<U>` is not the same type
47 /// as reference_wrapper and the expression `FUN(declval<U>())` is
48 /// well-formed, where FUN names the set of imaginary functions:
49 ///
50 /// \code
51 /// void FUN(T&) noexcept;
52 /// void FUN(T&&) = delete;
53 /// \endcode
54 ///
55 /// https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper
56 template <
57 typename U,
58 typename
59 = decltype(detail::FUN<T>(declval<U>()), enable_if_t<!is_same_v<reference_wrapper, remove_cvref_t<U>>>())
60 >
61 constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(etl::forward<U>(u))))
62 : _ptr(addressof(detail::FUN<T>(etl::forward<U>(u))))
63 {
64 }
65
66 /// \brief Constructs a new reference wrapper. Copy constructor. Stores a
67 /// reference to other.get().
68 constexpr reference_wrapper(reference_wrapper const& x) noexcept = default;
69
70 /// \brief Copy assignment operator. Drops the current reference and stores
71 /// a reference to other.get().
72 constexpr auto operator=(reference_wrapper const& x) noexcept -> reference_wrapper& = default;
73
74 /// \brief Returns the stored reference.
75 [[nodiscard]] constexpr operator type&() const noexcept
76 {
77 return *_ptr;
78 }
79
80 /// \brief Returns the stored reference.
81 [[nodiscard]] constexpr auto get() const noexcept -> type&
82 {
83 return *_ptr;
84 }
85
86 /// \brief Calls the Callable object, reference to which is stored. This
87 /// function is available only if the stored reference points to a Callable
88 /// object. T must be a complete type.
89 ///
90 /// \returns The return value of the called function.
91 template <typename... Args>
92 constexpr auto operator()(Args&&... args) const noexcept(noexcept(invoke(get(), etl::forward<Args>(args)...)))
93 -> invoke_result_t<T&, Args...>
94 {
95 return invoke(get(), etl::forward<Args>(args)...);
96 }
97
98private:
99 type* _ptr;
100};
101
102// One deduction guide is provided for reference_wrapper to support
103// deduction of the sole class template parameter.
104template <typename T>
106
107/// \brief Function templates ref and cref are helper functions that generate an
108/// object of type reference_wrapper, using template argument deduction to
109/// determine the template argument of the result.
110template <typename T>
111[[nodiscard]] constexpr auto ref(T& t) noexcept -> reference_wrapper<T>
112{
113 return reference_wrapper<T>(t);
114}
115
116/// \brief Function templates ref and cref are helper functions that generate an
117/// object of type reference_wrapper, using template argument deduction to
118/// determine the template argument of the result.
119template <typename T>
120[[nodiscard]] constexpr auto ref(reference_wrapper<T> t) noexcept -> reference_wrapper<T>
121{
122 return ref(t.get());
123}
124
125/// \brief Function templates ref and cref are helper functions that generate an
126/// object of type reference_wrapper, using template argument deduction to
127/// determine the template argument of the result.
128/// module Utility
129template <typename T>
130[[nodiscard]] constexpr auto cref(T const& t) noexcept -> reference_wrapper<T const>
131{
132 return reference_wrapper<T const>(t);
133}
134
135template <typename T>
136[[nodiscard]] constexpr auto cref(reference_wrapper<T> t) noexcept -> reference_wrapper<T const>
137{
138 return cref(t.get());
139}
140
141template <typename T>
142void cref(T const&&) = delete;
143
144} // namespace etl
145
146#endif // TETL_FUNCTIONAL_REFERENCE_WRAPPER_HPP
Definition adjacent_find.hpp:9
constexpr auto cref(T const &t) noexcept -> reference_wrapper< T const >
Function templates ref and cref are helper functions that generate an object of type reference_wrappe...
Definition reference_wrapper.hpp:130
constexpr auto ref(T &t) noexcept -> reference_wrapper< T >
Function templates ref and cref are helper functions that generate an object of type reference_wrappe...
Definition reference_wrapper.hpp:111
reference_wrapper(T &) -> reference_wrapper< T >
constexpr auto cref(reference_wrapper< T > t) noexcept -> reference_wrapper< T const >
Definition reference_wrapper.hpp:136
constexpr auto ref(reference_wrapper< T > t) noexcept -> reference_wrapper< T >
Function templates ref and cref are helper functions that generate an object of type reference_wrappe...
Definition reference_wrapper.hpp:120
void cref(T const &&)=delete
reference_wrapper is a class template that wraps a reference in a copyable, assignable object....
Definition reference_wrapper.hpp:41
constexpr auto operator=(reference_wrapper const &x) noexcept -> reference_wrapper &=default
Copy assignment operator. Drops the current reference and stores a reference to other....
constexpr reference_wrapper(reference_wrapper const &x) noexcept=default
Constructs a new reference wrapper. Copy constructor. Stores a reference to other....
constexpr operator type &() const noexcept
Returns the stored reference.
Definition reference_wrapper.hpp:75
constexpr reference_wrapper(U &&u) noexcept(noexcept(detail::FUN< T >(etl::forward< U >(u))))
Constructs a new reference wrapper. Converts x to T& as if by T& t = etl::forward(x);,...
Definition reference_wrapper.hpp:61
constexpr auto get() const noexcept -> type &
Returns the stored reference.
Definition reference_wrapper.hpp:81
constexpr auto operator()(Args &&... args) const noexcept(noexcept(invoke(get(), etl::forward< Args >(args)...))) -> invoke_result_t< T &, Args... >
Calls the Callable object, reference to which is stored. This function is available only if the store...
Definition reference_wrapper.hpp:92