Reference documentation for deal.II version 9.0.0
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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_any_data_h
17 #define dealii_any_data_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/exceptions.h>
21 #include <deal.II/base/subscriptor.h>
22 
23 #include <boost/any.hpp>
24 #include <vector>
25 #include <algorithm>
26 #include <typeinfo>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
35 class AnyData :
36  public Subscriptor
37 {
38 public:
40  AnyData() = default;
41 
43  unsigned int size() const;
44 
46  template <typename type>
47  void add(type entry, const std::string &name);
48 
52  void merge(const AnyData &other);
53 
62  template <typename type>
63  type entry (const std::string &name);
64 
73  template <typename type>
74  const type entry (const std::string &name) const;
75 
87  template <typename type>
88  const type read (const std::string &name) const;
89 
99  template <typename type>
100  const type *read_ptr (const std::string &name) const;
101 
106  template <typename type>
107  const type *try_read_ptr (const std::string &name) const;
108 
116  template <typename type>
117  const type *try_read (const std::string &name) const;
118 
122  template <typename type>
123  type entry (const unsigned int i);
124 
126  template <typename type>
127  const type entry (const unsigned int i) const;
128 
130  template <typename type>
131  const type read (const unsigned int i) const;
132 
134  template <typename type>
135  const type *read_ptr (const unsigned int i) const;
136 
138  template <typename type>
139  const type *try_read_ptr (const unsigned int i) const;
140 
142  template <typename type>
143  const type *try_read (const unsigned int i) const;
144 
146  const std::string &name(const unsigned int i) const;
147 
154  unsigned int find(const std::string &name) const;
155 
162  unsigned int try_find(const std::string &name) const;
163 
165  template <typename type>
166  bool is_type(const unsigned int i) const;
167 
169  template <class StreamType>
170  void list (StreamType &os) const;
171 
173  DeclException1(ExcNameNotFound, std::string,
174  << "No entry with the name " << arg1 << " exists.");
175 
178  char *, char *,
179  << "The requested type " << arg1
180  << " and the stored type " << arg2
181  << " must coincide.");
182 
187  DeclException2(ExcNameMismatch, int, std::string,
188  << "Name at position " << arg1 << " is not equal to " << arg2 << ".");
189 private:
191  std::vector<boost::any> data;
193  std::vector<std::string> names;
194 };
195 
196 
197 unsigned int
198 inline
200 {
201  AssertDimension(data.size(), names.size());
202  return data.size();
203 }
204 
205 
206 template <typename type>
207 inline
208 type
209 AnyData::entry (const unsigned int i)
210 {
211  AssertIndexRange(i, size());
212  type *p = boost::any_cast<type>(&data[i]);
213  Assert(p != nullptr,
214  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
215  return *p;
216 }
217 
218 
219 template <typename type>
220 inline
221 const type
222 AnyData::entry (const unsigned int i) const
223 {
224  AssertIndexRange(i, size());
225  const type *p = boost::any_cast<type>(&data[i]);
226  if (p==nullptr )
227  p = boost::any_cast<const type>(&data[i]);
228  Assert(p != nullptr,
229  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
230  return *p;
231 }
232 
233 
234 template <typename type>
235 inline
236 const type
237 AnyData::read(const unsigned int i) const
238 {
239  AssertIndexRange(i, size());
240  const type *p = boost::any_cast<type>(&data[i]);
241  if (p==nullptr)
242  p = boost::any_cast<const type>(&data[i]);
243  Assert(p != nullptr,
244  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
245  return *p;
246 }
247 
248 
249 template <typename type>
250 inline
251 const type *
252 AnyData::read_ptr(const unsigned int i) const
253 {
254  AssertIndexRange(i, size());
255  const type *const *p = boost::any_cast<type *>(&data[i]);
256  if (p==nullptr)
257  p = boost::any_cast<const type *>(&data[i]);
258  Assert(p != nullptr,
259  ExcTypeMismatch(typeid(type *).name(),data[i].type().name()));
260  return *p;
261 }
262 
263 
264 template <typename type>
265 inline
266 const type *
267 AnyData::try_read_ptr(const unsigned int i) const
268 {
269  AssertIndexRange(i, size());
270  const type *const *p = boost::any_cast<type *>(&data[i]);
271  if (p==nullptr)
272  p = boost::any_cast<const type *>(&data[i]);
273  if (p==nullptr)
274  return nullptr;
275  return *p;
276 }
277 
278 
279 template <typename type>
280 inline
281 const type *
282 AnyData::try_read(const unsigned int i) const
283 {
284  AssertIndexRange(i, size());
285  const type *p = boost::any_cast<type>(&data[i]);
286  if (p==0)
287  p = boost::any_cast<const type>(&data[i]);
288  return p;
289 }
290 
291 
292 inline
293 const std::string &
294 AnyData::name(const unsigned int i) const
295 {
296  AssertIndexRange(i, size());
297  return names[i];
298 }
299 
300 
301 inline
302 unsigned int
303 AnyData::try_find(const std::string &n) const
304 {
305  std::vector<std::string>::const_iterator it =
306  std::find(names.begin(), names.end(), n);
307 
308  if (it == names.end())
310 
311  return it - names.begin();
312 }
313 
314 
315 inline
316 unsigned int
317 AnyData::find(const std::string &n) const
318 {
319  const unsigned int i = try_find(n);
321 
322  return i;
323 }
324 
325 
326 template <typename type>
327 inline
328 bool
329 AnyData::is_type(const unsigned int i) const
330 {
331  return data[i].type() == typeid(type);
332 }
333 
334 
335 template <typename type>
336 inline
337 type
338 AnyData::entry (const std::string &n)
339 {
340  const unsigned int i = find(n);
341  type *p = boost::any_cast<type>(&data[i]);
342  Assert(p != 0,
343  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
344  return *p;
345 }
346 
347 
348 template <typename type>
349 inline
350 const type
351 AnyData::entry (const std::string &n) const
352 {
353  const unsigned int i = find(n);
354  const type *p = boost::any_cast<type>(&data[i]);
355  Assert(p != nullptr,
356  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
357  return *p;
358 }
359 
360 
361 template <typename type>
362 inline
363 const type
364 AnyData::read(const std::string &n) const
365 {
366  const unsigned int i = find(n);
367  const type *p = boost::any_cast<type>(&data[i]);
368  Assert(p != 0,
369  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
370  return *p;
371 }
372 
373 
374 template <typename type>
375 inline
376 const type *
377 AnyData::read_ptr(const std::string &n) const
378 {
379  const unsigned int i = find(n);
380  const type *const *p = boost::any_cast<type *>(&data[i]);
381  if (p==nullptr)
382  p = boost::any_cast<const type *>(&data[i]);
383  Assert(p != nullptr,
384  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
385  return *p;
386 }
387 
388 
389 template <typename type>
390 inline
391 const type *
392 AnyData::try_read_ptr(const std::string &n) const
393 {
394  const unsigned int i = try_find(n);
396  return 0;
397 
398  const type *const *p = boost::any_cast<type *>(&data[i]);
399  if (p==0)
400  p = boost::any_cast<const type *>(&data[i]);
401  return *p;
402 }
403 
404 
405 template <typename type>
406 inline
407 const type *
408 AnyData::try_read(const std::string &n) const
409 {
410  // Try to find name
411  std::vector<std::string>::const_iterator it =
412  std::find(names.begin(), names.end(), n);
413  // Return null pointer if not found
414  if (it == names.end())
415  return nullptr;
416 
417  // Compute index and return casted pointer
418  unsigned int i=it-names.begin();
419  const type *p = boost::any_cast<type>(&data[i]);
420  return p;
421 }
422 
423 
424 template <typename type>
425 inline
426 void
427 AnyData::add(type ent, const std::string &n)
428 {
429  boost::any e = ent;
430  data.push_back(e);
431  names.push_back(n);
432 }
433 
434 
435 inline
436 void
437 AnyData::merge(const AnyData &other)
438 {
439  for (unsigned int i=0; i<other.size(); ++i)
440  {
441  names.push_back(other.names[i]);
442  data.push_back(other.data[i]);
443  }
444 }
445 
446 
447 template <class StreamType>
448 inline
449 void AnyData::list(StreamType &os) const
450 {
451  for (unsigned int i=0; i<names.size(); ++i)
452  {
453  os << i
454  << '\t' << names[i]
455  << '\t' << data[i].type().name()
456  << std::endl;
457  }
458 }
459 
460 
461 //----------------------------------------------------------------------//
462 
463 
464 
465 DEAL_II_NAMESPACE_CLOSE
466 
467 #endif
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
Definition: any_data.h:329
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:338
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:358
void merge(const AnyData &other)
Merge the data of another AnyData to the end of this object.
Definition: any_data.h:437
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
const type read(const std::string &name) const
Dedicated read only access by name.
Definition: any_data.h:364
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:346
#define Assert(cond, exc)
Definition: exceptions.h:1142
const type * try_read_ptr(const std::string &name) const
Definition: any_data.h:392
static ::ExceptionBase & ExcTypeMismatch(char *arg1, char *arg2)
The requested type and the stored type are different.
std::vector< boost::any > data
The stored data.
Definition: any_data.h:191
const type * read_ptr(const std::string &name) const
Dedicated read only access by name for pointer data.
Definition: any_data.h:377
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition: any_data.h:408
unsigned int find(const std::string &name) const
Find index of a named object.
Definition: any_data.h:317
void add(type entry, const std::string &name)
Add a new data object.
Definition: any_data.h:427
unsigned int size() const
Number of stored data objects.
Definition: any_data.h:199
std::vector< std::string > names
The names of the stored data.
Definition: any_data.h:193
void list(StreamType &os) const
List the contents to a stream.
Definition: any_data.h:449
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition: any_data.h:303
static ::ExceptionBase & ExcNameMismatch(int arg1, std::string arg2)
const std::string & name(const unsigned int i) const
Name of object at index.
Definition: any_data.h:294