Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
Utopia::DataIO::HDFAttribute Class Referencefinal

Class for hdf5 attribute, which can be attached to groups and datasets. More...

#include <hdfattribute.hh>

Inheritance diagram for Utopia::DataIO::HDFAttribute:
Inheritance graph
[legend]
Collaboration diagram for Utopia::DataIO::HDFAttribute:
Collaboration graph
[legend]

Public Types

using Base = HDFObject< HDFCategory::attribute >
 alias base class
 

Public Member Functions

void swap (HDFAttribute &other)
 Exchange states between caller and argument.
 
HDFDataspace get_filespace ()
 Get the file-dataspace object.
 
auto get_type ()
 Get the type object.
 
HDFIdentifier get_parent_id ()
 Get the hdf5 identifier to which the attribute belongs.
 
void close ()
 closes the attribute
 
auto get_shape ()
 Get the shape object.
 
template<HDFCategory cat>
void open (const HDFObject< cat > &parent, std::string name)
 Open a new attribute on HDFObject 'parent' with name 'name'.
 
void open (const HDFIdentifier &parent, std::string name)
 Open a new attribute on HDFObject 'parent' with name 'name'.
 
template<typename Type >
auto read ()
 Reads data from attribute, and returns the data and its shape in the form of a hsize_t vector.
 
template<typename Type >
void read (Type &buffer)
 Reads data from attribute into a predefined buffer, and returns the data and its shape in the form of a hsize_t vector. User is responsible for providing a buffer which can hold the data and has the correct shape!
 
template<typename Type >
void write (Type attribute_data, std::vector< hsize_t > shape={})
 Function for writing data to the attribute.
 
template<typename Iter , typename Adaptor >
void write (Iter begin, Iter end, Adaptor adaptor=[](auto &value) { return value;}, std::vector< hsize_t > shape={})
 Function for writing data to the attribute.
 
 HDFAttribute ()=default
 Default constructor, deleted because of reference member.
 
 HDFAttribute (const HDFAttribute &other)=default
 Copy constructor.
 
 HDFAttribute (HDFAttribute &&other)=default
 Move constructor.
 
HDFAttributeoperator= (const HDFAttribute &other)=default
 Copy assignment operator.
 
HDFAttributeoperator= (HDFAttribute &&other)=default
 Attribute move assignment operator.
 
virtual ~HDFAttribute ()
 Destructor.
 
template<HDFCategory cat>
 HDFAttribute (const HDFObject< cat > &object, std::string name)
 Constructor for attribute.
 
- Public Member Functions inherited from Utopia::DataIO::HDFObject< HDFCategory::attribute >
void swap (HDFObject &other)
 swap the state of the caller with the state of the argument
 
std::string get_path () const
 Get the name or path object.
 
auto get_id_object () const
 Get the id object.
 
auto get_logger () const
 Get the logger object.
 
hid_t get_C_id () const
 Get the C id object.
 
auto get_refcount ()
 Get the reference count of object.
 
virtual bool is_valid () const
 Check if the object is still valid.
 
void close ()
 Close function which takes care of correctly closing the object and managing the reference counter.
 
