Reference documentation for deal.II version 8.5.1
any_data.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2016 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();
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 inline
199 {}
200 
201 
202 unsigned int
203 inline
205 {
206  AssertDimension(data.size(), names.size());
207  return data.size();
208 }
209 
210 
211 template <typename type>
212 inline
213 type
214 AnyData::entry (const unsigned int i)
215 {
216  AssertIndexRange(i, size());
217  type *p = boost::any_cast<type>(&data[i]);
218  Assert(p != 0,
219  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
220  return *p;
221 }
222 
223 
224 template <typename type>
225 inline
226 const type
227 AnyData::entry (const unsigned int i) const
228 {
229  AssertIndexRange(i, size());
230  const type *p = boost::any_cast<type>(&data[i]);
231  if (p==0 )
232  p = boost::any_cast<const type>(&data[i]);
233  Assert(p != 0,
234  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
235  return *p;
236 }
237 
238 
239 template <typename type>
240 inline
241 const type
242 AnyData::read(const unsigned int i) const
243 {
244  AssertIndexRange(i, size());
245  const type *p = boost::any_cast<type>(&data[i]);
246  if (p==0)
247  p = boost::any_cast<const type>(&data[i]);
248  Assert(p != 0,
249  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
250  return *p;
251 }
252 
253 
254 template <typename type>
255 inline
256 const type *
257 AnyData::read_ptr(const unsigned int i) const
258 {
259  AssertIndexRange(i, size());
260  const type *const *p = boost::any_cast<type *>(&data[i]);
261  if (p==0)
262  p = boost::any_cast<const type *>(&data[i]);
263  Assert(p != 0,
264  ExcTypeMismatch(typeid(type *).name(),data[i].type().name()));
265  return *p;
266 }
267 
268 
269 template <typename type>
270 inline
271 const type *
272 AnyData::try_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==0)
277  p = boost::any_cast<const type *>(&data[i]);
278  if (p==0)
279  return 0;
280  return *p;
281 }
282 
283 
284 template <typename type>
285 inline
286 const type *
287 AnyData::try_read(const unsigned int i) const
288 {
289  AssertIndexRange(i, size());
290  const type *p = boost::any_cast<type>(&data[i]);
291  if (p==0)
292  p = boost::any_cast<const type>(&data[i]);
293  return p;
294 }
295 
296 
297 inline
298 const std::string &
299 AnyData::name(const unsigned int i) const
300 {
301  AssertIndexRange(i, size());
302  return names[i];
303 }
304 
305 
306 inline
307 unsigned int
308 AnyData::try_find(const std::string &n) const
309 {
310  std::vector<std::string>::const_iterator it =
311  std::find(names.begin(), names.end(), n);
312 
313  if (it == names.end())
315 
316  return it - names.begin();
317 }
318 
319 
320 inline
321 unsigned int
322 AnyData::find(const std::string &n) const
323 {
324  const unsigned int i = try_find(n);
326 
327  return i;
328 }
329 
330 
331 template <typename type>
332 inline
333 bool
334 AnyData::is_type(const unsigned int i) const
335 {
336  return data[i].type() == typeid(type);
337 }
338 
339 
340 template <typename type>
341 inline
342 type
343 AnyData::entry (const std::string &n)
344 {
345  const unsigned int i = find(n);
346  type *p = boost::any_cast<type>(&data[i]);
347  Assert(p != 0,
348  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
349  return *p;
350 }
351 
352 
353 template <typename type>
354 inline
355 const type
356 AnyData::entry (const std::string &n) const
357 {
358  const unsigned int i = find(n);
359  const type *p = boost::any_cast<type>(&data[i]);
360  Assert(p != 0,
361  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
362  return *p;
363 }
364 
365 
366 template <typename type>
367 inline
368 const type
369 AnyData::read(const std::string &n) const
370 {
371  const unsigned int i = find(n);
372  const type *p = boost::any_cast<type>(&data[i]);
373  Assert(p != 0,
374  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
375  return *p;
376 }
377 
378 
379 template <typename type>
380 inline
381 const type *
382 AnyData::read_ptr(const std::string &n) const
383 {
384  const unsigned int i = find(n);
385  const type *const *p = boost::any_cast<type *>(&data[i]);
386  if (p==0)
387  p = boost::any_cast<const type *>(&data[i]);
388  Assert(p != 0,
389  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
390  return *p;
391 }
392 
393 
394 template <typename type>
395 inline
396 const type *
397 AnyData::try_read_ptr(const std::string &n) const
398 {
399  const unsigned int i = try_find(n);
401  return 0;
402 
403  const type *const *p = boost::any_cast<type *>(&data[i]);
404  if (p==0)
405  p = boost::any_cast<const type *>(&data[i]);
406  return *p;
407 }
408 
409 
410 template <typename type>
411 inline
412 const type *
413 AnyData::try_read(const std::string &n) const
414 {
415  // Try to find name
416  std::vector<std::string>::const_iterator it =
417  std::find(names.begin(), names.end(), n);
418  // Return null pointer if not found
419  if (it == names.end())
420  return 0;
421 
422  // Compute index and return casted pointer
423  unsigned int i=it-names.begin();
424  const type *p = boost::any_cast<type>(&data[i]);
425  return p;
426 }
427 
428 
429 template <typename type>
430 inline
431 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
441 void
442 AnyData::merge(const AnyData &other)
443 {
444  for (unsigned int i=0; i<other.size(); ++i)
445  {
446  names.push_back(other.names[i]);
447  data.push_back(other.data[i]);
448  }
449 }
450 
451 
452 template <class StreamType>
453 inline
454 void AnyData::list(StreamType &os) const
455 {
456  for (unsigned int i=0; i<names.size(); ++i)
457  {
458  os << i
459  << '\t' << names[i]
460  << '\t' << data[i].type().name()
461  << std::endl;
462  }
463 }
464 
465 
466 //----------------------------------------------------------------------//
467 
468 
469 
470 DEAL_II_NAMESPACE_CLOSE
471 
472 #endif
473 
474 
475 
476 
477 
478 
479 
480 
481 
482 
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
Definition: any_data.h:334
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:170
type entry(const std::string &name)
Access to stored data object by name.
Definition: any_data.h:343
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:576
void merge(const AnyData &other)
Merge the data of another AnyData to the end of this object.
Definition: any_data.h:442
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
const type read(const std::string &name) const
Dedicated read only access by name.
Definition: any_data.h:369
AnyData()
Default constructor for empty object.
Definition: any_data.h:198
#define AssertIndexRange(index, range)
Definition: exceptions.h:1170
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:564
#define Assert(cond, exc)
Definition: exceptions.h:313
const type * try_read_ptr(const std::string &name) const
Definition: any_data.h:397
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:382
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition: any_data.h:413
unsigned int find(const std::string &name) const
Find index of a named object.
Definition: any_data.h:322
void add(type entry, const std::string &name)
Add a new data object.
Definition: any_data.h:432
unsigned int size() const
Number of stored data objects.
Definition: any_data.h:204
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:454
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition: any_data.h:308
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:299