Loading [MathJax]/extensions/TeX/AMSsymbols.js
 deal.II version GIT relicensing-2684-gc61376a70f 2025-02-22 15:30:00+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\}}\)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 - 2024 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#include <deal.II/base/types.h>
23
24#include <algorithm>
25#include <any>
26#include <typeinfo>
27#include <vector>
28
30
37{
38public:
40 AnyData() = default;
41
43 unsigned int
44 size() const;
45
47 template <typename type>
48 void
49 add(type entry, const std::string &name);
50
54 void
55 merge(const AnyData &other);
56
65 template <typename type>
66 type
67 entry(const std::string &name);
68
77 template <typename type>
78 type
79 entry(const std::string &name) const;
80
92 template <typename type>
93 type
94 read(const std::string &name) const;
95
105 template <typename type>
106 const type *
107 read_ptr(const std::string &name) const;
108
113 template <typename type>
114 const type *
115 try_read_ptr(const std::string &name) const;
116
124 template <typename type>
125 const type *
126 try_read(const std::string &name) const;
127
131 template <typename type>
132 type
133 entry(const unsigned int i);
134
136 template <typename type>
137 type
138 entry(const unsigned int i) const;
139
141 template <typename type>
142 type
143 read(const unsigned int i) const;
144
146 template <typename type>
147 const type *
148 read_ptr(const unsigned int i) const;
149
151 template <typename type>
152 const type *
153 try_read_ptr(const unsigned int i) const;
154
156 template <typename type>
157 const type *
158 try_read(const unsigned int i) const;
159
161 const std::string &
162 name(const unsigned int i) const;
163
170 unsigned int
171 find(const std::string &name) const;
172
179 unsigned int
180 try_find(const std::string &name) const;
181
183 template <typename type>
184 bool
185 is_type(const unsigned int i) const;
186
188 template <typename StreamType>
189 void
190 list(StreamType &os) const;
191
194 std::string,
195 << "No entry with the name " << arg1 << " exists.");
196
199 std::string,
200 std::string,
201 << "The requested type " << arg1 << " and the stored type "
202 << arg2 << " must coincide.");
203
209 int,
210 std::string,
211 << "Name at position " << arg1 << " is not equal to " << arg2
212 << '.');
213
214private:
216 std::vector<std::any> data;
218 std::vector<std::string> names;
219};
220
221
222unsigned int inline AnyData::size() const
223{
224 AssertDimension(data.size(), names.size());
225 return data.size();
226}
227
228
229template <typename type>
230inline type
231AnyData::entry(const unsigned int i)
232{
234 const type *p = std::any_cast<type>(&data[i]);
235 Assert(p != nullptr,
236 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
237 return *p;
238}
239
240
241template <typename type>
242inline type
243AnyData::entry(const unsigned int i) const
244{
246 const type *p = std::any_cast<type>(&data[i]);
247 if (p == nullptr)
248 p = std::any_cast<const type>(&data[i]);
249 Assert(p != nullptr,
250 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
251 return *p;
252}
253
254
255template <typename type>
256inline type
257AnyData::read(const unsigned int i) const
258{
260 const type *p = std::any_cast<type>(&data[i]);
261 if (p == nullptr)
262 p = std::any_cast<const type>(&data[i]);
263 Assert(p != nullptr,
264 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
265 return *p;
266}
267
268
269template <typename type>
270inline const type *
271AnyData::read_ptr(const unsigned int i) const
272{
274 const type *const *p = std::any_cast<type *>(&data[i]);
275 if (p == nullptr)
276 p = std::any_cast<const type *>(&data[i]);
277 Assert(p != nullptr,
278 ExcTypeMismatch(typeid(type *).name(), data[i].type().name()));
279 return *p;
280}
281
282
283template <typename type>
284inline const type *
285AnyData::try_read_ptr(const unsigned int i) const
286{
288 const type *const *p = std::any_cast<type *>(&data[i]);
289 if (p == nullptr)
290 p = std::any_cast<const type *>(&data[i]);
291 if (p == nullptr)
292 return nullptr;
293 return *p;
294}
295
296
297template <typename type>
298inline const type *
299AnyData::try_read(const unsigned int i) const
300{
302 const type *p = std::any_cast<type>(&data[i]);
303 if (p == 0)
304 p = std::any_cast<const type>(&data[i]);
305 return p;
306}
307
308
309inline const std::string &
310AnyData::name(const unsigned int i) const
311{
313 return names[i];
314}
315
316
317inline unsigned int
318AnyData::try_find(const std::string &n) const
319{
320 std::vector<std::string>::const_iterator it =
321 std::find(names.begin(), names.end(), n);
322
323 if (it == names.end())
325
326 return it - names.begin();
327}
328
329
330inline unsigned int
331AnyData::find(const std::string &n) const
332{
333 const unsigned int i = try_find(n);
335
336 return i;
337}
338
339
340template <typename type>
341inline bool
342AnyData::is_type(const unsigned int i) const
343{
344 return data[i].type() == typeid(type);
345}
346
347
348template <typename type>
349inline type
350AnyData::entry(const std::string &n)
351{
352 const unsigned int i = find(n);
353 const type *p = std::any_cast<type>(&data[i]);
354 Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
355 return *p;
356}
357
358
359template <typename type>
360inline type
361AnyData::entry(const std::string &n) const
362{
363 const unsigned int i = find(n);
364 const type *p = std::any_cast<type>(&data[i]);
365 Assert(p != nullptr,
366 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
367 return *p;
368}
369
370
371template <typename type>
372inline type
373AnyData::read(const std::string &n) const
374{
375 const unsigned int i = find(n);
376 const type *p = std::any_cast<type>(&data[i]);
377 Assert(p != 0, ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
378 return *p;
379}
380
381
382template <typename type>
383inline const type *
384AnyData::read_ptr(const std::string &n) const
385{
386 const unsigned int i = find(n);
387 const type *const *p = std::any_cast<type *>(&data[i]);
388 if (p == nullptr)
389 p = std::any_cast<const type *>(&data[i]);
390 Assert(p != nullptr,
391 ExcTypeMismatch(typeid(type).name(), data[i].type().name()));
392 return *p;
393}
394
395
396template <typename type>
397inline const type *
398AnyData::try_read_ptr(const std::string &n) const
399{
400 const unsigned int i = try_find(n);
402 return 0;
403
404 const type *const *p = std::any_cast<type *>(&data[i]);
405 if (p == 0)
406 p = std::any_cast<const type *>(&data[i]);
407 return *p;
408}
409
410
411template <typename type>
412inline const type *
413AnyData::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 nullptr;
421
422 // Compute index and return casted pointer
423 unsigned int i = it - names.begin();
424 const type *p = std::any_cast<type>(&data[i]);
425 return p;
426}
427
428
429template <typename type>
430inline void
431AnyData::add(type ent, const std::string &n)
432{
433 std::any e = ent;
434 data.push_back(e);
435 names.push_back(n);
436}
437
438
439inline void
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
450template <typename StreamType>
451inline void
452AnyData::list(StreamType &os) const
453{
454 for (unsigned int i = 0; i < names.size(); ++i)
455 {
456 os << i << '\t' << names[i] << '\t' << data[i].type().name() << std::endl;
457 }
458}
459
460
461//----------------------------------------------------------------------//
462
463
464
466
467#endif
const std::string & name(const unsigned int i) const
Name of object at index.
Definition any_data.h:310
const type * try_read(const std::string &name) const
Dedicated read only access by name without exceptions.
Definition any_data.h:413
type entry(const std::string &name)
Access to stored data object by name.
Definition any_data.h:350
unsigned int try_find(const std::string &name) const
Try to find index of a named object.
Definition any_data.h:318
const type * read_ptr(const std::string &name) const
Dedicated read only access by name for pointer data.
Definition any_data.h:384
unsigned int find(const std::string &name) const
Find index of a named object.
Definition any_data.h:331
void add(type entry, const std::string &name)
Add a new data object.
Definition any_data.h:431
unsigned int size() const
Number of stored data objects.
Definition any_data.h:222
std::vector< std::any > data
The stored data.
Definition any_data.h:216
void list(StreamType &os) const
List the contents to a stream.
Definition any_data.h:452
bool is_type(const unsigned int i) const
Find out if object is of a certain type.
Definition any_data.h:342
void merge(const AnyData &other)
Merge the data of another AnyData to the end of this object.
Definition any_data.h:440
type read(const std::string &name) const
Dedicated read only access by name.
Definition any_data.h:373
const type * try_read_ptr(const std::string &name) const
Definition any_data.h:398
AnyData()=default
Default constructor for empty object.
std::vector< std::string > names
The names of the stored data.
Definition any_data.h:218
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:522
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:523
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)
#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)
constexpr unsigned int invalid_unsigned_int
Definition types.h:232