void bind_to (hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
 Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be created beforehand.
 
 HDFObject ()
 Construct HDFObject from the given arguments.
 
 HDFObject (HDFObject &&other)
 Construct HDFObject by moving.
 
 HDFObject (const HDFObject &other)=default
 Construct HDFObject by copying another object.
 
 HDFObject (hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
 Construct HDFObject from the given argument.
 
HDFObjectoperator= (const HDFObject &other)
 Copy assignment operator.
 
HDFObjectoperator= (HDFObject &&other)
 move assignment operator
 
virtual ~HDFObject ()
 Destroy the HDFObject object. Has to be implemented in subclass!
 

Private Member Functions

template<typename result_type >
void __create_attribute__ (hsize_t typesize=0)
 private helper function for creation of attribute
 
template<typename Type >
herr_t __write_container__ (Type attribute_data)
 Function for writing containers as attribute.
 
template<typename Type >
herr_t __write_stringtype__ (Type attribute_data)
 
template<typename Type >
herr_t __write_pointertype__ (Type attribute_data)
 
template<typename Type >
herr_t __write_scalartype__ (Type attribute_data)
 
template<typename Type >
herr_t __read_container__ (Type &buffer)
 
template<typename Type >
auto __read_stringtype__ (Type &buffer)
 
template<typename Type >
auto __read_pointertype__ (Type buffer)
 
template<typename Type >
auto __read_scalartype__ (Type &buffer)
 

Private Attributes

std::vector< hsize_t_shape
 size of the attributes dataspace
 
HDFIdentifier _parent_identifier
 Identifier of the parent object.
 
HDFDataspace _dataspace
 Dataspace object that manages topology of data written and read.
 
HDFType _type
 type done in the HDFAttribute
 

Additional Inherited Members

- Static Public Attributes inherited from Utopia::DataIO::HDFObject< HDFCategory::attribute >
static constexpr HDFCategory category
 Named variable for template arg.
 
- Protected Attributes inherited from Utopia::DataIO::HDFObject< HDFCategory::attribute >
HDFIdentifier _id
 Identifier object that binds an instance of this class to an HDF5 object.
 
std::string _path
 Name of the object.
 
std::shared_ptr< spdlog::logger > _log
 pointer to the logger for dataio
 

Detailed Description

Class for hdf5 attribute, which can be attached to groups and datasets.

Template Parameters
HDFObjectthe object class

Member Typedef Documentation

◆ Base

alias base class

Constructor & Destructor Documentation

◆ HDFAttribute() [1/4]

Utopia::DataIO::HDFAttribute::HDFAttribute ( )
default

Default constructor, deleted because of reference member.

◆ HDFAttribute() [2/4]

Utopia::DataIO::HDFAttribute::HDFAttribute ( const HDFAttribute other)
default

Copy constructor.

Parameters
otherThe other

◆ HDFAttribute() [3/4]

Utopia::DataIO::HDFAttribute::HDFAttribute ( HDFAttribute &&  other)
default

Move constructor.

Parameters
otherThe other

◆ ~HDFAttribute()

virtual Utopia::DataIO::HDFAttribute::~HDFAttribute ( )
inlinevirtual

Destructor.

960 {
961 close();
962 }
void close()
closes the attribute
Definition hdfattribute.hh:483

◆ HDFAttribute() [4/4]

template<HDFCategory cat>
Utopia::DataIO::HDFAttribute::HDFAttribute ( const HDFObject< cat > &  object,
std::string  name 
)
inline

Constructor for attribute.

Parameters
objectthe object to create the attribute at
namethe name of the attribute
sizethe size of the attribute if known, else 1
972 :
973 _shape(std::vector< hsize_t >())
974 {
975 open(object, name);
976 }
void open(const HDFObject< cat > &parent, std::string name)
Open a new attribute on HDFObject 'parent' with name 'name'.
Definition hdfattribute.hh:522
std::vector< hsize_t > _shape
size of the attributes dataspace
Definition hdfattribute.hh:51

Member Function Documentation

◆ __create_attribute__()

template<typename result_type >
void Utopia::DataIO::HDFAttribute::__create_attribute__ ( hsize_t  typesize = 0)
inlineprivate

private helper function for creation of attribute

Parameters
[in]typesizeThe typesize
Template Parameters
result_typeType of the resulting attribute
Returns
hid_t
82 {
83 this->_log->debug("Creating attribute {}", _path);
84
85 _dataspace.open(this->_path + " dataspace", _shape.size(), _shape, {});
86
87 _type.open< result_type >("datatype of " + _path, typesize);
88
90 _path.c_str(),
92 _dataspace.get_C_id(), // dspace
95 &H5Aclose,
96 _path);
97 }
HDFType _type
type done in the HDFAttribute
Definition hdfattribute.hh:68
HDFIdentifier _parent_identifier
Identifier of the parent object.
Definition hdfattribute.hh:56
HDFDataspace _dataspace
Dataspace object that manages topology of data written and read.
Definition hdfattribute.hh:62
hid_t get_id() const
Get the HDF5 id held by this object.
Definition hdfidentifier.hh:53
std::string _path
Name of the object.
Definition hdfobject.hh:50
std::shared_ptr< spdlog::logger > _log
pointer to the logger for dataio
Definition hdfobject.hh:56
hid_t get_C_id() const
Get the C id object.
Definition hdfobject.hh:120
void bind_to(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be cr...
Definition hdfobject.hh:186
void open(T &&object)
Open the HDF5 type associated with an HDFObject, i.e., a dataset or an attribute.
Definition hdftype.hh:224
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
void open()
Open the dataspace - set it to be equivalent to any data that later will be used to write or read.
Definition hdfdataspace.hh:117

◆ __read_container__()

template<typename Type >
herr_t Utopia::DataIO::HDFAttribute::__read_container__ ( Type buffer)
inlineprivate
253 {
254
255 this->_log->debug("Reading container data from attribute {} ...",
256 _path);
257
258 using value_type_1 =
259 Utils::remove_qualifier_t< typename Type::value_type >;
260
261 // when the value_type of Type is a container again, we want nested
262 // arrays basically. Therefore we have to check if the desired type
263 // Type is suitable to hold them, read the nested data into a hvl_t
264 // container, assuming that they are varlen because this is the more
265 // general case, and then turn them into the desired type again...
266 if constexpr (Utils::is_container_v< value_type_1 >)
267 {
268 using value_type_2 =
269 Utils::remove_qualifier_t< typename value_type_1::value_type >;
270
271 // if we have nested containers of depth larger than 2, throw a
272 // runtime error because we cannot handle this
273 // TODO extend this to work more generally
274 if constexpr (Utils::is_container_v< value_type_2 >)
275 {
276 throw std::runtime_error(
277 "Cannot read data into nested containers with depth > 3 "
278 "in attribute " +
279 _path + " into vector containers!");
280 }
281
282 // everything is fine.
283
284 // check if type given in the buffer is std::array.
285 // If it is, the user knew that the data stored there
286 // has always the same length, otherwise she does not
287 // know and thus it is assumed that the data is variable
288 // length.
289 if constexpr (Utils::is_array_like_v< value_type_1 >)
290 {
291 this->_log->debug("... of fixed size array type");
292 return H5Aread(get_C_id(), _type.get_C_id(), buffer.data());
293 }
294 else
295 {
296 this->_log->debug("... of variable size type");
297
298 std::vector< hvl_t > temp_buffer(buffer.size());
299
300 herr_t err =
302
303 // turn the varlen buffer into the desired type
304 // Cumbersome, but necessary...
305
306 this->_log->debug("... turning read data into desired type");
307
308 for (std::size_t i = 0; i < buffer.size(); ++i)
309 {
310 buffer[i].resize(temp_buffer[i].len);
311 for (std::size_t j = 0; j < temp_buffer[i].len; ++j)
312 {
313 buffer[i][j] =
314 static_cast< value_type_2* >(temp_buffer[i].p)[j];
315 }
316 }
317
318 #if H5_VERSION_GE(1, 12 , 0)
322 temp_buffer.data());
323 #else
327 temp_buffer.data());
328 #endif
329
330 if (status < 0)
331 {
332 throw std::runtime_error("Error, something went wrong while reading in " + _path + " while reclaiming vlen memory");
333 }
334 // return shape and buffer. Expect to use structured bindings
335 // to extract that later
336 return err;
337 }
338 }
339 else // no nested container, but one containing simple types
340 {
341 if constexpr (!std::is_same_v< std::vector< value_type_1 >, Type >)
342 {
343 throw std::runtime_error("Can only read data from " + _path +
344 " into vector containers!");
345 }
346 else
347 {
348 // when strings are desired to be stored as value_types of the
349 // container, we need to treat them a bit differently,
350 // because hdf5 cannot read directly to them.
351 if constexpr (Utils::is_string_v< value_type_1 >)
352 {
353 this->_log->debug("... of string type");
354
355 std::vector< char* > temp_buffer(buffer.size());
356
358 get_C_id(), _type.get_C_id(), temp_buffer.data());
359
360 // turn temp_buffer into the desired datatype and return
361 for (std::size_t i = 0; i < buffer.size(); ++i)
362 {
363 buffer[i] = temp_buffer[i];
364 }
365
366 // reclaim memory from the temp_buffer, because
367 // the char* therein are allocated by hdf5, but not freed
368 for (auto&& c: temp_buffer)
369 {
370 free(c);
371 }
372
373 return err;
374 }
375 else // others are straight forward
376 {
377 this->_log->debug("... of scalar type");
378
379 return H5Aread(get_C_id(), _type.get_C_id(), buffer.data());
380 }
381 }
382 }
383 }

