hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
soci_utils.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_POSTGRES_WSV_COMMON_HPP
7 #define IROHA_POSTGRES_WSV_COMMON_HPP
8 
9 #include <soci/soci.h>
10 #include <boost/optional.hpp>
11 #include <boost/range/adaptor/filtered.hpp>
12 #include <boost/range/adaptor/transformed.hpp>
13 #include <boost/range/iterator_range.hpp>
14 #include <boost/tuple/tuple.hpp>
15 #include "common/bind.hpp"
16 
17 namespace iroha {
18  namespace ametsuchi {
19 
20  template <typename ParamType, typename Function>
21  inline void processSoci(soci::statement &st,
22  soci::indicator &ind,
23  ParamType &row,
24  Function f) {
25  while (st.fetch()) {
26  switch (ind) {
27  case soci::i_ok:
28  f(row);
29  case soci::i_null:
30  case soci::i_truncated:
31  break;
32  }
33  }
34  }
35 
37  template <typename T>
38  constexpr std::size_t length_v = boost::tuples::length<T>::value;
39 
41  template <std::size_t N, typename T>
42  using element_t = typename boost::tuples::element<N, T>::type;
43 
45  template <class Tuple1, class Tuple2, std::size_t... Is, std::size_t... Js>
46  auto concat_impl(std::index_sequence<Is...>, std::index_sequence<Js...>)
47  -> boost::tuple<element_t<Is, std::decay_t<Tuple1>>...,
49 
51  template <class Tuple1, class Tuple2>
52  using concat = decltype(concat_impl<Tuple1, Tuple2>(
53  std::make_index_sequence<length_v<std::decay_t<Tuple1>>>{},
54  std::make_index_sequence<length_v<std::decay_t<Tuple2>>>{}));
55 
57  template <typename F, std::size_t... Is>
58  constexpr decltype(auto) index_apply_impl(F &&f,
59  std::index_sequence<Is...>) {
60  return std::forward<F>(f)(std::integral_constant<std::size_t, Is>{}...);
61  }
62 
64  template <size_t N, typename F>
65  constexpr decltype(auto) index_apply(F &&f) {
66  return index_apply_impl(std::forward<F>(f),
67  std::make_index_sequence<N>{});
68  }
69 
71  template <typename Tuple, typename F>
72  constexpr decltype(auto) apply(Tuple &&t, F &&f) {
73  return index_apply<length_v<std::decay_t<Tuple>>>(
74  [&](auto... Is) -> decltype(auto) {
75  return std::forward<F>(f)(
76  boost::get<Is>(std::forward<Tuple>(t))...);
77  });
78  }
79 
81  template <typename R, typename T>
82  constexpr auto viewQuery(T &&t) {
83  return index_apply<length_v<std::decay_t<R>>>([&](auto... Is) {
84  return boost::make_tuple(std::forward<T>(t).template get<Is>()...);
85  });
86  }
87 
89  template <typename R, typename T>
90  constexpr auto viewPermissions(T &&t) {
91  return index_apply<length_v<std::decay_t<R>>>([&](auto... Is) {
92  return boost::make_tuple(
93  std::forward<T>(t)
94  .template get<Is
95  + length_v<std::decay_t<
96  T>> - length_v<std::decay_t<R>>>()...);
97  });
98  }
99 
101  template <typename T>
102  constexpr auto rebind(T &&t) {
103  auto transform = [](auto &&... vals) {
104  return boost::make_tuple(*std::forward<decltype(vals)>(vals)...);
105  };
106 
107  using ReturnType = decltype(boost::make_optional(
108  iroha::ametsuchi::apply(std::forward<T>(t), transform)));
109 
111  std::forward<T>(t),
112  [&](auto &&... vals) {
113  bool temp[] = {static_cast<bool>(
114  std::forward<decltype(vals)>(vals))...};
115  return std::all_of(std::begin(temp),
116  std::end(temp),
117  [](auto b) { return b; });
118  })
119  ? boost::make_optional(
120  iroha::ametsuchi::apply(std::forward<T>(t), transform))
121  : ReturnType{};
122  }
123 
124  template <typename C, typename T, typename F>
125  auto mapValues(T &t, F &&f) {
126  return t | [&](auto &st) -> boost::optional<C> {
127  return boost::copy_range<C>(
128  st | boost::adaptors::transformed([&](auto &t) {
129  return iroha::ametsuchi::apply(t, std::forward<F>(f));
130  }));
131  };
132  }
133 
134  template <typename C, typename T, typename F>
135  boost::optional<C> flatMapValues(T &t, F &&f) {
136  if (t) {
137  C map_result;
138  for (auto &inp_el : *t) {
139  iroha::ametsuchi::apply(inp_el, std::forward<F>(f)) |
140  [&map_result](auto &&transformed_el) {
141  map_result.emplace_back(std::move(transformed_el));
142  };
143  }
144  return map_result;
145  }
146  return boost::none;
147  }
148 
149  template <typename R, typename T, typename F>
150  auto flatMapValue(T &t, F &&f) {
151  return t | [&](auto &st) -> R {
152  auto range = boost::make_iterator_range(st);
153 
154  if (range.empty()) {
155  return boost::none;
156  }
157 
158  return iroha::ametsuchi::apply(range.front(), std::forward<F>(f));
159  };
160  }
161 
162  } // namespace ametsuchi
163 } // namespace iroha
164 
165 #endif // IROHA_POSTGRES_WSV_COMMON_HPP
Definition: block_query.hpp:17
decltype(auto) constexpr apply(Tuple &&t, F &&f)
apply F to Tuple
Definition: soci_utils.hpp:72
decltype(auto) constexpr index_apply(F &&f)
apply F to an integer sequence [0, N)
Definition: soci_utils.hpp:65
auto mapValues(T &t, F &&f)
Definition: soci_utils.hpp:125
Definition: round.cpp:51
constexpr std::size_t length_v
tuple length shortcut
Definition: soci_utils.hpp:38
constexpr auto viewQuery(T &&t)
view first length_v<R> elements of T without copying
Definition: soci_utils.hpp:82
boost::optional< C > flatMapValues(T &t, F &&f)
Definition: soci_utils.hpp:135
Definition: block_query.hpp:15
decltype(auto) constexpr index_apply_impl(F &&f, std::index_sequence< Is... >)
index sequence helper for index_apply
Definition: soci_utils.hpp:58
auto concat_impl(std::index_sequence< Is... >, std::index_sequence< Js... >) -> boost::tuple< element_t< Is, std::decay_t< Tuple1 >>..., element_t< Js, std::decay_t< Tuple2 >>... >
index sequence helper for concat
constexpr auto rebind(T &&t)
map tuple<optional<Ts>...> to optional<tuple<Ts...>>
Definition: soci_utils.hpp:102
typename boost::tuples::element< N, T >::type element_t
tuple element type shortcut
Definition: soci_utils.hpp:42
void processSoci(soci::statement &st, soci::indicator &ind, ParamType &row, Function f)
Definition: soci_utils.hpp:21
decltype(concat_impl< Tuple1, Tuple2 >(std::make_index_sequence< length_v< std::decay_t< Tuple1 > >>{}, std::make_index_sequence< length_v< std::decay_t< Tuple2 > >>{})) concat
tuple with types from two given tuples
Definition: soci_utils.hpp:54
auto flatMapValue(T &t, F &&f)
Definition: soci_utils.hpp:150
constexpr auto viewPermissions(T &&t)
view last length_v<R> elements of T without copying
Definition: soci_utils.hpp:90