Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:03

0001 /*!
0002 @file
0003 Defines `boost::hana::lazy`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_LAZY_HPP
0011 #define BOOST_HANA_LAZY_HPP
0012 
0013 #include <boost/hana/fwd/lazy.hpp>
0014 
0015 #include <boost/hana/basic_tuple.hpp>
0016 #include <boost/hana/config.hpp>
0017 #include <boost/hana/core/make.hpp>
0018 #include <boost/hana/detail/decay.hpp>
0019 #include <boost/hana/detail/operators/adl.hpp>
0020 #include <boost/hana/detail/operators/monad.hpp>
0021 #include <boost/hana/functional/apply.hpp>
0022 #include <boost/hana/functional/compose.hpp>
0023 #include <boost/hana/functional/on.hpp>
0024 #include <boost/hana/fwd/ap.hpp>
0025 #include <boost/hana/fwd/duplicate.hpp>
0026 #include <boost/hana/fwd/eval.hpp>
0027 #include <boost/hana/fwd/extend.hpp>
0028 #include <boost/hana/fwd/extract.hpp>
0029 #include <boost/hana/fwd/flatten.hpp>
0030 #include <boost/hana/fwd/lift.hpp>
0031 #include <boost/hana/fwd/transform.hpp>
0032 
0033 #include <cstddef>
0034 #include <type_traits>
0035 #include <utility>
0036 
0037 
0038 namespace boost { namespace hana {
0039     //////////////////////////////////////////////////////////////////////////
0040     // lazy
0041     //////////////////////////////////////////////////////////////////////////
0042     template <typename Indices, typename F, typename ...Args>
0043     struct lazy_apply_t;
0044 
0045     namespace detail { struct lazy_secret { }; }
0046 
0047     template <std::size_t ...n, typename F, typename ...Args>
0048     struct lazy_apply_t<std::index_sequence<n...>, F, Args...>
0049         : detail::operators::adl<>
0050     {
0051         template <typename ...T>
0052         constexpr lazy_apply_t(detail::lazy_secret, T&& ...t)
0053             : storage_{static_cast<T&&>(t)...}
0054         { }
0055 
0056         basic_tuple<F, Args...> storage_;
0057         using hana_tag = lazy_tag;
0058     };
0059 
0060     template <typename X>
0061     struct lazy_value_t : detail::operators::adl<> {
0062         template <typename Y>
0063         constexpr lazy_value_t(detail::lazy_secret, Y&& y)
0064             : storage_{static_cast<Y&&>(y)}
0065         { }
0066 
0067         basic_tuple<X> storage_;
0068         using hana_tag = lazy_tag;
0069 
0070         // If this is called, we assume that `X` is in fact a function.
0071         template <typename ...Args>
0072         constexpr lazy_apply_t<
0073             std::make_index_sequence<sizeof...(Args)>,
0074             X, typename detail::decay<Args>::type...
0075         > operator()(Args&& ...args) const& {
0076             return {detail::lazy_secret{},
0077                     hana::at_c<0>(storage_), static_cast<Args&&>(args)...};
0078         }
0079 
0080         template <typename ...Args>
0081         constexpr lazy_apply_t<
0082             std::make_index_sequence<sizeof...(Args)>,
0083             X, typename detail::decay<Args>::type...
0084         > operator()(Args&& ...args) && {
0085             return {detail::lazy_secret{},
0086                 static_cast<X&&>(hana::at_c<0>(storage_)),
0087                 static_cast<Args&&>(args)...
0088             };
0089         }
0090     };
0091 
0092     //////////////////////////////////////////////////////////////////////////
0093     // make<lazy_tag>
0094     //////////////////////////////////////////////////////////////////////////
0095     template <>
0096     struct make_impl<lazy_tag> {
0097         template <typename X>
0098         static constexpr lazy_value_t<typename detail::decay<X>::type> apply(X&& x) {
0099             return {detail::lazy_secret{}, static_cast<X&&>(x)};
0100         }
0101     };
0102 
0103     //////////////////////////////////////////////////////////////////////////
0104     // Operators
0105     //////////////////////////////////////////////////////////////////////////
0106     namespace detail {
0107         template <>
0108         struct monad_operators<lazy_tag> { static constexpr bool value = true; };
0109     }
0110 
0111     //////////////////////////////////////////////////////////////////////////
0112     // eval for lazy_tag
0113     //////////////////////////////////////////////////////////////////////////
0114     template <>
0115     struct eval_impl<lazy_tag> {
0116         // lazy_apply_t
0117         template <std::size_t ...n, typename F, typename ...Args>
0118         static constexpr decltype(auto)
0119         apply(lazy_apply_t<std::index_sequence<n...>, F, Args...> const& expr) {
0120             return hana::at_c<0>(expr.storage_)(
0121                 hana::at_c<n+1>(expr.storage_)...
0122             );
0123         }
0124 
0125         template <std::size_t ...n, typename F, typename ...Args>
0126         static constexpr decltype(auto)
0127         apply(lazy_apply_t<std::index_sequence<n...>, F, Args...>& expr) {
0128             return hana::at_c<0>(expr.storage_)(
0129                 hana::at_c<n+1>(expr.storage_)...
0130             );
0131         }
0132 
0133         template <std::size_t ...n, typename F, typename ...Args>
0134         static constexpr decltype(auto)
0135         apply(lazy_apply_t<std::index_sequence<n...>, F, Args...>&& expr) {
0136             return static_cast<F&&>(hana::at_c<0>(expr.storage_))(
0137                 static_cast<Args&&>(hana::at_c<n+1>(expr.storage_))...
0138             );
0139         }
0140 
0141         // lazy_value_t
0142         template <typename X>
0143         static constexpr X const& apply(lazy_value_t<X> const& expr)
0144         { return hana::at_c<0>(expr.storage_); }
0145 
0146         template <typename X>
0147         static constexpr X& apply(lazy_value_t<X>& expr)
0148         { return hana::at_c<0>(expr.storage_); }
0149 
0150         template <typename X>
0151         static constexpr X apply(lazy_value_t<X>&& expr)
0152         { return static_cast<X&&>(hana::at_c<0>(expr.storage_)); }
0153     };
0154 
0155     //////////////////////////////////////////////////////////////////////////
0156     // Functor
0157     //////////////////////////////////////////////////////////////////////////
0158     template <>
0159     struct transform_impl<lazy_tag> {
0160         template <typename Expr, typename F>
0161         static constexpr auto apply(Expr&& expr, F&& f) {
0162             return hana::make_lazy(hana::compose(static_cast<F&&>(f), hana::eval))(
0163                 static_cast<Expr&&>(expr)
0164             );
0165         }
0166     };
0167 
0168     //////////////////////////////////////////////////////////////////////////
0169     // Applicative
0170     //////////////////////////////////////////////////////////////////////////
0171     template <>
0172     struct lift_impl<lazy_tag> {
0173         template <typename X>
0174         static constexpr lazy_value_t<typename detail::decay<X>::type>
0175         apply(X&& x) {
0176             return {detail::lazy_secret{}, static_cast<X&&>(x)};
0177         }
0178     };
0179 
0180     template <>
0181     struct ap_impl<lazy_tag> {
0182         template <typename F, typename X>
0183         static constexpr decltype(auto) apply(F&& f, X&& x) {
0184             return hana::make_lazy(hana::on(hana::apply, hana::eval))(
0185                 static_cast<F&&>(f), static_cast<X&&>(x)
0186             );
0187         }
0188     };
0189 
0190     //////////////////////////////////////////////////////////////////////////
0191     // Monad
0192     //////////////////////////////////////////////////////////////////////////
0193     template <>
0194     struct flatten_impl<lazy_tag> {
0195         template <typename Expr>
0196         static constexpr decltype(auto) apply(Expr&& expr) {
0197             return hana::make_lazy(hana::compose(hana::eval, hana::eval))(
0198                 static_cast<Expr&&>(expr)
0199             );
0200         }
0201     };
0202 
0203     //////////////////////////////////////////////////////////////////////////
0204     // Comonad
0205     //////////////////////////////////////////////////////////////////////////
0206     template <>
0207     struct extract_impl<lazy_tag> {
0208         template <typename Expr>
0209         static constexpr decltype(auto) apply(Expr&& expr)
0210         { return hana::eval(static_cast<Expr&&>(expr)); }
0211     };
0212 
0213     template <>
0214     struct duplicate_impl<lazy_tag> {
0215         template <typename Expr>
0216         static constexpr decltype(auto) apply(Expr&& expr)
0217         { return hana::make_lazy(static_cast<Expr&&>(expr)); }
0218     };
0219 
0220     template <>
0221     struct extend_impl<lazy_tag> {
0222         template <typename Expr, typename F>
0223         static constexpr decltype(auto) apply(Expr&& expr, F&& f) {
0224             return hana::make_lazy(static_cast<F&&>(f))(static_cast<Expr&&>(expr));
0225         }
0226     };
0227 }} // end namespace boost::hana
0228 
0229 #endif // !BOOST_HANA_LAZY_HPP