◆ __read_pointertype__()

template<typename Type >
auto Utopia::DataIO::HDFAttribute::__read_pointertype__ ( Type  buffer)
inlineprivate
407 {
408 this->_log->debug("Reading pointer type from attribute {}", _path);
409
410 return H5Aread(get_C_id(), _type.get_C_id(), buffer);
411 }

◆ __read_scalartype__()

template<typename Type >
auto Utopia::DataIO::HDFAttribute::__read_scalartype__ ( Type buffer)
inlineprivate
417 {
418 this->_log->debug("Reading scalar type from attribute {}", _path);
419
420 return H5Aread(get_C_id(), _type.get_C_id(), &buffer);
421 }

◆ __read_stringtype__()

template<typename Type >
auto Utopia::DataIO::HDFAttribute::__read_stringtype__ ( Type buffer)
inlineprivate
391 {
392
393 this->_log->debug("Reading string type from attribute {}", _path);
394
395 // resize buffer to the size of the type
396 buffer.resize(_type.size());
397
398 // read data
399 return H5Aread(get_C_id(), _type.get_C_id(), buffer.data());
400 }
std::size_t size() const
Size of the type held in bytes.
Definition hdftype.hh:210

◆ __write_container__()

template<typename Type >
herr_t Utopia::DataIO::HDFAttribute::__write_container__ ( Type  attribute_data)
inlineprivate

