LCOV - code coverage report
Current view: top level - libs/common - visitor.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 5 7 71.4 %
Date: 2018-12-05 17:11:35 Functions: 735 800 91.9 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. 2018 All Rights Reserved.
       3             :  * http://soramitsu.co.jp
       4             :  *
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #ifndef IROHA_VISITOR_HPP
      19             : #define IROHA_VISITOR_HPP
      20             : 
      21             : #include <boost/variant/apply_visitor.hpp>  // for boost::apply_visitor
      22             : #include <type_traits>                      // for std::decay
      23             : #include <utility>                          // for std::forward
      24             : 
      25             : namespace iroha {
      26             : 
      27             :   template <typename... Lambdas>
      28             :   struct lambda_visitor;
      29             : 
      30             :   template <typename Lambda, typename... Lambdas>
      31             :   struct lambda_visitor<Lambda, Lambdas...>
      32             :       : public Lambda, public lambda_visitor<Lambdas...> {
      33             :     using Lambda::operator();
      34             :     using lambda_visitor<Lambdas...>::operator();
      35             : 
      36             :     lambda_visitor(Lambda lambda, Lambdas... lambdas)
      37       35398 :         : Lambda(lambda), lambda_visitor<Lambdas...>(lambdas...) {}
      38             :   };
      39             : 
      40             :   template <typename Lambda>
      41             :   struct lambda_visitor<Lambda> : public Lambda {
      42             :     using Lambda::operator();
      43             : 
      44             :     lambda_visitor(Lambda lambda) : Lambda(lambda) {}
      45             :   };
      46             : 
      47             :   /**
      48             :    * @brief Convenient in-place compile-time visitor creation, from a set of
      49             :    * lambdas
      50             :    *
      51             :    * @code
      52             :    * make_visitor([](int a){ return 1; },
      53             :    *              [](std::string b) { return 2; });
      54             :    * @nocode
      55             :    *
      56             :    * is essentially the same as
      57             :    *
      58             :    * @code
      59             :    * struct visitor : public boost::static_visitor<int> {
      60             :    *   int operator()(int a) { return 1; }
      61             :    *   int operator()(std::string b) { return 2; }
      62             :    * }
      63             :    * @nocode
      64             :    *
      65             :    * @param lambdas
      66             :    * @return visitor
      67             :    */
      68             :   template <class... Fs>
      69             :   constexpr auto make_visitor(Fs &&... fs) {
      70             :     using visitor_type = lambda_visitor<std::decay_t<Fs>...>;
      71       36113 :     return visitor_type(std::forward<Fs>(fs)...);
      72           0 :   }
      73             : 
      74             :   /**
      75             :    * @brief Inplace visitor for boost::variant.
      76             :    * @code
      77             :    *   boost::variant<int, std::string> value = "1234";
      78             :    *   ...
      79             :    *   visit_in_place(value,
      80             :    *                  [](int v) { std::cout << "(int)" << v; },
      81             :    *                  [](std::string v) { std::cout << "(string)" << v;}
      82             :    *                  );
      83             :    * @nocode
      84             :    *
      85             :    * @param variant
      86             :    * @param lambdas
      87             :    * @param lambdas
      88             :    */
      89             :   template <typename TVariant, typename... TVisitors>
      90             :   constexpr decltype(auto) visit_in_place(TVariant &&variant,
      91             :                                           TVisitors &&... visitors) {
      92       36112 :     return boost::apply_visitor(
      93       36112 :         make_visitor(std::forward<TVisitors>(visitors)...),
      94       36112 :         std::forward<TVariant>(variant));
      95           0 :   }
      96             : 
      97             :   /// apply Matcher to optional T
      98             :   template <typename T, typename Matcher>
      99             :   constexpr decltype(auto) match(T &&t, Matcher &&m) {
     100             :     return std::forward<T>(t) ? std::forward<Matcher>(m)(*std::forward<T>(t))
     101             :                               : std::forward<Matcher>(m)();
     102             :   }
     103             : 
     104             :   /// construct visitor from Fs and apply it to optional T
     105             :   template <typename T, typename... Fs>
     106             :   constexpr decltype(auto) match_in_place(T &&t, Fs &&... fs) {
     107             :     return match(std::forward<T>(t), make_visitor(std::forward<Fs>(fs)...));
     108             :   }
     109             : }  // namespace iroha
     110             : 
     111             : #endif  // IROHA_VISITOR_HPP

Generated by: LCOV version 1.13