/// \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_INDIRECT_HPP #define RANGES_V3_FUNCTIONAL_INDIRECT_HPP #include #include #include #include #include #include namespace ranges { /// \addtogroup group-functional /// @{ template struct indirected { private: RANGES_NO_UNIQUE_ADDRESS Fn fn_; public: indirected() = default; indirected(Fn fn) : fn_(std::move(fn)) {} // value_type (needs no impl) template [[noreturn]] auto operator()(copy_tag, Its...) const -> invoke_result_t...> { RANGES_EXPECT(false); } // Reference // clang-format off template auto CPP_auto_fun(operator())(Its... its) ( return invoke(fn_, *its...) ) template auto CPP_auto_fun(operator())(Its... its)(const) ( return invoke((Fn const &)fn_, *its...) ) // Rvalue reference template auto CPP_auto_fun(operator())(move_tag, Its... its) ( return static_cast< aux::move_t...>>>( aux::move(invoke(fn_, *its...))) ) template auto CPP_auto_fun(operator())(move_tag, Its... its)(const) ( return static_cast< aux::move_t...>>>( aux::move(invoke((Fn const &)fn_, *its...))) ) // clang-format on }; struct indirect_fn { template constexpr indirected operator()(Fn fn) const { return indirected{detail::move(fn)}; } }; /// \ingroup group-functional /// \sa `indirect_fn` RANGES_INLINE_VARIABLE(indirect_fn, indirect) /// @} } // namespace ranges #endif