MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
arrays_by_name.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_ARRAYS_BY_NAME
13#define MFEM_ARRAYS_BY_NAME
14
15#include "../config/config.hpp"
16#include "array.hpp"
17#include "text.hpp"
18
19#include <iostream>
20#include <map>
21#include <set>
22#include <string>
23
24namespace mfem
25{
26
27/**
28 Container class for storing arrays indexed by strings.
29
30 The Array<T> objects stored within this container must all be based on the
31 same underlying generic type T, which must be a trivial type, see
32 `std::is_trivial`.
33
34 In order to provide some level of protection against typos this class will
35 not create new named arrays when access to unrecognized names is requested.
36 New named arrays must be explicitly created using `CreateArray()`. To
37 facilitate this behavior and avoid such errors the method `EntryExists()` is
38 provided.
39
40 This container does not store pointers to pre-existing arrays. It will copy
41 or move entries as appropriate from existing Array<T> objects into new
42 Array<T> objects stored within this container.
43*/
44template <class T>
46{
47protected:
48 /// Reusing STL map iterators
49 using container = std::map<std::string,Array<T> >;
50 using iterator = typename container::iterator;
51 using const_iterator = typename container::const_iterator;
52
53 /// Map containing the data sorted alphabetically by name
55
56public:
57
58 /// Default constructor
59 ArraysByName() = default;
60
61 /// Copy constructor: deep copy from @a src
62 ArraysByName(const ArraysByName &src) = default;
63
64 /// Move constructor
65 ArraysByName(ArraysByName &&src) noexcept = default;
66
67 /// Return the number of named arrays in the container
68 int Size() const { return static_cast<int>(data.size()); }
69
70 /// Return an STL set of strings giving the names of the arrays
71 inline std::set<std::string> GetNames() const;
72
73 /// @brief Return true if an array with the given name is present in the
74 /// container
75 inline bool EntryExists(const std::string &name) const;
76
77 /// @brief Reference access to the named entry.
78 ///
79 /// @note Passing a name for a nonexistent array will print an error
80 /// message and halt execution. This is intended to call attention to
81 /// possible typos or other errors. To handle such errors more gracefully
82 /// consider first calling EntryExists.
83 inline Array<T> &operator[](const std::string &name);
84
85 /// @brief Const reference access to the named entry.
86 ///
87 /// @note Passing a name for a nonexistent array will print an error
88 /// message and halt execution. This is intended to call attention to
89 /// possible typos or other errors. To handle such errors more gracefully
90 /// consider first calling EntryExists.
91 inline const Array<T> &operator[](const std::string &name) const;
92
93 /// @brief Create a new empty array with the given name
94 ///
95 /// @note Passing a name for an already existent array will print an error
96 /// message and halt execution. This is intended to call attention to
97 /// possible typos or other errors. To handle such errors more gracefully
98 /// consider first calling EntryExists.
99 inline Array<T> &CreateArray(const std::string &name);
100
101 /// Delete all named arrays from the container
102 inline void DeleteAll();
103
104 /// @brief Delete the named array from the container
105 ///
106 /// @note Passing a name for a nonexistent array will print an error
107 /// message and halt execution. This is intended to call attention to
108 /// possible typos or other errors. To handle such errors more gracefully
109 /// consider first calling EntryExists.
110 inline void DeleteArray(const std::string &name);
111
112 /// Copy assignment operator: deep copy from 'src'.
114
115 /// Move assignment operator
116 ArraysByName<T> &operator=(ArraysByName<T> &&src) noexcept = default;
117
118 /// @brief Print the contents of the container to an output stream
119 ///
120 /// @note Each array will be printed on at least three lines; the name on
121 /// one line, the length of the associated array, lastly the array contents
122 /// with @a width entries per line. A specific number of entries per line
123 /// can be used by changing the @a width argument.
124 inline void Print(std::ostream &out = mfem::out, int width = -1) const;
125
126 /// @brief Load the contents of the container from an input stream
127 ///
128 /// @note This method will not first empty the container. First call
129 /// DeleteAll if this behavior is needed.
130 void Load(std::istream &in);
131
132 /// Sort each named array in the container
133 inline void SortAll();
134
135 /// @brief Remove duplicates from each, previously sorted, named array
136 ///
137 /// @note Identical entries may exist in multiple arrays but will only occur
138 /// at most once in each array.
139 inline void UniqueAll();
140
141 /// STL-like begin. Returns pointer to the first entry of the container.
142 iterator begin() { return data.begin(); }
143
144 /// STL-like end. Returns pointer after the last entry of the container.
145 iterator end() { return data.end(); }
146
147 /// @brief STL-like begin. Returns const pointer to the first entry of the
148 /// container.
149 const_iterator begin() const { return data.cbegin(); }
150
151 /// @brief STL-like end. Returns const pointer after the last entry of the
152 /// container.
153 const_iterator end() const { return data.cend(); }
154};
155
156template <class T>
157inline bool operator==(const ArraysByName<T> &LHS, const ArraysByName<T> &RHS)
158{
159 if ( LHS.Size() != RHS.Size() ) { return false; }
160 for (auto it1 = LHS.begin(), it2 = RHS.begin();
161 it1 != LHS.end() && it2 != RHS.end(); it1++, it2++)
162 {
163 if (it1->first != it2->first) { return false; }
164 if (it1->second != it2->second) { return false; }
165 }
166 return true;
167}
168
169template<class T>
170inline std::set<std::string> ArraysByName<T>::GetNames() const
171{
172 std::set<std::string> names;
173 for (auto const &entry : data)
174 {
175 names.insert(entry.first);
176 }
177 return names;
178}
179
180template<class T>
181inline bool ArraysByName<T>::EntryExists(const std::string &name) const
182{
183 return data.find(name) != data.end();
184}
185
186template<class T>
187inline Array<T> &ArraysByName<T>::operator[](const std::string &name)
188{
189 MFEM_VERIFY( data.find(name) != data.end(),
190 "Access to unknown named array \"" << name << "\"");
191 return data[name];
192}
193
194template<class T>
195inline const Array<T> &ArraysByName<T>::operator[](const std::string &name)
196const
197{
198 MFEM_VERIFY( data.find(name) != data.end(),
199 "Access to unknown named array \"" << name << "\"");
200 return data.at(name);
201}
202
203template<class T>
204inline Array<T> &ArraysByName<T>::CreateArray(const std::string &name)
205{
206 MFEM_VERIFY( data.find(name) == data.end(),
207 "Named array \"" << name << "\" already exists");
208 Array<T> empty_array;
209 data.insert(std::pair<std::string,Array<T> >(name,empty_array));
210 return data[name];
211}
212
213template<class T>
215{
216 data.clear();
217}
218
219template<class T>
220inline void ArraysByName<T>::DeleteArray(const std::string &name)
221{
222 MFEM_VERIFY( data.find(name) != data.end(),
223 "Attempting to delete unknown named array \"" << name << "\"");
224 data.erase(name);
225}
226
227template <class T>
229{
230 for (auto &a : data)
231 {
232 a.second.Sort();
233 }
234}
235
236template <class T>
238{
239 for (auto &a : data)
240 {
241 a.second.Unique();
242 }
243}
244
245template <class T>
246inline void ArraysByName<T>::Print(std::ostream &os, int width) const
247{
248 os << data.size() << '\n';
249 for (auto const &it : data)
250 {
251 // Note: The method Load() can read any string formatted with std::quoted.
252 os << std::quoted(it.first) << '\n' << it.second.Size() << '\n';
253 it.second.Print(os, width > 0 ? width : it.second.Size());
254 }
255}
256
257template <class T>
258void ArraysByName<T>::Load(std::istream &in)
259{
260 int NumArrays;
261 in >> NumArrays;
262
263 for (int i = 0; i < NumArrays; i++)
264 {
265 in >> std::ws;
266 // Read the name:
267 // - If the stream 'in' starts with " then parse it with the function
268 // parse_quoted_string() from text.hpp. In this case, the name can be
269 // empty. Note: this case allows for reading any string formatted using
270 // std::quoted, e.g. as in the method Print().
271 // - If the name does not start with " then the name ends with the first
272 // white space character (and the white space character is not included
273 // in the name). Since white space characters are skipped before reading
274 // the name, there will be at least one non-white-space character in the
275 // name in this case.
276 std::string ArrayName;
277 if (in.peek() == '"')
278 {
279 if (parse_quoted_string(ArrayName, in) != 0)
280 {
281 MFEM_ABORT("error parsing input!");
282 }
283 }
284 else
285 {
286 in >> ArrayName;
287 MFEM_VERIFY(in.good(), "error parsing input!");
288 }
289
290 // Read the array
291 data[ArrayName].Load(in);
292 }
293}
294
295}
296
297#endif
void Print(std::ostream &out=mfem::out, int width=-1) const
Print the contents of the container to an output stream.
void SortAll()
Sort each named array in the container.
ArraysByName()=default
Default constructor.
iterator end()
STL-like end. Returns pointer after the last entry of the container.
ArraysByName(ArraysByName &&src) noexcept=default
Move constructor.
Array< T > & operator[](const std::string &name)
Reference access to the named entry.
void UniqueAll()
Remove duplicates from each, previously sorted, named array.
const Array< T > & operator[](const std::string &name) const
Const reference access to the named entry.
typename container::const_iterator const_iterator
ArraysByName< T > & operator=(ArraysByName< T > &&src) noexcept=default
Move assignment operator.
std::set< std::string > GetNames() const
Return an STL set of strings giving the names of the arrays.
iterator begin()
STL-like begin. Returns pointer to the first entry of the container.
container data
Map containing the data sorted alphabetically by name.
ArraysByName(const ArraysByName &src)=default
Copy constructor: deep copy from src.
void DeleteAll()
Delete all named arrays from the container.
std::map< std::string, Array< T > > container
Reusing STL map iterators.
void DeleteArray(const std::string &name)
Delete the named array from the container.
int Size() const
Return the number of named arrays in the container.
bool EntryExists(const std::string &name) const
Return true if an array with the given name is present in the container.
const_iterator end() const
STL-like end. Returns const pointer after the last entry of the container.
typename container::iterator iterator
void Load(std::istream &in)
Load the contents of the container from an input stream.
const_iterator begin() const
STL-like begin. Returns const pointer to the first entry of the container.
ArraysByName< T > & operator=(const ArraysByName< T > &src)=default
Copy assignment operator: deep copy from 'src'.
Array< T > & CreateArray(const std::string &name)
Create a new empty array with the given name.
real_t a
Definition lissajous.cpp:41
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
int parse_quoted_string(std::string &result, std::istream &in, char delim='"', char escape = '\\')
Read a string formatted using std::quoted. Return nonzero on error.
Definition text.hpp:71
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition array.hpp:435