////
Copyright 2024 Christian Mazakas
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#function_ref]
# <boost/compat/function_ref.hpp>
:idprefix: ref_function_ref_
## Description
The header `<boost/compat/function_ref.hpp>` implements the {cpp}26 class
`std::function_ref`.
`function_ref` is a lightweight polymorphic function wrapper that only stores a pointer to the supplied https://en.cppreference.com/w/cpp/named_req/Callable[Callable] object and a pointer to an unspecified function, meaning it does not participate in ownership of the Callable and does not allocate. All specializations of `function_ref` satisfy https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable[TriviallyCopyable].
`function_ref` supports every combination of `const` and `noexcept` and is useful for writing higher-order functions as
it can avoid a template parameter or an allocation (as `std::function` is known for).
## Example
```cpp
int add(int x, int y) noexcept { return x * 10 + y; }
auto add2 = [](int x, int y) { return x * 100 + y; };
std::vector<boost::compat::function_ref<int(int, int)>> fns;
fns.push_back({add});
fns.push_back({add2});
for (auto fn : fns) {
std::cout << fn(1, 2) << std::endl;
}
```
## Synopsis
```cpp
namespace boost
{
namespace compat
{
template <class... S>
struct function_ref;
// cv is either `const` or empty
// noex is either `true` or `false`
template<class R, class... ArgTypes>
class function_ref<R(ArgTypes...) cv noexcept(noex)> {
public:
template<class F> function_ref(F*) noexcept;
template<class F> function_ref(F&&) noexcept;
template<auto f> function_ref(nontype_t<f>) noexcept;
template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;
function_ref(const function_ref&) noexcept = default;
function_ref& operator=(const function_ref&) noexcept = default;
template<class T> function_ref& operator=(T) = delete;
R operator()(ArgTypes...) const noexcept(noex);
};
} // namespace compat
} // namespace boost
```
## Constructors
### Function Pointer Constructor
```cpp
template<class F> function_ref(F* fn) noexcept;
```
[horizontal]
Preconditions:: `fn` != `nullptr`.
Effects::
Constructs a `function_ref` which uses the supplied function pointer as its Callable. +
+
Calling the `function_ref` is expression-equivalent to `invoke_r<R>(f, call-args...)`.
### Object Constructor
```cpp
template<class F> function_ref(F&& fn) noexcept;
```
[horizontal]
Effects:;; Constructs a `function_ref` that stores the address of the supplied Callable object `fn`. This overload only
participates in resolution when `fn` is not a pointer-to-member or pointer-to-member-function. +
+
Calling the `function_ref` is expression-equivalent to: + `invoke_r<R>(static_cast<cv T&>(f), call-args...)`.
### Pointer to Member Function Constructor
```cpp
template<auto f> function_ref(nontype_t<f>) noexcept;
```
[horizontal]
Effects:;; Constructs a `function_ref` using the supplied pointer to member function. This overload only participates
in resolution when `f` is a pointer to member or pointer to member function. +
+
Calling the `function_ref` is express-equivalent to: `invoke_r<R>(f, class-args)`.
Example:;;
+
--
```cpp
struct point { int x = 1, y = 2; };
point p;
compat::function_ref<int(point const&)> f(compat::nontype_t<&point::x>{});
BOOST_TEST_EQ(f(p), 1);
```
--
### Bound Object Constructor
```cpp
template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
```
[horizontal]
Effects:;; Constructs a `function_ref` using the supplied pointer to member or pointer to member function and a reference
to an object to bind it to. +
+
This overload only participates in resolution if `is_rvalue_reference_v<U&&>` is false.
Example:;;
+
--
```cpp
struct point { int x = 1, y = 2; };
point p;
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, p);
BOOST_TEST_EQ(f(), 1);
```
--
### Bound Pointer Constructor
```cpp
template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;
```
[horizontal]
Effects:;; Constructs a `function_ref` using the supplied pointer to member or pointer to member function and a pointer
to an object.
Example:;;
+
--
```cpp
struct point { int x = 1, y = 2; };
point p;
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, &p);
BOOST_TEST_EQ(f(), 1);
```
--
### Copy Constructor
```cpp
function_ref(const function_ref&) noexcept = default;
```
[horizontal]
Effects:;; `function_ref` is a TriviallyCopyable type.
## Member Functions
### call operator
```cpp
R operator()(ArgTypes...) const noexcept(noex);
```
[horizontal]
Effects:;; Invokes the underlying Callable object by forwarding the supplied arguments.
## Assignment
### Copy Assignment
```cpp
function_ref& operator=(const function_ref&) noexcept = default;
template<class T> function_ref& operator=(T) = delete;
```
[horizontal]
Effects:;; `operator=(T)` participates in overload resolution if:
* `T` is not the same as `function_ref`
* `is_pointer_v<T>` is `false`.