Function for writing containers as attribute.

Only buffers if necessary, i.e. if non-vector containers or nested containers or containers of strings have to be written.

108 {
109 this->_log->debug("Writing container data to attribute {} ...", _path);
110 using value_type_1 = typename Type::value_type;
111 using base_type = Utils::remove_qualifier_t< value_type_1 >;
112
113 // we can write directly if we have a plain vector, no nested or
114 // stringtype.
115 if constexpr (std::is_same_v< Type, std::vector< value_type_1 > > and
116 not Utils::is_container_v< value_type_1 > and
117 not Utils::is_string_v< value_type_1 >)
118 {
119 this->_log->debug("... of simple vector type");
120
121 // check if attribute has been created, else do
122 if (get_C_id() == -1)
123 {
125 }
126
127 return H5Awrite(
129 }
130 // when stringtype or containertype is stored in a container, then
131 // we have to buffer. bufferfactory handles how to do this in detail
132 else
133 {
134 this->_log->debug("... of non-trivial container type");
135 // if we want to write std::arrays then we can use
136 // fixed size array types. Else we use variable length arrays.
137 if constexpr (Utils::is_array_like_v< value_type_1 >)
138 {
139 this->_log->debug("... of fixed size array type");
140 constexpr std::size_t s =
141 Utils::get_size< value_type_1 >::value;
142
143 if (get_C_id() == -1)
144 {
146 }
147
148 auto buffer = HDFBufferFactory::buffer(
149 std::begin(attribute_data),
150 std::end(attribute_data),
151 [](auto& value) -> value_type_1& { return value; });
152
153 return H5Awrite(get_C_id(), _type.get_C_id(), buffer.data());
154 }
155 else
156 {
157 this->_log->debug("... of variable length type");
158 if (get_C_id() == -1)
159 {
161 }
162
163 auto buffer = HDFBufferFactory::buffer(
164 std::begin(attribute_data),
165 std::end(attribute_data),
166 [](auto& value) -> value_type_1& { return value; });
167
168 return H5Awrite(get_C_id(), _type.get_C_id(), buffer.data());
169 }
170 }
171 }
static auto buffer(Iter begin, Iter end, Adaptor &&adaptor)
static function for turning an iterator range with arbitrarty datatypes into a vector of data as retu...
Definition hdfbufferfactory.hh:96

◆ __write_pointertype__()

template<typename Type >
herr_t Utopia::DataIO::HDFAttribute::__write_pointertype__ ( Type  attribute_data)
inlineprivate
214 {
215 this->_log->debug("Writing pointer data to attribute {} ...", _path);
216
217 // result types removes pointers, references, and qualifiers
218 using basetype = Utils::remove_qualifier_t< Type >;
219
220 if (get_C_id() == -1)
221 {
223 }
224
226 }

◆ __write_scalartype__()

template<typename Type >
herr_t Utopia::DataIO::HDFAttribute::__write_scalartype__ ( Type  attribute_data)
inlineprivate
232 {
233 this->_log->debug("Writing scalar data to attribute {} ...", _path);
234
235 // because we just write a scalar, the shape tells basically that
236 // the attribute is pointlike: 1D and 1 entry.
237 if (get_C_id() == -1)
238 {
240 }
241
243 }

◆ __write_stringtype__()

template<typename Type >
herr_t Utopia::DataIO::HDFAttribute::__write_stringtype__ ( Type  attribute_data)
inlineprivate
177 {
178
179 this->_log->debug("Writing string data to attribute {} ...", _path);
180
181 // Since std::string cannot be written directly,
182 // (only const char*/char* can), a buffer pointer has been added
183 // to handle writing in a clearer way and with less code
184 auto len = 0;
185 const char* buffer = nullptr;
186
187 if constexpr (std::is_pointer_v< Type >) // const char* or char* ->
188 // strlen needed
189 {
190 len = std::strlen(attribute_data);
191 buffer = attribute_data;
192 }
193 else // simple for strings
194 {
195 len = attribute_data.size();
196 buffer = attribute_data.c_str();
197 }
198
199 // check if attribute has been created, else do
200 if (get_C_id() == -1)
201 {
203 }
204
205 // use that strings store data in consecutive memory
206 return H5Awrite(get_C_id(), _type.get_C_id(), buffer);
207 }

◆ close()

void Utopia::DataIO::HDFAttribute::close ( )
inline

closes the attribute

484 {
485 _type.close();
487 _shape.resize(0);
489
491
492 if (is_valid())
493 {
494 Base::close();
495 }
496 }
void close()
Close the identifier and render the C-Level id held invalid.
Definition hdfidentifier.hh:134
void close()
Close function which takes care of correctly closing the object and managing the reference counter.
Definition hdfobject.hh:161
virtual bool is_valid() const
Check if the object is still valid.
Definition hdfobject.hh:143
void close()
Construct close from the given arguments.
Definition hdftype.hh:322

◆ get_filespace()

HDFDataspace Utopia::DataIO::HDFAttribute::get_filespace ( )
inline

Get the file-dataspace object.

Returns
HDFDataspace
453 {
454 return _dataspace;
455 }

◆ get_parent_id()

HDFIdentifier Utopia::DataIO::HDFAttribute::get_parent_id ( )
inline

Get the hdf5 identifier to which the attribute belongs.

Returns
weak pointer to HDFObject
475 {
476 return _parent_identifier;
477 }

◆ get_shape()

auto Utopia::DataIO::HDFAttribute::get_shape ( )
inline

Get the shape object.

Returns
std::vector<hsize_t>
505 {
506 // the below is done to retain vector type for _shape member,
507 // which otherwise would break interface due to type change.
508 auto shape = _dataspace.size();
509 _shape.assign(shape.begin(), shape.end());
510
511 return _shape;
512 }
arma::Row< hsize_t > size()
Get the current size of the dataspace in each dimension.
Definition hdfdataspace.hh:94

◆ get_type()

auto Utopia::DataIO::HDFAttribute::get_type ( )
inline

Get the type object.

Returns
hid_t
464 {
465 return _type;
466 }

◆ open() [1/2]

void Utopia::DataIO::HDFAttribute::open ( const HDFIdentifier parent,
std::string  name 
)
inline

Open a new attribute on HDFObject 'parent' with name 'name'.

Parameters
parentHDFIdentifier to open the attribute on
nameThe attribute's name
537 {
538 // update members
540
541 _path = name;
542
543 if (parent.is_valid())
544 {
545
547 _path.c_str()) == 1)
548 {
549 this->_log->debug("... attribute exists already, opening");
550 // attribute exists, open
552 _path.c_str(),
554 &H5Aclose,
555 name);
556
557 _type.open(*this);
558
559 // README (regarding usage of this in constructors): the usage
560 // of *this is save here, because we always have a valid object
561 // of type HDFDataspace even in ctor given that this is neither
562 // a derived class nor we call a virtual function
563 _dataspace.open(*this);
564 get_shape();
565 }
566 else
567 {
568 this->_log->debug("... attribute does not yet exist, have to "
569 "wait for incoming data to build it");
570
571 this->_id = HDFIdentifier();
572 }
573 }
574 else
575 {
576 throw std::invalid_argument(
577 "Parent object of attribute '" + _path +
578 "' is invalid! Has it been closed already or not been opened "
579 "yet?");
580 }
581 }
auto get_shape()
Get the shape object.
Definition hdfattribute.hh:504
HDFIdentifier _id
Identifier object that binds an instance of this class to an HDF5 object.
Definition hdfobject.hh:44

