Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
general_data_storage.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_algorithms_general_data_storage_h
17 #define dealii_algorithms_general_data_storage_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/subscriptor.h>
23 
24 #include <boost/any.hpp>
25 #include <boost/core/demangle.hpp>
26 
27 #include <algorithm>
28 #include <map>
29 #include <string>
30 #include <typeinfo>
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 
57 {
58 public:
62  GeneralDataStorage() = default;
63 
67  GeneralDataStorage(const GeneralDataStorage &) = default;
68 
73 
77  std::size_t
78  size() const;
79 
83  void
84  merge(const GeneralDataStorage &other_data);
85 
94  template <class Stream>
95  void
96  print_info(Stream &stream);
97 
177  void
178  reset();
179 
184 
193  template <typename Type>
194  void
195  add_unique_copy(const std::string &name, const Type &entry);
196 
206  template <typename Type>
207  void
208  add_or_overwrite_copy(const std::string &name, const Type &entry);
209 
219  template <typename Type>
220  void
221  add_unique_reference(const std::string &name, Type &entry);
222 
233  template <typename Type>
234  void
235  add_or_overwrite_reference(const std::string &name, Type &entry);
236 
247  template <typename Type, typename Arg, typename... Args>
248  Type &
249  get_or_add_object_with_name(const std::string &name,
250  Arg & argument,
251  Args &... arguments);
252 
263  template <typename Type, typename Arg, typename... Args>
264  Type &
265  get_or_add_object_with_name(const std::string &name,
266  Arg && argument,
267  Args &&... arguments);
268 
272  template <typename Type>
273  Type &
274  get_or_add_object_with_name(const std::string &name);
275 
283  template <typename Type>
284  Type &
285  get_object_with_name(const std::string &name);
286 
294  template <typename Type>
295  const Type &
296  get_object_with_name(const std::string &name) const;
297 
301  bool
302  stores_object_with_name(const std::string &name) const;
303 
307  void
308  remove_object_with_name(const std::string &name);
309 
311 
316  std::string,
317  << "No entry with the name " << arg1 << " exists.");
318 
323  std::string,
324  << "An entry with the name " << arg1 << " already exists.");
325 
330  std::string,
331  const char *,
332  const char *,
333  << "The stored type for entry with name \"" << arg1 << "\" is "
334  << arg2 << " but you requested type " << arg3 << ".");
335 
336 private:
340  std::map<std::string, boost::any> any_data;
341 };
342 
343 
344 /*----------------- Inline and template methods -----------------*/
345 
346 
347 #ifndef DOXYGEN
348 
349 
350 template <class Stream>
351 void
353 {
354  for (auto it : any_data)
355  {
356  os << it.first << '\t' << '\t'
357  << boost::core::demangle(it.second.type().name()) << std::endl;
358  }
359 }
360 
361 
362 template <typename Type>
363 void
364 GeneralDataStorage::add_unique_copy(const std::string &name, const Type &entry)
365 {
367  add_or_overwrite_copy(name, entry);
368 }
369 
370 
371 template <typename Type>
372 void
373 GeneralDataStorage::add_or_overwrite_copy(const std::string &name,
374  const Type & entry)
375 {
376  any_data[name] = entry;
377 }
378 
379 
380 template <typename Type>
381 void
382 GeneralDataStorage::add_unique_reference(const std::string &name, Type &entry)
383 {
385  add_or_overwrite_reference(name, entry);
386 }
387 
388 
389 template <typename Type>
390 void
391 GeneralDataStorage::add_or_overwrite_reference(const std::string &name,
392  Type & entry)
393 {
394  Type *ptr = &entry;
395  any_data[name] = ptr;
396 }
397 
398 
399 template <typename Type>
400 Type &
401 GeneralDataStorage::get_object_with_name(const std::string &name)
402 {
404 
405  Type *p = nullptr;
406 
407  if (any_data[name].type() == typeid(Type *))
408  {
409  p = boost::any_cast<Type *>(any_data[name]);
410  }
411  else if (any_data[name].type() == typeid(Type))
412  {
413  p = boost::any_cast<Type>(&any_data[name]);
414  }
415  else
416  {
417  AssertThrow(false,
418  ExcTypeMismatch(name,
419  any_data[name].type().name(),
420  typeid(Type).name()));
421  }
422 
423  return *p;
424 }
425 
426 
427 template <typename Type>
428 const Type &
429 GeneralDataStorage::get_object_with_name(const std::string &name) const
430 {
432 
433  const auto it = any_data.find(name);
434 
435  if (it->second.type() == typeid(Type *))
436  {
437  const Type *p = boost::any_cast<Type *>(it->second);
438  return *p;
439  }
440  else if (it->second.type() == typeid(Type))
441  {
442  const Type *p = boost::any_cast<Type>(&it->second);
443  return *p;
444  }
445  else
446  {
447  AssertThrow(false,
448  ExcTypeMismatch(name,
449  it->second.type().name(),
450  typeid(Type).name()));
451  const Type *p = nullptr;
452  return *p;
453  }
454 }
455 
456 
457 template <typename Type, typename Arg, typename... Args>
458 Type &
460  Arg & argument,
461  Args &... arguments)
462 {
463  if (!stores_object_with_name(name))
464  add_unique_copy(name, Type(argument, arguments...));
465 
466  return get_object_with_name<Type>(name);
467 }
468 
469 
470 template <typename Type, typename Arg, typename... Args>
471 Type &
473  Arg && argument,
474  Args &&... arguments)
475 {
476  if (!stores_object_with_name(name))
477  add_unique_copy(name,
478  Type(std::forward<Arg>(argument),
479  std::forward<Args>(arguments)...));
480 
481  return get_object_with_name<Type>(name);
482 }
483 
484 
485 template <typename Type>
486 Type &
488 {
489  if (!stores_object_with_name(name))
490  add_unique_copy(name, Type());
491 
492  return get_object_with_name<Type>(name);
493 }
494 
495 
496 #endif // DOXYGEN
497 
498 
499 DEAL_II_NAMESPACE_CLOSE
500 
501 #endif // dealii_algorithms_general_data_storage_h
void add_unique_copy(const std::string &name, const Type &entry)
void add_or_overwrite_copy(const std::string &name, const Type &entry)
void add_or_overwrite_reference(const std::string &name, Type &entry)
std::size_t size() const
#define AssertThrow(cond, exc)
Definition: exceptions.h:1519
Type & get_object_with_name(const std::string &name)
Type & get_or_add_object_with_name(const std::string &name, Arg &argument, Args &... arguments)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
bool stores_object_with_name(const std::string &name) const
void print_info(Stream &stream)
static ::ExceptionBase & ExcNameNotFound(std::string arg1)
std::map< std::string, boost::any > any_data
void add_unique_reference(const std::string &name, Type &entry)
void merge(const GeneralDataStorage &other_data)
static ::ExceptionBase & ExcTypeMismatch(std::string arg1, const char *arg2, const char *arg3)
GeneralDataStorage()=default
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
static ::ExceptionBase & ExcNameHasBeenFound(std::string arg1)
void remove_object_with_name(const std::string &name)