/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_FUNCTIONAL_BIND_HPP #define RANGES_V3_FUNCTIONAL_BIND_HPP #include #include #include #include #include #include namespace ranges { /// \addtogroup group-functional /// @{ template, std::reference_wrapper>>, T &&>> U bind_forward(meta::_t> & t) noexcept { return static_cast(t); } template T && bind_forward(meta::_t> && t) noexcept { // This is to catch way sketchy stuff like: forward(42) static_assert(!std::is_lvalue_reference::value, "You didn't just do that!"); return static_cast(t); } template struct bind_element : meta::if_c, T), meta::id, bind_element>> {}; template struct bind_element> { using type = T &; }; template struct bind_element> { using type = typename reference_wrapper::reference; }; template using bind_element_t = meta::_t>; template struct protector { private: Bind bind_; public: protector() = default; protector(Bind b) : bind_(std::move(b)) {} // clang-format off template auto CPP_auto_fun(operator())(Ts &&...ts) ( return bind_(static_cast(ts)...) ) /// \overload template auto CPP_auto_fun(operator())(Ts &&...ts) (const) ( return bind_(static_cast(ts)...) ) // clang-format on }; struct protect_fn { template auto operator()(F && f) const -> CPP_ret(protector>)( // requires std::is_bind_expression>::value) { return {static_cast(f)}; } /// \overload template auto operator()(F && f) const -> CPP_ret(F)( // requires(!std::is_bind_expression>::value)) { return static_cast(f); } }; /// Protect a callable so that it can be safely used in a bind expression without /// accidentally becoming a "nested" bind. /// \ingroup group-functional /// \sa `protect_fn` RANGES_INLINE_VARIABLE(protect_fn, protect) /// @} } // namespace ranges #endif