◆ open() [2/2]

template<HDFCategory cat>
void Utopia::DataIO::HDFAttribute::open ( const HDFObject< cat > &  parent,
std::string  name 
)
inline

Open a new attribute on HDFObject 'parent' with name 'name'.

Parameters
parentHDFObject to open the attribute on
nameThe attribute's name
523 {
524 this->_log->debug(
525 "Opening attribute named {} in object {}", name, parent.get_path());
526 open(parent.get_id_object(), name);
527 }

◆ operator=() [1/2]

HDFAttribute & Utopia::DataIO::HDFAttribute::operator= ( const HDFAttribute other)
default

Copy assignment operator.

Parameters
otherObject to copy assign from
Returns
HDFAttribute&

◆ operator=() [2/2]

HDFAttribute & Utopia::DataIO::HDFAttribute::operator= ( HDFAttribute &&  other)
default

Attribute move assignment operator.

Parameters
otherObject to move assing from
Returns
HDFAttribute&

◆ read() [1/2]

template<typename Type >
auto Utopia::DataIO::HDFAttribute::read ( )
inline

Reads data from attribute, and returns the data and its shape in the form of a hsize_t vector.

This function has a quirk:

  • N-dimensional data are read into 1d arrays, and the shape has to be used to regain the original layout via index arithmetic.

