Line data Source code
1 : /*! \file common.hpp 2 : \brief Support common types - always included automatically 3 : \ingroup OtherTypes */ 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_COMMON_HPP_ 31 : #define CEREAL_TYPES_COMMON_HPP_ 32 : 33 : #include "cereal/cereal.hpp" 34 : 35 : namespace cereal 36 : { 37 : namespace common_detail 38 : { 39 : //! Serialization for arrays if BinaryData is supported and we are arithmetic 40 : /*! @internal */ 41 : template <class Archive, class T> inline 42 : void serializeArray( Archive & ar, T & array, std::true_type /* binary_supported */ ) 43 : { 44 : ar( binary_data( array, sizeof(array) ) ); 45 : } 46 : 47 : //! Serialization for arrays if BinaryData is not supported or we are not arithmetic 48 : /*! @internal */ 49 : template <class Archive, class T> inline 50 : void serializeArray( Archive & ar, T & array, std::false_type /* binary_supported */ ) 51 : { 52 : for( auto & i : array ) 53 : ar( i ); 54 : } 55 : 56 : namespace 57 : { 58 : //! Gets the underlying type of an enum 59 : /*! @internal */ 60 : template <class T, bool IsEnum> 61 : struct enum_underlying_type : std::false_type {}; 62 : 63 : //! Gets the underlying type of an enum 64 : /*! Specialization for when we actually have an enum 65 : @internal */ 66 : template <class T> 67 : struct enum_underlying_type<T, true> { using type = typename std::underlying_type<T>::type; }; 68 : } // anon namespace 69 : 70 : //! Checks if a type is an enum 71 : /*! This is needed over simply calling std::is_enum because the type 72 : traits checking at compile time will attempt to call something like 73 : load_minimal with a special NoConvertRef struct that wraps up the true type. 74 : 75 : This will strip away any of that and also expose the true underlying type. 76 : @internal */ 77 : template <class T> 78 : class is_enum 79 : { 80 : private: 81 : using DecayedT = typename std::decay<T>::type; 82 : using StrippedT = typename ::cereal::traits::strip_minimal<DecayedT>::type; 83 : 84 : public: 85 : static const bool value = std::is_enum<StrippedT>::value; 86 : using type = StrippedT; 87 : using base_type = typename enum_underlying_type<StrippedT, value>::type; 88 : }; 89 : } 90 : 91 : //! Saving for enum types 92 : template <class Archive, class T> inline 93 : typename std::enable_if<common_detail::is_enum<T>::value, 94 : typename common_detail::is_enum<T>::base_type>::type 95 2000 : CEREAL_SAVE_MINIMAL_FUNCTION_NAME( Archive const &, T const & t ) 96 : { 97 2000 : return static_cast<typename common_detail::is_enum<T>::base_type>(t); 98 : } 99 : 100 : //! Loading for enum types 101 : template <class Archive, class T> inline 102 : typename std::enable_if<common_detail::is_enum<T>::value, void>::type 103 2000 : CEREAL_LOAD_MINIMAL_FUNCTION_NAME( Archive const &, T && t, 104 : typename common_detail::is_enum<T>::base_type const & value ) 105 : { 106 2000 : t = reinterpret_cast<typename common_detail::is_enum<T>::type const &>( value ); 107 2000 : } 108 : 109 : //! Serialization for raw pointers 110 : /*! This exists only to throw a static_assert to let users know we don't support raw pointers. */ 111 : template <class Archive, class T> inline 112 : void CEREAL_SERIALIZE_FUNCTION_NAME( Archive &, T * & ) 113 : { 114 : static_assert(cereal::traits::detail::delay_static_assert<T>::value, 115 : "Cereal does not support serializing raw pointers - please use a smart pointer"); 116 : } 117 : 118 : //! Serialization for C style arrays 119 : template <class Archive, class T> inline 120 : typename std::enable_if<std::is_array<T>::value, void>::type 121 : CEREAL_SERIALIZE_FUNCTION_NAME(Archive & ar, T & array) 122 : { 123 : common_detail::serializeArray( ar, array, 124 : std::integral_constant<bool, traits::is_output_serializable<BinaryData<T>, Archive>::value && 125 : std::is_arithmetic<typename std::remove_all_extents<T>::type>::value>() ); 126 : } 127 : } // namespace cereal 128 : 129 : #endif // CEREAL_TYPES_COMMON_HPP_