1 // (C) Copyright 2005 Matthias Troyer and Dave Abrahams 2 // Copyright (c) 2015 Anton Bikineev 3 // Copyright (c) 2015 Andreas Schaefer 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef HPX_SERIALIZATION_ARRAY_HPP 9 #define HPX_SERIALIZATION_ARRAY_HPP 10 11 #include <hpx/config.hpp> 12 #include <hpx/runtime/serialization/serialize.hpp> 13 #include <hpx/traits/is_bitwise_serializable.hpp> 14 15 #include <boost/array.hpp> 16 17 #include <array> 18 #include <cstddef> 19 #include <type_traits> 20 21 namespace hpx { namespace serialization 22 { 23 template <class T> 24 class array 25 { 26 public: 27 typedef T value_type; 28 array(value_type * t,std::size_t s)29 array(value_type* t, std::size_t s): 30 m_t(t), 31 m_element_count(s) 32 {} 33 address() const34 value_type* address() const 35 { 36 return m_t; 37 } 38 count() const39 std::size_t count() const 40 { 41 return m_element_count; 42 } 43 44 template <class Archive> serialize_optimized(Archive & ar,unsigned int,std::false_type)45 void serialize_optimized(Archive& ar, unsigned int /*v*/, std::false_type) 46 { 47 for (std::size_t i = 0; i != m_element_count; ++i) 48 ar & m_t[i]; 49 } 50 serialize_optimized(output_archive & ar,unsigned int,std::true_type)51 void serialize_optimized(output_archive& ar, unsigned int, std::true_type) 52 { 53 // try using chunking 54 ar.save_binary_chunk(m_t, m_element_count * sizeof(T)); 55 } 56 serialize_optimized(input_archive & ar,unsigned int,std::true_type)57 void serialize_optimized(input_archive& ar, unsigned int, std::true_type) 58 { 59 // try using chunking 60 ar.load_binary_chunk(m_t, m_element_count * sizeof(T)); 61 } 62 63 template <class Archive> serialize(Archive & ar,unsigned int v)64 void serialize(Archive& ar, unsigned int v) 65 { 66 typedef std::integral_constant<bool, 67 hpx::traits::is_bitwise_serializable< 68 typename std::remove_const<T>::type 69 >::value> use_optimized; 70 71 #ifdef BOOST_BIG_ENDIAN 72 bool archive_endianess_differs = ar.endian_little(); 73 #else 74 bool archive_endianess_differs = ar.endian_big(); 75 #endif 76 77 if (ar.disable_array_optimization() || archive_endianess_differs) 78 serialize_optimized(ar, v, std::false_type()); 79 else 80 serialize_optimized(ar, v, use_optimized()); 81 } 82 83 private: 84 value_type* m_t; 85 std::size_t m_element_count; 86 }; 87 88 // make_array function 89 template <class T> HPX_FORCEINLINE make_array(T * begin,std::size_t size)90 array<T> make_array(T* begin, std::size_t size) 91 { 92 return array<T>(begin, size); 93 } 94 95 // implement serialization for boost::array 96 template <class Archive, class T, std::size_t N> serialize(Archive & ar,boost::array<T,N> & a,const unsigned int)97 void serialize(Archive& ar, boost::array<T,N>& a, const unsigned int /* version */) 98 { 99 ar & hpx::serialization::make_array(a.begin(), a.size()); 100 } 101 102 // implement serialization for std::array 103 template <class Archive, class T, std::size_t N> serialize(Archive & ar,std::array<T,N> & a,const unsigned int)104 void serialize(Archive& ar, std::array<T,N>& a, const unsigned int /* version */) 105 { 106 ar & hpx::serialization::make_array(a.data(), a.size()); 107 } 108 109 // allow our array to be serialized as prvalue 110 // compiler should support good ADL implementation 111 // but it is rather for all hpx serialization library 112 template <typename T> HPX_FORCEINLINE operator <<(output_archive & ar,array<T> t)113 output_archive & operator<<(output_archive & ar, array<T> t) 114 { 115 ar.invoke(t); 116 return ar; 117 } 118 119 template <typename T> HPX_FORCEINLINE operator >>(input_archive & ar,array<T> t)120 input_archive & operator>>(input_archive & ar, array<T> t) 121 { 122 ar.invoke(t); 123 return ar; 124 } 125 126 template <typename T> HPX_FORCEINLINE operator &(output_archive & ar,array<T> t)127 output_archive & operator&(output_archive & ar, array<T> t) //-V524 128 { 129 ar.invoke(t); 130 return ar; 131 } 132 133 template <typename T> HPX_FORCEINLINE operator &(input_archive & ar,array<T> t)134 input_archive & operator&(input_archive & ar, array<T> t) //-V524 135 { 136 ar.invoke(t); 137 return ar; 138 } 139 140 // serialize plain arrays: 141 template <typename T, std::size_t N> HPX_FORCEINLINE operator <<(output_archive & ar,T (& t)[N])142 output_archive & operator<<(output_archive & ar, T (&t)[N]) 143 { 144 array<T> array = make_array(t, N); 145 ar.invoke(array); 146 return ar; 147 } 148 149 template <typename T, std::size_t N> HPX_FORCEINLINE operator >>(input_archive & ar,T (& t)[N])150 input_archive & operator>>(input_archive & ar, T (&t)[N]) 151 { 152 array<T> array = make_array(t, N); 153 ar.invoke(array); 154 return ar; 155 } 156 157 template <typename T, std::size_t N> HPX_FORCEINLINE operator &(output_archive & ar,T (& t)[N])158 output_archive & operator&(output_archive & ar, T (&t)[N]) //-V524 159 { 160 array<T> array = make_array(t, N); 161 ar.invoke(array); 162 return ar; 163 } 164 165 template <typename T, std::size_t N> HPX_FORCEINLINE operator &(input_archive & ar,T (& t)[N])166 input_archive & operator&(input_archive & ar, T (&t)[N]) //-V524 167 { 168 array<T> array = make_array(t, N); 169 ar.invoke(array); 170 return ar; 171 } 172 }} 173 174 #endif // HPX_SERIALIZATION_ARRAY_HPP 175