// Copyright (C) 2022 T. Zachary Laine // // Distributed under 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) #ifndef BOOST_STL_INTERFACES_DETAIL_VIEW_CLOSURE_HPP #define BOOST_STL_INTERFACES_DETAIL_VIEW_CLOSURE_HPP #include #include namespace boost { namespace stl_interfaces { namespace detail { template struct box { T value_; }; template struct view_closure_impl; template struct view_closure_impl, Func, T...> : box... { view_closure_impl() = default; constexpr explicit view_closure_impl(Func, T &&... x) : box{std::move(x)}... {} #if BOOST_STL_INTERFACES_USE_CONCEPTS template requires std::ranges::viewable_range && std::invocable && std::ranges::view> constexpr auto operator()(R && r) & #else template constexpr auto operator()(R && r) & -> decltype( Func{}((R &&) r, std::declval &>().value_...)) #endif { return Func{}((R &&) r, static_cast &>(*this).value_...); } #if BOOST_STL_INTERFACES_USE_CONCEPTS template requires std::ranges::viewable_range && std::invocable && std::ranges::view> constexpr auto operator()(R && r) const & #else template constexpr auto operator()(R && r) const & -> decltype( Func{}((R &&) r, std::declval const &>().value_...)) #endif { return Func{}( (R &&) r, static_cast const &>(*this).value_...); } #if BOOST_STL_INTERFACES_USE_CONCEPTS template requires std::ranges::viewable_range && std::invocable && std::ranges::view> constexpr auto operator()(R && r) && #else template constexpr auto operator()(R && r) && -> decltype( Func{}((R &&) r, std::declval &&>().value_...)) #endif { return Func{}((R &&) r, static_cast &&>(*this).value_...); } }; #if BOOST_STL_INTERFACES_USE_CONCEPTS template #else template #endif struct view_closure : pipeable>, view_closure_impl, Func, T...> { using base_type = view_closure_impl, Func, T...>; view_closure() = default; constexpr explicit view_closure(Func func, T &&... x) : base_type{func, std::move(x)...} {} }; #if defined(__cpp_deduction_guides) template view_closure(Func, T...) -> view_closure; #endif }}} #endif