Reference documentation for deal.II version GIT relicensing-478-g3275795167 2024-04-24 07:10:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
any_data.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2014 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_any_data_h
16#define dealii_any_data_h
17
18#include <deal.II/base/config.h>
19
22
23#include <algorithm>
24#include <any>
25#include <typeinfo>
26#include <vector>
27
29
35class AnyData : public Subscriptor
36{
37public:
39 AnyData() = default;
40
42 unsigned int
43 size() const;
44
46 template <typename type>
47 void
48 add(type entry, const std::string &name);
49
53 void
54 merge(const AnyData &other);
55
64 template <typename type>
65 type
66 entry(const std::string &name);
67
76 template <typename type>
77 type
78 entry(const std::string &name) const;
79
91 template <typename type>
92 type
93 read(const std::string &name) const;
94
104 template <typename type>
105 const type *
106 read_ptr(const std::string &name) const;
107
112 template <typename type>
113 const type *
114 try_read_ptr(const std::string &name) const;
115
123 template <typename type>
124 const type *
125 try_read(const std::string &name) const;
126
130 template <typename type>
131 type
132 entry(const unsigned int i);
133
135 template <typename type>
136 type
137 entry(const unsigned int i) const;
138
140 template <typename type>
141 type
142 read(const unsigned int i) const;
143
145 template <typename type>
146 const type *
147 read_ptr(const unsigned int i) const;
148
150 template <typename type>
151 const type *
152 try_read_ptr(const unsigned int i) const;
153
155 template <typename type>
156 const type *
157 try_read(const unsigned int i) const;
158
160 const std::string &
161 name(const unsigned int i) const;
162
169 unsigned int
170 find(const std::string &name) const;
171
178 unsigned int
179 try_find(const std::string &name) const;
180
182 template <typename type>
183 bool
184 is_type(const unsigned int i) const;
185
187 template <typename StreamType>
188 void
189 list(StreamType &os) const;
190
193 std::string,
194 << "No entry with the name " << arg1 << " exists.");
195
198 std::string,
199 std::string,
200 << "The requested type " << arg1 << " and the stored type "
201 << arg2 << " must coincide.");
202
208 int,
209 std::string,
210 << "Name at position " << arg1 << " is not equal to " << arg2
211 << '.');
212
213private:
215 std::vector<std::any> data;
217 std::vector<std::string> names;
218};
219
220
221unsigned int inline AnyData::size() const
222{
223 AssertDimension(data.size(), names.size());
224 return data.size();
225}
226
227
228template <typename type>
229inline type
230AnyData::entry(const unsigned int i)
231{
233 type *p = std::any_cast<type>(&data[i]);
234 Assert(p != nullptr,
235 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
236 return *p;
237}
238
239
240template <typename type>
241inline type
242AnyData::entry(const unsigned int i) const
243{
245 const type *p = std::any_cast<type>(&data[i]);
246 if (p == nullptr)
247 p = std::any_cast<const type>(&data[i]);
248 Assert(p != nullptr,
249 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
250 return *p;
251}
252
253
254template <typename type>
255inline type
256AnyData::read(const unsigned int i) const
257{
259 const type *p = std::any_cast<type>(&data[i]);
260 if (p == nullptr)
261 p = std::any_cast<const type>(&data[i]);
262 Assert(p != nullptr,
263 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
264 return *p;
265}
266
267
268template <typename type>
269inline const type *
270AnyData::read_ptr(const unsigned int i) const
271{
273 const type *const *p = std::any_cast<type *>(&data[i]);
274 if (p == nullptr)
275 p = std::any_cast<const type *>(&data[i]);
276 Assert(p != nullptr,
277 ExcTypeMismatch(typeid(type *).name(), data[i].type().name()));
278 return *p;
279}
280
281
282template <typename type>
283inline const type *
284AnyData::try_read_ptr(const unsigned int i) const
285{
287 const type *const *p = std::any_cast<type *>(&data[i]);
288 if (p == nullptr)
289 p = std::any_cast<const type *>(&data[i]);
290 if (p == nullptr)
291 return nullptr;
292 return *p;
293}
294
295
296template <typename type>
297inline const type *
298AnyData::try_read(const unsigned int i) const
299{
301 const type *p = std::any_cast<type>(&data[i]);
302 if (p == 0)
303 p = std::any_cast<const type>(&data[i]);
304 return p;
305}
306
307
308inline const std::string &
309AnyData::name(const unsigned int i) const
310{
312 return names[i];
313}
314
315
316inline unsigned int
317AnyData::try_find(const std::string &n) const
318{
319 std::vector<std::string>::const_iterator it =
320 std::find(names.begin(), names.end(), n);
321
322 if (it == names.end())
324
325 return it - names.begin();
326}
327
328
329inline unsigned int
330AnyData::find(const std::string &n) const
331{
332 const unsigned int i = try_find(n);
334
335 return i;
336}
337
338
339template <typename type>
340inline bool
341AnyData::is_type(const unsigned int i) const
342{
343 return data[i].type() == typeid(type);
344}
345
346
347template <typename type>
348inline type
349AnyData::entry(const std::string &n)
350{
351 const unsigned int i = find(n);
352 type *p = std::any_cast<type>(&data[i]);
353 Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
354 return *p;
355}
356
357
358template <typename type>
359inline type
360AnyData::entry(const std::string &n) const
361{
362 const unsigned int i = find(n);
363 const type *p = std::any_cast<type>(&data[i]);
364 Assert(p != nullptr,
365 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
366 return *p;
367}
368
369
370template <typename type>
371inline type
372AnyData::read(const std::string &n) const
373{
374 const unsigned int i = find(n);
375 const type *p = std::any_cast<type>(&data[i]);
376 Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
377 return *p;
378}
379
380
381template <typename type>
382inline const type *
383AnyData::read_ptr(const std::string &n) const
384{
385 const unsigned int i = find(n);
386 const type *const *p = std::any_cast<type *>(&data[i]);
387 if (p == nullptr)
388 p = std::any_cast<const type *>(&data[i]);
389 Assert(p != nullptr,
390 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
391 return *p;
392}
393
394
395template <typename type>
396inline const type *
397AnyData::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 = std::any_cast<type *>(&data[i]);
404 if (p == 0)
405 p = std::any_cast<const type *>(&data[i]);
406 return *p;
407}
408
409
410template <typename type>
411inline const type *
412AnyData::try_read(const std::string &n) const
413{
414 // Try to find name
415 std::vector<std::string>::const_iterator it =
416 std::find(names.begin(), names.end(), n);
417 // Return null pointer if not found
418 if (it == names.end())
419 return nullptr;
420
421 // Compute index and return casted pointer
422 unsigned int i = it - names.begin();
423 const type *p = std::any_cast<type>(&data[i]);
424 return p;
425}
426
427
428template <typename type>
429inline void
430AnyData::add(type ent, const std::string &n)
431{
432 std::any e = ent;
433 data.push_back(e);
434 names.push_back(n);
435}
436
437
438inline void
440{
441 for (unsigned int i = 0; i < other.size(); ++i)
442 {
443 names.push_back(other.names[i]);
444 data.push_back(other.data[i]);
445 }
446}
447
448
449template <typename StreamType>
450inline void
451AnyData::list(StreamType &os) const
452{
453 for (unsigned int i = 0; i < names.size(); ++i)
454 {
455 os << i << '\t' << names[i] << '\t' << data[i].type().name() << std::endl;
456 }
457}
458
459
460//----------------------------------------------------------------------//
461
462
463
465
466#endif
const std::string & name(const unsigned int i) const
Name of object at index.
Definition any_data.h:309
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition any_data.h:412
type entry(const std::string &name)
Access to stored data object by name.
Definition any_data.h:349
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition any_data.h:317
const type * read_ptr(const std::string &name) const
Dedicated read only access by name for pointer data.
Definition any_data.h:383
unsigned int find(const std::string &name) const
Find index of a named object.
Definition any_data.h:330
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:221
std::vector< std::any > data
The stored data.
Definition any_data.h:215
void list(StreamType &os) const
List the contents to a stream.
Definition any_data.h:451
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
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:439
type read(const std::string &name) const
Dedicated read only access by name.
Definition any_data.h:372
const type * try_read_ptr(const std::string &name) const
Definition any_data.h:397
AnyData()=default
Default constructor for empty object.
std::vector< std::string > names
The names of the stored data.
Definition any_data.h:217
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
static ::ExceptionBase & ExcNameMismatch(int arg1, std::string arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcNameNotFound(std::string arg1)
An entry with this name does not exist in the AnyData object.
#define DeclException2(Exception2, type1, type2, outsequence)
Definition exceptions.h:539
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcTypeMismatch(std::string arg1, std::string arg2)
The requested type and the stored type are different.
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:516
static const unsigned int invalid_unsigned_int
Definition types.h:220