Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / detail / array_wrapper.hpp
1 // Copyright 2019 Hans Dembinski
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt
5 // or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
8 #define BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
9
10 #include <boost/core/nvp.hpp>
11 #include <boost/histogram/detail/span.hpp>
12 #include <boost/histogram/detail/static_if.hpp>
13 #include <boost/mp11/function.hpp>
14 #include <boost/mp11/utility.hpp>
15 #include <type_traits>
16
17 namespace boost {
18 namespace histogram {
19 namespace detail {
20
21 template <class T, class = decltype(&T::template save_array<int>)>
22 struct has_save_array_impl;
23
24 template <class T, class = decltype(&T::template load_array<int>)>
25 struct has_load_array_impl;
26
27 template <class T>
28 using has_array_optimization = mp11::mp_or<mp11::mp_valid<has_save_array_impl, T>,
29                                            mp11::mp_valid<has_load_array_impl, T>>;
30
31 template <class T>
32 struct array_wrapper {
33   using pointer = T*;
34
35   pointer ptr;
36   std::size_t size;
37
38   template <class Archive>
39   void serialize(Archive& ar, unsigned /* version */) {
40     static_if_c<(has_array_optimization<Archive>::value &&
41                  std::is_trivially_copyable<T>::value)>(
42         [this](auto& ar) {
43           // cannot use and therefore bypass save_array / load_array interface, because
44           // it requires exact type boost::serialization::array_wrapper<T>
45           static_if_c<Archive::is_loading::value>(
46               [this](auto& ar) { ar.load_binary(this->ptr, sizeof(T) * this->size); },
47               [this](auto& ar) { ar.save_binary(this->ptr, sizeof(T) * this->size); },
48               ar);
49         },
50         [this](auto& ar) {
51           for (auto&& x : boost::histogram::detail::make_span(this->ptr, this->size))
52             ar& make_nvp("item", x);
53         },
54         ar);
55   }
56 };
57
58 template <class T>
59 auto make_array_wrapper(T* t, std::size_t s) {
60   return array_wrapper<T>{t, s};
61 }
62
63 } // namespace detail
64 } // namespace histogram
65 } // namespace boost
66
67 #endif