HiPipe  0.7.0
C++17 data pipeline with Python bindings.
create.hpp
1 /****************************************************************************
2  * hipipe library
3  * Copyright (c) 2017, Cognexa Solutions s.r.o.
4  * Copyright (c) 2018, Iterait a.s.
5  * Author(s) Filip Matzner
6  *
7  * This file is distributed under the MIT License.
8  * See the accompanying file LICENSE.txt for the complete license agreement.
9  ****************************************************************************/
10 
11 #pragma once
12 
13 #include <hipipe/core/stream/stream_t.hpp>
14 #include <hipipe/core/utility/tuple.hpp>
15 
16 #include <range/v3/view/transform.hpp>
17 #include <range/v3/view/chunk.hpp>
18 
19 #include <typeinfo>
20 #include <unordered_map>
21 
22 namespace hipipe::stream {
23 
24 namespace rgv = ranges::views;
25 
26 namespace detail {
27 
28  template<typename... Columns>
29  struct create_impl {
30 
31  template<typename Source>
32  batch_t operator()(Source&& source) const
33  {
34  batch_t batch;
35 
36  if constexpr(sizeof...(Columns) == 0) {
37  static_assert("hipipe::stream::create: At least one column has to be provided.");
38  } else if constexpr(sizeof...(Columns) == 1) {
39  static_assert(std::is_constructible_v<Columns..., Source&&>,
40  "hipipe::stream::create: "
41  "Cannot convert the given data range to the selected column type.");
42  batch.insert_or_assign<Columns...>(ranges::to_vector(std::forward<Source>(source)));
43  } else {
44  using SourceValue = ranges::range_value_t<Source>;
45  static_assert(std::is_constructible_v<
46  std::tuple<typename Columns::example_type...>, SourceValue&&>,
47  "hipipe::stream::create: "
48  "Cannot convert the given data range to the selected column types.");
49  std::tuple<Columns...> data = utility::unzip(std::forward<Source>(source));
50  utility::tuple_for_each(data, [&batch](auto& column){
51  batch.insert_or_assign<std::decay_t<decltype(column)>>(std::move(column));
52  });
53  }
54 
55  return batch;
56  }
57  };
58 
59  template<typename... Columns>
60  class create_fn {
61  private:
62  friend rgv::view_access;
63 
64  static auto bind(create_fn<Columns...> fun, std::size_t batch_size = 1)
65  {
66  return ranges::make_pipeable(std::bind(fun, std::placeholders::_1, batch_size));
67  }
68  public:
69  CPP_template(class Rng)(requires ranges::forward_range<Rng>)
70  forward_stream_t operator()(Rng&& rng, std::size_t batch_size = 1) const
71  {
72  return rgv::transform(
73  rgv::chunk(std::forward<Rng>(rng), batch_size),
74  create_impl<Columns...>{});
75  }
76 
78  CPP_template(class Rng)(requires !ranges::forward_range<Rng>)
79  void operator()(Rng&&, std::size_t batch_size = 1) const
80  {
81  CONCEPT_ASSERT_MSG(ranges::forward_range<Rng>(),
82  "stream::create only works on ranges satisfying the forward_range concept.");
83  }
85  };
86 
87 } // namespace detail
88 
112 template<typename... Columns>
113 rgv::view<detail::create_fn<Columns...>> create{};
114 
115 } // end namespace hipipe::stream
hipipe::utility::CPP_template
CPP_template(class Rng)(requires ranges
Unzips a range of tuples to a tuple of std::vectors.
Definition: tuple.hpp:255
hipipe::stream::create
rgv::view< detail::create_fn< Columns... > > create
Converts a data range to a HiPipe stream.
Definition: create.hpp:119
hipipe::stream::forward_stream_t
ranges::any_view< batch_t, ranges::category::forward > forward_stream_t
The stream itself, i.e., a range of batches.
Definition: stream_t.hpp:29
hipipe::utility::tuple_for_each
constexpr auto tuple_for_each(Tuple &&tuple, Fun &&fun)
Apply a function on each element of a tuple.
Definition: tuple.hpp:118
hipipe::stream::transform
auto transform(from_t< FromColumns... > f, to_t< ToColumns... > t, Fun fun, dim_t< Dim > d=dim_t< 1 >{})
Transform a subset of hipipe columns to a different subset of hipipe columns.
Definition: transform.hpp:218