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