Back to home page

EIC code displayed by LXR

 
 

    


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

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_PIPEABLE_VIEW_HPP
0007 #define BOOST_STL_INTERFACES_DETAIL_PIPEABLE_VIEW_HPP
0008 
0009 #include <boost/stl_interfaces/config.hpp>
0010 
0011 #include <type_traits>
0012 
0013 
0014 namespace boost { namespace stl_interfaces { namespace detail {
0015 
0016     template<typename T>
0017     using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
0018 
0019     struct pipeable_base;
0020 
0021 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0022     template<typename T>
0023     concept pipeable_ = std::derived_from<T, pipeable_base> &&
0024         std::is_object_v<T> && std::copy_constructible<T>;
0025 #else
0026     template<typename T>
0027     constexpr bool pipeable_ = std::is_base_of<pipeable_base, T>::value &&
0028         std::is_object<T>::value && std::is_copy_constructible<T>::value;
0029 #endif
0030 
0031 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0032     template<pipeable_ T, pipeable_ U>
0033 #else
0034     template<
0035         typename T,
0036         typename U,
0037         typename Enable = std::enable_if_t<pipeable_<T> && pipeable_<U>>>
0038 #endif
0039     struct view_pipeline;
0040 
0041     struct pipeable_base
0042     {
0043 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0044         template<pipeable_ T, pipeable_ U>
0045         requires std::constructible_from<std::remove_cvref_t<T>, T> &&
0046             std::constructible_from<std::remove_cvref_t<U>, U>
0047 #else
0048         template<
0049             typename T,
0050             typename U,
0051             typename Enable = std::enable_if_t<
0052                 pipeable_<T> && pipeable_<U> &&
0053                 std::is_constructible<remove_cvref_t<T>, T>::value &&
0054                 std::is_constructible<remove_cvref_t<U>, U>::value>>
0055 #endif
0056         friend constexpr auto operator|(T && t, U && u)
0057         {
0058             return view_pipeline<T, U>{(T &&) t, (U &&) u};
0059         }
0060     };
0061 
0062     template<typename Derived>
0063     struct pipeable : pipeable_base
0064     {
0065         template<typename R>
0066         friend constexpr auto operator|(R && r, Derived & d)
0067             -> decltype(((Derived &&) d)((R &&) r))
0068         {
0069             return ((Derived &&) d)((R &&) r);
0070         }
0071 
0072         template<typename R>
0073         friend constexpr auto operator|(R && r, Derived const & d)
0074             -> decltype(((Derived &&) d)((R &&) r))
0075         {
0076             return ((Derived &&) d)((R &&) r);
0077         }
0078 
0079         template<typename R>
0080         friend constexpr auto operator|(R && r, Derived && d)
0081             -> decltype(((Derived &&) d)((R &&) r))
0082         {
0083             return ((Derived &&) d)((R &&) r);
0084         }
0085     };
0086 
0087 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0088     template<pipeable_ T, pipeable_ U>
0089 #else
0090     template<typename T, typename U, typename>
0091 #endif
0092     struct view_pipeline : pipeable<view_pipeline<T, U>>
0093     {
0094         view_pipeline() = default;
0095 
0096         constexpr view_pipeline(T && t, U && u) :
0097             left_(std::move(t)), right_(std::move(u))
0098         {}
0099 
0100 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0101         template<std::ranges::viewable_range R>
0102         requires std::invocable<T &, R> &&
0103             std::invocable<U &, std::invoke_result_t<T &, R>>
0104         constexpr decltype(auto) operator()(R && r) &
0105 #else
0106         template<typename R>
0107         constexpr auto
0108         operator()(R && r) & -> decltype(this->right_(this->left_((R &&) r)))
0109 #endif
0110         {
0111             return right_(left_((R &&) r));
0112         }
0113 
0114 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0115         template<std::ranges::viewable_range R>
0116         requires std::invocable<T const &, R> &&
0117             std::invocable<U const &, std::invoke_result_t<T const &, R>>
0118         constexpr decltype(auto) operator()(R && r) const &
0119 #else
0120         template<typename R>
0121         constexpr auto operator()(
0122             R && r) const & -> decltype(this->right_(this->left_((R &&) r)))
0123 #endif
0124         {
0125             return right_(left_((R &&) r));
0126         }
0127 
0128 #if BOOST_STL_INTERFACES_USE_CONCEPTS
0129         template<std::ranges::viewable_range R>
0130         requires std::invocable<T, R> &&
0131             std::invocable<U, std::invoke_result_t<T, R>>
0132         constexpr decltype(auto) operator()(R && r) &&
0133 #else
0134         template<typename R>
0135         constexpr auto operator()(R && r) && -> decltype(std::move(
0136             this->right_)(std::move(this->left_)((R &&) r)))
0137 #endif
0138         {
0139             return std::move(right_)(std::move(left_)((R &&) r));
0140         }
0141 
0142         T left_;
0143         U right_;
0144     };
0145 
0146 }}}
0147 
0148 #endif