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,257 @@
/*
@file
Defines `boost::hana::experimental::print`.
@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_EXPERIMENTAL_PRINTABLE_HPP
#define BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
#include <boost/hana/concept/constant.hpp>
#include <boost/hana/concept/product.hpp>
#include <boost/hana/concept/sequence.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/to.hpp>
#include <boost/hana/core/dispatch.hpp>
#include <boost/hana/first.hpp>
#include <boost/hana/for_each.hpp>
#include <boost/hana/intersperse.hpp>
#include <boost/hana/second.hpp>
#include <boost/hana/transform.hpp>
#include <boost/hana/tuple.hpp>
// models for different containers
#include <boost/hana/fwd/map.hpp>
#include <boost/hana/fwd/optional.hpp>
#include <boost/hana/fwd/set.hpp>
#include <boost/hana/fwd/string.hpp>
#include <boost/hana/fwd/type.hpp>
#include <boost/core/demangle.hpp>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>
#include <typeinfo>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
template <typename T>
struct Printable;
//! @cond
template <typename T, typename = void>
struct print_impl : print_impl<T, hana::when<true>> { };
template <typename T, bool condition>
struct print_impl<T, hana::when<condition>> : hana::default_ {
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};
//! @endcond
//! @ingroup group-experimental
//! Returns a string representation of the given object.
//!
//! This function is defined for most containers provided by Hana, and
//! also for objects that define an `operator<<` that can be used with
//! a `std::basic_ostream`. It can recursively print containers within
//! containers, but do not expect any kind of proper indentation.
//!
//! This function requires (the rest of) Boost to be available on the
//! system. It also requires RTTI to be enabled.
#ifdef BOOST_HANA_DOXYGEN_INVOKED
auto print = [](auto const& x) -> std::string {
return tag-dispatched;
};
#else
struct print_t {
template <typename T>
std::string operator()(T const& t) const {
using Tag = typename hana::tag_of<T>::type;
using Print = BOOST_HANA_DISPATCH_IF(print_impl<Tag>,
hana::experimental::Printable<Tag>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::experimental::Printable<Tag>::value,
"hana::experimental::print(t) requires 't' to be Printable");
#endif
return Print::apply(t);
}
};
constexpr print_t print{};
#endif
// Define the `Printable` concept
template <typename T>
struct Printable {
using Tag = typename hana::tag_of<T>::type;
static constexpr bool value = !hana::is_default<print_impl<Tag>>::value;
};
namespace print_detail {
std::string strip_type_junk(std::string const& str) {
return std::regex_replace(str, std::regex("^([a-z_]+::)*([a-z_]*)_t<"), "$2<");
}
}
// model for Sequences
template <typename S>
struct print_impl<S, hana::when<hana::Sequence<S>::value>> {
template <typename Xs>
static std::string apply(Xs const& xs) {
std::string result = "(";
auto comma_separated = hana::intersperse(xs, ", ");
hana::for_each(comma_separated, [&result](auto const& x) {
result += hana::experimental::print(x);
});
result += ")";
return result;
}
};
// model for OutputStreamable types
//! @cond
template <typename S>
struct print_impl<S, hana::when_valid<decltype(
std::declval<std::ostringstream&>() << std::declval<S const&>()
)>> {
template <typename T>
static std::string apply(T const& t) {
std::ostringstream os;
os << t;
return os.str();
}
};
//! @endcond
// model for hana::optional
template <>
struct print_impl<hana::optional_tag> {
template <typename O>
static std::string apply(O const& optional) {
return hana::maybe("nothing",
[](auto const& x) {
return "just(" + hana::experimental::print(x) + ")";
}, optional);
}
};
// model for hana::maps
template <>
struct print_impl<hana::map_tag> {
template <typename M>
static std::string apply(M const& map) {
std::string result = "{";
auto pairs = hana::transform(hana::to_tuple(map),
[](auto const& pair) {
return hana::experimental::print(hana::first(pair))
+ " => "
+ hana::experimental::print(hana::second(pair));
});
auto comma_separated = hana::intersperse(pairs, ", ");
hana::for_each(comma_separated, [&result](auto const& element) {
result += element;
});
result += "}";
return result;
}
};
// model for hana::metafunctions
template <template <typename ...> class F>
struct print_impl<hana::metafunction_t<F>> {
template <typename T>
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for hana::metafunction_classes
template <typename F>
struct print_impl<hana::metafunction_class_t<F>> {
template <typename T>
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for Constants holding a `Printable`
template <typename C>
struct print_impl<C, hana::when<
hana::Constant<C>::value &&
Printable<typename C::value_type>::value
>> {
template <typename T>
static std::string apply(T const&) {
constexpr auto value = hana::value<T>();
return hana::experimental::print(value);
}
};
// model for Products
template <typename P>
struct print_impl<P, hana::when<hana::Product<P>::value>> {
template <typename T>
static std::string apply(T const& t) {
return '(' + hana::experimental::print(hana::first(t))
+ ", "
+ hana::experimental::print(hana::second(t)) + ')';
}
};
// model for hana::strings
template <>
struct print_impl<hana::string_tag> {
template <typename S>
static std::string apply(S const& s) {
return '"' + std::string{hana::to<char const*>(s)} + '"';
}
};
// model for hana::sets
template <>
struct print_impl<hana::set_tag> {
template <typename S>
static std::string apply(S const& set) {
std::string result = "{";
auto as_tuple = hana::transform(hana::to_tuple(set),
hana::experimental::print);
auto comma_separated = hana::intersperse(as_tuple, ", ");
hana::for_each(comma_separated, [&result](auto const& element) {
result += element;
});
result += "}";
return result;
}
};
// model for hana::templates
template <template <typename ...> class F>
struct print_impl<template_t<F>> {
template <typename T>
static std::string apply(T const&) {
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
}
};
// model for hana::types
template <>
struct print_impl<hana::type_tag> {
template <typename T>
static std::string apply(T const&) {
using Type = typename T::type;
return "type<" + boost::core::demangle(typeid(Type).name()) + '>';
}
};
} BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
@@ -0,0 +1,64 @@
/*
@file
Defines `boost::hana::experimental::type_name`.
@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_EXPERIMENTAL_TYPE_NAME_HPP
#define BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/string.hpp>
#include <cstddef>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
namespace detail {
struct cstring {
char const* ptr;
std::size_t length;
};
// Note: We substract the null terminator from the string sizes below.
template <typename T>
constexpr cstring type_name_impl2() {
#if defined(__clang__)
constexpr char const* pretty_function = __PRETTY_FUNCTION__;
constexpr std::size_t total_size = sizeof(__PRETTY_FUNCTION__) - 1;
constexpr std::size_t prefix_size = sizeof("boost::hana::experimental::detail::cstring boost::hana::experimental::detail::type_name_impl2() [T = ") - 1;
constexpr std::size_t suffix_size = sizeof("]") - 1;
#else
#error "No support for this compiler."
#endif
return {pretty_function + prefix_size, total_size - prefix_size - suffix_size};
}
template <typename T, std::size_t ...i>
auto type_name_impl1(std::index_sequence<i...>) {
constexpr auto name = detail::type_name_impl2<T>();
return hana::string<*(name.ptr + i)...>{};
}
} // end namespace detail
//! @ingroup group-experimental
//! Returns a `hana::string` representing the name of the given type, at
//! compile-time.
//!
//! This only works on Clang (and apparently MSVC, but Hana does not work
//! there as of writing this). Original idea taken from
//! https://github.com/Manu343726/ctti.
template <typename T>
auto type_name() {
constexpr auto name = detail::type_name_impl2<T>();
return detail::type_name_impl1<T>(std::make_index_sequence<name.length>{});
}
} BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
@@ -0,0 +1,158 @@
/*!
@file
Defines `boost::hana::experimental::types`.
@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_EXPERIMENTAL_TYPES_HPP
#define BOOST_HANA_EXPERIMENTAL_TYPES_HPP
#include <boost/hana/bool.hpp>
#include <boost/hana/concept/metafunction.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/any_of.hpp>
#include <boost/hana/detail/type_at.hpp>
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/contains.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/equal.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/transform.hpp>
#include <boost/hana/fwd/unpack.hpp>
#include <boost/hana/type.hpp>
#include <cstddef>
#include <type_traits>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN
namespace experimental {
//! @ingroup group-experimental
//! Container optimized for holding types.
//!
//! It is often useful to manipulate a sequence that contains types
//! only, without any associated runtime value. This container allows
//! storing and manipulating pure types in a much more compile-time
//! efficient manner than using `hana::tuple`, which must assume that
//! its contents might have runtime values.
template <typename ...T>
struct types;
struct types_tag;
template <typename ...T>
struct types { };
} // end namespace experimental
template <typename ...T>
struct tag_of<experimental::types<T...>> {
using type = experimental::types_tag;
};
// Foldable
template <>
struct unpack_impl<hana::experimental::types_tag> {
template <typename ...T, typename F, typename = typename std::enable_if<
!hana::Metafunction<F>::value
>::type>
static constexpr decltype(auto) apply(hana::experimental::types<T...> const&, F&& f) {
return static_cast<F&&>(f)(hana::type<T>{}...);
}
template <typename ...T, typename F, typename = typename std::enable_if<
hana::Metafunction<F>::value
>::type>
static constexpr hana::type<typename F::template apply<T...>::type>
apply(hana::experimental::types<T...> const&, F const&) { return {}; }
};
// Functor
template <>
struct transform_impl<hana::experimental::types_tag> {
template <typename ...T, typename F, typename = typename std::enable_if<
!hana::Metafunction<F>::value
>::type>
static constexpr auto apply(hana::experimental::types<T...> const&, F&& f)
-> hana::experimental::types<typename decltype(+f(hana::type<T>{}))::type...>
{ return {}; }
template <typename ...T, typename F, typename = typename std::enable_if<
hana::Metafunction<F>::value
>::type>
static constexpr hana::experimental::types<typename F::template apply<T>::type...>
apply(hana::experimental::types<T...> const&, F const&) { return {}; }
};
// Iterable
template <>
struct at_impl<hana::experimental::types_tag> {
template <typename ...T, typename N>
static constexpr auto
apply(hana::experimental::types<T...> const&, N const&) {
using Nth = typename detail::type_at<N::value, T...>::type;
return hana::type<Nth>{};
}
};
template <>
struct is_empty_impl<hana::experimental::types_tag> {
template <typename ...T>
static constexpr hana::bool_<sizeof...(T) == 0>
apply(hana::experimental::types<T...> const&)
{ return {}; }
};
template <>
struct drop_front_impl<hana::experimental::types_tag> {
template <std::size_t n, typename ...T, std::size_t ...i>
static hana::experimental::types<typename detail::type_at<i + n, T...>::type...>
helper(std::index_sequence<i...>);
template <typename ...T, typename N>
static constexpr auto
apply(hana::experimental::types<T...> const&, N const&) {
constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value;
using Indices = std::make_index_sequence<sizeof...(T) - n>;
return decltype(helper<n, T...>(Indices{})){};
}
};
// Searchable
template <>
struct contains_impl<hana::experimental::types_tag> {
template <typename U>
struct is_same_as {
template <typename T>
struct apply {
static constexpr bool value = std::is_same<U, T>::value;
};
};
template <typename ...T, typename U>
static constexpr auto apply(hana::experimental::types<T...> const&, U const&)
-> hana::bool_<
detail::any_of<is_same_as<typename U::type>::template apply, T...>::value
>
{ return {}; }
static constexpr hana::false_ apply(...) { return {}; }
};
// Comparable
template <>
struct equal_impl<hana::experimental::types_tag, hana::experimental::types_tag> {
template <typename Types>
static constexpr hana::true_ apply(Types const&, Types const&)
{ return {}; }
template <typename Ts, typename Us>
static constexpr hana::false_ apply(Ts const&, Us const&)
{ return {}; }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXPERIMENTAL_TYPES_HPP
@@ -0,0 +1,514 @@
/*
@file
Defines experimental views.
@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_EXPERIMENTAL_VIEW_HPP
#define BOOST_HANA_EXPERIMENTAL_VIEW_HPP
#include <boost/hana/and.hpp>
#include <boost/hana/at.hpp>
#include <boost/hana/bool.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/fold_left.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/fwd/ap.hpp>
#include <boost/hana/fwd/concat.hpp>
#include <boost/hana/fwd/drop_front.hpp>
#include <boost/hana/fwd/empty.hpp>
#include <boost/hana/fwd/equal.hpp>
#include <boost/hana/fwd/flatten.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/less.hpp>
#include <boost/hana/fwd/lift.hpp>
#include <boost/hana/fwd/transform.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/length.hpp>
#include <boost/hana/lexicographical_compare.hpp>
#include <boost/hana/range.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/unpack.hpp>
#include <cstddef>
#include <type_traits>
#include <utility>
// Pros of views
// - No temporary container created between algorithms
// - Lazy, so only the minimum is required
//
// Cons of views
// - Reference semantics mean possibility for dangling references
// - Lose the ability to move from temporary containers
// - When fetching the members of a view multiple times, no caching is done.
// So for example, `t = transform(xs, f); at_c<0>(t); at_c<0>(t)` will
// compute `f(at_c<0>(xs))` twice.
// - push_back creates a joint_view and a single_view. The single_view holds
// the value as a member. When doing multiple push_backs, we end up with a
// joint_view<xxx, joint_view<single_view<T>, joint_view<single_view<T>, ....>>>
// which contains a reference to `xxx` and all the `T`s by value. Such a
// "view" is not cheap to copy, which is inconsistent with the usual
// expectations about views.
BOOST_HANA_NAMESPACE_BEGIN
namespace experimental {
struct view_tag;
namespace detail {
template <typename Sequence>
struct is_view {
static constexpr bool value = false;
};
template <typename Sequence>
using view_storage = typename std::conditional<
detail::is_view<Sequence>::value, Sequence, Sequence&
>::type;
}
//////////////////////////////////////////////////////////////////////////
// sliced_view
//////////////////////////////////////////////////////////////////////////
template <typename Sequence, std::size_t ...indices>
struct sliced_view_t {
detail::view_storage<Sequence> sequence_;
using hana_tag = view_tag;
};
template <typename Sequence, typename Indices>
constexpr auto sliced(Sequence& sequence, Indices const& indices) {
return hana::unpack(indices, [&](auto ...i) {
return sliced_view_t<Sequence, decltype(i)::value...>{sequence};
});
}
namespace detail {
template <typename Sequence, std::size_t ...i>
struct is_view<sliced_view_t<Sequence, i...>> {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// transformed_view
//////////////////////////////////////////////////////////////////////////
template <typename Sequence, typename F>
struct transformed_view_t {
detail::view_storage<Sequence> sequence_;
F f_;
using hana_tag = view_tag;
};
template <typename Sequence, typename F>
constexpr transformed_view_t<Sequence, typename hana::detail::decay<F>::type>
transformed(Sequence& sequence, F&& f) {
return {sequence, static_cast<F&&>(f)};
}
namespace detail {
template <typename Sequence, typename F>
struct is_view<transformed_view_t<Sequence, F>> {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// filtered_view
//////////////////////////////////////////////////////////////////////////
#if 0
template <typename Sequence, typename Pred>
using filtered_view_t = sliced_view_t<Sequence, detail::filtered_indices<...>>;
template <typename Sequence, typename Pred>
constexpr filtered_view_t<Sequence, Pred> filtered(Sequence& sequence, Pred&& pred) {
return {sequence};
}
#endif
//////////////////////////////////////////////////////////////////////////
// joined_view
//////////////////////////////////////////////////////////////////////////
template <typename Sequence1, typename Sequence2>
struct joined_view_t {
detail::view_storage<Sequence1> sequence1_;
detail::view_storage<Sequence2> sequence2_;
using hana_tag = view_tag;
};
struct make_joined_view_t {
template <typename Sequence1, typename Sequence2>
constexpr joined_view_t<Sequence1, Sequence2> operator()(Sequence1& s1, Sequence2& s2) const {
return {s1, s2};
}
};
constexpr make_joined_view_t joined{};
namespace detail {
template <typename Sequence1, typename Sequence2>
struct is_view<joined_view_t<Sequence1, Sequence2>> {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// single_view
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct single_view_t {
T value_;
using hana_tag = view_tag;
};
template <typename T>
constexpr single_view_t<typename hana::detail::decay<T>::type> single_view(T&& t) {
return {static_cast<T&&>(t)};
}
namespace detail {
template <typename T>
struct is_view<single_view_t<T>> {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// empty_view
//////////////////////////////////////////////////////////////////////////
struct empty_view_t {
using hana_tag = view_tag;
};
constexpr empty_view_t empty_view() {
return {};
}
namespace detail {
template <>
struct is_view<empty_view_t> {
static constexpr bool value = true;
};
}
} // end namespace experimental
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct unpack_impl<experimental::view_tag> {
// sliced_view
template <typename Sequence, std::size_t ...i, typename F>
static constexpr decltype(auto)
apply(experimental::sliced_view_t<Sequence, i...> view, F&& f) {
(void)view; // Remove spurious unused variable warning with GCC
return static_cast<F&&>(f)(hana::at_c<i>(view.sequence_)...);
}
// transformed_view
template <typename Sequence, typename F, typename G>
static constexpr decltype(auto)
apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
return hana::unpack(view.sequence_, hana::on(static_cast<G&&>(g), view.f_));
}
// joined_view
template <typename View, typename F, std::size_t ...i1, std::size_t ...i2>
static constexpr decltype(auto)
unpack_joined(View view, F&& f, std::index_sequence<i1...>,
std::index_sequence<i2...>)
{
(void)view; // Remove spurious unused variable warning with GCC
return static_cast<F&&>(f)(hana::at_c<i1>(view.sequence1_)...,
hana::at_c<i2>(view.sequence2_)...);
}
template <typename S1, typename S2, typename F>
static constexpr decltype(auto)
apply(experimental::joined_view_t<S1, S2> view, F&& f) {
constexpr auto N1 = decltype(hana::length(view.sequence1_))::value;
constexpr auto N2 = decltype(hana::length(view.sequence2_))::value;
return unpack_joined(view, static_cast<F&&>(f),
std::make_index_sequence<N1>{},
std::make_index_sequence<N2>{});
}
// single_view
template <typename T, typename F>
static constexpr decltype(auto) apply(experimental::single_view_t<T> view, F&& f) {
return static_cast<F&&>(f)(view.value_);
}
// empty_view
template <typename F>
static constexpr decltype(auto) apply(experimental::empty_view_t, F&& f) {
return static_cast<F&&>(f)();
}
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct at_impl<experimental::view_tag> {
// sliced_view
template <typename Sequence, std::size_t ...i, typename N>
static constexpr decltype(auto)
apply(experimental::sliced_view_t<Sequence, i...> view, N const&) {
constexpr std::size_t indices[] = {i...};
constexpr std::size_t n = indices[N::value];
return hana::at_c<n>(view.sequence_);
}
// transformed_view
template <typename Sequence, typename F, typename N>
static constexpr decltype(auto)
apply(experimental::transformed_view_t<Sequence, F> view, N const& n) {
return view.f_(hana::at(view.sequence_, n));
}
// joined_view
template <std::size_t Left, typename View, typename N>
static constexpr decltype(auto) at_joined_view(View view, N const&, hana::true_) {
return hana::at_c<N::value>(view.sequence1_);
}
template <std::size_t Left, typename View, typename N>
static constexpr decltype(auto) at_joined_view(View view, N const&, hana::false_) {
return hana::at_c<N::value - Left>(view.sequence2_);
}
template <typename S1, typename S2, typename N>
static constexpr decltype(auto)
apply(experimental::joined_view_t<S1, S2> view, N const& n) {
constexpr auto Left = decltype(hana::length(view.sequence1_))::value;
return at_joined_view<Left>(view, n, hana::bool_c<(N::value < Left)>);
}
// single_view
template <typename T, typename N>
static constexpr decltype(auto) apply(experimental::single_view_t<T> view, N const&) {
static_assert(N::value == 0,
"trying to fetch an out-of-bounds element in a hana::single_view");
return view.value_;
}
// empty_view
template <typename N>
static constexpr decltype(auto) apply(experimental::empty_view_t, N const&) = delete;
};
template <>
struct length_impl<experimental::view_tag> {
// sliced_view
template <typename Sequence, std::size_t ...i>
static constexpr auto
apply(experimental::sliced_view_t<Sequence, i...>) {
return hana::size_c<sizeof...(i)>;
}
// transformed_view
template <typename Sequence, typename F>
static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
return hana::length(view.sequence_);
}
// joined_view
template <typename S1, typename S2>
static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
return hana::size_c<
decltype(hana::length(view.sequence1_))::value +
decltype(hana::length(view.sequence2_))::value
>;
}
// single_view
template <typename T>
static constexpr auto apply(experimental::single_view_t<T>) {
return hana::size_c<1>;
}
// empty_view
static constexpr auto apply(experimental::empty_view_t) {
return hana::size_c<0>;
}
};
template <>
struct is_empty_impl<experimental::view_tag> {
// sliced_view
template <typename Sequence, std::size_t ...i>
static constexpr auto
apply(experimental::sliced_view_t<Sequence, i...>) {
return hana::bool_c<sizeof...(i) == 0>;
}
// transformed_view
template <typename Sequence, typename F>
static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
return hana::is_empty(view.sequence_);
}
// joined_view
template <typename S1, typename S2>
static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
return hana::and_(hana::is_empty(view.sequence1_),
hana::is_empty(view.sequence2_));
}
// single_view
template <typename T>
static constexpr auto apply(experimental::single_view_t<T>) {
return hana::false_c;
}
// empty_view
static constexpr auto apply(experimental::empty_view_t) {
return hana::true_c;
}
};
template <>
struct drop_front_impl<experimental::view_tag> {
template <typename View, typename N>
static constexpr auto apply(View view, N const&) {
constexpr auto n = N::value;
constexpr auto Length = decltype(hana::length(view))::value;
return experimental::sliced(view, hana::range_c<std::size_t, n, Length>);
}
};
//////////////////////////////////////////////////////////////////////////
// Functor
//////////////////////////////////////////////////////////////////////////
template <>
struct transform_impl<experimental::view_tag> {
template <typename Sequence, typename F, typename G>
static constexpr auto
apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
return experimental::transformed(view.sequence_,
hana::compose(static_cast<G&&>(g), view.f_));
}
template <typename View, typename F>
static constexpr auto apply(View view, F&& f) {
return experimental::transformed(view, static_cast<F&&>(f));
}
};
//////////////////////////////////////////////////////////////////////////
// Applicative
//////////////////////////////////////////////////////////////////////////
template <>
struct lift_impl<experimental::view_tag> {
template <typename T>
static constexpr auto apply(T&& t) {
return experimental::single_view(static_cast<T&&>(t));
}
};
template <>
struct ap_impl<experimental::view_tag> {
template <typename F, typename X>
static constexpr auto apply(F&& f, X&& x) {
// TODO: Implement cleverly; we most likely need a cartesian_product
// view or something like that.
return hana::ap(hana::to_tuple(f), hana::to_tuple(x));
}
};
//////////////////////////////////////////////////////////////////////////
// Monad
//////////////////////////////////////////////////////////////////////////
template <>
struct flatten_impl<experimental::view_tag> {
template <typename View>
static constexpr auto apply(View view) {
// TODO: Implement a flattened_view instead
return hana::fold_left(view, experimental::empty_view(),
experimental::joined);
}
};
//////////////////////////////////////////////////////////////////////////
// MonadPlus
//////////////////////////////////////////////////////////////////////////
template <>
struct concat_impl<experimental::view_tag> {
template <typename View1, typename View2>
static constexpr auto apply(View1 view1, View2 view2) {
return experimental::joined(view1, view2);
}
};
template <>
struct empty_impl<experimental::view_tag> {
static constexpr auto apply() {
return experimental::empty_view();
}
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl<experimental::view_tag, experimental::view_tag> {
template <typename View1, typename View2>
static constexpr auto apply(View1 v1, View2 v2) {
// TODO: Use a lexicographical comparison algorithm.
return hana::equal(hana::to_tuple(v1), hana::to_tuple(v2));
}
};
template <typename S>
struct equal_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
template <typename View1, typename Seq>
static constexpr auto apply(View1 v1, Seq const& s) {
// TODO: Use a lexicographical comparison algorithm.
return hana::equal(hana::to_tuple(v1), hana::to_tuple(s));
}
};
template <typename S>
struct equal_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
template <typename Seq, typename View2>
static constexpr auto apply(Seq const& s, View2 v2) {
// TODO: Use a lexicographical comparison algorithm.
return hana::equal(hana::to_tuple(s), hana::to_tuple(v2));
}
};
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl<experimental::view_tag, experimental::view_tag> {
template <typename View1, typename View2>
static constexpr auto apply(View1 v1, View2 v2) {
return hana::lexicographical_compare(v1, v2);
}
};
template <typename S>
struct less_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
template <typename View1, typename Seq>
static constexpr auto apply(View1 v1, Seq const& s) {
return hana::lexicographical_compare(v1, s);
}
};
template <typename S>
struct less_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
template <typename Seq, typename View2>
static constexpr auto apply(Seq const& s, View2 v2) {
return hana::lexicographical_compare(s, v2);
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_EXPERIMENTAL_VIEW_HPP