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 =
108  decltype(boost::make_optional(apply(std::forward<T>(t), transform)));
109 
110  return apply(std::forward<T>(t),
111  [&](auto &&... vals) {
112  bool temp[] = {static_cast<bool>(
113  std::forward<decltype(vals)>(vals))...};
114  return std::all_of(std::begin(temp),
115  std::end(temp),
116  [](auto b) { return b; });
117  })
118  ? boost::make_optional(apply(std::forward<T>(t), transform))
119  : ReturnType{};
120  }
121 
122  template <typename C, typename T, typename F>
123  auto mapValues(T &t, F &&f) {
124  return t | [&](auto &st) -> boost::optional<C> {
125  return boost::copy_range<C>(
126  st | boost::adaptors::transformed([&](auto &t) {
127  return apply(t, std::forward<F>(f));
128  }));
129  };
130  }
131 
132  template <typename C, typename T, typename F>
133  auto flatMapValues(T &t, F &&f) {
134  return t | [&](auto &st) -> boost::optional<C> {
135  return boost::copy_range<C>(
136  st | boost::adaptors::transformed([&](auto &t) {
137  return apply(t, std::forward<F>(f));
138  })
139  | boost::adaptors::filtered(
140  [](auto &r) { return static_cast<bool>(r); })
141  | boost::adaptors::transformed([](auto &&r) { return *r; }));
142  };
143  }
144 
145  template <typename R, typename T, typename F>
146  auto flatMapValue(T &t, F &&f) {
147  return t | [&](auto &st) -> R {
148  auto range = boost::make_iterator_range(st);
149 
150  if (range.empty()) {
151  return boost::none;
152  }
153 
154  return apply(range.front(), std::forward<F>(f));
155  };
156  }
157 
158  } // namespace ametsuchi
159 } // namespace iroha
160 
161 #endif // IROHA_POSTGRES_WSV_COMMON_HPP
auto flatMapValues(T &t, F &&f)
Definition: soci_utils.hpp:133
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:123
Definition: peer.hpp:48
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
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
Definition: block_query.hpp:16
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
const std::string end
Definition: logger.cpp:9
auto flatMapValue(T &t, F &&f)
Definition: soci_utils.hpp:146
constexpr auto viewPermissions(T &&t)
view last length_v<R> elements of T without copying
Definition: soci_utils.hpp:90