Edit: /usr/include/boost/hana/tuple.hpp (11651B)
/*!
@file
Defines `boost::hana::tuple`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
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_TUPLE_HPP
#define BOOST_HANA_TUPLE_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // required by fwd decl of tuple_t
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
template
constexpr void assign(Xs& xs, Ys&& ys, std::index_sequence) {
int sequence[] = {int{}, ((void)(
hana::at_c(xs) = hana::at_c(static_cast(ys))
), int{})...};
(void)sequence;
}
struct from_index_sequence_t { };
template
struct is_same_tuple : std::false_type { };
template
struct is_same_tuple::type, Tuple>
: std::true_type
{ };
template
struct enable_tuple_variadic_ctor;
template
struct enable_tuple_variadic_ctor, Yn...>
: std::enable_if<
detail::fast_and::value
>
{ };
}
//////////////////////////////////////////////////////////////////////////
// tuple
//////////////////////////////////////////////////////////////////////////
template <>
#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
struct __declspec(empty_bases) tuple<> final
#else
struct tuple<> final
#endif
: detail::operators::adl>
, detail::iterable_operators>
{
constexpr tuple() { }
using hana_tag = tuple_tag;
};
template
#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
struct __declspec(empty_bases) tuple final
#else
struct tuple final
#endif
: detail::operators::adl>
, detail::iterable_operators>
{
basic_tuple storage_;
using hana_tag = tuple_tag;
private:
template
explicit constexpr tuple(detail::from_index_sequence_t, std::index_sequence, Other&& other)
: storage_(hana::at_c(static_cast(other))...)
{ }
public:
template ::value
>::type>
constexpr tuple()
: storage_()
{ }
template ::value
>::type>
constexpr tuple(Xn const& ...xn)
: storage_(xn...)
{ }
template ::value,
sizeof...(Xn) == sizeof...(Yn), tuple, Yn...
>::type>
constexpr tuple(Yn&& ...yn)
: storage_(static_cast(yn)...)
{ }
template ::value
>::type>
constexpr tuple(tuple const& other)
: tuple(detail::from_index_sequence_t{},
std::make_index_sequence{},
other.storage_)
{ }
template ::value
>::type>
constexpr tuple(tuple&& other)
: tuple(detail::from_index_sequence_t{},
std::make_index_sequence{},
static_cast&&>(other).storage_)
{ }
// The three following constructors are required to make sure that
// the tuple(Yn&&...) constructor is _not_ preferred over the copy
// constructor for unary tuples containing a type that is constructible
// from tuple<...>. See test/tuple/cnstr.trap.cpp
template ::value
>::type>
constexpr tuple(tuple const& other)
: tuple(detail::from_index_sequence_t{},
std::make_index_sequence{},
other.storage_)
{ }
template ::value
>::type>
constexpr tuple(tuple& other)
: tuple(const_cast(other))
{ }
template ::value
>::type>
constexpr tuple(tuple&& other)
: tuple(detail::from_index_sequence_t{},
std::make_index_sequence{},
static_cast(other).storage_)
{ }
template ::value
>::type>
constexpr tuple& operator=(tuple const& other) {
detail::assign(this->storage_, other.storage_,
std::make_index_sequence{});
return *this;
}
template ::value
>::type>
constexpr tuple& operator=(tuple&& other) {
detail::assign(this->storage_, static_cast&&>(other).storage_,
std::make_index_sequence{});
return *this;
}
};
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <>
struct comparable_operators {
static constexpr bool value = true;
};
template <>
struct orderable_operators {
static constexpr bool value = true;
};
template <>
struct monad_operators {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct unpack_impl {
template
static constexpr decltype(auto) apply(tuple<>&&, F&& f)
{ return static_cast(f)(); }
template
static constexpr decltype(auto) apply(tuple<>&, F&& f)
{ return static_cast(f)(); }
template
static constexpr decltype(auto) apply(tuple<> const&, F&& f)
{ return static_cast(f)(); }
template
static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
return hana::unpack(static_cast(xs).storage_, static_cast(f));
}
};
template <>
struct length_impl {
template
static constexpr auto apply(tuple const&)
{ return hana::size_c; }
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct at_impl {
template
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
constexpr std::size_t index = N::value;
return hana::at_c(static_cast(xs).storage_);
}
};
template <>
struct drop_front_impl {
template
static constexpr auto helper(Xs&& xs, std::index_sequence) {
return hana::make(hana::at_c(static_cast(xs))...);
}
template
static constexpr auto apply(Xs&& xs, N const&) {
constexpr std::size_t len = decltype(hana::length(xs))::value;
return helper(static_cast(xs), std::make_index_sequence<
(N::value < len) ? len - N::value : 0
>{});
}
};
template <>
struct is_empty_impl {
template
static constexpr auto apply(tuple const&)
{ return hana::bool_c; }
};
// compile-time optimizations (to reduce the # of function instantiations)
template
constexpr decltype(auto) at_c(tuple const& xs) {
return hana::at_c(xs.storage_);
}
template
constexpr decltype(auto) at_c(tuple& xs) {
return hana::at_c(xs.storage_);
}
template
constexpr decltype(auto) at_c(tuple&& xs) {
return hana::at_c(static_cast&&>(xs).storage_);
}
template <>
struct index_if_impl {
template
static constexpr auto apply(tuple const&, Pred const&)
-> typename detail::index_if::type
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Sequence
//////////////////////////////////////////////////////////////////////////
template <>
struct Sequence {
static constexpr bool value = true;
};
template <>
struct make_impl {
template
static constexpr
tuple::type...> apply(Xs&& ...xs)
{ return {static_cast(xs)...}; }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_TUPLE_HPP