Reference documentation for deal.II version 8.4.2
any_data.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2015 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 
177  DeclException2(ExcTypeMismatch,
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  return *p;
279 }
280 
281 
282 template <typename type>
283 inline
284 const type *
285 AnyData::try_read(const unsigned int i) const
286 {
287  AssertIndexRange(i, size());
288  const type *p = boost::any_cast<type>(&data[i]);
289  if (p==0)
290  p = boost::any_cast<const type>(&data[i]);
291  return p;
292 }
293 
294 
295 inline
296 const std::string &
297 AnyData::name(const unsigned int i) const
298 {
299  AssertIndexRange(i, size());
300  return names[i];
301 }
302 
303 
304 inline
305 unsigned int
306 AnyData::try_find(const std::string &n) const
307 {
308  std::vector<std::string>::const_iterator it =
309  std::find(names.begin(), names.end(), n);
310 
311  if (it == names.end())
313 
314  return it - names.begin();
315 }
316 
317 
318 inline
319 unsigned int
320 AnyData::find(const std::string &n) const
321 {
322  const unsigned int i = try_find(n);
323  Assert(i != numbers::invalid_unsigned_int, ExcNameNotFound(n));
324 
325  return i;
326 }
327 
328 
329 template <typename type>
330 inline
331 bool
332 AnyData::is_type(const unsigned int i) const
333 {
334  return data[i].type() == typeid(type);
335 }
336 
337 
338 template <typename type>
339 inline
340 type
341 AnyData::entry (const std::string &n)
342 {
343  const unsigned int i = find(n);
344  type *p = boost::any_cast<type>(&data[i]);
345  Assert(p != 0,
346  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
347  return *p;
348 }
349 
350 
351 template <typename type>
352 inline
353 const type
354 AnyData::entry (const std::string &n) const
355 {
356  const unsigned int i = find(n);
357  const type *p = boost::any_cast<type>(&data[i]);
358  Assert(p != 0,
359  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
360  return *p;
361 }
362 
363 
364 template <typename type>
365 inline
366 const type
367 AnyData::read(const std::string &n) const
368 {
369  const unsigned int i = find(n);
370  const type *p = boost::any_cast<type>(&data[i]);
371  Assert(p != 0,
372  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
373  return *p;
374 }
375 
376 
377 template <typename type>
378 inline
379 const type *
380 AnyData::read_ptr(const std::string &n) const
381 {
382  const unsigned int i = find(n);
383  const type *const *p = boost::any_cast<type *>(&data[i]);
384  if (p==0)
385  p = boost::any_cast<const type *>(&data[i]);
386  Assert(p != 0,
387  ExcTypeMismatch(typeid(type).name(),data[i].type().name()));
388  return *p;
389 }
390 
391 
392 template <typename type>
393 inline
394 const type *
395 AnyData::try_read_ptr(const std::string &n) const
396 {
397  const unsigned int i = try_find(n);
399  return 0;
400 
401  const type *const *p = boost::any_cast<type *>(&data[i]);
402  if (p==0)
403  p = boost::any_cast<const type *>(&data[i]);
404  return *p;
405 }
406 
407 
408 template <typename type>
409 inline
410 const type *
411 AnyData::try_read(const std::string &n) const
412 {
413  // Try to find name
414  std::vector<std::string>::const_iterator it =
415  std::find(names.begin(), names.end(), n);
416  // Return null pointer if not found
417  if (it == names.end())
418  return 0;
419 
420  // Compute index and return casted pointer
421  unsigned int i=it-names.begin();
422  const type *p = boost::any_cast<type>(&data[i]);
423  return p;
424 }
425 
426 
427 template <typename type>
428 inline
429 void
430 AnyData::add(type ent, const std::string &n)
431 {
432  boost::any e = ent;
433  data.push_back(e);
434  names.push_back(n);
435 }
436 
437 
438 inline
439 void
440 AnyData::merge(const AnyData &other)
441 {
442  for (unsigned int i=0; i<other.size(); ++i)
443  {
444  names.push_back(other.names[i]);
445  data.push_back(other.data[i]);
446  }
447 }
448 
449 
450 template <class StreamType>
451 inline
452 void AnyData::list(StreamType &os) const
453 {
454  for (unsigned int i=0; i<names.size(); ++i)
455  {
456  os << i
457  << '\t' << names[i]
458  << '\t' << data[i].type().name()
459  << std::endl;
460  }
461 }
462 
463 
464 //----------------------------------------------------------------------//
465 
466 
467 
468 DEAL_II_NAMESPACE_CLOSE
469 
470 #endif
471 
472 
473 
474 
475 
476 
477 
478 
479 
480 
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
Definition: any_data.h:332
static const unsigned int invalid_unsigned_int
Definition: types.h:164
type entry(const std::string &name)
Access to stored data object by name.
Definition: any_data.h:341
void merge(const AnyData &other)
Merge the data of another AnyData to the end of this object.
Definition: any_data.h:440
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
const type read(const std::string &name) const
Dedicated read only access by name.
Definition: any_data.h:367
AnyData()
Default constructor for empty object.
Definition: any_data.h:198
#define AssertIndexRange(index, range)
Definition: exceptions.h:1081
#define Assert(cond, exc)
Definition: exceptions.h:294
const type * try_read_ptr(const std::string &name) const
Definition: any_data.h:395
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:380
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition: any_data.h:411
unsigned int find(const std::string &name) const
Find index of a named object.
Definition: any_data.h:320
DeclException1(ExcNameNotFound, std::string,<< "No entry with the name "<< arg1<< " exists.")
An entry with this name does not exist in the AnyData object.
void add(type entry, const std::string &name)
Add a new data object.
Definition: any_data.h:430
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:452
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition: any_data.h:306
DeclException2(ExcTypeMismatch, char *, char *,<< "The requested type "<< arg1<< " and the stored type "<< arg2<< " must coincide")
The requested type and the stored type are different.
const std::string & name(const unsigned int i) const
Name of object at index.
Definition: any_data.h:297