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