Depending on the type 'Type', the data will be returned as:

  • if Type is a container other than vector: Will throw runtime_error
  • if Type is a vector or vector of vectors: Will return this, filled with data
  • if Type is a stringtype, i.e. char*, const char*, std::string: Will return std::string
  • if Type is a plain type, will return plain type
  • if Type as a pointer type, it will return a shared_ptr, i.e. Type = double*, return will be std::shared_ptr<double>;
Template Parameters
Typewhich can hold elements in the attribute and which will be returned
Returns
tuple containing (shape, data)
610 {
611 this->_log->debug("Reading attribute {}", _path);
612
613 if (_shape.size() == 0)
614 {
615 get_shape();
616 }
617
618 // Read can only be done in 1d, and this loop takes care of
619 // computing a 1d size which can accomodate all elements.
620 // This is then passed to the container holding the elements in the end.
621 std::size_t size = 1;
622 for (auto& value : _shape)
623 {
624 size *= value;
625 }
626
627 // type to read in is a container type, which can hold containers
628 // themselvels or just plain types.
629 if constexpr (Utils::is_container_v< Type >)
630 {
631 Type buffer(size);
632 herr_t err = __read_container__(buffer);
633 if (err < 0)
634 {
635 throw std::runtime_error("Error in reading data from " + _path +
636 " into container types");
637 }
638
639 return std::make_tuple(_shape, buffer);
640 }
641 else if constexpr (Utils::is_string_v< Type >) // we can have string
642 // types too, i.e. char*,
643 // const char*,
644 // std::string
645 {
646 std::string buffer; // resized in __read_stringtype__ because this
647 // as a scalar
649 if (err < 0)
650 {
651 throw std::runtime_error("Error in reading data from " + _path +
652 " into stringtype");
653 }
654
655 return std::make_tuple(_shape, buffer);
656 }
657 else if constexpr (std::is_pointer_v< Type > &&
658 !Utils::is_string_v< Type >)
659 {
660 std::shared_ptr< Utils::remove_qualifier_t<Type> > buffer(
661 new Utils::remove_qualifier_t<Type>[size], std::default_delete<Utils::remove_qualifier_t<Type>[]>());
662
663 herr_t err = __read_pointertype__(buffer.get());
664 if (err < 0)
665 {
666 throw std::runtime_error("Error in reading data from " + _path +
667 " into pointertype");
668 }
669 return std::make_tuple(_shape, buffer);
670 }
671 else // reading scalar types is simple enough
672 {
673 Type buffer(0);
675 if (err < 0)
676 {
677 throw std::runtime_error("Error in reading data from " + _path +
678 " into scalar");
679 }
680 return std::make_tuple(_shape, buffer);
681 }
682 }
auto __read_pointertype__(Type buffer)
Definition hdfattribute.hh:406
herr_t __read_container__(Type &buffer)
Definition hdfattribute.hh:252
auto __read_scalartype__(Type &buffer)
Definition hdfattribute.hh:416
auto __read_stringtype__(Type &buffer)
Definition hdfattribute.hh:390

