cxtream  0.5.1
C++17 data pipeline with Python bindings.
unpack.hpp
1 /****************************************************************************
2  * cxtream library
3  * Copyright (c) 2017, Cognexa Solutions s.r.o.
4  * Author(s) Filip Matzner
5  *
6  * This file is distributed under the MIT License.
7  * See the accompanying file LICENSE.txt for the complete license agreement.
8  ****************************************************************************/
9 
10 #ifndef CXTREAM_CORE_STREAM_UNPACK_HPP
11 #define CXTREAM_CORE_STREAM_UNPACK_HPP
12 
13 #include <cxtream/core/stream/template_arguments.hpp>
14 #include <cxtream/core/utility/tuple.hpp>
15 #include <cxtream/core/utility/vector.hpp>
16 
17 #include <range/v3/view/move.hpp>
18 #include <range/v3/view/transform.hpp>
19 #include <range/v3/to_container.hpp>
20 
21 namespace cxtream::stream {
22 
23 namespace detail {
24 
25  // replace the columns in the stream with their values (i.e., raw batches)
26  template<typename... FromColumns>
27  constexpr auto unpack_columns()
28  {
29  return ranges::view::transform([](auto source) {
30  auto proj = [](auto& column) { return std::move(column.value()); };
31  auto subtuple = utility::tuple_type_view<FromColumns...>(source);
32  return utility::tuple_transform(std::move(subtuple), std::move(proj));
33  });
34  }
35 
36  template<std::size_t Dim, bool OnlyOne, typename... FromColumns>
37  struct unpack_impl
38  {
39  template<typename Rng>
40  static constexpr auto impl(Rng range_of_tuples)
41  {
42  // project the selected columns to their values (i.e., batches)
43  auto raw_range_of_tuples = range_of_tuples | unpack_columns<FromColumns...>();
44  auto tuple_of_batches = utility::unzip(std::move(raw_range_of_tuples));
45  // flatten the values in each column upto the given dimension
46  return utility::tuple_transform(std::move(tuple_of_batches), [](auto&& batch_range) {
47  // make sure to convert the flat view to std::vector to avoid dangling ref
48  return utility::flat_view<Dim+1>(batch_range)
49  | ranges::view::move | ranges::to_vector;
50  });
51  }
52  };
53 
54  // if only a single column is unpacked, do not return a tuple
55  template<std::size_t Dim, typename FromColumn>
56  struct unpack_impl<Dim, true, FromColumn>
57  {
58  template<typename Rng>
59  static constexpr auto impl(Rng&& range_of_tuples)
60  {
61  return std::get<0>(
62  unpack_impl<Dim, false, FromColumn>::impl(std::forward<Rng>(range_of_tuples)));
63  }
64  };
65 
66 } // namespace detail
67 
99 template<typename Rng, typename... FromColumns, int Dim = 1>
100 constexpr auto unpack(Rng&& rng, from_t<FromColumns...> f, dim_t<Dim> d = dim_t<1>{})
101 {
102  return detail::unpack_impl<Dim, (sizeof...(FromColumns)==1), FromColumns...>::impl(
103  std::forward<Rng>(rng));
104 }
105 
106 } // end namespace cxtream::stream
107 #endif
auto unzip(Rng range_of_tuples)
Unzips a range of tuples to a tuple of ranges.
Definition: tuple.hpp:408
constexpr auto transform(from_t< FromColumns... > f, to_t< ToColumns... > t, Fun fun, dim_t< Dim > d=dim_t< 1 >{})
Transform a subset of cxtream columns to a different subset of cxtream columns.
Definition: transform.hpp:177
constexpr auto tuple_type_view(Tuple &tuple)
Makes a sub-tuple made of references to the original tuple (selected by type).
Definition: tuple.hpp:186
constexpr auto unpack(Rng &&rng, from_t< FromColumns... > f, dim_t< Dim > d=dim_t< 1 >{})
Unpack a stream into a tuple of ranges.
Definition: unpack.hpp:100
constexpr auto tuple_transform(Tuple &&tuple, Fun &&fun)
Transform each element of a tuple.
Definition: tuple.hpp:155