LCOV - code coverage report
Current view: top level - libs/common - visitor.hpp (source / functions) Hit Total Coverage
Test: cleared_cor.info Lines: 5 7 71.4 %
Date: 2019-03-07 14:46:43 Functions: 663 721 92.0 %

          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_VISITOR_HPP
       7             : #define IROHA_VISITOR_HPP
       8             : 
       9             : #include <boost/variant/apply_visitor.hpp>  // for boost::apply_visitor
      10             : #include <type_traits>                      // for std::decay
      11             : #include <utility>                          // for std::forward
      12             : 
      13             : namespace iroha {
      14             : 
      15             :   template <typename... Lambdas>
      16             :   struct lambda_visitor;
      17             : 
      18             :   template <typename Lambda, typename... Lambdas>
      19             :   struct lambda_visitor<Lambda, Lambdas...>
      20             :       : public Lambda, public lambda_visitor<Lambdas...> {
      21             :     using Lambda::operator();
      22             :     using lambda_visitor<Lambdas...>::operator();
      23             : 
      24             :     lambda_visitor(Lambda lambda, Lambdas... lambdas)
      25       83970 :         : Lambda(lambda), lambda_visitor<Lambdas...>(lambdas...) {}
      26             :   };
      27             : 
      28             :   template <typename Lambda>
      29             :   struct lambda_visitor<Lambda> : public Lambda {
      30             :     using Lambda::operator();
      31             : 
      32             :     lambda_visitor(Lambda lambda) : Lambda(lambda) {}
      33             :   };
      34             : 
      35             :   /**
      36             :    * @brief Convenient in-place compile-time visitor creation, from a set of
      37             :    * lambdas
      38             :    *
      39             :    * @code
      40             :    * make_visitor([](int a){ return 1; },
      41             :    *              [](std::string b) { return 2; });
      42             :    * @nocode
      43             :    *
      44             :    * is essentially the same as
      45             :    *
      46             :    * @code
      47             :    * struct visitor : public boost::static_visitor<int> {
      48             :    *   int operator()(int a) { return 1; }
      49             :    *   int operator()(std::string b) { return 2; }
      50             :    * }
      51             :    * @nocode
      52             :    *
      53             :    * @param lambdas
      54             :    * @return visitor
      55             :    */
      56             :   template <class... Fs>
      57             :   constexpr auto make_visitor(Fs &&... fs) {
      58             :     using visitor_type = lambda_visitor<std::decay_t<Fs>...>;
      59       87040 :     return visitor_type(std::forward<Fs>(fs)...);
      60           0 :   }
      61             : 
      62             :   /**
      63             :    * @brief Inplace visitor for boost::variant.
      64             :    * @code
      65             :    *   boost::variant<int, std::string> value = "1234";
      66             :    *   ...
      67             :    *   visit_in_place(value,
      68             :    *                  [](int v) { std::cout << "(int)" << v; },
      69             :    *                  [](std::string v) { std::cout << "(string)" << v;}
      70             :    *                  );
      71             :    * @nocode
      72             :    *
      73             :    * @param variant
      74             :    * @param lambdas
      75             :    * @param lambdas
      76             :    */
      77             :   template <typename TVariant, typename... TVisitors>
      78             :   constexpr decltype(auto) visit_in_place(TVariant &&variant,
      79             :                                           TVisitors &&... visitors) {
      80       87131 :     return boost::apply_visitor(
      81       87131 :         make_visitor(std::forward<TVisitors>(visitors)...),
      82       87131 :         std::forward<TVariant>(variant));
      83           0 :   }
      84             : 
      85             :   /// apply Matcher to optional T
      86             :   template <typename T, typename Matcher>
      87             :   constexpr decltype(auto) match(T &&t, Matcher &&m) {
      88             :     return std::forward<T>(t) ? std::forward<Matcher>(m)(*std::forward<T>(t))
      89             :                               : std::forward<Matcher>(m)();
      90             :   }
      91             : 
      92             :   /// construct visitor from Fs and apply it to optional T
      93             :   template <typename T, typename... Fs>
      94             :   constexpr decltype(auto) match_in_place(T &&t, Fs &&... fs) {
      95             :     return match(std::forward<T>(t), make_visitor(std::forward<Fs>(fs)...));
      96             :   }
      97             : }  // namespace iroha
      98             : 
      99             : #endif  // IROHA_VISITOR_HPP

Generated by: LCOV version 1.13