Skip to content

Commit

Permalink
Add range_iota(), range_fill(), range_generate()
Browse files Browse the repository at this point in the history
  • Loading branch information
mbeutel committed Mar 2, 2020
1 parent 2bfc62b commit 9f5e632
Showing 1 changed file with 56 additions and 8 deletions.
64 changes: 56 additions & 8 deletions include/makeshift/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ constexpr auto
range_zip(Rs&&... ranges)
{
auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
static_assert(!std::is_same<decltype(mergedSize), detail::dim_constant<detail::unknown_size>>::value, "no range argument and no size given");
static_assert(!std::is_same<decltype(mergedSize), detail::dim_constant<detail::unknown_size>>::value, "no range argument given");

return detail::make_zip_common_range(mergedSize, std::forward<Rs>(ranges)...);
}
Expand All @@ -84,7 +84,7 @@ template <typename F, typename... Rs>
constexpr void
range_for(F&& func, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto it = detail::make_zip_begin_iterator(mergedSize, ranges...);
Expand All @@ -96,6 +96,54 @@ range_for(F&& func, Rs&&... ranges)
}


//
// Fills the range with sequentially increasing values, starting with `value` and repetitively evaluating `++value`.
//
template <typename R, typename T>
constexpr void
range_iota(R&& range, T value)
{
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
for (; it != end; ++it)
{
*it = value++;
}
}


//
// Fills the range with the given value.
//
template <typename R, typename T>
constexpr void
range_fill(R&& range, T const& value)
{
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
for (; it != end; ++it)
{
*it = value;
}
}


//
// Fills the range with the values generated by the given functor.
//
template <typename R, typename F>
constexpr void
range_generate(R&& range, F const& generate)
{
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
for (; it != end; ++it)
{
*it = generate();
}
}


//
// Takes an initial value, a reducer, a transformer, and a list of ranges and reduces them to a scalar value.
//
Expand All @@ -110,7 +158,7 @@ template <typename T, typename ReduceFuncT, typename TransformFuncT, typename...
gsl_NODISCARD constexpr std::decay_t<T>
range_transform_reduce(T&& initialValue, ReduceFuncT&& reduce, TransformFuncT&& transform, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto result = std::forward<T>(initialValue);
Expand All @@ -137,7 +185,7 @@ template <typename T, typename ReduceFuncT, typename R>
gsl_NODISCARD constexpr auto
range_reduce(T&& initialValue, ReduceFuncT&& reduce, R&& range)
{
static_assert(!std::is_same<std::decay_t<R>, detail::range_index_t>::value, "no range argument and no size given");
static_assert(!std::is_same<std::decay_t<R>, detail::range_index_t>::value, "no range argument given");

auto result = std::forward<T>(initialValue);
for (auto&& elem : range)
Expand All @@ -160,7 +208,7 @@ template <typename PredicateT, typename... Rs>
gsl_NODISCARD constexpr std::ptrdiff_t
range_count_if(PredicateT&& predicate, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto it = detail::make_zip_begin_iterator(mergedSize, ranges...);
Expand All @@ -186,7 +234,7 @@ template <typename PredicateT, typename... Rs>
gsl_NODISCARD constexpr bool
range_all_of(PredicateT&& predicate, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto it = detail::make_zip_begin_iterator(mergedSize, ranges...);
Expand All @@ -211,7 +259,7 @@ template <typename PredicateT, typename... Rs>
gsl_NODISCARD constexpr bool
range_any_of(PredicateT&& predicate, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto it = detail::make_zip_begin_iterator(mergedSize, ranges...);
Expand All @@ -236,7 +284,7 @@ template <typename PredicateT, typename... Rs>
gsl_NODISCARD constexpr bool
range_none_of(PredicateT&& predicate, Rs&&... ranges)
{
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument and no size given");
static_assert(!gsl::conjunction_v<std::is_same<std::decay_t<Rs>, detail::range_index_t>...>, "no range argument given");

auto mergedSize = detail::merge_sizes(detail::range_size(ranges)...);
auto it = detail::make_zip_begin_iterator(mergedSize, ranges...);
Expand Down

0 comments on commit 9f5e632

Please sign in to comment.