◆ read() [2/2]

template<typename Type >
void Utopia::DataIO::HDFAttribute::read ( Type buffer)
inline

Reads data from attribute into a predefined buffer, and returns the data and its shape in the form of a hsize_t vector. User is responsible for providing a buffer which can hold the data and has the correct shape!

Template Parameters
Typewhich can hold elements in the attribute and which will be returned
696 {
697 this->_log->debug("Reading attribute {} into given buffer", _path);
698
699 if (_shape.size() == 0)
700 {
701 get_shape();
702 }
703
704 // type to read in is a container type, which can hold containers
705 // themselvels or just plain types.
706 if constexpr (Utils::is_container_v< Type >)
707 {
708 // needed to make sure that the buffer has the correct size
709
710 std::size_t size = 1;
711 for (auto& value : _shape)
712 {
713 size *= value;
714 }
715
716 if (buffer.size() != size)
717 {
718 buffer.resize(size);
719 }
720
721 herr_t err = __read_container__(buffer);
722 if (err < 0)
723 {
724 throw std::runtime_error("Error in reading data from " + _path +
725 " into container types");
726 }
727 }
728 else if constexpr (Utils::is_string_v< Type >) // we can have string
729 // types too, i.e. char*,
730 // const char*,
731 // std::string
732 {
733 // resized in __read_stringtype__ because this as a scalar
735 if (err < 0)
736 {
737 throw std::runtime_error("Error in reading data from " + _path +
738 " into stringtype");
739 }
740 }
741 else if constexpr (std::is_pointer_v< Type > &&
742 !Utils::is_string_v< Type >)
743 {
745
746 if (err < 0)
747 {
748 throw std::runtime_error("Error in reading data from " + _path +
749 " into pointertype");
750 }
751 }
752 else // reading scalar types is simple enough
753 {
755 if (err < 0)
756 {
757 throw std::runtime_error("Error in reading data from " + _path +
758 " into scalar");
759 }
760 }
761 }

◆ swap()

void Utopia::DataIO::HDFAttribute::swap ( HDFAttribute other)
inline

Exchange states between caller and argument.

Parameters
other
437 {
438 using std::swap;
440 swap(static_cast< Base& >(*this), static_cast< Base& >(other));
441 swap(_shape, other._shape);
442 swap(_parent_identifier, other._parent_identifier);
443 swap(_dataspace, other._dataspace);
444 }
void swap(HDFAttribute &other)
Exchange states between caller and argument.
Definition hdfattribute.hh:436
HDFObject< HDFCategory::attribute > Base
alias base class
Definition hdfattribute.hh:428
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition write_task.hh:240

◆ write() [1/2]

template<typename Iter , typename Adaptor >
void Utopia::DataIO::HDFAttribute::write ( Iter  begin,
Iter  end,
Adaptor  adaptor = [](auto& value) { return value; },
std::vector< hsize_t shape = {} 
)
inline

Function for writing data to the attribute.

Template Parameters
IterIterator type
AdaptorAdaptor which allows for extraction of a value from compound types, i.e. classes or structs
Parameters
beginStart of iterator range
endEnd of iterator range
adaptorFunction which turns the elements of the iterator into the objects to be written. Should (auto&) argument (simplest), but else must have (typename Iter::value_type&) argument
892 { return value; },
893 [[maybe_unused]] std::vector< hsize_t > shape = {})
894 {
895 this->_log->debug("Writing data from iterator range to attribute {}",
896 _path);
897
898 using Type = Utils::remove_qualifier_t< decltype(adaptor(*begin)) >;
899 // if we copy only the content of [begin, end), then simple vector
900 // copy suffices
901 if constexpr (std::is_same< Type, typename Iter::value_type >::value)
902 {
903 write(std::vector< Type >(begin, end));
904 }
905 else
906 {
907
908 std::vector< Type > buff(std::distance(begin, end));
909 std::generate(buff.begin(), buff.end(), [&begin, &adaptor]() {
910 return adaptor(*(begin++));
911 });
912
913 write(buff, shape);
914 }
915 }
void write(Type attribute_data, std::vector< hsize_t > shape={})
Function for writing data to the attribute.
Definition hdfattribute.hh:780
typename remove_qualifier< T >::type remove_qualifier_t
Shorthand for 'typename remove_qualifier::value'.
Definition type_traits.hh:97

