array_wrapper.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. #ifndef BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
  7. #define BOOST_HISTOGRAM_DETAIL_ARRAY_WRAPPER_HPP
  8. #include <boost/core/nvp.hpp>
  9. #include <boost/histogram/detail/span.hpp>
  10. #include <boost/histogram/detail/static_if.hpp>
  11. #include <boost/mp11/function.hpp>
  12. #include <boost/mp11/utility.hpp>
  13. #include <type_traits>
  14. namespace boost {
  15. namespace histogram {
  16. namespace detail {
  17. template <class T, class = decltype(&T::template save_array<int>)>
  18. struct has_save_array_impl;
  19. template <class T, class = decltype(&T::template load_array<int>)>
  20. struct has_load_array_impl;
  21. template <class T>
  22. using has_array_optimization = mp11::mp_or<mp11::mp_valid<has_save_array_impl, T>,
  23. mp11::mp_valid<has_load_array_impl, T>>;
  24. template <class T>
  25. struct array_wrapper {
  26. using pointer = T*;
  27. pointer ptr;
  28. std::size_t size;
  29. template <class Archive>
  30. void serialize(Archive& ar, unsigned /* version */) {
  31. static_if_c<(has_array_optimization<Archive>::value &&
  32. std::is_trivially_copyable<T>::value)>(
  33. [this](auto& ar) {
  34. // cannot use and therefore bypass save_array / load_array interface, because
  35. // it requires exact type boost::serialization::array_wrapper<T>
  36. static_if_c<Archive::is_loading::value>(
  37. [this](auto& ar) { ar.load_binary(this->ptr, sizeof(T) * this->size); },
  38. [this](auto& ar) { ar.save_binary(this->ptr, sizeof(T) * this->size); },
  39. ar);
  40. },
  41. [this](auto& ar) {
  42. for (auto&& x : boost::histogram::detail::make_span(this->ptr, this->size))
  43. ar& make_nvp("item", x);
  44. },
  45. ar);
  46. }
  47. };
  48. template <class T>
  49. auto make_array_wrapper(T* t, std::size_t s) {
  50. return array_wrapper<T>{t, s};
  51. }
  52. } // namespace detail
  53. } // namespace histogram
  54. } // namespace boost
  55. #endif