stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,163 @@
/*!
@file
Adapts `std::array` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_ARRAY_HPP
#define BOOST_HANA_EXT_STD_ARRAY_HPP
#include <boost/hana/bool.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/algorithm.hpp>
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/drop_front.hpp>
#include <boost/hana/fwd/equal.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/less.hpp>
#include <boost/hana/integral_constant.hpp>
#include <array>
#include <cstddef>
#include <type_traits>
#include <utility>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adaptation of `std::array` for Hana.
//!
//!
//!
//! Modeled concepts
//! ----------------
//! 1. `Comparable`\n
//! `std::array`s are compared as per `std::equal`, except that two arrays
//! with different sizes compare unequal instead of triggering an error
//! and the result of the comparison is `constexpr` if both arrays are
//! `constexpr`.
//! @include example/ext/std/array/comparable.cpp
//!
//! 2. `Orderable`\n
//! `std::array`s are ordered with the usual lexicographical ordering,
//! except that two arrays with different size can be ordered instead
//! of triggering an error and the result of the comparison is `constexpr`
//! if both arrays are `constexpr`.
//! @include example/ext/std/array/orderable.cpp
//!
//! 3. `Foldable`\n
//! Folding an array from the left is equivalent to calling
//! `std::accumulate` on it, except it can be `constexpr`.
//! @include example/ext/std/array/foldable.cpp
//!
//! 4. `Iterable`\n
//! Iterating over a `std::array` is equivalent to iterating over it with
//! a normal `for` loop.
//! @include example/ext/std/array/iterable.cpp
template <typename T, std::size_t N>
struct array { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct array_tag; }}
template <typename T, std::size_t N>
struct tag_of<std::array<T, N>> {
using type = ext::std::array_tag;
};
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct length_impl<ext::std::array_tag> {
template <typename Xs>
static constexpr auto apply(Xs const&) {
return hana::size_c<std::tuple_size<Xs>::type::value>;
}
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct at_impl<ext::std::array_tag> {
template <typename Xs, typename N>
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
constexpr std::size_t n = N::value;
return std::get<n>(static_cast<Xs&&>(xs));
}
};
template <>
struct drop_front_impl<ext::std::array_tag> {
template <std::size_t n, typename Xs, std::size_t ...i>
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
using T = typename std::remove_reference<Xs>::type::value_type;
return std::array<T, sizeof...(i)>{{static_cast<Xs&&>(xs)[n + i]...}};
}
template <typename Xs, typename N>
static constexpr auto apply(Xs&& xs, N const&) {
constexpr std::size_t n = N::value;
constexpr std::size_t len = std::tuple_size<
typename std::remove_cv<
typename std::remove_reference<Xs>::type
>::type
>::value;
return drop_front_helper<n>(static_cast<Xs&&>(xs),
std::make_index_sequence<(n < len ? len - n : 0)>{});
}
};
template <>
struct is_empty_impl<ext::std::array_tag> {
template <typename T, std::size_t N>
static constexpr auto apply(std::array<T, N> const&) {
return hana::bool_c<N == 0>;
}
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl<ext::std::array_tag, ext::std::array_tag> {
template <typename T, std::size_t n, typename U>
static constexpr bool apply(std::array<T, n> const& xs, std::array<U, n> const& ys)
{ return detail::equal(&xs[0], &xs[0] + n, &ys[0], &ys[0] + n); }
template <typename T, typename U>
static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
{ return hana::true_c; }
template <typename T, std::size_t n, typename U, std::size_t m>
static constexpr auto apply(std::array<T, n> const&, std::array<U, m> const&)
{ return hana::false_c; }
};
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl<ext::std::array_tag, ext::std::array_tag> {
template <typename T, typename U>
static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
{ return hana::false_c; }
template <typename T, std::size_t n, typename U, std::size_t m>
static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) {
return detail::lexicographical_compare(&xs[0], &xs[0] + n, &ys[0], &ys[0] + m);
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_ARRAY_HPP
@@ -0,0 +1,140 @@
/*!
@file
Adapts `std::integer_sequence` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_INTEGER_SEQUENCE_HPP
#define BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
#include <boost/hana/bool.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/fast_and.hpp>
#include <boost/hana/ext/std/integral_constant.hpp>
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/drop_front.hpp>
#include <boost/hana/fwd/equal.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/unpack.hpp>
#include <cstddef>
#include <type_traits>
#include <utility>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adaptation of `std::integer_sequence` for Hana.
//!
//!
//!
//! Modeled concepts
//! ----------------
//! 1. `Comparable`\n
//! Two `std::integer_sequence`s are equal if and only if they have the
//! same number of elements, and if corresponding elements compare equal.
//! The types of the elements held in both `integer_sequence`s may be
//! different, as long as they can be compared.
//! @include example/ext/std/integer_sequence/comparable.cpp
//!
//! 2. `Foldable`\n
//! Folding an `integer_sequence` is equivalent to folding a sequence of
//! `std::integral_constant`s with the corresponding types.
//! @include example/ext/std/integer_sequence/foldable.cpp
//!
//! 3. `Iterable`\n
//! Iterating over an `integer_sequence` is equivalent to iterating over
//! a sequence of the corresponding `std::integral_constant`s.
//! @include example/ext/std/integer_sequence/iterable.cpp
//!
//! 4. `Searchable`\n
//! Searching through an `integer_sequence` is equivalent to searching
//! through the corresponding sequence of `std::integral_constant`s.
//! @include example/ext/std/integer_sequence/searchable.cpp
template <typename T, T ...v>
struct integer_sequence { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct integer_sequence_tag; }}
template <typename T, T ...v>
struct tag_of<std::integer_sequence<T, v...>> {
using type = ext::std::integer_sequence_tag;
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl<ext::std::integer_sequence_tag, ext::std::integer_sequence_tag> {
template <typename X, X ...xs, typename Y, Y ...ys>
static constexpr hana::bool_<detail::fast_and<(xs == ys)...>::value>
apply(std::integer_sequence<X, xs...> const&, std::integer_sequence<Y, ys...> const&)
{ return {}; }
template <typename Xs, typename Ys>
static constexpr hana::false_ apply(Xs const&, Ys const&, ...)
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct unpack_impl<ext::std::integer_sequence_tag> {
template <typename T, T ...v, typename F>
static constexpr decltype(auto)
apply(std::integer_sequence<T, v...> const&, F&& f) {
return static_cast<F&&>(f)(std::integral_constant<T, v>{}...);
}
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct at_impl<ext::std::integer_sequence_tag> {
template <typename T, T ...v, typename N>
static constexpr auto apply(std::integer_sequence<T, v...> const&, N const&) {
constexpr std::size_t n = N::value;
constexpr T values_[] = {v...};
return std::integral_constant<T, values_[n]>{};
}
};
template <>
struct drop_front_impl<ext::std::integer_sequence_tag> {
template <std::size_t n, typename T, T ...t, std::size_t ...i>
static constexpr auto drop_front_helper(std::integer_sequence<T, t...>,
std::index_sequence<i...>)
{
constexpr T ts[sizeof...(t)+1] = {t...}; // avoid 0-sized array
return std::integer_sequence<T, ts[n + i]...>{};
}
template <typename T, T ...t, typename N>
static constexpr auto apply(std::integer_sequence<T, t...> ts, N const&) {
constexpr std::size_t n = N::value;
constexpr std::size_t len = sizeof...(t);
return drop_front_helper<n>(ts,
std::make_index_sequence<(n < len ? len - n : 0)>{});
}
};
template <>
struct is_empty_impl<ext::std::integer_sequence_tag> {
template <typename T, T ...xs>
static constexpr auto apply(std::integer_sequence<T, xs...> const&)
{ return hana::bool_c<sizeof...(xs) == 0>; }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
@@ -0,0 +1,96 @@
/*!
@file
Adapts `std::integral_constant` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_INTEGRAL_CONSTANT_HPP
#define BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP
#include <boost/hana/concept/integral_constant.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>
#include <boost/hana/fwd/core/to.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/integral_constant.hpp>
#include <type_traits>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adapter for `std::integral_constant`s.
//!
//! Provided models
//! ---------------
//! 1. `Constant` and `IntegralConstant`\n
//! A `std::integral_constant` is a model of the `IntegralConstant` and
//! `Constant` concepts, just like `hana::integral_constant`s are. As a
//! consequence, they are also implicitly a model of the concepts provided
//! for all models of `Constant`.
//! @include example/ext/std/integral_constant.cpp
template <typename T, T v>
struct integral_constant { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std {
template <typename T>
struct integral_constant_tag { using value_type = T; };
}}
namespace detail {
template <typename T, T v>
constexpr bool
is_std_integral_constant(std::integral_constant<T, v>*)
{ return true; }
constexpr bool is_std_integral_constant(...)
{ return false; }
template <typename T, T v>
constexpr bool
is_hana_integral_constant(hana::integral_constant<T, v>*)
{ return true; }
constexpr bool is_hana_integral_constant(...)
{ return false; }
}
template <typename T>
struct tag_of<T, when<
detail::is_std_integral_constant((T*)0) &&
!detail::is_hana_integral_constant((T*)0)
>> {
using type = ext::std::integral_constant_tag<
typename hana::tag_of<typename T::value_type>::type
>;
};
//////////////////////////////////////////////////////////////////////////
// Constant/IntegralConstant
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct IntegralConstant<ext::std::integral_constant_tag<T>> {
static constexpr bool value = true;
};
template <typename T, typename C>
struct to_impl<ext::std::integral_constant_tag<T>, C, when<
hana::IntegralConstant<C>::value
>> : embedding<is_embedded<typename C::value_type, T>::value> {
template <typename N>
static constexpr auto apply(N const&) {
return std::integral_constant<T, N::value>{};
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP
@@ -0,0 +1,91 @@
/*!
@file
Adapts `std::pair` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_PAIR_HPP
#define BOOST_HANA_EXT_STD_PAIR_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/first.hpp>
#include <boost/hana/fwd/second.hpp>
#include <utility>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adaptation of `std::pair` for Hana.
//!
//!
//! Modeled concepts
//! ----------------
//! A `std::pair` models exactly the same concepts as a `hana::pair`.
//! Please refer to the documentation of `hana::pair` for details.
//!
//! @include example/ext/std/pair.cpp
template <typename First, typename Second>
struct pair { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct pair_tag; }}
template <typename First, typename Second>
struct tag_of<std::pair<First, Second>> {
using type = ext::std::pair_tag;
};
//////////////////////////////////////////////////////////////////////////
// Product
//////////////////////////////////////////////////////////////////////////
template <>
struct make_impl<ext::std::pair_tag> {
template <typename X, typename Y>
static constexpr decltype(auto) apply(X&& x, Y&& y) {
return std::make_pair(static_cast<X&&>(x),
static_cast<Y&&>(y));
}
};
template <>
struct first_impl<ext::std::pair_tag> {
template <typename T, typename U>
static constexpr T const& apply(std::pair<T, U> const& p)
{ return p.first; }
template <typename T, typename U>
static constexpr T& apply(std::pair<T, U>& p)
{ return p.first; }
template <typename T, typename U>
static constexpr T&& apply(std::pair<T, U>&& p)
{ return static_cast<T&&>(p.first); }
};
template <>
struct second_impl<ext::std::pair_tag> {
template <typename T, typename U>
static constexpr U const& apply(std::pair<T, U> const& p)
{ return p.second; }
template <typename T, typename U>
static constexpr U& apply(std::pair<T, U>& p)
{ return p.second; }
template <typename T, typename U>
static constexpr U&& apply(std::pair<T, U>&& p)
{ return static_cast<U&&>(p.second); }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_PAIR_HPP
@@ -0,0 +1,164 @@
/*!
@file
Adapts `std::ratio` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_RATIO_HPP
#define BOOST_HANA_EXT_STD_RATIO_HPP
#include <boost/hana/bool.hpp>
#include <boost/hana/concept/integral_constant.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>
#include <boost/hana/fwd/core/to.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/div.hpp>
#include <boost/hana/fwd/equal.hpp>
#include <boost/hana/fwd/less.hpp>
#include <boost/hana/fwd/minus.hpp>
#include <boost/hana/fwd/mod.hpp>
#include <boost/hana/fwd/mult.hpp>
#include <boost/hana/fwd/one.hpp>
#include <boost/hana/fwd/plus.hpp>
#include <boost/hana/fwd/zero.hpp>
#include <cstdint>
#include <ratio>
#include <type_traits>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adaptation of `std::ratio` for Hana.
//!
//!
//! Modeled concepts
//! ----------------
//! 1. `Comparable`\n
//! `std::ratio`s are compared for equality using `std::ratio_equal`.
//! @include example/ext/std/ratio/comparable.cpp
//!
//! 2. `Orderable`\n
//! `std::ratio`s are ordered using `std::ratio_less`.
//! @include example/ext/std/ratio/orderable.cpp
//!
//! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n
//! `std::ratio`s are added, subtracted, multiplied and divided using
//! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and
//! `std::ratio_divide`, respectively. Furthermore, the neutral element
//! for the additive operation is `std::ratio<0, 1>{}`, and the neutral
//! element for the multiplicative operation is `std::ratio<1, 1>{}`.
//! @include example/ext/std/ratio/arithmetic.cpp
template <std::intmax_t Num, std::intmax_t Denom>
class ratio { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct ratio_tag; }}
template <std::intmax_t num, std::intmax_t den>
struct tag_of<std::ratio<num, den>> {
using type = ext::std::ratio_tag;
};
//////////////////////////////////////////////////////////////////////////
// Conversion from IntegralConstants
//////////////////////////////////////////////////////////////////////////
template <typename C>
struct to_impl<ext::std::ratio_tag, C, when<
hana::IntegralConstant<C>::value
>> {
template <typename N>
static constexpr auto apply(N const&) {
return std::ratio<N::value>{};
}
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr auto apply(R1 const&, R2 const&)
{ return hana::bool_c<std::ratio_equal<R1, R2>::value>; }
};
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr auto apply(R1 const&, R2 const&)
{ return hana::bool_c<std::ratio_less<R1, R2>::value>; }
};
//////////////////////////////////////////////////////////////////////////
// Monoid
//////////////////////////////////////////////////////////////////////////
template <>
struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&)
{ return {}; }
};
template <>
struct zero_impl<ext::std::ratio_tag> {
static constexpr std::ratio<0> apply()
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Group
//////////////////////////////////////////////////////////////////////////
template <>
struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&)
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Ring
//////////////////////////////////////////////////////////////////////////
template <>
struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&)
{ return {}; }
};
template <>
struct one_impl<ext::std::ratio_tag> {
static constexpr std::ratio<1> apply()
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// EuclideanRing
//////////////////////////////////////////////////////////////////////////
template <>
struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&)
{ return {}; }
};
template <>
struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
template <typename R1, typename R2>
static constexpr std::ratio<0> apply(R1 const&, R2 const&)
{ return {}; }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_RATIO_HPP
@@ -0,0 +1,191 @@
/*!
@file
Adapts `std::tuple` for use with Hana.
@copyright Louis Dionne 2013-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_EXT_STD_TUPLE_HPP
#define BOOST_HANA_EXT_STD_TUPLE_HPP
#include <boost/hana/bool.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/fwd/at.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/empty.hpp>
#include <boost/hana/fwd/flatten.hpp>
#include <boost/hana/fwd/front.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/lift.hpp>
#include <boost/hana/integral_constant.hpp>
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
#ifdef BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER
# error The adapter for std::tuple is not supported with versions of \
libc++ prior to the one shipped with Clang 3.7 because of a bug \
in the tuple implementation.
#endif
#ifdef BOOST_HANA_DOXYGEN_INVOKED
namespace std {
//! @ingroup group-ext-std
//! Adapter for `std::tuple`s.
//!
//!
//! Modeled concepts
//! ----------------
//! A `std::tuple` is a model of the `Sequence` concept, and all the
//! concepts it refines. That makes it essentially the same as a Hana
//! tuple, although the complexity of some operations might differ from
//! that of Hana's tuple.
//!
//! @include example/ext/std/tuple.cpp
template <typename ...T>
struct tuple { };
}
#endif
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct tuple_tag; }}
template <typename ...Xs>
struct tag_of<std::tuple<Xs...>> {
using type = ext::std::tuple_tag;
};
//////////////////////////////////////////////////////////////////////////
// make
//////////////////////////////////////////////////////////////////////////
template <>
struct make_impl<ext::std::tuple_tag> {
template <typename ...Xs>
static constexpr decltype(auto) apply(Xs&& ...xs) {
return std::make_tuple(static_cast<Xs&&>(xs)...);
}
};
//////////////////////////////////////////////////////////////////////////
// Applicative
//////////////////////////////////////////////////////////////////////////
template <>
struct lift_impl<ext::std::tuple_tag> {
template <typename X>
static constexpr auto apply(X&& x) {
return std::tuple<typename detail::decay<X>::type>{
static_cast<X&&>(x)};
}
};
//////////////////////////////////////////////////////////////////////////
// Monad
//////////////////////////////////////////////////////////////////////////
template <>
struct flatten_impl<ext::std::tuple_tag> {
template <typename Xs, std::size_t ...i>
static constexpr decltype(auto)
flatten_helper(Xs&& xs, std::index_sequence<i...>) {
#if defined(BOOST_HANA_CONFIG_LIBCPP_HAS_BUG_22806)
return std::tuple_cat(std::get<i>(xs)...);
#else
return std::tuple_cat(std::get<i>(static_cast<Xs&&>(xs))...);
#endif
}
template <typename Xs>
static constexpr decltype(auto) apply(Xs&& xs) {
using Raw = typename std::remove_reference<Xs>::type;
constexpr std::size_t Length = std::tuple_size<Raw>::value;
return flatten_helper(static_cast<Xs&&>(xs),
std::make_index_sequence<Length>{});
}
};
//////////////////////////////////////////////////////////////////////////
// MonadPlus
//////////////////////////////////////////////////////////////////////////
template <>
struct empty_impl<ext::std::tuple_tag> {
static constexpr auto apply()
{ return std::tuple<>{}; }
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct front_impl<ext::std::tuple_tag> {
template <typename Xs>
static constexpr decltype(auto) apply(Xs&& xs) {
return std::get<0>(static_cast<Xs&&>(xs));
}
};
template <>
struct drop_front_impl<ext::std::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 std::make_tuple(
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
);
}
template <typename Xs, typename N>
static constexpr auto apply(Xs&& xs, N const&) {
using Raw = typename std::remove_reference<Xs>::type;
constexpr std::size_t n = N::value;
constexpr auto len = std::tuple_size<Raw>::value;
return drop_front_helper<n>(static_cast<Xs&&>(xs),
std::make_index_sequence<(n < len ? len - n : 0)>{});
}
};
template <>
struct is_empty_impl<ext::std::tuple_tag> {
template <typename ...Xs>
static constexpr auto apply(std::tuple<Xs...> const&)
{ return hana::bool_c<sizeof...(Xs) == 0>; }
};
template <>
struct at_impl<ext::std::tuple_tag> {
template <typename Xs, typename N>
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
constexpr std::size_t index = N::value;
return std::get<index>(static_cast<Xs&&>(xs));
}
};
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct length_impl<ext::std::tuple_tag> {
template <typename ...Xs>
static constexpr auto apply(std::tuple<Xs...> const&) {
return hana::size_c<sizeof...(Xs)>;
}
};
//////////////////////////////////////////////////////////////////////////
// Sequence
//////////////////////////////////////////////////////////////////////////
template <>
struct Sequence<ext::std::tuple_tag> {
static constexpr bool value = true;
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_TUPLE_HPP
@@ -0,0 +1,110 @@
/*!
@file
Adapts `std::vector` for use with Hana.
@copyright Louis Dionne 2013-2017
@copyright Gonzalo Brito Gadeschi 2015
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_EXT_STD_VECTOR_HPP
#define BOOST_HANA_EXT_STD_VECTOR_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/less.hpp>
#include <algorithm>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
BOOST_HANA_NAMESPACE_BEGIN
namespace ext { namespace std { struct vector_tag; }}
template <typename T, typename Allocator>
struct tag_of<std::vector<T, Allocator>> {
using type = ext::std::vector_tag;
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl<ext::std::vector_tag, ext::std::vector_tag> {
template <typename T1, typename A1, typename T2, typename A2>
static bool apply(std::vector<T1, A1> const& v1,
std::vector<T2, A2> const& v2)
{
return std::equal(begin(v1), end(v1),
begin(v2), end(v2),
hana::equal);
}
};
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl<ext::std::vector_tag, ext::std::vector_tag> {
template <typename T1, typename A1, typename T2, typename A2>
static bool apply(std::vector<T1, A1> const& v1,
std::vector<T2, A2> const& v2)
{
return std::lexicographical_compare(begin(v1), end(v1),
begin(v2), end(v2),
hana::less);
}
};
#if 0
//////////////////////////////////////////////////////////////////////////
// Functor
//////////////////////////////////////////////////////////////////////////
template <>
struct transform_impl<ext::std::vector_tag> {
template <typename V, typename F>
static auto apply(V&& v, F&& f) {
using U = std::remove_cv_t<std::remove_reference_t<
decltype(f(*v.begin()))
>>;
using Alloc = typename std::remove_reference_t<V>::allocator_type;
using NewAlloc = typename std::allocator_traits<Alloc>::
template rebind_alloc<U>;
std::vector<U, NewAlloc> result; result.reserve(v.size());
std::transform(begin(v), end(v),
std::back_inserter(result), std::forward<F>(f));
return result;
}
template <typename T, typename Alloc, typename F>
static auto apply(std::vector<T, Alloc>&& v, F&& f)
-> std::enable_if_t<
std::is_same<
T,
std::remove_cv_t<std::remove_reference_t<
decltype(f(*v.begin()))
>>
>{}
, std::vector<T, Alloc>
>
{
// If we receive a rvalue and the function returns elements of
// the same type, we modify the vector in-place instead of
// returning a new one.
std::transform(std::make_move_iterator(begin(v)),
std::make_move_iterator(end(v)),
begin(v), std::forward<F>(f));
return std::move(v);
}
};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXT_STD_VECTOR_HPP