123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- // 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 <boost/stl_interfaces/detail/pipeable_view.hpp>
- #include <utility>
- namespace boost { namespace stl_interfaces { namespace detail {
- template<std::size_t I, typename T>
- struct box
- {
- T value_;
- };
- template<typename Indices, typename Func, typename... T>
- struct view_closure_impl;
- template<std::size_t... I, typename Func, typename... T>
- struct view_closure_impl<std::index_sequence<I...>, Func, T...>
- : box<I, T>...
- {
- view_closure_impl() = default;
- constexpr explicit view_closure_impl(Func, T &&... x) :
- box<I, T>{std::move(x)}...
- {}
- #if BOOST_STL_INTERFACES_USE_CONCEPTS
- template<std::ranges::input_range R>
- requires std::ranges::viewable_range<R> &&
- std::invocable<Func, R, T &...> &&
- std::ranges::view<std::invoke_result_t<Func, R, T &...>>
- constexpr auto operator()(R && r) &
- #else
- template<typename R>
- constexpr auto operator()(R && r) & -> decltype(
- Func{}((R &&) r, std::declval<box<I, T> &>().value_...))
- #endif
- {
- return Func{}((R &&) r, static_cast<box<I, T> &>(*this).value_...);
- }
- #if BOOST_STL_INTERFACES_USE_CONCEPTS
- template<std::ranges::input_range R>
- requires std::ranges::viewable_range<R> &&
- std::invocable<Func, R, T const &...> &&
- std::ranges::view<std::invoke_result_t<Func, R, T const &...>>
- constexpr auto operator()(R && r) const &
- #else
- template<typename R>
- constexpr auto operator()(R && r) const & -> decltype(
- Func{}((R &&) r, std::declval<box<I, T> const &>().value_...))
- #endif
- {
- return Func{}(
- (R &&) r, static_cast<box<I, T> const &>(*this).value_...);
- }
- #if BOOST_STL_INTERFACES_USE_CONCEPTS
- template<std::ranges::input_range R>
- requires std::ranges::viewable_range<R> &&
- std::invocable<Func, R, T...> &&
- std::ranges::view<std::invoke_result_t<Func, R, T...>>
- constexpr auto operator()(R && r) &&
- #else
- template<typename R>
- constexpr auto operator()(R && r) && -> decltype(
- Func{}((R &&) r, std::declval<box<I, T> &&>().value_...))
- #endif
- {
- return Func{}((R &&) r, static_cast<box<I, T> &&>(*this).value_...);
- }
- };
- #if BOOST_STL_INTERFACES_USE_CONCEPTS
- template<std::semiregular Func, std::copy_constructible... T>
- #else
- template<typename Func, typename... T>
- #endif
- struct view_closure
- : pipeable<view_closure<Func, T...>>,
- view_closure_impl<std::index_sequence_for<T...>, Func, T...>
- {
- using base_type =
- view_closure_impl<std::index_sequence_for<T...>, 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<typename Func, typename... T>
- view_closure(Func, T...) -> view_closure<Func, T...>;
- #endif
- }}}
- #endif
|