ALPSCore reference
vector.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_STD_VECTOR_HPP
8 #define ALPS_HDF5_STD_VECTOR_HPP
9 
10 #include <alps/hdf5/archive.hpp>
11 #include <alps/utilities/cast.hpp>
12 
13 #include <type_traits>
14 #include <vector>
15 #include <iterator>
16 #include <algorithm>
17 
18 namespace alps {
19  namespace hdf5 {
20 
21  template<typename T, typename A> struct scalar_type<std::vector<T, A> > {
23  };
24 
25  template<typename T, typename A> struct is_content_continuous<std::vector<T, A> >
26  : public is_continuous<T>
27  {};
28  template<typename A> struct is_content_continuous<std::vector<bool, A> >
29  : public std::false_type
30  {};
31 
32  template<typename T, typename A> struct has_complex_elements<std::vector<T, A> >
33  : public has_complex_elements<typename alps::detail::remove_cvr<typename std::vector<T, A>::value_type>::type>
34  {};
35 
36  namespace detail {
37 
38  template<typename T, typename A> struct get_extent<std::vector<T, A> > {
39  static std::vector<std::size_t> apply(std::vector<T, A> const & value) {
41  std::vector<std::size_t> result(1, value.size());
42  if (value.size()) {
43  std::vector<std::size_t> first(get_extent(value[0]));
44  if (!std::is_scalar<typename std::vector<T, A>::value_type>::value)
45  for(typename std::vector<T, A>::const_iterator it = value.begin() + 1; it != value.end(); ++it) {
46  std::vector<std::size_t> size(get_extent(*it));
47  if (
48  first.size() != size.size()
49  || !std::equal(first.begin(), first.end(), size.begin())
50  )
51  throw archive_error("no rectangular matrix" + ALPS_STACKTRACE);
52  }
53  std::copy(first.begin(), first.end(), std::back_inserter(result));
54  }
55  return result;
56  }
57  };
58 
59  template<typename T, typename A> struct set_extent<std::vector<T, A> > {
60  static void apply(std::vector<T, A> & value, std::vector<std::size_t> const & extent) {
62  value.resize(extent[0]);
63  if (extent.size() > 1)
64  for(typename std::vector<T, A>::iterator it = value.begin(); it != value.end(); ++it)
65  set_extent(*it, std::vector<std::size_t>(extent.begin() + 1, extent.end()));
66  else if (extent.size() == 1 && (
67  (!std::is_enum<T>::value && !std::is_same<typename scalar_type<T>::type, T>::value)
68  || (std::is_enum<T>::value && is_continuous<T>::value && sizeof(T) != sizeof(typename scalar_type<T>::type))
69  ))
70  throw archive_error("dimensions do not match" + ALPS_STACKTRACE);
71  }
72  };
73 
74  template<typename A> struct set_extent<std::vector<bool, A> > {
75  static void apply(std::vector<bool, A> & value, std::vector<std::size_t> const & extent) {
76  if (extent.size() != 1)
77  throw archive_error("dimensions do not match" + ALPS_STACKTRACE);
78  value.resize(extent[0]);
79  }
80  };
81 
82  template<typename T, typename A> struct is_vectorizable<std::vector<T, A> > {
83  static bool apply(std::vector<T, A> const & value) {
86  if (value.size()) {
87  if (!is_vectorizable(value[0]))
88  return false;
89  std::vector<std::size_t> first(get_extent(value[0]));
90  if (!std::is_scalar<typename std::vector<T, A>::value_type>::value) {
91  for(typename std::vector<T, A>::const_iterator it = value.begin(); it != value.end(); ++it)
92  if (!is_vectorizable(*it))
93  return false;
94  else {
95  std::vector<std::size_t> size(get_extent(*it));
96  if (
97  first.size() != size.size()
98  || !std::equal(first.begin(), first.end(), size.begin())
99  )
100  return false;
101  }
102  }
103  }
104  return true;
105  }
106  };
107 
108  template<typename A> struct is_vectorizable<std::vector<bool, A> > {
109  static bool apply(std::vector<bool, A> const & value) {
110  return true;
111  }
112  };
113 
114  template<typename T, typename A> struct get_pointer<std::vector<T, A> > {
115  static typename alps::hdf5::scalar_type<std::vector<T, A> >::type * apply(std::vector<T, A> & value) {
117  return get_pointer(value[0]);
118  }
119  };
120 
121  template<typename T, typename A> struct get_pointer<std::vector<T, A> const> {
122  static typename alps::hdf5::scalar_type<std::vector<T, A> >::type const * apply(std::vector<T, A> const & value) {
124  return get_pointer(value[0]);
125  }
126  };
127 
128  template<typename A> struct get_pointer<std::vector<bool, A> > {
129  static typename alps::hdf5::scalar_type<std::vector<bool, A> >::type * apply(std::vector<bool, A> & value) {
130  throw archive_error("std::vector<bool, A>[0] cannot be dereferenced" + ALPS_STACKTRACE);
131  return NULL;
132  }
133  };
134 
135  template<typename A> struct get_pointer<std::vector<bool, A> const> {
136  static typename alps::hdf5::scalar_type<std::vector<bool, A> >::type const * apply(std::vector<bool, A> const & value) {
137  throw archive_error("std::vector<bool>[0] cannot be dereferenced" + ALPS_STACKTRACE);
138  return NULL;
139  }
140  };
141 
142  }
143 
144 
145  template<typename T, typename A> void save(
146  archive & ar
147  , std::string const & path
148  , std::vector<T, A> const & value
149  , std::vector<std::size_t> size = std::vector<std::size_t>()
150  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
151  , std::vector<std::size_t> offset = std::vector<std::size_t>()
152  ) {
153  using alps::cast;
154  if (ar.is_group(path))
155  ar.delete_group(path);
156  if (is_continuous<T>::value && value.size() == 0)
157  ar.write(path, static_cast<typename scalar_type<std::vector<T, A> >::type const *>(NULL), std::vector<std::size_t>());
158  else if (is_continuous<T>::value) {
159  std::vector<std::size_t> extent(get_extent(value));
160  std::copy(extent.begin(), extent.end(), std::back_inserter(size));
161  std::copy(extent.begin(), extent.end(), std::back_inserter(chunk));
162  std::fill_n(std::back_inserter(offset), extent.size(), 0);
163  ar.write(path, get_pointer(value), size, chunk, offset);
164  } else if (value.size() == 0)
165  ar.write(path, static_cast<int const *>(NULL), std::vector<std::size_t>());
166  else if (is_vectorizable(value)) {
167  size.push_back(value.size());
168  chunk.push_back(1);
169  offset.push_back(0);
170  for(typename std::vector<T, A>::const_iterator it = value.begin(); it != value.end(); ++it) {
171  offset.back() = it - value.begin();
172  save(ar, path, *it, size, chunk, offset);
173  }
174  } else {
175  if (path.find_last_of('@') == std::string::npos && ar.is_data(path))
176  ar.delete_data(path);
177  else if (path.find_last_of('@') != std::string::npos && ar.is_attribute(path))
178  ar.delete_attribute(path);
179  for(typename std::vector<T, A>::const_iterator it = value.begin(); it != value.end(); ++it)
180  save(ar, ar.complete_path(path) + "/" + cast<std::string>(it - value.begin()), *it);
181  }
182  }
183 
184  template<typename A> void save(
185  archive & ar
186  , std::string const & path
187  , std::vector<bool, A> const & value
188  , std::vector<std::size_t> size = std::vector<std::size_t>()
189  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
190  , std::vector<std::size_t> offset = std::vector<std::size_t>()
191  ) {
192  if (ar.is_group(path))
193  ar.delete_group(path);
194  if (value.size() == 0)
195  ar.write(path, static_cast<bool const *>(NULL), std::vector<std::size_t>());
196  else {
197  size.push_back(value.size());
198  chunk.push_back(1);
199  offset.push_back(0);
200  for(typename std::vector<bool, A>::const_iterator it = value.begin(); it != value.end(); ++it) {
201  offset.back() = it - value.begin();
202  bool const elem = *it;
203  ar.write(path, &elem, size, chunk, offset);
204  }
205  }
206  }
207 
208  template<typename T, typename A> void load(
209  archive & ar
210  , std::string const & path
211  , std::vector<T, A> & value
212  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
213  , std::vector<std::size_t> offset = std::vector<std::size_t>()
214  ) {
215  using alps::cast;
216  if (ar.is_group(path)) {
217  std::vector<std::string> children = ar.list_children(path);
218  value.resize(children.size());
219  for (typename std::vector<std::string>::const_iterator it = children.begin(); it != children.end(); ++it)
220  load(ar, ar.complete_path(path) + "/" + *it, value[cast<std::size_t>(*it)]);
221  } else {
223  throw archive_error("no complex value in archive" + ALPS_STACKTRACE);
224  std::vector<std::size_t> size(ar.extent(path));
225  if (size.size() == 0)
226  throw archive_error("invalid dimensions" + ALPS_STACKTRACE);
227  else if (size[0] == 0)
228  value.resize(0);
229  else if (is_continuous<T>::value) {
230  set_extent(value, std::vector<std::size_t>(size.begin() + chunk.size(), size.end()));
231  if (value.size()) {
232  std::copy(size.begin() + chunk.size(), size.end(), std::back_inserter(chunk));
233  std::fill_n(std::back_inserter(offset), size.size() - offset.size(), 0);
234  ar.read(path, get_pointer(value), chunk, offset);
235  }
236  } else {
237  value.resize(*(size.begin() + chunk.size()));
238  chunk.push_back(1);
239  offset.push_back(0);
240  for(typename std::vector<T, A>::iterator it = value.begin(); it != value.end(); ++it) {
241  offset.back() = it - value.begin();
242  load(ar, path, *it, chunk, offset);
243  }
244  }
245  }
246  }
247 
248  template<typename A> void load(
249  archive & ar
250  , std::string const & path
251  , std::vector<bool, A> & value
252  , std::vector<std::size_t> chunk = std::vector<std::size_t>()
253  , std::vector<std::size_t> offset = std::vector<std::size_t>()
254  ) {
255  if (ar.is_group(path))
256  throw archive_error("invalid dimensions" + ALPS_STACKTRACE);
257  else {
258  if (ar.is_complex(path))
259  throw archive_error("no complex value in archive" + ALPS_STACKTRACE);
260  std::vector<std::size_t> size(ar.extent(path));
261  if (size.size() == 0)
262  throw archive_error("invalid dimensions" + ALPS_STACKTRACE);
263  else if (size[0] == 0)
264  value.resize(0);
265  else {
266  value.resize(*(size.begin() + chunk.size()));
267  chunk.push_back(1);
268  offset.push_back(0);
269  for(typename std::vector<bool, A>::iterator it = value.begin(); it != value.end(); ++it) {
270  offset.back() = it - value.begin();
271  bool elem;
272  ar.read(path, &elem, chunk, offset);
273  *it = elem;
274  }
275  }
276  }
277  }
278 
279  }
280 }
281 
282 #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
bool is_attribute(std::string path) const
Definition: archive.cpp:180
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
STL namespace.
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
void delete_attribute(std::string path) const
Definition: archive.cpp:388
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
scalar_type< typename std::vector< T, A >::value_type >::type type
Definition: vector.hpp:22
#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
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