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

flatten.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_MEMORY_FLATTEN_HPP
10 #define EAGINE_MEMORY_FLATTEN_HPP
11 
12 #include "../all_are_same.hpp"
13 #include "flatten_fwd.hpp"
14 #include "span_algo.hpp"
15 #include <array>
16 #include <tuple>
17 #include <utility>
18 #include <vector>
19 
20 namespace eagine {
21 
22 template <typename Src, typename Dst>
23 struct flatten_traits;
24 
25 namespace memory {
26 //------------------------------------------------------------------------------
27 template <
28  typename Ts,
29  typename Ps,
30  typename Ss,
31  typename Td,
32  typename Pd,
33  typename Sd>
34 auto flatten(basic_span<Ts, Ps, Ss> src, basic_span<Td, Pd, Sd> dst) noexcept
35  -> basic_span<Td, Pd, Sd> {
36  flatten_traits<std::remove_cv_t<Ts>, Td> traits{};
37  EAGINE_ASSERT(traits.required_size(src) <= dst.size());
38 
39  auto tmp = dst;
40  for(auto& elem : src) {
41  tmp = traits.apply(elem, tmp);
42  }
43  return head(dst, dst.size() - tmp.size());
44 }
45 //------------------------------------------------------------------------------
46 template <typename Ts, typename Ps, typename Ss, typename Td, typename A>
47 auto flatten(basic_span<Ts, Ps, Ss> src, std::vector<Td, A>& dst) -> auto& {
48  flatten_traits<std::remove_cv_t<Ts>, Td> traits{};
49  dst.resize(std_size(traits.required_size(src)));
50  flatten(src, cover(dst));
51  return dst;
52 }
53 //------------------------------------------------------------------------------
54 } // namespace memory
55 
56 template <typename Ts, std::size_t N, typename Td>
57 struct flatten_traits<std::array<Ts, N>, Td> {
58  static_assert(std::is_convertible_v<Ts, Td>);
59 
60  template <typename Ps, typename Ss>
61  static constexpr auto required_size(
62  memory::basic_span<const std::array<Ts, N>, Ps, Ss> src) noexcept
63  -> span_size_t {
64  return src.size() * span_size(N);
65  }
66 
67  template <typename Pd, typename Sd>
68  static auto apply(
69  const std::array<Ts, N>& src,
70  memory::basic_span<Td, Pd, Sd> dst) noexcept {
71  EAGINE_ASSERT(span_size(N) <= dst.size());
72  copy(view(src), dst);
73  return skip(dst, span_size(N));
74  }
75 };
76 //------------------------------------------------------------------------------
77 template <typename T, typename... P>
78 struct flatten_traits<std::tuple<P...>, T> {
79  static_assert(all_are_convertible_to_v<T, P...>);
80 
81  template <typename Ps, typename Ss>
82  static constexpr auto required_size(
83  memory::basic_span<const std::tuple<P...>, Ps, Ss> src) noexcept
84  -> span_size_t {
85  return src.size() * span_size(sizeof...(P));
86  }
87 
88  template <typename Pd, typename Sd>
89  static auto apply(
90  const std::tuple<P...>& src,
91  memory::basic_span<T, Pd, Sd> dst) noexcept {
92  EAGINE_ASSERT(span_size(sizeof...(P)) <= dst.size());
93  _do_apply(src, dst, std::make_index_sequence<sizeof...(P)>{});
94  return skip(dst, span_size(sizeof...(P)));
95  }
96 
97 private:
98  template <typename Pd, typename Sd, std::size_t... I>
99  static void _do_apply(
100  const std::tuple<P...>& src,
101  memory::basic_span<T, Pd, Sd> dst,
102  std::index_sequence<I...>) noexcept {
103  ((dst[I] = T(std::get<I>(src))), ...);
104  }
105 };
106 //------------------------------------------------------------------------------
107 } // namespace eagine
108 
109 #endif // EAGINE_MEMORY_FLATTEN_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 head(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Returns the first l elements from the front of a span.
Definition: span_algo.hpp:99
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
static constexpr auto skip(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Skips a specified count of elements from the front of a span.
Definition: span_algo.hpp:60

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