Distributed Ranges
Loading...
Searching...
No Matches
sliding.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <dr/detail/ranges.hpp>
8#include <dr/detail/segments_tools.hpp>
9#include <dr/mp/views/segmented.hpp>
10
11namespace dr::mp {
12namespace views {
13namespace __detail {
14
15struct sliding_fn {
16
17 // one can not use local algorithms if n is not equal to halo_bounds.prev + 1
18 // + halo_bounds.next
19 template <typename Rng, typename Int>
20 requires rng::viewable_range<Rng> && rng::forward_range<Rng> &&
21 rng::detail::integer_like_<Int>
22 auto operator()(Rng &&r, Int n) const {
23 return rng::views::sliding(static_cast<Rng &&>(r), n);
24 }
25};
26
27} // namespace __detail
28
29inline constexpr __detail::sliding_fn sliding{};
30
31} // namespace views
32} // namespace dr::mp
33
34namespace DR_RANGES_NAMESPACE {
35
36template <rng::range V>
37 requires(dr::is_sliding_view_v<V>)
38auto segments_(V &&v) {
39
40 auto base_segments = dr::ranges::segments(v.base());
41 auto elements_to_skip_in_base = rng::size(v.base());
42 auto elements_to_take = 0;
43 if (!rng::empty(v)) {
44 // need to reverse engineer `n` which was passed to sliding_view
45 elements_to_take = rng::size(v);
46 const auto slide_size = elements_to_skip_in_base - elements_to_take + 1;
47 // TODO: this code assumes that halo is symmetric, thus odd (center + 2n)
48 // note, it is not an assertion preventing all wrong use cases
49 // other ones are caught by assert during attempt to read outside halo
50 assert(slide_size % 2 == 1);
51 elements_to_skip_in_base = slide_size / 2;
52 }
53
54 return dr::mp::views::segmented(
55 v,
56 dr::__detail::take_segments(
57 dr::__detail::drop_segments(base_segments, elements_to_skip_in_base),
58 elements_to_take));
59}
60
61// TODO: add support for dr::mp::halo(dr::mp::views::sliding(r)).exchange()
62} // namespace DR_RANGES_NAMESPACE
Definition: sliding.hpp:15