LCOV - code coverage report
Current view: top level - cereal/details - static_object.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 11 100.0 %
Date: 2017-02-12 13:57:59 Functions: 139 171 81.3 %

          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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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             : #ifdef _MSC_VER
      48             : #   define CEREAL_DLL_EXPORT __declspec(dllexport)
      49             : #   define CEREAL_USED
      50             : #else // clang or gcc
      51             : #   define CEREAL_DLL_EXPORT
      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             :         //! Forces instantiation at pre-execution time
      71       29390 :         static void instantiate( T const & ) {}
      72             : 
      73       29390 :         static T & create()
      74             :         {
      75       29382 :           static T t;
      76       29390 :           instantiate(instance);
      77       29390 :           return t;
      78             :         }
      79             : 
      80             :         StaticObject( StaticObject const & /*other*/ ) {}
      81             : 
      82             :       public:
      83       29290 :         static T & getInstance()
      84             :         {
      85       29290 :           return create();
      86             :         }
      87             : 
      88             :         //! A class that acts like std::lock_guard
      89             :         class LockGuard
      90             :         {
      91             :           #if CEREAL_THREAD_SAFE
      92             :           public:
      93             :             LockGuard(std::mutex & m) : lock(m) {}
      94             :           private:
      95             :             std::unique_lock<std::mutex> lock;
      96             :           #else
      97             :           public:
      98        6824 :             ~LockGuard() CEREAL_NOEXCEPT {} // prevents variable not used
      99             :           #endif
     100             :         };
     101             : 
     102             :         //! Attempts to lock this static object for the current scope
     103             :         /*! @note This function is a no-op if cereal is not compiled with
     104             :                   thread safety enabled (CEREAL_THREAD_SAFE = 1).
     105             : 
     106             :             This function returns an object that holds a lock for
     107             :             this StaticObject that will release its lock upon destruction. This
     108             :             call will block until the lock is available. */
     109        6824 :         static LockGuard lock()
     110             :         {
     111             :           #if CEREAL_THREAD_SAFE
     112             :           static std::mutex instanceMutex;
     113             :           return LockGuard{instanceMutex};
     114             :           #else
     115        6824 :           return LockGuard{};
     116             :           #endif
     117             :         }
     118             : 
     119             :       private:
     120             :         static T & instance;
     121             :     };
     122             : 
     123          36 :     template <class T> T & StaticObject<T>::instance = StaticObject<T>::create();
     124             :   } // namespace detail
     125             : } // namespace cereal
     126             : 
     127             : #endif // CEREAL_DETAILS_STATIC_OBJECT_HPP_

Generated by: LCOV version 1.11