tuple.hpp 4.5 KB

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