7 #ifndef ALPS_HDF5_ARCHIVE_HPP 8 #define ALPS_HDF5_ARCHIVE_HPP 16 #ifndef ALPS_SINGLE_THREAD 18 #include <boost/thread.hpp> 25 #include <type_traits> 28 #define ALPS_FOREACH_NATIVE_HDF5_TYPE(CALLBACK) \ 30 CALLBACK(signed char) \ 31 CALLBACK(unsigned char) \ 33 CALLBACK(unsigned short) \ 37 CALLBACK(unsigned long) \ 39 CALLBACK(unsigned long long) \ 42 CALLBACK(long double) \ 52 #define ALPS_HDF5_IS_NATIVE_TYPE_CALLER(__type__) \ 53 template <> struct is_native_type<__type__> : public std::true_type {}; 55 #undef ALPS_HDF5_IS_NATIVE_TYPE_CALLER 57 #define ONLY_NATIVE(T,R) typename std::enable_if<is_native_type<T>::value, R>::type 58 #define ONLY_NOT_NATIVE(T,R) typename std::enable_if<!is_native_type<T>::value, R>::type 61 struct archivecontext;
63 template<
typename A,
typename T>
struct is_datatype_caller {
64 static bool apply(A
const & ar, std::string path) {
65 throw std::logic_error(
"only native datatypes can be probed: " + path +
ALPS_STACKTRACE);
70 #define ALPS_HDF5_IS_DATATYPE_CALLER(T) \ 71 template<typename A> struct is_datatype_caller<A, T > { \ 72 static bool apply(A const & ar, std::string path, T unused = alps::detail::type_wrapper<T>::type()) { \ 73 return ar.is_datatype_impl(path, unused); \ 77 #undef ALPS_HDF5_IS_DATATYPE_CALLER 79 template<
typename A>
struct archive_proxy {
81 explicit archive_proxy(std::string
const & path, A & ar)
82 : path_(path), ar_(ar)
85 template<
typename T> archive_proxy & operator=(T
const & value);
86 template<
typename T> archive_proxy &
operator<<(T
const & value);
87 template<
typename T> archive_proxy &
operator>>(T & value);
111 archive(std::string
const & filename, std::string mode =
"r");
112 archive(std::string
const & filename,
int prop);
118 std::string
const & get_filename()
const;
120 std::string encode_segment(std::string segment)
const;
121 std::string decode_segment(std::string segment)
const;
123 std::string get_context()
const;
124 void set_context(std::string
const & context);
125 std::string complete_path(std::string path)
const;
128 void open(
const std::string & filename,
const std::string &mode =
"r");
132 bool is_data(std::string path)
const;
133 bool is_attribute(std::string path)
const;
134 bool is_group(std::string path)
const;
137 bool is_null(std::string path)
const;
140 template<
typename T>
bool is_datatype(std::string path)
const {
141 return detail::is_datatype_caller<archive, T>::apply(*
this, path);
144 std::vector<std::string> list_children(std::string path)
const;
145 std::vector<std::string> list_attributes(std::string path)
const;
147 std::vector<std::size_t> extent(std::string path)
const;
148 std::size_t dimensions(std::string path)
const;
150 void create_group(std::string path)
const;
152 void delete_data(std::string path)
const;
153 void delete_group(std::string path)
const;
154 void delete_attribute(std::string path)
const;
156 void set_complex(std::string path);
163 detail::archive_proxy<archive> operator[](std::string
const & path);
165 template<
typename T>
auto read(
168 , std::vector<std::size_t>
169 , std::vector<std::size_t> = std::vector<std::size_t>()
171 throw std::logic_error(
"Invalid type on path: " + path +
ALPS_STACKTRACE);
174 template<
typename T>
auto write(
177 , std::vector<std::size_t>
size 178 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
179 , std::vector<std::size_t> offset = std::vector<std::size_t>()
181 throw std::logic_error(
"Invalid type on path: " + path +
ALPS_STACKTRACE);
184 template<
typename T>
auto read(std::string path, T & value)
const ->
ONLY_NATIVE(T,
void);
186 template<
typename T>
auto read(std::string path
188 , std::vector<std::size_t> chunk
189 , std::vector<std::size_t> offset = std::vector<std::size_t>()
192 template<
typename T>
auto write(std::string path, T value)
const ->
ONLY_NATIVE(T,
void);
194 template<
typename T>
auto write(std::string path
195 , T
const * value, std::vector<std::size_t> size
196 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
197 , std::vector<std::size_t> offset = std::vector<std::size_t>()
200 template<
typename T>
auto is_datatype_impl(std::string path, T)
const ->
ONLY_NATIVE(T,
bool);
204 void construct(std::string
const & filename, std::size_t props = READ);
205 std::string file_key(std::string filename,
bool memory)
const;
207 std::string current_;
208 detail::archivecontext * context_;
210 #ifndef ALPS_SINGLE_THREAD 211 static boost::recursive_mutex mutex_;
213 static std::map<std::string, std::pair<detail::archivecontext *, std::size_t> > ref_cnt_;
218 :
public std::false_type
226 :
public std::false_type
236 static std::vector<std::size_t> apply(T
const & ) {
237 return std::vector<std::size_t>();
242 static void apply(T &, std::vector<std::size_t>
const &) {}
245 #define ALPS_HDF5_DEFINE_SET_EXTENT(T) \ 246 template<> struct set_extent<T> { \ 247 static void apply(T &, std::vector<std::size_t> const & extent) { \ 248 if (extent.size() > 0) \ 249 throw wrong_type("The extents do not match" + ALPS_STACKTRACE); \ 253 #undef ALPS_HDF5_DEFINE_SET_EXTENT 256 static bool apply(T
const & value){
276 return detail::get_pointer<T>::apply(value);
280 return detail::get_pointer<T const>::apply(value);
283 template<
typename T> std::vector<std::size_t>
get_extent(T
const & value) {
284 return detail::get_extent<T>::apply(value);
287 template<
typename T>
void set_extent(T & value, std::vector<std::size_t>
const & size) {
288 detail::set_extent<T>::apply(value, size);
292 return detail::is_vectorizable<T>::apply(value);
295 template<
typename T>
void save(
297 , std::string
const & path
299 , std::vector<std::size_t> = std::vector<std::size_t>()
300 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
301 , std::vector<std::size_t> = std::vector<std::size_t>()
305 throw std::logic_error(
"user defined objects needs to be written continously" +
ALPS_STACKTRACE);
312 template<
typename T>
void load(
314 , std::string
const & path
316 , std::vector<std::size_t> chunk = std::vector<std::size_t>()
317 , std::vector<std::size_t> = std::vector<std::size_t>()
320 throw std::logic_error(
"user defined objects needs to be written continously" +
ALPS_STACKTRACE);
327 #define ALPS_HDF5_DEFINE_FREE_FUNCTIONS(T) \ 328 template<> struct is_continuous< T > \ 329 : public std::true_type \ 331 template<> struct is_continuous< T const > \ 332 : public std::true_type \ 336 template<> struct is_vectorizable< T > { \ 337 static bool apply(T const & value); \ 339 template<> struct is_vectorizable< T const > { \ 340 static bool apply(T & value); \ 343 template<> struct get_pointer< T > { \ 344 static alps::hdf5::scalar_type< T >::type * apply( T & value); \ 347 template<> struct get_pointer< T const > { \ 348 static alps::hdf5::scalar_type< T >::type const * apply( T const & value); \ 354 , std::string const & path \ 356 , std::vector<std::size_t> size = std::vector<std::size_t>() \ 357 , std::vector<std::size_t> chunk = std::vector<std::size_t>() \ 358 , std::vector<std::size_t> offset = std::vector<std::size_t>() \ 363 , std::string const & path \ 365 , std::vector<std::size_t> chunk = std::vector<std::size_t>() \ 366 , std::vector<std::size_t> offset = std::vector<std::size_t>() \ 369 #undef ALPS_HDF5_DEFINE_FREE_FUNCTIONS 373 template<
typename T>
struct make_pvp_proxy {
375 explicit make_pvp_proxy(std::string
const & path, T value)
376 : path_(path), value_(value)
379 make_pvp_proxy(make_pvp_proxy<T>
const & arg)
380 : path_(arg.path_), value_(arg.value_)
389 template <
typename T>
typename std::enable_if<
392 >::type operator<< (archive & ar, detail::make_pvp_proxy<T>
const & proxy) {
393 save(ar, proxy.path_, proxy.value_);
398 template <
typename T>
typename std::enable_if<
401 >::type operator<< (archive & ar, detail::make_pvp_proxy<T>
const & proxy) {
402 save(ar, proxy.path_, proxy.value_);
407 load(ar, proxy.path_, proxy.value_);
412 template <
typename T>
typename std::enable_if<!(
413 std::is_same<typename alps::detail::remove_cvr<typename std::remove_all_extents<T>::type>::type,
char>::value
414 && std::is_array<T>::value)
415 , hdf5::detail::make_pvp_proxy<T &> >::type
make_pvp(std::string
const & path, T & value) {
416 return hdf5::detail::make_pvp_proxy<T &>(path, value);
418 template <
typename T>
typename std::enable_if<!(
419 std::is_same<typename alps::detail::remove_cvr<typename std::remove_all_extents<T>::type>::type,
char>::value
420 && std::is_array<T>::value)
421 , hdf5::detail::make_pvp_proxy<T const &> >::type
make_pvp(std::string
const & path, T
const & value) {
422 return hdf5::detail::make_pvp_proxy<T const &>(path, value);
424 template <
typename T>
typename std::enable_if<
425 std::is_same<typename alps::detail::remove_cvr<typename std::remove_all_extents<T>::type>::type,
char>::value
426 && std::is_array<T>::value
427 , hdf5::detail::make_pvp_proxy<std::string const> >::type
make_pvp(std::string
const & path, T
const & value) {
428 return hdf5::detail::make_pvp_proxy<std::string const>(path, value);
434 template<
typename A>
template<
typename T> archive_proxy<A> & archive_proxy<A>::operator=(T
const & value) {
440 return *
this = value;
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 >())
bool is_vectorizable(T const &value)
void set_extent(T &value, std::vector< std::size_t > const &size)
#define ALPS_HDF5_DEFINE_FREE_FUNCTIONS(T)
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
std::vector< std::size_t > get_extent(T const &value)
scalar_type< T >::type * get_pointer(T &value)
std::enable_if< has_complex_elements< typename alps::detail::remove_cvr< T >::type >::value, archive & >::type operator<<(archive &ar, detail::make_pvp_proxy< T > const &proxy)
ALPS_FOREACH_NATIVE_HDF5_TYPE(ALPS_HDF5_READ_SCALAR)
void set_context(std::string const &context)
#define ONLY_NATIVE(T, R)
std::string get_context() const
#define ONLY_NOT_NATIVE(T, R)
#define ALPS_HDF5_DEFINE_SET_EXTENT(T)
#define ALPS_HDF5_IS_NATIVE_TYPE_CALLER(__type__)
void set_complex(std::string path)
std::enable_if<!(std::is_same< typename alps::detail::remove_cvr< typename std::remove_all_extents< T >::type >::type, char >::value &&std::is_array< T >::value), hdf5::detail::make_pvp_proxy< T & > >::type make_pvp(std::string const &path, T &value)
Metafunction-predicate: returns true_type if type T is scalar.
std::string complete_path(std::string path) const
std::enable_if< !has_complex_elements< typename alps::detail::remove_cvr< T >::type >::value, archive & >::type operator<<(archive &ar, detail::make_pvp_proxy< T > const &proxy)
Inherits from true_type if T is a native type, from false_type otherwise.
archive & operator>>(archive &ar, detail::make_pvp_proxy< T > proxy)
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 >())
#define ALPS_HDF5_IS_DATATYPE_CALLER(T)