Reference documentation for deal.II version 9.1.0-pre
any_data.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2017 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_any_data_h
17 #define dealii_any_data_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 
26 #include <algorithm>
27 #include <typeinfo>
28 #include <vector>
29 
30 DEAL_II_NAMESPACE_OPEN
31 
37 class AnyData : public Subscriptor
38 {
39 public:
41  AnyData() = default;
42 
44  unsigned int
45  size() const;
46 
48  template <typename type>
49  void
50  add(type entry, const std::string &name);
51 
55  void
56  merge(const AnyData &other);
57 
66  template <typename type>
67  type
68  entry(const std::string &name);
69 
78  template <typename type>
79  const type
80  entry(const std::string &name) const;
81 
93  template <typename type>
94  const type
95  read(const std::string &name) const;
96 
106  template <typename type>
107  const type *
108  read_ptr(const std::string &name) const;
109 
114  template <typename type>
115  const type *
116  try_read_ptr(const std::string &name) const;
117 
125  template <typename type>
126  const type *
127  try_read(const std::string &name) const;
128 
132  template <typename type>
133  type
134  entry(const unsigned int i);
135 
137  template <typename type>
138  const type
139  entry(const unsigned int i) const;
140 
142  template <typename type>
143  const type
144  read(const unsigned int i) const;
145 
147  template <typename type>
148  const type *
149  read_ptr(const unsigned int i) const;
150 
152  template <typename type>
153  const type *
154  try_read_ptr(const unsigned int i) const;
155 
157  template <typename type>
158  const type *
159  try_read(const unsigned int i) const;
160 
162  const std::string &
163  name(const unsigned int i) const;
164 
171  unsigned int
172  find(const std::string &name) const;
173 
180  unsigned int
181  try_find(const std::string &name) const;
182 
184  template <typename type>
185  bool
186  is_type(const unsigned int i) const;
187 
189  template <class StreamType>
190  void
191  list(StreamType &os) const;
192 
195  std::string,
196  << "No entry with the name " << arg1 << " exists.");
197 
200  std::string,
201  std::string,
202  << "The requested type " << arg1 << " and the stored type "
203  << arg2 << " must coincide.");
204 
210  int,
211  std::string,
212  << "Name at position " << arg1 << " is not equal to " << arg2
213  << ".");
214 
215 private:
217  std::vector<boost::any> data;
219  std::vector<std::string> names;
220 };
221 
222 
223 unsigned int inline AnyData::size() const
224 {
225  AssertDimension(data.size(), names.size());
226  return data.size();
227 }
228 
229 
230 template <typename type>
231 inline type
232 AnyData::entry(const unsigned int i)
233 {
234  AssertIndexRange(i, size());
235  type *p = boost::any_cast<type>(&data[i]);
236  Assert(p != nullptr,
237  ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
238  return *p;
239 }
240 
241 
242 template <typename type>
243 inline const type
244 AnyData::entry(const unsigned int i) const
245 {
246  AssertIndexRange(i, size());
247  const type *p = boost::any_cast<type>(&data[i]);
248  if (p == nullptr)
249  p = boost::any_cast<const type>(&data[i]);
250  Assert(p != nullptr,
251  ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
252  return *p;
253 }
254 
255 
256 template <typename type>
257 inline const type
258 AnyData::read(const unsigned int i) const
259 {
260  AssertIndexRange(i, size());
261  const type *p = boost::any_cast<type>(&data[i]);
262  if (p == nullptr)
263  p = boost::any_cast<const type>(&data[i]);
264  Assert(p != nullptr,
265  ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
266  return *p;
267 }
268 
269 
270 template <typename type>
271 inline const type *
272 AnyData::read_ptr(const unsigned int i) const
273 {
274  AssertIndexRange(i, size());
275  const type *const *p = boost::any_cast<type *>(&data[i]);
276  if (p == nullptr)
277  p = boost::any_cast<const type *>(&data[i]);
278  Assert(p != nullptr,
279  ExcTypeMismatch(typeid(type *).name(), data[i].type().name()));
280  return *p;
281 }
282 
283 
284 template <typename type>
285 inline const type *
286 AnyData::try_read_ptr(const unsigned int i) const
287 {
288  AssertIndexRange(i, size());
289  const type *const *p = boost::any_cast<type *>(&data[i]);
290  if (p == nullptr)
291  p = boost::any_cast<const type *>(&data[i]);
292  if (p == nullptr)
293  return nullptr;
294  return *p;
295 }
296 
297 
298 template <typename type>
299 inline const type *
300 AnyData::try_read(const unsigned int i) const
301 {
302  AssertIndexRange(i, size());
303  const type *p = boost::any_cast<type>(&data[i]);
304  if (p == 0)
305  p = boost::any_cast<const type>(&data[i]);
306  return p;
307 }
308 
309 
310 inline const std::string &
311 AnyData::name(const unsigned int i) const
312 {
313  AssertIndexRange(i, size());
314  return names[i];
315 }
316 
317 
318 inline unsigned int
319 AnyData::try_find(const std::string &n) const
320 {
321  std::vector<std::string>::const_iterator it =
322  std::find(names.begin(), names.end(), n);
323 
324  if (it == names.end())
326 
327  return it - names.begin();
328 }
329 
330 
331 inline unsigned int
332 AnyData::find(const std::string &n) const
333 {
334  const unsigned int i = try_find(n);
336 
337  return i;
338 }
339 
340 
341 template <typename type>
342 inline bool
343 AnyData::is_type(const unsigned int i) const
344 {
345  return data[i].type() == typeid(type);
346 }
347 
348 
349 template <typename type>
350 inline type
351 AnyData::entry(const std::string &n)
352 {
353  const unsigned int i = find(n);
354  type * p = boost::any_cast<type>(&data[i]);
355  Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
356  return *p;
357 }
358 
359 
360 template <typename type>
361 inline const type
362 AnyData::entry(const std::string &n) const
363 {
364  const unsigned int i = find(n);
365  const type * p = boost::any_cast<type>(&data[i]);
366  Assert(p != nullptr,
367  ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
368  return *p;
369 }
370 
371 
372 template <typename type>
373 inline const type
374 AnyData::read(const std::string &n) const
375 {
376  const unsigned int i = find(n);
377  const type * p = boost::any_cast<type>(&data[i]);
378  Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
379  return *p;
380 }
381 
382 
383 template <typename type>
384 inline const type *
385 AnyData::read_ptr(const std::string &n) const
386 {
387  const unsigned int i = find(n);
388  const type *const *p = boost::any_cast<type *>(&data[i]);
389  if (p == nullptr)
390  p = boost::any_cast<const type *>(&data[i]);
391  Assert(p != nullptr,
392  ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
393  return *p;
394 }
395 
396 
397 template <typename type>
398 inline const type *
399 AnyData::try_read_ptr(const std::string &n) const
400 {
401  const unsigned int i = try_find(n);
403  return 0;
404 
405  const type *const *p = boost::any_cast<type *>(&data[i]);
406  if (p == 0)
407  p = boost::any_cast<const type *>(&data[i]);
408  return *p;
409 }
410 
411 
412 template <typename type>
413 inline const type *
414 AnyData::try_read(const std::string &n) const
415 {
416  // Try to find name
417  std::vector<std::string>::const_iterator it =
418  std::find(names.begin(), names.end(), n);
419  // Return null pointer if not found
420  if (it == names.end())
421  return nullptr;
422 
423  // Compute index and return casted pointer
424  unsigned int i = it - names.begin();
425  const type * p = boost::any_cast<type>(&data[i]);
426  return p;
427 }
428 
429 
430 template <typename type>
431 inline void
432 AnyData::add(type ent, const std::string &n)
433 {
434  boost::any e = ent;
435  data.push_back(e);
436  names.push_back(n);
437 }
438 
439 
440 inline void
441 AnyData::merge(const AnyData &other)
442 {
443  for (unsigned int i = 0; i < other.size(); ++i)
444  {
445  names.push_back(other.names[i]);
446  data.push_back(other.data[i]);
447  }
448 }
449 
450 
451 template <class StreamType>
452 inline void
453 AnyData::list(StreamType &os) const
454 {
455  for (unsigned int i = 0; i < names.size(); ++i)
456  {
457  os << i << '\t' << names[i] << '\t' << data[i].type().name() << std::endl;
458  }
459 }
460 
461 
462 //----------------------------------------------------------------------//
463 
464 
465 
466 DEAL_II_NAMESPACE_CLOSE
467 
468 #endif
AnyData()=default
Default constructor for empty object.
static::ExceptionBase & ExcNameNotFound(std::string arg1)
An entry with this name does not exist in the AnyData object.
static const unsigned int invalid_unsigned_int
Definition: types.h:173
type entry(const std::string &name)
Access to stored data object by name.
Definition: any_data.h:351
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
void merge(const AnyData &other)
Merge the data of another AnyData to the end of this object.
Definition: any_data.h:441
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
Definition: any_data.h:343
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
const type * read_ptr(const std::string &name) const
Dedicated read only access by name for pointer data.
Definition: any_data.h:385
void list(StreamType &os) const
List the contents to a stream.
Definition: any_data.h:453
const std::string & name(const unsigned int i) const
Name of object at index.
Definition: any_data.h:311
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
#define Assert(cond, exc)
Definition: exceptions.h:1227
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition: any_data.h:414
static::ExceptionBase & ExcTypeMismatch(std::string arg1, std::string arg2)
The requested type and the stored type are different.
std::vector< boost::any > data
The stored data.
Definition: any_data.h:217
const type read(const std::string &name) const
Dedicated read only access by name.
Definition: any_data.h:374
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition: any_data.h:319
void add(type entry, const std::string &name)
Add a new data object.
Definition: any_data.h:432
std::vector< std::string > names
The names of the stored data.
Definition: any_data.h:219
unsigned int find(const std::string &name) const
Find index of a named object.
Definition: any_data.h:332
static::ExceptionBase & ExcNameMismatch(int arg1, std::string arg2)
unsigned int size() const
Number of stored data objects.
Definition: any_data.h:223
const type * try_read_ptr(const std::string &name) const
Definition: any_data.h:399