LCOV - code coverage report
Current view: top level - shared_model/utils - variant_deserializer.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 6 8 75.0 %
Date: 2018-12-05 17:11:35 Functions: 114 126 90.5 %

          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_VARIANT_DESERIALIZER_HPP
       7             : #define IROHA_VARIANT_DESERIALIZER_HPP
       8             : 
       9             : #include <boost/serialization/variant.hpp>
      10             : 
      11             : #define NORETURN [[noreturn]]
      12             : 
      13             : namespace shared_model {
      14             :   namespace detail {
      15             :     /**
      16             :      * Helper for variant deserialization
      17             :      * Iterate through type list to use type specified by type index in list
      18             :      * @tparam S list of types
      19             :      */
      20             :     template <class S>
      21             :     struct variant_impl {
      22             :       /**
      23             :        * Dummy deserializer for empty list
      24             :        */
      25             :       struct load_null {
      26             :         /**
      27             :          * Dummy deserializer
      28             :          * @tparam V variant type for deserialization
      29             :          * @tparam Archive container type
      30             :          */
      31             :         template <class V, class Archive>
      32             :         NORETURN static V invoke(Archive &&, int) {
      33           0 :           BOOST_ASSERT_MSG(false, "Required type not found");
      34             :           std::abort();
      35           0 :         }
      36             :       };
      37             : 
      38             :       /**
      39             :        * Deserializer implementation
      40             :        */
      41             :       struct load_impl {
      42             :         /**
      43             :          * Deserialize container in variant using type in list by specified
      44             :          * index
      45             :          * If type selector is 0, head type is required type, and it is used
      46             :          * Otherwise call helper without front element in type list
      47             :          * @tparam V variant type for deserialization
      48             :          * @tparam Archive container type
      49             :          * @param ar container to be deserialized
      50             :          * @param which type index in list
      51             :          * @param v result variant
      52             :          */
      53             :         template <class V, class Archive>
      54             :         static V invoke(Archive &&ar, int which) {
      55       59682 :           if (which == 0) {
      56             :             using head_type = typename boost::mpl::front<S>::type;
      57       11648 :             return head_type(std::forward<Archive>(ar));
      58             :           } else {
      59             :             using type = typename boost::mpl::pop_front<S>::type;
      60       58077 :             return variant_impl<type>::template load<V>(
      61       58077 :                 std::forward<Archive>(ar), which - 1);
      62             :           }
      63       59668 :         }
      64             :       };
      65             : 
      66             :       /**
      67             :        * Deserialize container in variant using type in list by specified index
      68             :        * Choose dummy or concrete deserializer depending on type list size
      69             :        * @tparam V variant type for deserialization
      70             :        * @tparam Archive container type
      71             :        * @param ar container to be deserialized
      72             :        * @param which type index in list
      73             :        * @param v result variant
      74             :        */
      75             :       template <class V, class Archive>
      76             :       static V load(Archive &&ar, int which) {
      77             :         using typex =
      78             :             typename boost::mpl::eval_if<boost::mpl::empty<S>,
      79             :                                          boost::mpl::identity<load_null>,
      80             :                                          boost::mpl::identity<load_impl>>::type;
      81       59679 :         return typex::template invoke<V>(std::forward<Archive>(ar), which);
      82             :       }
      83             :     };
      84             :   }  // namespace detail
      85             : }  // namespace shared_model
      86             : 
      87             : #endif  // IROHA_VARIANT_DESERIALIZER_HPP

Generated by: LCOV version 1.13