Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*!
0002 @file
0003 Adapts `std::integer_sequence` 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_INTEGER_SEQUENCE_HPP
0011 #define BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
0012 
0013 #include <boost/hana/bool.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/fast_and.hpp>
0016 #include <boost/hana/ext/std/integral_constant.hpp>
0017 #include <boost/hana/fwd/at.hpp>
0018 #include <boost/hana/fwd/core/tag_of.hpp>
0019 #include <boost/hana/fwd/drop_front.hpp>
0020 #include <boost/hana/fwd/equal.hpp>
0021 #include <boost/hana/fwd/is_empty.hpp>
0022 #include <boost/hana/fwd/unpack.hpp>
0023 
0024 #include <cstddef>
0025 #include <type_traits>
0026 #include <utility>
0027 
0028 
0029 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0030 namespace std {
0031     //! @ingroup group-ext-std
0032     //! Adaptation of `std::integer_sequence` for Hana.
0033     //!
0034     //!
0035     //!
0036     //! Modeled concepts
0037     //! ----------------
0038     //! 1. `Comparable`\n
0039     //! Two `std::integer_sequence`s are equal if and only if they have the
0040     //! same number of elements, and if corresponding elements compare equal.
0041     //! The types of the elements held in both `integer_sequence`s may be
0042     //! different, as long as they can be compared.
0043     //! @include example/ext/std/integer_sequence/comparable.cpp
0044     //!
0045     //! 2. `Foldable`\n
0046     //! Folding an `integer_sequence` is equivalent to folding a sequence of
0047     //! `std::integral_constant`s with the corresponding types.
0048     //! @include example/ext/std/integer_sequence/foldable.cpp
0049     //!
0050     //! 3. `Iterable`\n
0051     //! Iterating over an `integer_sequence` is equivalent to iterating over
0052     //! a sequence of the corresponding `std::integral_constant`s.
0053     //! @include example/ext/std/integer_sequence/iterable.cpp
0054     //!
0055     //! 4. `Searchable`\n
0056     //! Searching through an `integer_sequence` is equivalent to searching
0057     //! through the corresponding sequence of `std::integral_constant`s.
0058     //! @include example/ext/std/integer_sequence/searchable.cpp
0059     template <typename T, T ...v>
0060     struct integer_sequence { };
0061 }
0062 #endif
0063 
0064 
0065 namespace boost { namespace hana {
0066     namespace ext { namespace std { struct integer_sequence_tag; }}
0067 
0068     template <typename T, T ...v>
0069     struct tag_of<std::integer_sequence<T, v...>> {
0070         using type = ext::std::integer_sequence_tag;
0071     };
0072 
0073     //////////////////////////////////////////////////////////////////////////
0074     // Comparable
0075     //////////////////////////////////////////////////////////////////////////
0076     template <>
0077     struct equal_impl<ext::std::integer_sequence_tag, ext::std::integer_sequence_tag> {
0078         template <typename X, X ...xs, typename Y, Y ...ys>
0079         static constexpr hana::bool_<detail::fast_and<(xs == ys)...>::value>
0080         apply(std::integer_sequence<X, xs...> const&, std::integer_sequence<Y, ys...> const&)
0081         { return {}; }
0082 
0083         template <typename Xs, typename Ys>
0084         static constexpr hana::false_ apply(Xs const&, Ys const&, ...)
0085         { return {}; }
0086     };
0087 
0088     //////////////////////////////////////////////////////////////////////////
0089     // Foldable
0090     //////////////////////////////////////////////////////////////////////////
0091     template <>
0092     struct unpack_impl<ext::std::integer_sequence_tag> {
0093         template <typename T, T ...v, typename F>
0094         static constexpr decltype(auto)
0095         apply(std::integer_sequence<T, v...> const&, F&& f) {
0096             return static_cast<F&&>(f)(std::integral_constant<T, v>{}...);
0097         }
0098     };
0099 
0100     //////////////////////////////////////////////////////////////////////////
0101     // Iterable
0102     //////////////////////////////////////////////////////////////////////////
0103     template <>
0104     struct at_impl<ext::std::integer_sequence_tag> {
0105         template <typename T, T ...v, typename N>
0106         static constexpr auto apply(std::integer_sequence<T, v...> const&, N const&) {
0107             constexpr std::size_t n = N::value;
0108             constexpr T values_[] = {v...};
0109             return std::integral_constant<T, values_[n]>{};
0110         }
0111     };
0112 
0113     template <>
0114     struct drop_front_impl<ext::std::integer_sequence_tag> {
0115         template <std::size_t n, typename T, T ...t, std::size_t ...i>
0116         static constexpr auto drop_front_helper(std::integer_sequence<T, t...>,
0117                                                 std::index_sequence<i...>)
0118         {
0119             constexpr T ts[sizeof...(t)+1] = {t...}; // avoid 0-sized array
0120             return std::integer_sequence<T, ts[n + i]...>{};
0121         }
0122 
0123         template <typename T, T ...t, typename N>
0124         static constexpr auto apply(std::integer_sequence<T, t...> ts, N const&) {
0125             constexpr std::size_t n = N::value;
0126             constexpr std::size_t len = sizeof...(t);
0127             return drop_front_helper<n>(ts,
0128                     std::make_index_sequence<(n < len ? len - n : 0)>{});
0129         }
0130     };
0131 
0132     template <>
0133     struct is_empty_impl<ext::std::integer_sequence_tag> {
0134         template <typename T, T ...xs>
0135         static constexpr auto apply(std::integer_sequence<T, xs...> const&)
0136         { return hana::bool_c<sizeof...(xs) == 0>; }
0137     };
0138 }} // end namespace boost::hana
0139 
0140 #endif // !BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP