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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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 4000 : CEREAL_SAVE_MINIMAL_FUNCTION_NAME( Archive const &, T const & t )
96 : {
97 4000 : return static_cast<typename common_detail::is_enum<T>::base_type>(t);
98 : }
99 1000 :
100 : //! Loading for enum types
101 1000 : template <class Archive, class T> inline
102 : typename std::enable_if<common_detail::is_enum<T>::value, void>::type
103 1000 : CEREAL_LOAD_MINIMAL_FUNCTION_NAME( Archive const &, T && t,
104 : typename common_detail::is_enum<T>::base_type const & value )
105 1000 : {
106 : t = reinterpret_cast<typename common_detail::is_enum<T>::type const &>( value );
107 1000 : }
108 :
109 1000 : //! Serialization for raw pointers
110 : /*! This exists only to throw a static_assert to let users know we don't support raw pointers. */
111 1000 : template <class Archive, class T> inline
112 : void CEREAL_SERIALIZE_FUNCTION_NAME( Archive &, T * & )
113 1000 : {
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 4000 : 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 4000 : {
123 4000 : common_detail::serializeArray( ar, array,
124 1000 : 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 1000 : } // namespace cereal
128 1000 :
129 1000 : #endif // CEREAL_TYPES_COMMON_HPP_
|