LCOV - code coverage report

Current view: | top level - cereal/types - bitset.hpp (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 50 | 58 | 86.2 %
Date: | 2022-01-16 21:05:07 |  | Functions: | 32 | 32 | 100.0 %

              Line data    Source code

           1             : /*! \file bitset.hpp
           2             :     \brief Support for types found in \<bitset\>
           3             :     \ingroup STLSupport */
           4             : /*
           5             :   Copyright (c) 2014, Randolph Voorhies, Shane Grant
           6             :   All rights reserved.
           7             :
           8             :   Redistribution and use in source and binary forms, with or without
           9             :   modification, are permitted provided that the following conditions are met:
          10             :       * Redistributions of source code must retain the above copyright
          11             :         notice, this list of conditions and the following disclaimer.
          12             :       * Redistributions in binary form must reproduce the above copyright
          13             :         notice, this list of conditions and the following disclaimer in the
          14             :         documentation and/or other materials provided with the distribution.
          15             :       * Neither the name of the copyright holder nor the
          16             :         names of its contributors may be used to endorse or promote products
          17             :         derived from this software without specific prior written permission.
          18             :
          19             :   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
          20             :   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
          21             :   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
          22             :   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
          23             :   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
          24             :   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
          25             :   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
          26             :   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          27             :   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
          28             :   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          29             : */
          30             : #ifndef CEREAL_TYPES_BITSET_HPP_
          31             : #define CEREAL_TYPES_BITSET_HPP_
          32             :
          33             : #include "cereal/cereal.hpp"
          34             : #include "cereal/types/string.hpp"
          35             : #include <bitset>
          36             :
          37             : namespace cereal
          38             : {
          39             :   namespace bitset_detail
          40             :   {
          41             :     //! The type the bitset is encoded with
          42             :     /*! @internal */
          43             :     enum class type : uint8_t
          44             :     {
          45             :       ulong,
          46             :       ullong,
          47             :       string,
          48             :       bits
          49             :     };
          50             :   }
          51             :
          52             :   //! Serializing (save) for std::bitset when BinaryData optimization supported
          53             :   template <class Archive, size_t N,
          54             :             traits::EnableIf<traits::is_output_serializable<BinaryData<std::uint32_t>, Archive>::value>
          55             :             = traits::sfinae> inline
          56        1000 :   void CEREAL_SAVE_FUNCTION_NAME( Archive & ar, std::bitset<N> const & bits )
          57             :   {
          58        1000 :     ar( CEREAL_NVP_("type", bitset_detail::type::bits) );
          59             :
          60             :     // Serialize 8 bit chunks
          61        1000 :     std::uint8_t chunk = 0;
          62        1000 :     std::uint8_t mask = 0x80;
          63             :
          64             :     // Set each chunk using a rotating mask for the current bit
          65      180400 :     for( std::size_t i = 0; i < N; ++i )
          66             :     {
          67      179400 :       if( bits[i] )
          68       86476 :         chunk |= mask;
          69             :
          70      179400 :       mask = static_cast<std::uint8_t>(mask >> 1);
          71             :
          72             :       // output current chunk when mask is empty (8 bits)
          73      179400 :       if( mask == 0 )
          74             :       {
          75       22400 :         ar( chunk );
          76       22400 :         chunk = 0;
          77       22400 :         mask = 0x80;
          78             :       }
          79             :     }
          80             :
          81             :     // serialize remainder, if it exists
          82        1000 :     if( mask != 0x80 )
          83         200 :       ar( chunk );
          84        1000 :   }
          85             :
          86             :   //! Serializing (save) for std::bitset when BinaryData is not supported
          87             :   template <class Archive, size_t N,
          88             :             traits::DisableIf<traits::is_output_serializable<BinaryData<std::uint32_t>, Archive>::value>
          89             :             = traits::sfinae> inline
          90        1000 :   void CEREAL_SAVE_FUNCTION_NAME( Archive & ar, std::bitset<N> const & bits )
          91             :   {
          92             :     try
          93             :     {
          94        1000 :       auto const b = bits.to_ulong();
          95         498 :       ar( CEREAL_NVP_("type", bitset_detail::type::ulong) );
          96         498 :       ar( CEREAL_NVP_("data", b) );
          97             :     }
          98        1004 :     catch( std::overflow_error const & )
          99             :     {
         100             :       try
         101             :       {
         102         502 :         auto const b = bits.to_ullong();
         103           0 :         ar( CEREAL_NVP_("type", bitset_detail::type::ullong) );
         104           0 :         ar( CEREAL_NVP_("data", b) );
         105             :       }
         106         502 :       catch( std::overflow_error const & )
         107             :       {
         108         502 :         ar( CEREAL_NVP_("type", bitset_detail::type::string) );
         109         502 :         ar( CEREAL_NVP_("data", bits.to_string()) );
         110             :       }
         111             :     }
         112        1000 :   }
         113             :
         114             :   //! Serializing (load) for std::bitset
         115             :   template <class Archive, size_t N> inline
         116        2000 :   void CEREAL_LOAD_FUNCTION_NAME( Archive & ar, std::bitset<N> & bits )
         117             :   {
         118             :     bitset_detail::type t;
         119        2000 :     ar( CEREAL_NVP_("type", t) );
         120             :
         121        2000 :     switch( t )
         122             :     {
         123         498 :       case bitset_detail::type::ulong:
         124             :       {
         125             :         unsigned long b;
         126         498 :         ar( CEREAL_NVP_("data", b) );
         127         498 :         bits = std::bitset<N>( b );
         128         498 :         break;
         129             :       }
         130           0 :       case bitset_detail::type::ullong:
         131             :       {
         132             :         unsigned long long b;
         133           0 :         ar( CEREAL_NVP_("data", b) );
         134           0 :         bits = std::bitset<N>( b );
         135           0 :         break;
         136             :       }
         137         502 :       case bitset_detail::type::string:
         138             :       {
         139        1004 :         std::string b;
         140         502 :         ar( CEREAL_NVP_("data", b) );
         141         502 :         bits = std::bitset<N>( b );
         142         502 :         break;
         143             :       }
         144        1000 :       case bitset_detail::type::bits:
         145             :       {
         146             :         // Normally we would use BinaryData to route this at compile time,
         147             :         // but doing this at runtime doesn't break any old serialization
         148        1000 :         std::uint8_t chunk = 0;
         149        1000 :         std::uint8_t mask  = 0;
         150             :
         151        1000 :         bits.reset();
         152             :
         153             :         // Load one chunk at a time, rotating through the chunk
         154             :         // to set bits in the bitset
         155      180400 :         for( std::size_t i = 0; i < N; ++i )
         156             :         {
         157      179400 :           if( mask == 0 )
         158             :           {
         159       22600 :             ar( chunk );
         160       22600 :             mask = 0x80;
         161             :           }
         162             :
         163      179400 :           if( chunk & mask )
         164       86476 :             bits[i] = 1;
         165             :
         166      179400 :           mask = static_cast<std::uint8_t>(mask >> 1);
         167             :         }
         168        1000 :         break;
         169             :       }
         170           0 :       default:
         171           0 :         throw Exception("Invalid bitset data representation");
         172             :     }
         173        2000 :   }
         174             : } // namespace cereal
         175             :
         176             : #endif // CEREAL_TYPES_BITSET_HPP_

Generated by: LCOV version 1.14