Edit: /usr/include/boost/hana/range.hpp (9910B)
/*!
@file
Defines `boost::hana::range`.
@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_RANGE_HPP
#define BOOST_HANA_RANGE_HPP
#include
#include
#include
#include
#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 and below
#include
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// range<>
//////////////////////////////////////////////////////////////////////////
//! @cond
template
struct range
: detail::operators::adl>
, detail::iterable_operators>
{
static_assert(From <= To,
"hana::make_range(from, to) requires 'from <= to'");
using value_type = T;
static constexpr value_type from = From;
static constexpr value_type to = To;
};
//! @endcond
template
struct tag_of> {
using type = range_tag;
};
//////////////////////////////////////////////////////////////////////////
// make
//////////////////////////////////////////////////////////////////////////
template <>
struct make_impl {
template
static constexpr auto apply(From const&, To const&) {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::IntegralConstant::value,
"hana::make_range(from, to) requires 'from' to be an IntegralConstant");
static_assert(hana::IntegralConstant::value,
"hana::make_range(from, to) requires 'to' to be an IntegralConstant");
#endif
using T = typename common<
typename hana::tag_of::type::value_type,
typename hana::tag_of::type::value_type
>::type;
constexpr T from = hana::to(From::value);
constexpr T to = hana::to(To::value);
return range{};
}
};
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <>
struct comparable_operators {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl {
template
static constexpr auto apply(R1 const&, R2 const&) {
return hana::bool_c<
(R1::from == R1::to && R2::from == R2::to) ||
(R1::from == R2::from && R1::to == R2::to)
>;
}
};
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct unpack_impl {
template
static constexpr decltype(auto)
unpack_helper(F&& f, std::integer_sequence) {
return static_cast(f)(integral_constant{}...);
}
template
static constexpr decltype(auto) apply(range const&, F&& f) {
return unpack_helper(static_cast(f),
std::make_integer_sequence{});
}
};
template <>
struct length_impl {
template
static constexpr auto apply(range const&)
{ return hana::size_c(to - from)>; }
};
template <>
struct minimum_impl {
template
static constexpr auto apply(range const&)
{ return integral_c; }
};
template <>
struct maximum_impl {
template
static constexpr auto apply(range const&)
{ return integral_c; }
};
template <>
struct sum_impl {
// Returns the sum of `[m, n]`, where `m <= n` always hold.
template
static constexpr I sum_helper(I m, I n) {
if (m == n)
return m;
// 0 == m < n
else if (0 == m)
return n * (n+1) / 2;
// 0 < m < n
else if (0 < m)
return sum_helper(0, n) - sum_helper(0, m-1);
// m < 0 <= n
else if (0 <= n)
return sum_helper(0, n) - sum_helper(0, -m);
// m < n < 0
else
return -sum_helper(-n, -m);
}
template
static constexpr auto apply(range const&) {
return integral_c;
}
};
template <>
struct product_impl {
// Returns the product of `[m, n)`, where `m <= n` always hold.
template
static constexpr I product_helper(I m, I n) {
if (m <= 0 && 0 < n)
return 0;
else {
I p = 1;
for (; m != n; ++m)
p *= m;
return p;
}
}
template
static constexpr auto apply(range const&)
{ return integral_c; }
};
//////////////////////////////////////////////////////////////////////////
// Searchable
//////////////////////////////////////////////////////////////////////////
template <>
struct find_impl {
template
static constexpr auto find_helper(hana::true_) {
constexpr T n = N::value;
return hana::just(hana::integral_c);
}
template
static constexpr auto find_helper(hana::false_)
{ return hana::nothing; }
template
static constexpr auto apply(range const&, N const&) {
constexpr auto n = N::value;
return find_helper(hana::bool_c<(n >= from && n < to)>);
}
};
template <>
struct contains_impl {
template
static constexpr auto apply(range const&, N const&) {
constexpr auto n = N::value;
return bool_c<(n >= from && n < to)>;
}
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct front_impl {
template
static constexpr auto apply(range const&)
{ return integral_c; }
};
template <>
struct is_empty_impl {
template
static constexpr auto apply(range const&)
{ return bool_c; }
};
template <>
struct at_impl {
template
static constexpr auto apply(range const&, N const&) {
constexpr auto n = N::value;
return integral_c;
}
};
template <>
struct back_impl {
template
static constexpr auto apply(range const&)
{ return integral_c; }
};
template <>
struct drop_front_impl {
template
static constexpr auto apply(range const&, N const&) {
constexpr auto n = N::value;
return range{};
}
};
template <>
struct drop_front_exactly_impl {
template
static constexpr auto apply(range const&, N const&) {
constexpr auto n = N::value;
return range{};
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_RANGE_HPP