Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Adapts `std::tuple` for use with Hana.
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_EXT_STD_TUPLE_HPP
0011 #define BOOST_HANA_EXT_STD_TUPLE_HPP
0012 
0013 #include <boost/hana/bool.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/decay.hpp>
0016 #include <boost/hana/fwd/at.hpp>
0017 #include <boost/hana/fwd/core/make.hpp>
0018 #include <boost/hana/fwd/core/tag_of.hpp>
0019 #include <boost/hana/fwd/drop_front.hpp>
0020 #include <boost/hana/fwd/empty.hpp>
0021 #include <boost/hana/fwd/flatten.hpp>
0022 #include <boost/hana/fwd/front.hpp>
0023 #include <boost/hana/fwd/is_empty.hpp>
0024 #include <boost/hana/fwd/length.hpp>
0025 #include <boost/hana/fwd/lift.hpp>
0026 #include <boost/hana/integral_constant.hpp>
0027 
0028 #include <cstddef>
0029 #include <tuple>
0030 #include <type_traits>
0031 #include <utility>
0032 
0033 
0034 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0035 namespace std {
0036     //! @ingroup group-ext-std
0037     //! Adapter for `std::tuple`s.
0038     //!
0039     //!
0040     //! Modeled concepts
0041     //! ----------------
0042     //! A `std::tuple` is a model of the `Sequence` concept, and all the
0043     //! concepts it refines. That makes it essentially the same as a Hana
0044     //! tuple, although the complexity of some operations might differ from
0045     //! that of Hana's tuple.
0046     //!
0047     //! @include example/ext/std/tuple.cpp
0048     template <typename ...T>
0049     struct tuple { };
0050 }
0051 #endif
0052 
0053 
0054 namespace boost { namespace hana {
0055     namespace ext { namespace std { struct tuple_tag; }}
0056 
0057     template <typename ...Xs>
0058     struct tag_of<std::tuple<Xs...>> {
0059         using type = ext::std::tuple_tag;
0060     };
0061 
0062     //////////////////////////////////////////////////////////////////////////
0063     // make
0064     //////////////////////////////////////////////////////////////////////////
0065     template <>
0066     struct make_impl<ext::std::tuple_tag> {
0067         template <typename ...Xs>
0068         static constexpr decltype(auto) apply(Xs&& ...xs) {
0069             return std::make_tuple(static_cast<Xs&&>(xs)...);
0070         }
0071     };
0072 
0073     //////////////////////////////////////////////////////////////////////////
0074     // Applicative
0075     //////////////////////////////////////////////////////////////////////////
0076     template <>
0077     struct lift_impl<ext::std::tuple_tag> {
0078         template <typename X>
0079         static constexpr auto apply(X&& x) {
0080             return std::tuple<typename detail::decay<X>::type>{
0081                                                 static_cast<X&&>(x)};
0082         }
0083     };
0084 
0085     //////////////////////////////////////////////////////////////////////////
0086     // Monad
0087     //////////////////////////////////////////////////////////////////////////
0088     template <>
0089     struct flatten_impl<ext::std::tuple_tag> {
0090         template <typename Xs, std::size_t ...i>
0091         static constexpr decltype(auto)
0092         flatten_helper(Xs&& xs, std::index_sequence<i...>) {
0093             return std::tuple_cat(std::get<i>(static_cast<Xs&&>(xs))...);
0094         }
0095 
0096         template <typename Xs>
0097         static constexpr decltype(auto) apply(Xs&& xs) {
0098             using Raw = typename std::remove_reference<Xs>::type;
0099             constexpr std::size_t Length = std::tuple_size<Raw>::value;
0100             return flatten_helper(static_cast<Xs&&>(xs),
0101                                   std::make_index_sequence<Length>{});
0102         }
0103     };
0104 
0105     //////////////////////////////////////////////////////////////////////////
0106     // MonadPlus
0107     //////////////////////////////////////////////////////////////////////////
0108     template <>
0109     struct empty_impl<ext::std::tuple_tag> {
0110         static constexpr auto apply()
0111         { return std::tuple<>{}; }
0112     };
0113 
0114     //////////////////////////////////////////////////////////////////////////
0115     // Iterable
0116     //////////////////////////////////////////////////////////////////////////
0117     template <>
0118     struct front_impl<ext::std::tuple_tag> {
0119         template <typename Xs>
0120         static constexpr decltype(auto) apply(Xs&& xs) {
0121             return std::get<0>(static_cast<Xs&&>(xs));
0122         }
0123     };
0124 
0125     template <>
0126     struct drop_front_impl<ext::std::tuple_tag> {
0127         template <std::size_t n, typename Xs, std::size_t ...i>
0128         static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
0129             return std::make_tuple(
0130                 hana::at_c<n + i>(static_cast<Xs&&>(xs))...
0131             );
0132         }
0133 
0134         template <typename Xs, typename N>
0135         static constexpr auto apply(Xs&& xs, N const&) {
0136             using Raw = typename std::remove_reference<Xs>::type;
0137             constexpr std::size_t n = N::value;
0138             constexpr auto len = std::tuple_size<Raw>::value;
0139             return drop_front_helper<n>(static_cast<Xs&&>(xs),
0140                     std::make_index_sequence<(n < len ? len - n : 0)>{});
0141         }
0142     };
0143 
0144     template <>
0145     struct is_empty_impl<ext::std::tuple_tag> {
0146         template <typename ...Xs>
0147         static constexpr auto apply(std::tuple<Xs...> const&)
0148         { return hana::bool_c<sizeof...(Xs) == 0>; }
0149     };
0150 
0151     template <>
0152     struct at_impl<ext::std::tuple_tag> {
0153         template <typename Xs, typename N>
0154         static constexpr decltype(auto) apply(Xs&& xs, N const&) {
0155             constexpr std::size_t index = N::value;
0156             return std::get<index>(static_cast<Xs&&>(xs));
0157         }
0158     };
0159 
0160     //////////////////////////////////////////////////////////////////////////
0161     // Foldable
0162     //////////////////////////////////////////////////////////////////////////
0163     template <>
0164     struct length_impl<ext::std::tuple_tag> {
0165         template <typename ...Xs>
0166         static constexpr auto apply(std::tuple<Xs...> const&) {
0167             return hana::size_c<sizeof...(Xs)>;
0168         }
0169     };
0170 
0171     //////////////////////////////////////////////////////////////////////////
0172     // Sequence
0173     //////////////////////////////////////////////////////////////////////////
0174     template <>
0175     struct Sequence<ext::std::tuple_tag> {
0176         static constexpr bool value = true;
0177     };
0178 }} // end namespace boost::hana
0179 
0180 #endif // !BOOST_HANA_EXT_STD_TUPLE_HPP