OGLplus  (0.59.0) a C++ wrapper for rendering APIs

network_sorter.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_NETWORK_SORTER_HPP
10 #define EAGINE_NETWORK_SORTER_HPP
11 
12 #include "assert.hpp"
13 #include "integer_range.hpp"
14 #include "memory/span_algo.hpp"
15 #include "sorting_network.hpp"
16 #include "span.hpp"
17 #include <array>
18 #include <utility>
19 
20 namespace eagine {
21 
22 template <
23  typename T,
24  std::size_t N,
25  typename Compare = std::less<T>,
26  typename Network = sorting_network<N>>
27 class basic_network_sorter {
28 private:
29  Compare _before;
30  Network _sn;
31 
32  auto _min(const T& a, const T& b) const -> const T& {
33  return _before(a, b) ? a : b;
34  }
35 
36  auto _max(const T& a, const T& b) const -> const T& {
37  return _before(a, b) ? b : a;
38  }
39 
40  auto _min_max_cpy(const T& a, const T& b, bool min, bool max) const
41  -> const T& {
42  return min ? _min(a, b) : max ? _max(a, b) : a;
43  }
44 
45 public:
46  void single_sort_step(
47  std::array<T, N>& src,
48  std::array<T, N>& dst,
49  span_size_t r,
50  span_size_t i) const {
51  span_size_t j = _sn.index(r, i);
52  dst[std_size(i)] = _min_max_cpy(
53  src[std_size(i)],
54  src[std_size(j)],
55  _sn.min(r, i, j),
56  _sn.max(r, i, j));
57  }
58 
59  auto size() const noexcept -> span_size_t {
60  return _sn.size();
61  }
62 
63  auto rounds() const noexcept -> span_size_t {
64  return _sn.rounds();
65  }
66 };
67 
68 template <
69  typename T,
70  std::size_t N,
71  typename Compare = std::less<T>,
72  typename Network = sorting_network<N>>
73 class network_sorter : basic_network_sorter<T, N, Compare, Network> {
74 private:
75  span_size_t _round{0};
76  std::array<std::array<T, N>, 2> _a;
77 
78 public:
79  constexpr network_sorter(std::array<T, N> a)
80  : _a{{a, a}} {}
81 
82  using basic_network_sorter<T, N, Compare, Network>::rounds;
83 
84  auto done() const noexcept -> bool {
85  return _round >= rounds();
86  }
87 
88  auto next_round() noexcept -> bool {
89  return !done() && (++_round < rounds());
90  }
91 
92  auto sort_single(span_size_t r, span_size_t i) -> auto& {
93  span_size_t src = (r + 0) % 2;
94  span_size_t dst = (r + 1) % 2;
95  this->single_sort_step(_a[std_size(src)], _a[std_size(dst)], r, i);
96  return *this;
97  }
98 
99  auto sort_single(span_size_t i) -> auto& {
100  return sort_single(_round, i);
101  }
102 
103  auto sort_round() -> auto& {
104  EAGINE_ASSERT(!done());
105  for(auto i : integer_range(span_size(N))) {
106  sort_single(i);
107  }
108  return *this;
109  }
110 
111  auto sort() -> auto& {
112  while(sort_round().next_round()) {
113  }
114  return *this;
115  }
116 
117  auto result() const noexcept -> const std::array<T, N>& {
118  return _a[rounds() % 2];
119  }
120 
121  auto operator()() -> const std::array<T, N>& {
122  return sort().result();
123  }
124 };
125 
126 template <std::size_t N, typename Cmp, typename T, typename P, typename S>
127 auto network_sort(memory::basic_span<T, P, S> spn)
128  -> memory::basic_span<T, P, S> {
129  EAGINE_ASSERT(spn.size() == span_size_t(N));
130  using memory::copy;
131  std::array<T, N> init{};
132  copy(spn, cover(init));
133  network_sorter<T, N, Cmp> sorter(std::move(init));
134  return copy(view(sorter.sort().result()), spn);
135 }
136 
137 } // namespace eagine
138 
139 #endif // EAGINE_NETWORK_SORTER_HPP
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
static constexpr auto span_size(T v) noexcept
Converts argument to span size type.
Definition: types.hpp:59
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto cover(T *addr, S size) noexcept -> span_if_mutable< T >
Creates a span starting at the specified pointer and specified length.
Definition: span.hpp:465
static constexpr auto view(T *addr, S size) noexcept -> const_span< T >
Creates a view starting at the specified pointer and specified length.
Definition: span.hpp:458
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
static auto sort(basic_span< T, P, S > spn) -> basic_span< T, P, S >
Sorts the elements of a span.
Definition: span_algo.hpp:609
integer_range(B, E) -> integer_range< std::common_type_t< B, E >>
Deduction guide for integer_range.
static auto copy(const_block source, block dest) -> block
Copies the content of source block to destination block.
Definition: copy.hpp:23

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).