LCOV - code coverage report

Current view: | top level - cereal/details - static_object.hpp (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 8 | 8 | 100.0 %
Date: | 2022-01-16 21:05:07 |  | Functions: | 85 | 117 | 72.6 %

              Line data    Source code

           1             : /*! \file static_object.hpp
           2             :     \brief Internal polymorphism static object support
           3             :     \ingroup Internal */
           4             : /*
           5             :   Copyright (c) 2014, Randolph Voorhies, Shane Grant
           6             :   All rights reserved.
           7             :   Redistribution and use in source and binary forms, with or without
           8             :   modification, are permitted provided that the following conditions are met:
           9             :       * Redistributions of source code must retain the above copyright
          10             :         notice, this list of conditions and the following disclaimer.
          11             :       * Redistributions in binary form must reproduce the above copyright
          12             :         notice, this list of conditions and the following disclaimer in the
          13             :         documentation and/or other materials provided with the distribution.
          14             :       * Neither the name of the copyright holder nor the
          15             :         names of its contributors may be used to endorse or promote products
          16             :         derived from this software without specific prior written permission.
          17             :   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
          18             :   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
          19             :   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
          20             :   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
          21             :   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
          22             :   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
          23             :   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
          24             :   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          25             :   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
          26             :   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          27             : */
          28             : #ifndef CEREAL_DETAILS_STATIC_OBJECT_HPP_
          29             : #define CEREAL_DETAILS_STATIC_OBJECT_HPP_
          30             :
          31             : #include "cereal/macros.hpp"
          32             :
          33             : #if CEREAL_THREAD_SAFE
          34             : #include <mutex>
          35             : #endif
          36             :
          37             : //! Prevent link optimization from removing non-referenced static objects
          38             : /*! Especially for polymorphic support, we create static objects which
          39             :     may not ever be explicitly referenced.  Most linkers will detect this
          40             :     and remove the code causing various unpleasant runtime errors.  These
          41             :     macros, adopted from Boost (see force_include.hpp) prevent this
          42             :     (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
          43             :     Use, modification and distribution is subject to the Boost Software
          44             :     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
          45             :     http://www.boost.org/LICENSE_1_0.txt) */
          46             :
          47             : #if defined(_MSC_VER) && !defined(__clang__)
          48             : #   define CEREAL_DLL_EXPORT __declspec(dllexport)
          49             : #   define CEREAL_USED
          50             : #else // clang or gcc
          51             : #   define CEREAL_DLL_EXPORT __attribute__ ((visibility("default")))
          52             : #   define CEREAL_USED __attribute__ ((__used__))
          53             : #endif
          54             :
          55             : namespace cereal
          56             : {
          57             :   namespace detail
          58             :   {
          59             :     //! A static, pre-execution object
          60             :     /*! This class will create a single copy (singleton) of some
          61             :         type and ensures that merely referencing this type will
          62             :         cause it to be instantiated and initialized pre-execution.
          63             :         For example, this is used heavily in the polymorphic pointer
          64             :         serialization mechanisms to bind various archive types with
          65             :         different polymorphic classes */
          66             :     template <class T>
          67             :     class CEREAL_DLL_EXPORT StaticObject
          68             :     {
          69             :       private:
          70             :
          71       39780 :         static T & create()
          72             :         {
          73       39772 :           static T t;
          74             :           //! Forces instantiation at pre-execution time
          75             :           (void)instance;
          76       39780 :           return t;
          77             :         }
          78             :
          79             :         StaticObject( StaticObject const & /*other*/ ) {}
          80             :
          81             :       public:
          82       39676 :         static T & getInstance()
          83             :         {
          84       39676 :           return create();
          85             :         }
          86             :
          87             :         //! A class that acts like std::lock_guard
          88             :         class LockGuard
          89             :         {
          90             :           #if CEREAL_THREAD_SAFE
          91             :           public:
          92             :             LockGuard(std::mutex & m) : lock(m) {}
          93             :           private:
          94             :             std::unique_lock<std::mutex> lock;
          95             :           #else
          96             :           public:
          97             :             LockGuard() = default;
          98             :             LockGuard(LockGuard const &) = default; // prevents implicit copy ctor warning
          99        7624 :             ~LockGuard() CEREAL_NOEXCEPT {} // prevents variable not used
         100             :           #endif
         101             :         };
         102             :
         103             :         //! Attempts to lock this static object for the current scope
         104             :         /*! @note This function is a no-op if cereal is not compiled with
         105             :                   thread safety enabled (CEREAL_THREAD_SAFE = 1).
         106             :
         107             :             This function returns an object that holds a lock for
         108             :             this StaticObject that will release its lock upon destruction. This
         109             :             call will block until the lock is available. */
         110        7624 :         static LockGuard lock()
         111             :         {
         112             :           #if CEREAL_THREAD_SAFE
         113             :           static std::mutex instanceMutex;
         114             :           return LockGuard{instanceMutex};
         115             :           #else
         116        7624 :           return LockGuard{};
         117             :           #endif
         118             :         }
         119             :
         120             :       private:
         121             :         static T & instance;
         122             :     };
         123             :
         124             :     template <class T> T & StaticObject<T>::instance = StaticObject<T>::create();
         125             :   } // namespace detail
         126             : } // namespace cereal
         127             :
         128             : #endif // CEREAL_DETAILS_STATIC_OBJECT_HPP_

Generated by: LCOV version 1.14