Line data Source code
1 : /*! \file tuple.hpp
2 : \brief Support for types found in \<tuple\>
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_TUPLE_HPP_
31 : #define CEREAL_TYPES_TUPLE_HPP_
32 :
33 : #include "cereal/cereal.hpp"
34 : #include <tuple>
35 :
36 : namespace cereal
37 : {
38 : namespace tuple_detail
39 : {
40 : //! Creates a c string from a sequence of characters
41 : /*! The c string created will always be prefixed by "tuple_element"
42 : Based on code from: http://stackoverflow/a/20973438/710791
43 : @internal */
44 : template<char...Cs>
45 : struct char_seq_to_c_str
46 : {
47 : static const int size = 14;// Size of array for the word: tuple_element
48 : typedef const char (&arr_type)[sizeof...(Cs) + size];
49 : static const char str[sizeof...(Cs) + size];
50 : };
51 :
52 : // the word tuple_element plus a number
53 : //! @internal
54 : template<char...Cs>
55 : const char char_seq_to_c_str<Cs...>::str[sizeof...(Cs) + size] =
56 : {'t','u','p','l','e','_','e','l','e','m','e','n','t', Cs..., '\0'};
57 :
58 : //! Converts a number into a sequence of characters
59 : /*! @tparam Q The quotient of dividing the original number by 10
60 : @tparam R The remainder of dividing the original number by 10
61 : @tparam C The sequence built so far
62 : @internal */
63 : template <size_t Q, size_t R, char ... C>
64 : struct to_string_impl
65 : {
66 : using type = typename to_string_impl<Q/10, Q%10, static_cast<char>(R+std::size_t{'0'}), C...>::type;
67 : };
68 :
69 : //! Base case with no quotient
70 : /*! @internal */
71 : template <size_t R, char ... C>
72 : struct to_string_impl<0, R, C...>
73 : {
74 : using type = char_seq_to_c_str<static_cast<char>(R+std::size_t{'0'}), C...>;
75 : };
76 :
77 : //! Generates a c string for a given index of a tuple
78 : /*! Example use:
79 : @code{cpp}
80 : tuple_element_name<3>::c_str();// returns "tuple_element3"
81 : @endcode
82 : @internal */
83 : template<size_t T>
84 : struct tuple_element_name
85 : {
86 : using type = typename to_string_impl<T/10, T%10>::type;
87 24800 : static const typename type::arr_type c_str(){ return type::str; }
88 : };
89 :
90 : // unwinds a tuple to save it
91 : //! @internal
92 : template <size_t Height>
93 : struct serialize
94 : {
95 : template <class Archive, class ... Types> inline
96 24800 : static void apply( Archive & ar, std::tuple<Types...> & tuple )
97 : {
98 24800 : serialize<Height - 1>::template apply( ar, tuple );
99 24800 : ar( CEREAL_NVP_(tuple_element_name<Height - 1>::c_str(),
100 : std::get<Height - 1>( tuple )) );
101 24800 : }
102 : };
103 :
104 : // Zero height specialization - nothing to do here
105 : //! @internal
106 : template <>
107 : struct serialize<0>
108 : {
109 : template <class Archive, class ... Types> inline
110 4800 : static void apply( Archive &, std::tuple<Types...> & )
111 4800 : { }
112 : };
113 : }
114 :
115 : //! Serializing for std::tuple
116 : template <class Archive, class ... Types> inline
117 4800 : void CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, std::tuple<Types...> & tuple )
118 : {
119 4800 : tuple_detail::serialize<std::tuple_size<std::tuple<Types...>>::value>::template apply( ar, tuple );
120 4800 : }
121 : } // namespace cereal
122 :
123 : #endif // CEREAL_TYPES_TUPLE_HPP_
|