ALPSCore reference
array.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #ifndef ALPS_HDF5_BOOST_ARRAY_HPP
8 #define ALPS_HDF5_BOOST_ARRAY_HPP
9 
10 #include <alps/hdf5/archive.hpp>
11 #include <alps/utilities/cast.hpp>
12 
13 #include <boost/array.hpp>
14 
15 #include <vector>
16 #include <type_traits>
17 #include <iterator>
18 #include <algorithm>
19 
20 namespace alps {
21  namespace hdf5 {
22 
23  template<typename T, std::size_t N> struct scalar_type<boost::array<T, N> > {
25  };
26 
27  template<typename T, std::size_t N> struct is_continuous<boost::array<T, N> >
28  : public is_continuous<T>
29  {};
30  template<typename T, std::size_t N> struct is_continuous<boost::array<T, N> const >
31  : public is_continuous<T>
32  {};
33 
34  template<typename T, std::size_t N> struct has_complex_elements<boost::array<T, N> >
35  : public has_complex_elements<typename alps::detail::remove_cvr<typename boost::array<T, N>::value_type>::type>
36  {};
37 
38  namespace detail {
39 
40  template<typename T, std::size_t N> struct get_extent<boost::array<T, N> > {
41  static std::vector<std::size_t> apply(boost::array<T, N> const & value) {
43  std::vector<std::size_t> result(1, value.size());
44  if (value.size()) {
45  std::vector<std::size_t> first(get_extent(value[0]));
46  std::copy(first.begin(), first.end(), std::back_inserter(result));
47  }
48  return result;
49  }
50  };
51 
52  template<typename T, std::size_t N> struct set_extent<boost::array<T, N> > {
53  static void apply(boost::array<T, N> & value, std::vector<std::size_t> const & extent) {
55  if (extent.size() > 1)
56  for(typename boost::array<T, N>::iterator it = value.begin(); it != value.end(); ++it)
57  set_extent(*it, std::vector<std::size_t>(extent.begin() + 1, extent.end()));
58  else if (extent.size() == 0 && !std::is_same<typename scalar_type<T>::type, T>::value)
59  throw archive_error("dimensions do not match" + ALPS_STACKTRACE);
60  }
61  };
62 
63  template<typename T, std::size_t N> struct is_vectorizable<boost::array<T, N> > {
64  static bool apply(boost::array<T, N> const & value) {
67  if (!is_continuous<boost::array<T, N> >::value) {
68  if (!is_vectorizable(value[0]))
69  return false;
70  std::vector<std::size_t> first(get_extent(value[0]));
71  for(typename boost::array<T, N>::const_iterator it = value.begin(); it != value.end(); ++it)
72  if (!is_vectorizable(*it))
73  return false;
74  else {
75  std::vector<std::size_t> size(get_extent(*it));
76  if (
77  first.size() != size.size()
78  || !std::equal(first.begin(), first.end(), size.begin())
79  )
80  return false;
81  }
82  }
83  return true;
84  }
85  };
86 
87  template<typename T, std::size_t N> struct get_pointer<boost::array<T, N> > {
88  static typename alps::hdf5::scalar_type<boost::array<T, N> >::type * apply(boost::array<T, N> & value) {
90  return get_pointer(value[0]);
91  }
92  };
93 
94  template<typename T, std::size_t N> struct get_pointer<boost::array<T, N> const > {
95  static typename alps::hdf5::scalar_type<boost::array<T, N> >::type const * apply(boost::array<T, N> const & value) {
97  return get_pointer(value[0]);
98  }
99  };
100  }
101 
102  template<typename T, std::size_t N> void save(
103  archive & ar
104  , std::string const & path
105  , boost::array<T, N> const & value
106  , std::vector<std::size_t> size = std::vector<std::size_t>()
107  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
108  , std::vector<std::size_t> offset = std::vector<std::size_t>()
109  ) {
110  using alps::cast;
111  if (ar.is_group(path))
112  ar.delete_group(path);
113  if (is_continuous<T>::value && value.size() == 0)
114  ar.write(path, static_cast<typename scalar_type<boost::array<T, N> >::type const *>(NULL), std::vector<std::size_t>());
115  else if (is_continuous<T>::value) {
116  std::vector<std::size_t> extent(get_extent(value));
117  std::copy(extent.begin(), extent.end(), std::back_inserter(size));
118  std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
119  std::fill_n(std::back_inserter(offset), extent.size(), 0);
120  ar.write(path, get_pointer(value), size, chunk, offset);
121  } else if (value.size() == 0)
122  ar.write(path, static_cast<int const *>(NULL), std::vector<std::size_t>());
123  else if (is_vectorizable(value)) {
124  size.push_back(value.size());
125  chunk.push_back(1);
126  offset.push_back(0);
127  for(typename boost::array<T, N>::const_iterator it = value.begin(); it != value.end(); ++it) {
128  offset.back() = it - value.begin();
129  save(ar, path, *it, size, chunk, offset);
130  }
131  } else {
132  if (ar.is_data(path))
133  ar.delete_data(path);
134  for(typename boost::array<T, N>::const_iterator it = value.begin(); it != value.end(); ++it)
135  save(ar, ar.complete_path(path) + "/" + cast<std::string>(it - value.begin()), *it);
136  }
137  }
138 
139  template<typename T, std::size_t N> void load(
140  archive & ar
141  , std::string const & path
142  , boost::array<T, N> & value
143  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
144  , std::vector<std::size_t> offset = std::vector<std::size_t>()
145  ) {
146  using alps::cast;
147  if (ar.is_group(path)) {
148  std::vector<std::string> children = ar.list_children(path);
149  if (children.size() != N)
150  throw invalid_path("size does not match: " + path + ALPS_STACKTRACE);
151  for (typename std::vector<std::string>::const_iterator it = children.begin(); it != children.end(); ++it)
152  load(ar, ar.complete_path(path) + "/" + *it, value[cast<std::size_t>(*it)]);
153  } else {
155  throw archive_error("no complex value in archive" + ALPS_STACKTRACE);
156  std::vector<std::size_t> size(ar.extent(path));
157  if (size.size() > 0 && N != *(size.begin() + chunk.size()) && (is_continuous<T>::value || *(size.begin() + chunk.size()) > 0))
158  throw archive_error("dimensions do not match" + ALPS_STACKTRACE);
160  set_extent(value, std::vector<std::size_t>(size.begin() + chunk.size(), size.end()));
161  if (value.size()) {
162  std::copy(size.begin() + chunk.size(), size.end(), std::back_inserter(chunk));
163  std::fill_n(std::back_inserter(offset), size.size() - offset.size(), 0);
164  ar.read(path, get_pointer(value), chunk, offset);
165  }
166  } else {
167  set_extent(value, std::vector<std::size_t>(1, *(size.begin() + chunk.size())));
168  chunk.push_back(1);
169  offset.push_back(0);
170  for(typename boost::array<T, N>::iterator it = value.begin(); it != value.end(); ++it) {
171  offset.back() = it - value.begin();
172  load(ar, path, *it, chunk, offset);
173  }
174  }
175  }
176  }
177  }
178 }
179 
180 #endif
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:309
bool is_vectorizable(T const &value)
Definition: archive.hpp:288
void set_extent(T &value, std::vector< std::size_t > const &size)
Definition: archive.hpp:284
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
bool is_data(std::string path) const
Definition: archive.cpp:170
std::vector< std::size_t > get_extent(T const &value)
Definition: archive.hpp:280
void delete_data(std::string path) const
Definition: archive.cpp:364
void delete_group(std::string path) const
Definition: archive.cpp:376
scalar_type< T >::type * get_pointer(T &value)
Definition: archive.hpp:272
std::vector< std::size_t > extent(std::string path) const
Definition: archive.cpp:291
std::vector< std::string > list_children(std::string path) const
Definition: archive.cpp:259
auto read(std::string path, T *, std::vector< std::size_t >, std::vector< std::size_t >=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:163
auto write(std::string path, T const *value, std::vector< std::size_t > size, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t > offset=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
Definition: archive.hpp:172
U cast(T const &)
Definition: cast.hpp:151
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
traits< Acc >::result_type result(const Acc &acc)
Definition: util.hpp:53
bool is_group(std::string path) const
Definition: archive.cpp:189
std::string complete_path(std::string path) const
Definition: archive.cpp:153
scalar_type< typename boost::array< T, N >::value_type >::type type
Definition: array.hpp:24
bool is_complex(std::string path) const
Definition: archive.cpp:242
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:292