HDTree  0.5.2
HDTree C++ API
GeneralBranch.h
1 #pragma once
2 
3 #include "hdtree/Exception.h"
4 
5 namespace hdtree {
6 
45 template <typename DataType, typename Enable = void>
46 class Branch : public AbstractBranch<DataType> {
47  public:
54  enum SaveLoad {
55  Both,
57  SaveOnly
58  };
59 
73  explicit Branch(const std::string& branch_name, DataType* handle = nullptr)
74  : AbstractBranch<DataType>(branch_name, handle) {
75  hdtree::access::connect(*this->handle_, *this);
76  }
77 
92  void load() final override try {
93  for (auto& [save, load, m] : members_)
94  if (load) m->load();
95  } catch (const HighFive::DataSetException& e) {
96  const auto& [memt, memv] = this->save_type_;
97  const auto& [diskt, diskv] =
98  this->load_type_.value_or(std::make_pair("NULL", -1));
99  std::stringstream msg, help;
100  msg << "HDTreeBadType: Branch at " << this->name_
101  << " could not be loaded into " << memt << " (version " << memv
102  << ") from the type it was written as " << diskt << " (version " << diskv
103  << ")";
104  help << "Check that your implementation of attach can handle any "
105  "previous versions of your class you are trying to read.\n"
106  " Caused by: " << e.what();
107  throw HDTreeException(msg.str(), help.str());
108  }
109 
110  void attach(Reader& f) final override try {
111  this->load_type_ = f.type(this->name_);
112  for (auto& [save, load, m] : members_)
113  if (load) m->attach(f);
114  } catch (const HDTreeException& e) {
115  const auto& [memt, memv] = this->save_type_;
116  const auto& [diskt, diskv] = f.type(this->name_);
117  std::stringstream msg, help;
118  msg << "HDTreeBadType: Branch at " << this->name_
119  << " could not be attached to " << memt << " (version " << memv
120  << ") from the type it was written as " << diskt << " (version " << diskv
121  << ")";
122  help << "Check that your implementation of attach can handle any "
123  "previous versions of your class you are trying to read.\n"
124  " Caused by: " << e.what();
125  throw HDTreeException(msg.str(), help.str());
126  }
127 
128  /*
129  * Saving this dataset from the file involves simply saving
130  * all of the members of the data type.
131  */
132  void save() final override {
133  for (auto& [save, load, m] : members_)
134  if (save) m->save();
135  }
136 
137  void attach(Writer& f) final override {
138  f.structure(this->name_, this->save_type_);
139  for (auto& [save, load, m] : members_)
140  if (save) m->attach(f);
141  }
142 
156  template <typename MemberType>
157  void attach(const std::string& name, MemberType& m,
158  SaveLoad sl = SaveLoad::Both) {
159  if (name == constants::SIZE_NAME) {
160  throw HDTreeException(
161  "HDTreeBadName: The member name '" + constants::SIZE_NAME +
162  "' is not allowed due to "
163  "its use in the serialization of variable length types.",
164  "Please give your member a more detailed name corresponding to "
165  "your class"
166  );
167  }
168  bool save{false}, load{false};
169  if (sl == SaveLoad::LoadOnly)
170  load = true;
171  else if (sl == SaveLoad::SaveOnly) {
172  save = true;
173  } else {
174  save = true;
175  load = true;
176  }
177  members_.push_back(std::make_tuple(
178  save, load,
179  std::make_unique<Branch<MemberType>>(this->name_ + "/" + name, &m)));
180  }
181 
196  template <typename MemberType>
197  void rename(const std::string& old_name, const std::string& new_name,
198  MemberType& m) {
199  attach(old_name, m, SaveLoad::LoadOnly);
200  attach(new_name, m, SaveLoad::SaveOnly);
201  }
202 
203  private:
213  std::vector<std::tuple<bool, bool, std::unique_ptr<BaseBranch>>> members_;
216 }; // Branch
217 
218 } // namespace hdtree
Type-specific base class to hold common data methods.
Definition: AbstractBranch.h:87
std::pair< std::string, int > save_type_
type this data that is being used to write
Definition: AbstractBranch.h:244
std::optional< std::pair< std::string, int > > load_type_
type this data is loading from
Definition: AbstractBranch.h:242
DataType * handle_
handle on current object in memory
Definition: AbstractBranch.h:247
std::string name_
name of branch
Definition: AbstractBranch.h:74
General data set.
Definition: GeneralBranch.h:46
Branch(const std::string &branch_name, DataType *handle=nullptr)
Attach ourselves to the input type after construction.
Definition: GeneralBranch.h:73
void attach(Writer &f) final override
pure virtual method for saving structure
Definition: GeneralBranch.h:137
void save() final override
pure virtual method for saving data
Definition: GeneralBranch.h:132
std::vector< std::tuple< bool, bool, std::unique_ptr< BaseBranch > > > members_
list of members in this dataset
Definition: GeneralBranch.h:213
SaveLoad
Flag how a member variable should be accessed by serialization.
Definition: GeneralBranch.h:54
@ Both
load and save the member
Definition: GeneralBranch.h:55
@ SaveOnly
only save the member (write out)
Definition: GeneralBranch.h:57
@ LoadOnly
only load the member (read in)
Definition: GeneralBranch.h:56
void load() final override
Loading this dataset from the file involves simply loading all of the members of the data type.
Definition: GeneralBranch.h:92
void attach(Reader &f) final override
pure virtual method for loading data from the input file
Definition: GeneralBranch.h:110
Reader * input_file_
pointer to the input file (if there is one)
Definition: GeneralBranch.h:215
void rename(const std::string &old_name, const std::string &new_name, MemberType &m)
Rename a member variable.
Definition: GeneralBranch.h:197
void attach(const std::string &name, MemberType &m, SaveLoad sl=SaveLoad::Both)
Attach a member object from the our data handle.
Definition: GeneralBranch.h:157
user-facing exception class for hdtree
Definition: Exception.h:15
const char * what() const noexcept
Override the message from the base class.
Definition: Exception.cxx:8
Reading a file generated by fire.
Definition: Reader.h:24
Write the fire DataSets into a deterministic structure in the output HDF5 data file.
Definition: Writer.h:21
Geant4 does a GLOBAL definition of the keyword TRUE.
Definition: Atomic.cxx:3
static void connect(T &t, D &d)
Connect the input types by attaching t to do.
Definition: Access.h:32
static const std::string SIZE_NAME
the name of the size dataset for variable-length types
Definition: Constants.h:21