LCOV - code coverage report
Current view: top level - irohad/ametsuchi/impl - soci_utils.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 32 35 91.4 %
Date: 2018-12-05 17:11:35 Functions: 273 282 96.8 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       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          49 :       while (st.fetch()) {
      26          84 :         switch (ind) {
      27             :           case soci::i_ok:
      28          28 :             f(row);
      29             :           case soci::i_null:
      30             :           case soci::i_truncated:
      31          28 :             break;
      32             :         }
      33             :       }
      34          21 :     }
      35             : 
      36             :     /// tuple length shortcut
      37             :     template <typename T>
      38             :     constexpr std::size_t length_v = boost::tuples::length<T>::value;
      39             : 
      40             :     /// tuple element type shortcut
      41             :     template <std::size_t N, typename T>
      42             :     using element_t = typename boost::tuples::element<N, T>::type;
      43             : 
      44             :     /// index sequence helper for concat
      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>>...,
      48             :                         element_t<Js, std::decay_t<Tuple2>>...>;
      49             : 
      50             :     /// tuple with types from two given tuples
      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             : 
      56             :     /// index sequence helper for index_apply
      57             :     template <typename F, std::size_t... Is>
      58             :     constexpr decltype(auto) index_apply_impl(F &&f,
      59             :                                               std::index_sequence<Is...>) {
      60        4065 :       return std::forward<F>(f)(std::integral_constant<std::size_t, Is>{}...);
      61             :     }
      62             : 
      63             :     /// apply F to an integer sequence [0, N)
      64             :     template <size_t N, typename F>
      65             :     constexpr decltype(auto) index_apply(F &&f) {
      66        4065 :       return index_apply_impl(std::forward<F>(f),
      67             :                               std::make_index_sequence<N>{});
      68             :     }
      69             : 
      70             :     /// apply F to Tuple
      71             :     template <typename Tuple, typename F>
      72             :     constexpr decltype(auto) apply(Tuple &&t, F &&f) {
      73        4065 :       return index_apply<length_v<std::decay_t<Tuple>>>(
      74             :           [&](auto... Is) -> decltype(auto) {
      75        4065 :             return std::forward<F>(f)(
      76        4065 :                 boost::get<Is>(std::forward<Tuple>(t))...);
      77             :           });
      78             :     }
      79             : 
      80             :     /// view first length_v<R> elements of T without copying
      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         157 :         return boost::make_tuple(std::forward<T>(t).template get<Is>()...);
      85             :       });
      86             :     }
      87             : 
      88             :     /// view last length_v<R> elements of T without copying
      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          55 :         return boost::make_tuple(
      93          55 :             std::forward<T>(t)
      94          55 :                 .template get<Is
      95             :                               + length_v<std::decay_t<
      96             :                                     T>> - length_v<std::decay_t<R>>>()...);
      97             :       });
      98             :     }
      99             : 
     100             :     /// map tuple<optional<Ts>...> to optional<tuple<Ts...>>
     101             :     template <typename T>
     102             :     constexpr auto rebind(T &&t) {
     103             :       auto transform = [](auto &&... vals) {
     104         154 :         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         157 :       return apply(std::forward<T>(t),
     111             :                    [&](auto &&... vals) {
     112         157 :                      bool temp[] = {static_cast<bool>(
     113         157 :                          std::forward<decltype(vals)>(vals))...};
     114         157 :                      return std::all_of(std::begin(temp),
     115         157 :                                         std::end(temp),
     116             :                                         [](auto b) { return b; });
     117             :                    })
     118         154 :           ? boost::make_optional(apply(std::forward<T>(t), transform))
     119           3 :           : ReturnType{};
     120           0 :     }
     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         146 :         return boost::copy_range<C>(
     126             :             st | boost::adaptors::transformed([&](auto &t) {
     127         182 :               return apply(t, std::forward<F>(f));
     128             :             }));
     129           0 :       };
     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        1928 :         return boost::copy_range<C>(
     136             :             st | boost::adaptors::transformed([&](auto &t) {
     137        3908 :               return apply(t, std::forward<F>(f));
     138             :             })
     139        1928 :             | boost::adaptors::filtered(
     140             :                   [](auto &r) { return static_cast<bool>(r); })
     141             :             | boost::adaptors::transformed([](auto &&r) { return *r; }));
     142           0 :       };
     143             :     }
     144             : 
     145             :     template <typename T, typename F>
     146             :     auto flatMapValue(T &t, F &&f) {
     147             :       return t | [&](auto &st) -> decltype(
     148             :                                    apply(boost::make_iterator_range(st).front(),
     149             :                                          std::forward<F>(f))) {
     150          29 :         auto range = boost::make_iterator_range(st);
     151             : 
     152          29 :         if (range.empty()) {
     153           3 :           return boost::none;
     154             :         }
     155             : 
     156          29 :         return apply(range.front(), std::forward<F>(f));
     157          29 :       };
     158             :     }
     159             : 
     160             :   }  // namespace ametsuchi
     161             : }  // namespace iroha
     162             : 
     163             : #endif  // IROHA_POSTGRES_WSV_COMMON_HPP

Generated by: LCOV version 1.13