◆ write() [2/2]

template<typename Type >
void Utopia::DataIO::HDFAttribute::write ( Type  attribute_data,
std::vector< hsize_t shape = {} 
)
inline

Function for writing data to the attribute.

Template Parameters
TypeAutomatically determined type of the data to write
Parameters
attribute_dataData to write
shapeLayout of the data, i.e. {20, 50} would indicate a 2d array like int a[20][50]; The parameter has only to be given if the data to be written is given as plain pointers, because the shape cannot be determined automatically then.
typelenIf the elements of the data to be written are arrays of equal length, and the data should be written as 1d attribute, then we can give the length of the arrays in order to speed up the memory allocation and avoid unecessary buffering. This can be useful for grids for instance.
780 {})
781 {
782 this->_log->debug("Writing data to attribute {}", _path);
783
784 // check if we have a container. Writing containers requires further
785 // t tests, plain old data can be written right away
786
787 if constexpr (Utils::is_container_v< Type >) // container type
788 {
789 // get the shape from the data. This function is written such
790 // that it writes always 1d, unless a pointer type with different
791 // shape is given.
792 if (_shape.size() == 0)
793 {
794 _shape = { attribute_data.size() };
795 }
796 else
797 {
798 _shape = shape;
799 }
801
802 if (err < 0)
803 {
804 throw std::runtime_error(
805 "An error occurred while writing a containertype to "
806 "attribute " +
807 _path + "!");
808 }
809 }
810 // write string types, i.e. const char*, char*, std::string
811 // These are not containers but not normal scalars either,
812 // so they have to be treated separatly
813 else if constexpr (Utils::is_string_v< Type >)
814 {
815 _shape = { 1 };
816
818
819 if (err < 0)
820 {
821 throw std::runtime_error(
822 "An error occurred while writing a stringtype to "
823 "attribute " +
824 _path + "!");
825 }
826 }
827 // We can also write pointer types, but then the shape of the array
828 // has to be given explicitly. This does not handle stringtypes,
829 // even though const char* /char* are pointer types
830 else if constexpr (std::is_pointer_v< Type > &&
831 !Utils::is_string_v< Type >)
832 {
833 if (shape.size() == 0)
834 {
835 throw std::runtime_error(
836 "Attribute: " + _path +
837 ","
838 "The shape parameter has to be given for pointers "
839 "because "
840 "it cannot be determined automatically");
841 }
842 else
843 {
844 _shape = shape;
845 }
846
848
849 if (err < 0)
850 {
851 throw std::runtime_error(
852 "An error occurred while writing a pointertype/plain array "
853 "to "
854 "attribute " +
855 _path + "!");
856 }
857 }
858 // plain scalar types are treated in a straight forward way
859 else
860 {
861 _shape = { 1 };
862
864 if (err < 0)
865 {
866 throw std::runtime_error(
867 "An error occurred while writing a scalar "
868 "to "
869 "attribute " +
870 _path + "!");
871 }
872 }
873 }
herr_t __write_stringtype__(Type attribute_data)
Definition hdfattribute.hh:176
herr_t __write_pointertype__(Type attribute_data)
Definition hdfattribute.hh:213
herr_t __write_container__(Type attribute_data)
Function for writing containers as attribute.
Definition hdfattribute.hh:107
herr_t __write_scalartype__(Type attribute_data)
Definition hdfattribute.hh:231

Member Data Documentation

◆ _dataspace

HDFDataspace Utopia::DataIO::HDFAttribute::_dataspace
private

Dataspace object that manages topology of data written and read.

◆ _parent_identifier

HDFIdentifier Utopia::DataIO::HDFAttribute::_parent_identifier
private

Identifier of the parent object.

◆ _shape

std::vector< hsize_t > Utopia::DataIO::HDFAttribute::_shape
private

size of the attributes dataspace

◆ _type

HDFType Utopia::DataIO::HDFAttribute::_type
private

type done in the HDFAttribute


The documentation for this class was generated from the following file: