HiPipe  0.6.0
C++17 data pipeline with Python bindings.
generate.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/transform.hpp>
14 #include <hipipe/core/utility/ndim.hpp>
15 
16 namespace hipipe::stream {
17 namespace detail {
18 
19  // Create a transformation function that can be sent to stream::transform.
20  template<typename FromColumn, typename ToColumn, typename Gen, int Dim>
21  struct wrap_generate_fun_for_transform {
22  Gen gen;
23  long gendims;
24 
25  typename ToColumn::data_type operator()(typename FromColumn::data_type& source)
26  {
27  using SourceVector = typename FromColumn::data_type;
28  using TargetVector = typename ToColumn::data_type;
29  constexpr long SourceDims = utility::ndims<SourceVector>::value;
30  constexpr long TargetDims = utility::ndims<TargetVector>::value;
31  static_assert(Dim <= SourceDims, "hipipe::stream::generate requires"
32  " the dimension in which to apply the generator to be at most the number"
33  " of dimensions of the source column (i.e., the column the shape is taken"
34  " from).");
35  static_assert(Dim <= TargetDims, "hipipe::stream::generate: The requested"
36  " dimension is higher than the number of dimensions of the target column.");
37  // get the size of the source up to the dimension of the target
38  std::vector<std::vector<long>> target_size = utility::ndim_size<Dim>(source);
39  // create, resize, and fill the target using the generator
40  TargetVector target;
41  static_assert(std::is_invocable_r_v<utility::ndim_type_t<TargetVector, Dim>, Gen>,
42  " hipipe::stream::generate: The given generator does not generate a"
43  " type convertible to the given column in the given dimension.");
44  utility::ndim_resize<Dim>(target, target_size);
45  utility::generate<Dim>(target, gen, gendims);
46  return target;
47  }
48  };
49 
50 } // namespace detail
51 
80 template<typename FromColumn, typename ToColumn, typename Gen,
81  int Dim = utility::ndims<typename ToColumn::data_type>::value
82  - utility::ndims<std::result_of_t<Gen()>>::value>
83 auto generate(from_t<FromColumn> size_from,
84  to_t<ToColumn> fill_to,
85  Gen gen,
86  long gendims = std::numeric_limits<long>::max(),
87  dim_t<Dim> d = dim_t<Dim>{})
88 {
89  // a bit of function type erasure to speed up compilation
90  using GenT = std::function<
91  utility::ndim_type_t<typename ToColumn::data_type, Dim>()>;
92  detail::wrap_generate_fun_for_transform<FromColumn, ToColumn, GenT, Dim>
93  trans_fun{std::move(gen), gendims};
94  return stream::transform(from<FromColumn>, to<ToColumn>, std::move(trans_fun), dim<0>);
95 }
96 
97 } // namespace hipipe::stream
void generate(Rng &&rng, Gen &&gen, long gendims=std::numeric_limits< long >::max())
Fill a multidimensional range with values generated by a nullary function.
Definition: ndim.hpp:625
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:187
Definition: ndim.hpp:144