HOPS
HOPS class reference
MHO_ParameterStore.hh
Go to the documentation of this file.
1 #ifndef MHO_ParameterStore_HH__
2 #define MHO_ParameterStore_HH__
3 
4 #include <string>
5 
7 #include "MHO_Message.hh"
8 #include "MHO_Tokenizer.hh"
9 
10 namespace hops
11 {
12 
53 {
54  public:
56  {
57  fTokenizer.SetDelimiter("/");
59  fTokenizer.SetIncludeEmptyTokensFalse();
60  };
61 
63 
67  void Dump() { std::cout << fStore.dump(2) << std::endl; }
68 
74  void CopyFrom(const MHO_ParameterStore& copy) { fStore = copy.fStore; }
75 
81  void DumpData(mho_json& data) { data = fStore; }
82 
88  void FillData(const mho_json& data) { fStore = data; }
89 
93  void ClearData() { fStore.clear(); }
94 
95  //returns true if no error adding value
103  template< typename XValueType > bool Set(const std::string& value_path, const XValueType& value);
104 
110  bool Set(const std::string& value_path, const mho_json& value)
111  {
112  try
113  {
114  fStore[mho_json::json_pointer(SanitizePath(value_path))] = value;
115  return true;
116  }
117  catch(...)
118  {
119  return false;
120  }
121  }
122 
131  template< typename XValueType > bool Get(const std::string& value_path, XValueType& value) const;
132 
140  template< typename XValueType > XValueType GetAs(const std::string& value_path) const;
141 
149  template< typename XValueType > XValueType GetRequiredAs(const std::string& value_path) const;
150 
158  bool IsPresent(const std::string& value_path) const
159  {
160  std::string path = SanitizePath(value_path);
161  fPath.clear();
162  fTokenizer.SetString(&path);
163  fTokenizer.GetTokens(&fPath);
164 
165  auto* p = &fStore;
166  for(auto it = fPath.begin(); it != fPath.end(); it++)
167  {
168  auto jit = p->find(*it);
169  if(jit == p->end())
170  {
171  return false;
172  }
173  else if(*it == *(fPath.rbegin()))
174  {
175  return true;
176  }
177  else
178  {
179  p = &(jit.value());
180  }
181  }
182  return false;
183  }
184 
185  private:
192  std::string SanitizePath(const std::string& value_path) const
193  {
194  std::string vpath = MHO_Tokenizer::TrimLeadingAndTrailingWhitespace(value_path);
195  if(vpath.size() > 0 && vpath.back() == '/') //trim any trailing '/'
196  {
197  vpath.pop_back();
198  }
199  return vpath;
200  }
201 
202  //helpers
203  mutable MHO_Tokenizer fTokenizer;
204  mutable std::vector< std::string > fPath;
205 
206  //stash data in a json object
207  mho_json fStore;
208 };
209 
217 template< typename XValueType > bool MHO_ParameterStore::Set(const std::string& value_path, const XValueType& value)
218 {
219  //first we tokenize the value path into a sequence of names
220  std::string path = SanitizePath(value_path);
221  fPath.clear();
222  fTokenizer.SetString(&path);
223  fTokenizer.GetTokens(&fPath);
224 
225  bool ok = false;
226  if(fPath.size() > 0)
227  {
228  //insert and/or replace an object
229  auto* p = &fStore;
230  for(auto it = fPath.begin(); it != fPath.end(); it++)
231  {
232  if(*it != *(fPath.rbegin()))
233  {
234  if(p->contains(*it)) //item with path exists
235  {
236  p = &(p->at(*it)); //point to this item
237  }
238  else
239  {
240  //item doesn't exist yet, so create an entry with this key (*it)
241  p = &(*p)[*it];
242  }
243  }
244  else //we've arrived at the terminal point, so set this item to the value
245  {
246  p = &(*p)[*it];
247  *p = value;
248  ok = true;
249  }
250  }
251  }
252  return ok;
253 }
254 
262 template< typename XValueType > bool MHO_ParameterStore::Get(const std::string& value_path, XValueType& value) const
263 {
264  //NOTE: we do not use json_pointer to access values specified by path
265  //because it will throw an exception if used when the path is not present/complete
266  std::string path = SanitizePath(value_path);
267  fPath.clear();
268  fTokenizer.SetString(&path);
269  fTokenizer.GetTokens(&fPath);
270 
271  bool present = false;
272  auto* p = &fStore;
273  for(auto it = fPath.begin(); it != fPath.end(); it++)
274  {
275  auto jit = p->find(*it);
276  if(jit == p->end())
277  {
278  return false;
279  }
280  else if(*it == *(fPath.rbegin()))
281  {
282  value = jit->get< XValueType >();
283  return true;
284  }
285  else
286  {
287  p = &(jit.value());
288  }
289  }
290  return false;
291 }
292 
299 template< typename XValueType > XValueType MHO_ParameterStore::GetAs(const std::string& value_path) const
300 {
301  XValueType v = XValueType(); //default constructor (zero for int, double, etc)
302  bool ok = Get(value_path, v);
303  if(!ok)
304  {
305  msg_error("utility", "failed to retrieve value for: " << value_path << " returning a default value" << eom);
306  }
307  return v;
308 }
309 
310 template< typename XValueType > XValueType MHO_ParameterStore::GetRequiredAs(const std::string& value_path) const
311 {
312  XValueType v = XValueType(); //default constructor (zero for int, double, etc)
313  bool ok = Get(value_path, v);
314  if(!ok)
315  {
316  msg_fatal("utility", "failed to retrieve value: " << value_path << ", aborting" << eom);
317  HOPS_THROW;
318  }
319  return v;
320 }
321 
322 } // namespace hops
323 
324 #endif
nlohmann::json mho_json
Definition: MHO_JSONHeaderWrapper.hh:5
#define msg_fatal(xKEY, xCONTENT)
Definition: MHO_Message.hh:228
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:238
#define HOPS_THROW
Definition: MHO_TestAssertions.hh:19
Class MHO_ParameterStore.
Definition: MHO_ParameterStore.hh:53
~MHO_ParameterStore()
Definition: MHO_ParameterStore.hh:62
bool Set(const std::string &value_path, const XValueType &value)
Setter for value at specified path in the parameter store.
Definition: MHO_ParameterStore.hh:217
void Dump()
Dumps the store JSON data to std:cout (for debugging)
Definition: MHO_ParameterStore.hh:67
void ClearData()
Clears all data from fStore.
Definition: MHO_ParameterStore.hh:93
void FillData(const mho_json &data)
Stores input json data for later use.
Definition: MHO_ParameterStore.hh:88
MHO_ParameterStore()
Definition: MHO_ParameterStore.hh:55
void DumpData(mho_json &data)
Copies data from internal storage to provided json object.
Definition: MHO_ParameterStore.hh:81
XValueType GetAs(const std::string &value_path) const
Getter, cast to type, always returns a value, if not found the value returned is XValueType()
Definition: MHO_ParameterStore.hh:299
XValueType GetRequiredAs(const std::string &value_path) const
Getter, cast to type, throws an error if the path/value is not present, will not return a default.
Definition: MHO_ParameterStore.hh:310
bool Get(const std::string &value_path, XValueType &value) const
Retrieves a value by path and returns it as XValueType, using default constructor if not found.
Definition: MHO_ParameterStore.hh:262
bool IsPresent(const std::string &value_path) const
Function IsPresent, checks if path is present in parameter store.
Definition: MHO_ParameterStore.hh:158
void CopyFrom(const MHO_ParameterStore &copy)
Copies the parameter store from a given source.
Definition: MHO_ParameterStore.hh:74
bool Set(const std::string &value_path, const mho_json &value)
Explicit overload for mho_json values. Uses nlohmann::json_pointer to avoid template deduction ambigu...
Definition: MHO_ParameterStore.hh:110
void SetIncludeEmptyTokensFalse()
Definition: MHO_Tokenizer.cc:30
void SetString(const std::string *aString)
Definition: MHO_Tokenizer.cc:65
void GetTokens(std::vector< std::string > *tokens)
Definition: MHO_Tokenizer.cc:75
static std::string TrimLeadingAndTrailingWhitespace(const std::string &value)
Definition: MHO_Tokenizer.cc:283
void SetRemoveLeadingTrailingWhitespaceTrue()
Setter for remove leading trailing whitespace true.
Definition: MHO_Tokenizer.cc:55
void SetDelimiter(const std::string &aDelim)
Definition: MHO_Tokenizer.cc:70
Definition: fit_gsl.h:54
Definition: MHO_AdhocFlagging.hh:18
Definition: vex.h:175