ALPSCore reference
common.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 #pragma once
8 
9 #include <iostream>
10 #include <string>
11 #include <sstream>
12 #include <vector>
13 
14 #include <hdf5.h>
15 
16 #ifdef ALPS_SINGLE_THREAD
17  #define ALPS_HDF5_LOCK_MUTEX
18 #else
19  #define ALPS_HDF5_LOCK_MUTEX boost::lock_guard<boost::recursive_mutex> guard(mutex_);
20 #endif
21 
22 #ifdef H5_HAVE_THREADSAFE
23  #define ALPS_HDF5_FAKE_THREADSAFETY
24 #else
25  #define ALPS_HDF5_FAKE_THREADSAFETY ALPS_HDF5_LOCK_MUTEX
26 #endif
27 
28 #define ALPS_HDF5_NATIVE_INTEGRAL_TYPES \
29  char, signed char, unsigned char, \
30  short, unsigned short, \
31  int, unsigned, long, unsigned long, \
32  long long, unsigned long long, \
33  float, double, long double, \
34  bool
35 
36 #define ALPS_HDF5_FOREACH_NATIVE_TYPE_INTEGRAL(CALLBACK, ARG) \
37  CALLBACK(char, ARG) \
38  CALLBACK(signed char, ARG) \
39  CALLBACK(unsigned char, ARG) \
40  CALLBACK(short, ARG) \
41  CALLBACK(unsigned short, ARG) \
42  CALLBACK(int, ARG) \
43  CALLBACK(unsigned, ARG) \
44  CALLBACK(long, ARG) \
45  CALLBACK(unsigned long, ARG) \
46  CALLBACK(long long, ARG) \
47  CALLBACK(unsigned long long, ARG) \
48  CALLBACK(float, ARG) \
49  CALLBACK(double, ARG) \
50  CALLBACK(long double, ARG) \
51  CALLBACK(bool, ARG)
52 
53 namespace alps {
54  namespace hdf5 {
55  namespace detail {
56 
57  template<typename T> struct native_ptr_converter {
58  native_ptr_converter(std::size_t) {}
59  inline T const * apply(T const * v) {
60  return v;
61  }
62  };
63 
64  template<> struct native_ptr_converter<std::string> {
65  std::vector<char const *> data;
66  native_ptr_converter(std::size_t size): data(size) {}
67  inline char const * const * apply(std::string const * v) {
68  for (std::vector<char const *>::iterator it = data.begin(); it != data.end(); ++it)
69  *it = v[it - data.begin()].c_str();
70  return &data[0];
71  }
72  };
73 
74  inline herr_t noop(hid_t) {
75  return 0;
76  }
77 
78  class error {
79 
80  public:
81 
82  std::string invoke(hid_t id) {
83  std::ostringstream buffer;
84  buffer << "HDF5 error: " << cast<std::string>(id) << std::endl;
85  H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, callback, &buffer);
86  return buffer.str();
87  }
88 
89  private:
90 
91  static herr_t callback(unsigned n, H5E_error2_t const * desc, void * buffer) {
92  *reinterpret_cast<std::ostringstream *>(buffer)
93  << " #"
94  << cast<std::string>(n)
95  << " " << desc->file_name
96  << " line "
97  << cast<std::string>(desc->line)
98  << " in "
99  << desc->func_name
100  << "(): "
101  << desc->desc
102  << std::endl;
103  return 0;
104  }
105 
106  };
107 
108  template<herr_t(*F)(hid_t)> class resource {
109  public:
110  resource(): _id(-1) {}
111  resource(hid_t id): _id(id) {
112  if (_id < 0)
113  throw archive_error(error().invoke(_id) + ALPS_STACKTRACE);
114  }
115 
116  ~resource() {
117  if(_id < 0 || (_id = F(_id)) < 0) {
118  std::cerr << "Error in "
119  << __FILE__
120  << " on "
121  << ALPS_STRINGIFY(__LINE__)
122  << " in "
123  << __FUNCTION__ // TODO: check for gcc and use __PRETTY_FUNCTION__
124  << ":"
125  << std::endl
126  << error().invoke(_id)
127  << std::endl;
128  std::abort();
129  }
130  }
131 
132  operator hid_t() const {
133  return _id;
134  }
135 
136  resource<F> & operator=(hid_t id) {
137  if ((_id = id) < 0)
138  throw archive_error(error().invoke(_id) + ALPS_STACKTRACE);
139  return *this;
140  }
141 
142  private:
143  hid_t _id;
144  };
145 
146  typedef resource<H5Gclose> group_type;
147  typedef resource<H5Dclose> data_type;
148  typedef resource<H5Aclose> attribute_type;
149  typedef resource<H5Sclose> space_type;
150  typedef resource<H5Tclose> type_type;
151  typedef resource<H5Pclose> property_type;
152  typedef resource<noop> error_type;
153 
154  inline hid_t check_group(hid_t id) { group_type unused(id); return unused; }
155  inline hid_t check_data(hid_t id) { data_type unused(id); return unused; }
156  inline hid_t check_attribute(hid_t id) { attribute_type unused(id); return unused; }
157  inline hid_t check_space(hid_t id) { space_type unused(id); return unused; }
158  inline hid_t check_type(hid_t id) { type_type unused(id); return unused; }
159  inline hid_t check_property(hid_t id) { property_type unused(id); return unused; }
160  inline hid_t check_error(hid_t id) { error_type unused(id); return unused; }
161 
162  inline hid_t get_native_type(char) { return H5Tcopy(H5T_NATIVE_CHAR); }
163  inline hid_t get_native_type(signed char) { return H5Tcopy(H5T_NATIVE_SCHAR); }
164  inline hid_t get_native_type(unsigned char) { return H5Tcopy(H5T_NATIVE_UCHAR); }
165  inline hid_t get_native_type(short) { return H5Tcopy(H5T_NATIVE_SHORT); }
166  inline hid_t get_native_type(unsigned short) { return H5Tcopy(H5T_NATIVE_USHORT); }
167  inline hid_t get_native_type(int) { return H5Tcopy(H5T_NATIVE_INT); }
168  inline hid_t get_native_type(unsigned) { return H5Tcopy(H5T_NATIVE_UINT); }
169  inline hid_t get_native_type(long) { return H5Tcopy(H5T_NATIVE_LONG); }
170  inline hid_t get_native_type(unsigned long) { return H5Tcopy(H5T_NATIVE_ULONG); }
171  inline hid_t get_native_type(long long) { return H5Tcopy(H5T_NATIVE_LLONG); }
172  inline hid_t get_native_type(unsigned long long) { return H5Tcopy(H5T_NATIVE_ULLONG); }
173  inline hid_t get_native_type(float) { return H5Tcopy(H5T_NATIVE_FLOAT); }
174  inline hid_t get_native_type(double) { return H5Tcopy(H5T_NATIVE_DOUBLE); }
175  inline hid_t get_native_type(long double) { return H5Tcopy(H5T_NATIVE_LDOUBLE); }
176  inline hid_t get_native_type(bool) { return H5Tcopy(H5T_NATIVE_SCHAR); }
177  inline hid_t get_native_type(std::string) {
178  hid_t type_id = H5Tcopy(H5T_C_S1);
179  detail::check_error(H5Tset_size(type_id, H5T_VARIABLE));
180  return type_id;
181  }
182  }
183  }
184 }
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
error_type< T >::type error(T const &arg)
Definition: error.hpp:47
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
#define ALPS_STRINGIFY(arg)
Definition: stringify.hpp:10