LCOV - code coverage report
Current view: top level - shared_model/utils - lazy_initializer.hpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 8 9 88.9 %
Date: 2018-12-05 17:11:35 Functions: 229 398 57.5 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. 2017 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_LAZY_INITIALIZER_HPP
      19             : #define IROHA_LAZY_INITIALIZER_HPP
      20             : 
      21             : #include <boost/optional.hpp>
      22             : #include <functional>
      23             : 
      24             : namespace shared_model {
      25             :   namespace detail {
      26             : 
      27             :     /**
      28             :      * Lazy class for lazy converting one type to another
      29             :      * @tparam Target - output type
      30             :      */
      31             :     template <typename Target>
      32             :     class LazyInitializer {
      33             :      private:
      34             :       /// Type of generator function
      35             :       using GeneratorType = std::function<Target()>;
      36             : 
      37             :      public:
      38             :       /**
      39             :        * Default constructor prevents compilation error in pre 7.2 gcc.
      40             :        *
      41             :        * Short explanation: gcc needs default constructor
      42             :        * when the constructor is inherited (via using Base::Base)
      43             :        * if the inherited class has default initalizers for any of its members.
      44             :        * This can be found in shared_model/backend/protobuf/protobuf/block.hpp
      45             :        * where Lazy fields are initialized via default initializers.
      46             :        *
      47             :        * Note that this does not result in default constructor being called, so
      48             :        * the resulting code is still correct. This is an issue of gcc compiler
      49             :        * which is resolved in 7.2
      50             :        *
      51             :        * For more details: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054
      52             :        */
      53             :       LazyInitializer();
      54             : 
      55             :       template <typename T>
      56             :       explicit LazyInitializer(T &&generator)
      57       83646 :           : generator_(std::forward<T>(generator)) {}
      58             : 
      59             :       using PointerType = typename std::add_pointer_t<Target>;
      60             : 
      61             :       const Target &operator*() const {
      62       60423 :         return *ptr();
      63             :       }
      64             : 
      65             :       const PointerType ptr() const {
      66       60431 :         if (target_value_ == boost::none) {
      67             :           // Use type move constructor with emplace
      68             :           // since Target copy assignment operator could be deleted
      69             : 
      70       46544 :           target_value_.emplace(generator_());
      71       46544 :         }
      72       60432 :         return target_value_.get_ptr();
      73           0 :       }
      74             : 
      75             :       const PointerType operator->() const {
      76           3 :         return ptr();
      77             :       }
      78             : 
      79             :       /**
      80             :        * Remove generated value. Next ptr() call will generate new value
      81             :        */
      82             :       void invalidate() const {
      83             :         target_value_ = boost::none;
      84             :       }
      85             : 
      86             :      private:
      87             :       GeneratorType generator_;
      88             :       mutable boost::optional<Target> target_value_;
      89             :     };
      90             : 
      91             :     /**
      92             :      * Function for creating lazy object
      93             :      * @tparam Generator - type of generator
      94             :      * @param generator - instance of Generator
      95             :      * @return initialized lazy value
      96             :      */
      97             :     template <typename Generator>
      98             :     auto makeLazyInitializer(Generator &&generator) {
      99             :       using targetType = decltype(generator());
     100         865 :       return LazyInitializer<targetType>(std::forward<Generator>(generator));
     101             :     }
     102             :   }  // namespace detail
     103             : }  // namespace shared_model
     104             : #endif  // IROHA_LAZY_INITIALIZER_HPP

Generated by: LCOV version 1.13