Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:13:46

0001 /*!
0002 @file
0003 Defines `boost::hana::basic_tuple`.
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_BASIC_TUPLE_HPP
0011 #define BOOST_HANA_BASIC_TUPLE_HPP
0012 
0013 #include <boost/hana/fwd/basic_tuple.hpp>
0014 
0015 #include <boost/hana/config.hpp>
0016 #include <boost/hana/detail/decay.hpp>
0017 #include <boost/hana/detail/ebo.hpp>
0018 #include <boost/hana/fwd/at.hpp>
0019 #include <boost/hana/fwd/bool.hpp>
0020 #include <boost/hana/fwd/concept/sequence.hpp>
0021 #include <boost/hana/fwd/core/make.hpp>
0022 #include <boost/hana/fwd/core/tag_of.hpp>
0023 #include <boost/hana/fwd/drop_front.hpp>
0024 #include <boost/hana/fwd/integral_constant.hpp>
0025 #include <boost/hana/fwd/is_empty.hpp>
0026 #include <boost/hana/fwd/length.hpp>
0027 #include <boost/hana/fwd/transform.hpp>
0028 #include <boost/hana/fwd/unpack.hpp>
0029 
0030 #include <cstddef>
0031 #include <type_traits>
0032 #include <utility>
0033 
0034 
0035 namespace boost { namespace hana {
0036     namespace detail {
0037         //////////////////////////////////////////////////////////////////////
0038         // basic_tuple_impl<n, Xn>
0039         //////////////////////////////////////////////////////////////////////
0040         template <std::size_t> struct bti; // basic_tuple_index
0041 
0042         struct from_other { };
0043 
0044         template <typename Indices, typename ...Xn>
0045 #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
0046         struct __declspec(empty_bases) basic_tuple_impl;
0047 #else
0048         struct basic_tuple_impl;
0049 #endif
0050 
0051         template <std::size_t ...n, typename ...Xn>
0052 #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
0053         struct __declspec(empty_bases) basic_tuple_impl<std::index_sequence<n...>, Xn...>
0054 #else
0055         struct basic_tuple_impl<std::index_sequence<n...>, Xn...>
0056 #endif
0057             : detail::ebo<bti<n>, Xn>...
0058         {
0059             static constexpr std::size_t size_ = sizeof...(Xn);
0060 
0061             constexpr basic_tuple_impl() = default;
0062 
0063             template <typename Other>
0064             explicit constexpr basic_tuple_impl(detail::from_other, Other&& other)
0065                 : detail::ebo<bti<n>, Xn>(detail::ebo_get<bti<n>>(static_cast<Other&&>(other)))...
0066             { }
0067 
0068             template <typename ...Yn>
0069             explicit constexpr basic_tuple_impl(Yn&& ...yn)
0070                 : detail::ebo<bti<n>, Xn>(static_cast<Yn&&>(yn))...
0071             { }
0072         };
0073     }
0074 
0075     //////////////////////////////////////////////////////////////////////////
0076     // basic_tuple
0077     //////////////////////////////////////////////////////////////////////////
0078     //! @cond
0079     template <typename ...Xn>
0080     struct basic_tuple final
0081         : detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
0082     {
0083         using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;
0084 
0085         constexpr basic_tuple() = default;
0086 
0087         // copy constructor
0088         template <typename Other, typename = typename std::enable_if<
0089             std::is_same<typename detail::decay<Other>::type, basic_tuple>::value
0090         >::type>
0091         constexpr basic_tuple(Other&& other)
0092             : Base(detail::from_other{}, static_cast<Other&&>(other))
0093         { }
0094 
0095         template <typename ...Yn>
0096         explicit constexpr basic_tuple(Yn&& ...yn)
0097             : Base(static_cast<Yn&&>(yn)...)
0098         { }
0099     };
0100     //! @endcond
0101 
0102     template <typename ...Xn>
0103     struct tag_of<basic_tuple<Xn...>> {
0104         using type = basic_tuple_tag;
0105     };
0106 
0107     //////////////////////////////////////////////////////////////////////////
0108     // Foldable
0109     //////////////////////////////////////////////////////////////////////////
0110     template <>
0111     struct unpack_impl<basic_tuple_tag> {
0112         template <std::size_t ...i, typename ...Xn, typename F>
0113         static constexpr decltype(auto)
0114         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) {
0115             return static_cast<F&&>(f)(
0116                 detail::ebo_get<detail::bti<i>>(
0117                     static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
0118                 )...
0119             );
0120         }
0121 
0122         template <std::size_t ...i, typename ...Xn, typename F>
0123         static constexpr decltype(auto)
0124         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) {
0125             return static_cast<F&&>(f)(
0126                 detail::ebo_get<detail::bti<i>>(
0127                     static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
0128                 )...
0129             );
0130         }
0131 
0132         template <std::size_t ...i, typename ...Xn, typename F>
0133         static constexpr decltype(auto)
0134         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) {
0135             return static_cast<F&&>(f)(
0136                 detail::ebo_get<detail::bti<i>>(
0137                     static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
0138                 )...
0139             );
0140         }
0141     };
0142 
0143     //////////////////////////////////////////////////////////////////////////
0144     // Functor
0145     //////////////////////////////////////////////////////////////////////////
0146     template <>
0147     struct transform_impl<basic_tuple_tag> {
0148         template <std::size_t ...i, typename ...Xn, typename F>
0149         static constexpr auto
0150         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) {
0151             return hana::make_basic_tuple(
0152                 f(detail::ebo_get<detail::bti<i>>(
0153                     static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
0154                 ))...
0155             );
0156         }
0157 
0158         template <std::size_t ...i, typename ...Xn, typename F>
0159         static constexpr auto
0160         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) {
0161             return hana::make_basic_tuple(
0162                 f(detail::ebo_get<detail::bti<i>>(
0163                     static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
0164                 ))...
0165             );
0166         }
0167 
0168         template <std::size_t ...i, typename ...Xn, typename F>
0169         static constexpr auto
0170         apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) {
0171             return hana::make_basic_tuple(
0172                 f(detail::ebo_get<detail::bti<i>>(
0173                     static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
0174                 ))...
0175             );
0176         }
0177     };
0178 
0179     //////////////////////////////////////////////////////////////////////////
0180     // Iterable
0181     //////////////////////////////////////////////////////////////////////////
0182     template <>
0183     struct at_impl<basic_tuple_tag> {
0184         template <typename Xs, typename N>
0185         static constexpr decltype(auto) apply(Xs&& xs, N const&) {
0186             constexpr std::size_t index = N::value;
0187             return detail::ebo_get<detail::bti<index>>(static_cast<Xs&&>(xs));
0188         }
0189     };
0190 
0191     template <>
0192     struct drop_front_impl<basic_tuple_tag> {
0193         template <std::size_t N, typename Xs, std::size_t ...i>
0194         static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
0195             return hana::make_basic_tuple(
0196                 detail::ebo_get<detail::bti<i+N>>(static_cast<Xs&&>(xs))...
0197             );
0198         }
0199 
0200         template <typename Xs, typename N>
0201         static constexpr auto apply(Xs&& xs, N const&) {
0202             constexpr std::size_t len = detail::decay<Xs>::type::size_;
0203             return drop_front_helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
0204                 (N::value < len) ? len - N::value : 0
0205             >{});
0206         }
0207     };
0208 
0209     template <>
0210     struct is_empty_impl<basic_tuple_tag> {
0211         template <typename ...Xs>
0212         static constexpr hana::bool_<sizeof...(Xs) == 0>
0213         apply(basic_tuple<Xs...> const&)
0214         { return {}; }
0215     };
0216 
0217     // compile-time optimizations (to reduce the # of function instantiations)
0218     template <std::size_t n, typename ...Xs>
0219     constexpr decltype(auto) at_c(basic_tuple<Xs...> const& xs) {
0220         return detail::ebo_get<detail::bti<n>>(xs);
0221     }
0222 
0223     template <std::size_t n, typename ...Xs>
0224     constexpr decltype(auto) at_c(basic_tuple<Xs...>& xs) {
0225         return detail::ebo_get<detail::bti<n>>(xs);
0226     }
0227 
0228     template <std::size_t n, typename ...Xs>
0229     constexpr decltype(auto) at_c(basic_tuple<Xs...>&& xs) {
0230         return detail::ebo_get<detail::bti<n>>(static_cast<basic_tuple<Xs...>&&>(xs));
0231     }
0232 
0233     //////////////////////////////////////////////////////////////////////////
0234     // Sequence
0235     //////////////////////////////////////////////////////////////////////////
0236     template <>
0237     struct Sequence<basic_tuple_tag> {
0238         static constexpr bool value = true;
0239     };
0240 
0241     template <>
0242     struct make_impl<basic_tuple_tag> {
0243         template <typename ...Xn>
0244         static constexpr basic_tuple<typename detail::decay<Xn>::type...>
0245         apply(Xn&& ...xn) {
0246             return basic_tuple<typename detail::decay<Xn>::type...>{
0247                 static_cast<Xn&&>(xn)...
0248             };
0249         }
0250     };
0251 
0252     //////////////////////////////////////////////////////////////////////////
0253     // length
0254     //////////////////////////////////////////////////////////////////////////
0255     template <>
0256     struct length_impl<basic_tuple_tag> {
0257         template <typename ...Xn>
0258         static constexpr auto apply(basic_tuple<Xn...> const&) {
0259             return hana::size_t<sizeof...(Xn)>{};
0260         }
0261     };
0262 }} // end namespace boost::hana
0263 
0264 #endif // !BOOST_HANA_BASIC_TUPLE_HPP