Rocket.Chat.ReactNative/ios/Pods/boost-for-react-native/boost/hana/functional/fix.hpp

84 lines
2.8 KiB
C++

/*!
@file
Defines `boost::hana::fix`.
@copyright Louis Dionne 2013-2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_FUNCTIONAL_FIX_HPP
#define BOOST_HANA_FUNCTIONAL_FIX_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/detail/create.hpp>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN
//! @ingroup group-functional
//! Return a function computing the fixed point of a function.
//!
//! `fix` is an implementation of the [Y-combinator][], also called the
//! fixed-point combinator. It encodes the idea of recursion, and in fact
//! any recursive function can be written in terms of it.
//!
//! Specifically, `fix(f)` is a function such that
//! @code
//! fix(f)(x...) == f(fix(f), x...)
//! @endcode
//!
//! This definition allows `f` to use its first argument as a continuation
//! to call itself recursively. Indeed, if `f` calls its first argument
//! with `y...`, it is equivalent to calling `f(fix(f), y...)` per the
//! above equation.
//!
//! Most of the time, it is more convenient and efficient to define
//! recursive functions without using a fixed-point combinator. However,
//! there are some cases where `fix` provides either more flexibility
//! (e.g. the ability to change the callback inside `f`) or makes it
//! possible to write functions that couldn't be defined recursively
//! otherwise.
//!
//! @param f
//! A function called as `f(self, x...)`, where `x...` are the arguments
//! in the `fix(f)(x...)` expression and `self` is `fix(f)`.
//!
//! ### Example
//! @include example/functional/fix.cpp
//!
//! [Y-combinator]: http://en.wikipedia.org/wiki/Fixed-point_combinator
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto fix = [](auto&& f) {
return [perfect-capture](auto&& ...x) -> decltype(auto) {
return forwarded(f)(fix(f), forwarded(x)...);
};
};
#else
template <typename F>
struct fix_t;
constexpr detail::create<fix_t> fix{};
template <typename F>
struct fix_t {
F f;
template <typename ...X>
constexpr decltype(auto) operator()(X&& ...x) const&
{ return f(fix(f), static_cast<X&&>(x)...); }
template <typename ...X>
constexpr decltype(auto) operator()(X&& ...x) &
{ return f(fix(f), static_cast<X&&>(x)...); }
template <typename ...X>
constexpr decltype(auto) operator()(X&& ...x) &&
{ return std::move(f)(fix(f), static_cast<X&&>(x)...); }
};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FUNCTIONAL_FIX_HPP