123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /*!
- @file
- Defines `boost::hana::basic_tuple`.
- Copyright Louis Dionne 2013-2022
- Distributed under the Boost Software License, Version 1.0.
- (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
- */
- #ifndef BOOST_HANA_BASIC_TUPLE_HPP
- #define BOOST_HANA_BASIC_TUPLE_HPP
- #include <boost/hana/fwd/basic_tuple.hpp>
- #include <boost/hana/config.hpp>
- #include <boost/hana/detail/decay.hpp>
- #include <boost/hana/detail/ebo.hpp>
- #include <boost/hana/fwd/at.hpp>
- #include <boost/hana/fwd/bool.hpp>
- #include <boost/hana/fwd/concept/sequence.hpp>
- #include <boost/hana/fwd/core/make.hpp>
- #include <boost/hana/fwd/core/tag_of.hpp>
- #include <boost/hana/fwd/drop_front.hpp>
- #include <boost/hana/fwd/integral_constant.hpp>
- #include <boost/hana/fwd/is_empty.hpp>
- #include <boost/hana/fwd/length.hpp>
- #include <boost/hana/fwd/transform.hpp>
- #include <boost/hana/fwd/unpack.hpp>
- #include <cstddef>
- #include <type_traits>
- #include <utility>
- namespace boost { namespace hana {
- namespace detail {
- //////////////////////////////////////////////////////////////////////
- // basic_tuple_impl<n, Xn>
- //////////////////////////////////////////////////////////////////////
- template <std::size_t> struct bti; // basic_tuple_index
- struct from_other { };
- template <typename Indices, typename ...Xn>
- #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
- struct __declspec(empty_bases) basic_tuple_impl;
- #else
- struct basic_tuple_impl;
- #endif
- template <std::size_t ...n, typename ...Xn>
- #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
- struct __declspec(empty_bases) basic_tuple_impl<std::index_sequence<n...>, Xn...>
- #else
- struct basic_tuple_impl<std::index_sequence<n...>, Xn...>
- #endif
- : detail::ebo<bti<n>, Xn>...
- {
- static constexpr std::size_t size_ = sizeof...(Xn);
- constexpr basic_tuple_impl() = default;
- template <typename Other>
- explicit constexpr basic_tuple_impl(detail::from_other, Other&& other)
- : detail::ebo<bti<n>, Xn>(detail::ebo_get<bti<n>>(static_cast<Other&&>(other)))...
- { }
- template <typename ...Yn>
- explicit constexpr basic_tuple_impl(Yn&& ...yn)
- : detail::ebo<bti<n>, Xn>(static_cast<Yn&&>(yn))...
- { }
- };
- }
- //////////////////////////////////////////////////////////////////////////
- // basic_tuple
- //////////////////////////////////////////////////////////////////////////
- //! @cond
- template <typename ...Xn>
- struct basic_tuple final
- : detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
- {
- using Base = detail::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;
- constexpr basic_tuple() = default;
- // copy constructor
- template <typename Other, typename = typename std::enable_if<
- std::is_same<typename detail::decay<Other>::type, basic_tuple>::value
- >::type>
- constexpr basic_tuple(Other&& other)
- : Base(detail::from_other{}, static_cast<Other&&>(other))
- { }
- template <typename ...Yn>
- explicit constexpr basic_tuple(Yn&& ...yn)
- : Base(static_cast<Yn&&>(yn)...)
- { }
- };
- //! @endcond
- template <typename ...Xn>
- struct tag_of<basic_tuple<Xn...>> {
- using type = basic_tuple_tag;
- };
- //////////////////////////////////////////////////////////////////////////
- // Foldable
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct unpack_impl<basic_tuple_tag> {
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr decltype(auto)
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F&& f) {
- return static_cast<F&&>(f)(
- detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
- )...
- );
- }
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr decltype(auto)
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F&& f) {
- return static_cast<F&&>(f)(
- detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
- )...
- );
- }
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr decltype(auto)
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F&& f) {
- return static_cast<F&&>(f)(
- detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
- )...
- );
- }
- };
- //////////////////////////////////////////////////////////////////////////
- // Functor
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct transform_impl<basic_tuple_tag> {
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr auto
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...> const& xs, F const& f) {
- return hana::make_basic_tuple(
- f(detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn> const&>(xs)
- ))...
- );
- }
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr auto
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>& xs, F const& f) {
- return hana::make_basic_tuple(
- f(detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn>&>(xs)
- ))...
- );
- }
- template <std::size_t ...i, typename ...Xn, typename F>
- static constexpr auto
- apply(detail::basic_tuple_impl<std::index_sequence<i...>, Xn...>&& xs, F const& f) {
- return hana::make_basic_tuple(
- f(detail::ebo_get<detail::bti<i>>(
- static_cast<detail::ebo<detail::bti<i>, Xn>&&>(xs)
- ))...
- );
- }
- };
- //////////////////////////////////////////////////////////////////////////
- // Iterable
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct at_impl<basic_tuple_tag> {
- template <typename Xs, typename N>
- static constexpr decltype(auto) apply(Xs&& xs, N const&) {
- constexpr std::size_t index = N::value;
- return detail::ebo_get<detail::bti<index>>(static_cast<Xs&&>(xs));
- }
- };
- template <>
- struct drop_front_impl<basic_tuple_tag> {
- template <std::size_t N, typename Xs, std::size_t ...i>
- static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
- return hana::make_basic_tuple(
- detail::ebo_get<detail::bti<i+N>>(static_cast<Xs&&>(xs))...
- );
- }
- template <typename Xs, typename N>
- static constexpr auto apply(Xs&& xs, N const&) {
- constexpr std::size_t len = detail::decay<Xs>::type::size_;
- return drop_front_helper<N::value>(static_cast<Xs&&>(xs), std::make_index_sequence<
- (N::value < len) ? len - N::value : 0
- >{});
- }
- };
- template <>
- struct is_empty_impl<basic_tuple_tag> {
- template <typename ...Xs>
- static constexpr hana::bool_<sizeof...(Xs) == 0>
- apply(basic_tuple<Xs...> const&)
- { return {}; }
- };
- // compile-time optimizations (to reduce the # of function instantiations)
- template <std::size_t n, typename ...Xs>
- constexpr decltype(auto) at_c(basic_tuple<Xs...> const& xs) {
- return detail::ebo_get<detail::bti<n>>(xs);
- }
- template <std::size_t n, typename ...Xs>
- constexpr decltype(auto) at_c(basic_tuple<Xs...>& xs) {
- return detail::ebo_get<detail::bti<n>>(xs);
- }
- template <std::size_t n, typename ...Xs>
- constexpr decltype(auto) at_c(basic_tuple<Xs...>&& xs) {
- return detail::ebo_get<detail::bti<n>>(static_cast<basic_tuple<Xs...>&&>(xs));
- }
- //////////////////////////////////////////////////////////////////////////
- // Sequence
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct Sequence<basic_tuple_tag> {
- static constexpr bool value = true;
- };
- template <>
- struct make_impl<basic_tuple_tag> {
- template <typename ...Xn>
- static constexpr basic_tuple<typename detail::decay<Xn>::type...>
- apply(Xn&& ...xn) {
- return basic_tuple<typename detail::decay<Xn>::type...>{
- static_cast<Xn&&>(xn)...
- };
- }
- };
- //////////////////////////////////////////////////////////////////////////
- // length
- //////////////////////////////////////////////////////////////////////////
- template <>
- struct length_impl<basic_tuple_tag> {
- template <typename ...Xn>
- static constexpr auto apply(basic_tuple<Xn...> const&) {
- return hana::size_t<sizeof...(Xn)>{};
- }
- };
- }} // end namespace boost::hana
- #endif // !BOOST_HANA_BASIC_TUPLE_HPP
|