Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:34

0001 // Copyright (C) 2022 T. Zachary Laine
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 #ifndef BOOST_STL_INTERFACES_DETAIL_VIEW_CLOSURE_HPP
0007 #define BOOST_STL_INTERFACES_DETAIL_VIEW_CLOSURE_HPP
0008 
0009 #include <boost/stl_interfaces/detail/pipeable_view.hpp>
0010 
0011 #include <utility>
0012 
0013 
0014 namespace boost { namespace stl_interfaces { namespace detail {
0015 
0016     template<std::size_t I, typename T>
0017     struct box
0018     {
0019         T value_;
0020     };
0021 
0022     template<typename Indices, typename Func, typename... T>
0023     struct view_closure_impl;
0024 
0025     template<std::size_t... I, typename Func, typename... T>
0026     struct view_closure_impl<std::index_sequence<I...>, Func, T...>
0027         : box<I, T>...
0028     {
0029         view_closure_impl() = default;
0030         constexpr explicit view_closure_impl(Func, T &&... x) :
0031             box<I, T>{std::move(x)}...
0032         {}
0033 
0034 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0035         template<std::ranges::input_range R>
0036         requires std::ranges::viewable_range<R> &&
0037             std::invocable<Func, R, T &...> &&
0038             std::ranges::view<std::invoke_result_t<Func, R, T &...>>
0039         constexpr auto operator()(R && r) &
0040 #else
0041         template<typename R>
0042         constexpr auto operator()(R && r) & -> decltype(
0043             Func{}((R &&) r, std::declval<box<I, T> &>().value_...))
0044 #endif
0045         {
0046             return Func{}((R &&) r, static_cast<box<I, T> &>(*this).value_...);
0047         }
0048 
0049 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0050         template<std::ranges::input_range R>
0051         requires std::ranges::viewable_range<R> &&
0052             std::invocable<Func, R, T const &...> &&
0053             std::ranges::view<std::invoke_result_t<Func, R, T const &...>>
0054         constexpr auto operator()(R && r) const &
0055 #else
0056         template<typename R>
0057         constexpr auto operator()(R && r) const & -> decltype(
0058             Func{}((R &&) r, std::declval<box<I, T> const &>().value_...))
0059 #endif
0060         {
0061             return Func{}(
0062                 (R &&) r, static_cast<box<I, T> const &>(*this).value_...);
0063         }
0064 
0065 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0066         template<std::ranges::input_range R>
0067         requires std::ranges::viewable_range<R> &&
0068             std::invocable<Func, R, T...> &&
0069             std::ranges::view<std::invoke_result_t<Func, R, T...>>
0070         constexpr auto operator()(R && r) &&
0071 #else
0072         template<typename R>
0073         constexpr auto operator()(R && r) && -> decltype(
0074             Func{}((R &&) r, std::declval<box<I, T> &&>().value_...))
0075 #endif
0076         {
0077             return Func{}((R &&) r, static_cast<box<I, T> &&>(*this).value_...);
0078         }
0079     };
0080 
0081 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0082     template<std::semiregular Func, std::copy_constructible... T>
0083 #else
0084     template<typename Func, typename... T>
0085 #endif
0086     struct view_closure
0087         : pipeable<view_closure<Func, T...>>,
0088           view_closure_impl<std::index_sequence_for<T...>, Func, T...>
0089     {
0090         using base_type =
0091             view_closure_impl<std::index_sequence_for<T...>, Func, T...>;
0092 
0093         view_closure() = default;
0094 
0095         constexpr explicit view_closure(Func func, T &&... x) :
0096             base_type{func, std::move(x)...}
0097         {}
0098     };
0099 
0100 #if defined(__cpp_deduction_guides)
0101     template<typename Func, typename... T>
0102     view_closure(Func, T...) -> view_closure<Func, T...>;
0103 #endif
0104 
0105 }}}
0106 
0107 #endif