libMesh
Loading...
Searching...
No Matches
utility.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19#ifndef LIBMESH_UTILITY_H
20#define LIBMESH_UTILITY_H
21
22// LibMesh includes
23#include "libmesh/libmesh_common.h" // for Real
24
25// C++ includes
26#include <string>
27#include <vector>
28#include <algorithm> // is_sorted, lower_bound
29#include <memory> // unique_ptr
30
31namespace libMesh
32{
33
39#define libmesh_map_find(map, key) libMesh::Utility::map_find((map), (key), __FILE__, __LINE__)
40
46#define libmesh_vector_at(vec, idx) libMesh::Utility::vector_at((vec), (idx), __FILE__, __LINE__)
47
48// ------------------------------------------------------------
49// The Utility namespace is for functions
50// which are useful but don't necessarily belong anywhere else.
51
52namespace Utility
53{
54
59std::string system_info();
60
64template <typename T>
66{
67 template <typename U> // must be template to get SFINAE fall-through...
68 static auto test(const U* u) -> decltype(std::cout << *u);
69
70 static auto test(...) -> std::false_type;
71
72public:
73 enum { value = !std::is_same<decltype(test((T*)0)), std::false_type>::value };
74};
75
85#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
86#if (__GNUC__ > 12)
87#pragma GCC diagnostic push
88#pragma GCC diagnostic ignored "-Wdangling-reference"
89#endif
90#endif
91
101template<typename Map, typename Key,
102 typename std::enable_if<!is_streamable<Key>::value, Key>::type* = nullptr>
103inline
104typename Map::mapped_type &
105map_find(Map & map,
106 const Key & key,
107 const char * filename,
108 int line_number)
109{
110 auto it = map.find(key);
111 libmesh_error_msg_if(it == map.end(),
112 "map_find() error: key not found in file "
113 << filename << " on line " << line_number);
114 return it->second;
115}
116
120template<typename Map, typename Key,
121 typename std::enable_if<!is_streamable<Key>::value, Key>::type* = nullptr>
122inline
123const typename Map::mapped_type &
124map_find(const Map & map,
125 const Key & key,
126 const char * filename,
127 int line_number)
128{
129 auto it = map.find(key);
130 libmesh_error_msg_if(it == map.end(),
131 "map_find() error: key not found in file "
132 << filename << " on line " << line_number);
133 return it->second;
134}
135
140template<typename Map, typename Key,
141 typename std::enable_if<is_streamable<Key>::value, Key>::type* = nullptr>
142inline
143typename Map::mapped_type &
144map_find(Map & map,
145 const Key & key,
146 const char * filename,
147 int line_number)
148{
149 auto it = map.find(key);
150 libmesh_error_msg_if(it == map.end(),
151 "map_find() error: key \"" << key << "\" not found in file "
152 << filename << " on line " << line_number);
153 return it->second;
154}
155
159template<typename Map, typename Key,
160 typename std::enable_if<is_streamable<Key>::value, Key>::type* = nullptr>
161inline
162const typename Map::mapped_type &
163map_find(const Map & map,
164 const Key & key,
165 const char * filename,
166 int line_number)
167{
168 auto it = map.find(key);
169 libmesh_error_msg_if(it == map.end(),
170 "map_find() error: key \"" << key << "\" not found in file "
171 << filename << " on line " << line_number);
172 return it->second;
173}
174
175// The map_find functions are our only dangling-reference false positives
176
177#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
178#if (__GNUC__ > 12)
179#pragma GCC diagnostic pop
180#endif
181#endif
182
183
189template<typename Vector>
190inline
191typename Vector::reference &
192vector_at(Vector & vec,
193 typename Vector::size_type i,
194 const char * filename,
195 int line_number)
196{
197 libmesh_error_msg_if(i >= vec.size(),
198 "vec_at() error: Index " << i <<
199 " past end of vector in file " << filename <<
200 " on line " << line_number);
201 return vec[i];
202}
203
207template<typename Vector>
208inline
209typename Vector::const_reference &
210vector_at(const Vector & vec,
211 typename Vector::size_type i,
212 const char * filename,
213 int line_number)
214{
215 libmesh_error_msg_if(i >= vec.size(),
216 "vec_at() error: Index " << i <<
217 " past end of vector in file " << filename <<
218 " on line " << line_number);
219 return vec[i];
220}
221
222
232template<class ForwardIterator, class T>
233ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value)
234{
235 ForwardIterator it = std::lower_bound(first, last, value);
236 return (it == last || value < *it) ? last : it;
237}
238
242template<class ForwardIterator, class T, class Compare>
243ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T & value, Compare comp)
244{
245 ForwardIterator it = std::lower_bound(first, last, value, comp);
246 return (it == last || comp(value,*it)) ? last : it;
247}
248
249
254template <int N, typename T>
255struct do_pow {
256 static inline T apply (const T & x)
257 {
258 libmesh_assert(N>1);
259
260 if (N%2) // odd exponent
261 return x * do_pow<N-1,T>::apply(x);
262
263 const T xNover2 = do_pow<N/2,T>::apply(x);
264
265 return xNover2*xNover2;
266 }
267};
268
269// An efficient compiler would distill N=6 down to 3
270// multiplications, but an inefficient one (or a complicated
271// T::operator*) might do worse, so we'll specialize here.
272template <typename T>
273struct do_pow<6,T> {
274 static inline T apply (const T & x)
275 {
276 const T x2 = x*x,
277 x4 = x2*x2;
278
279 return x4*x2;
280 }
281};
282
283template <typename T>
284struct do_pow<1,T> {
285 static inline T apply (const T & x) { return x; }
286};
287
288template <typename T>
289struct do_pow<0,T> {
290 static inline T apply (const T &) { return 1; }
291};
292
293
294template <int N, typename T>
295inline
296T pow(const T & x)
297{
298 return do_pow<N,T>::apply(x);
299}
300
304inline
305unsigned int factorial(unsigned int n)
306{
307
308 unsigned int factorial_n = 1;
309
310 if (n==0)
311 return factorial_n;
312
313 for (unsigned int i=1; i<n; i++)
314 factorial_n *= i+1;
315
316 return factorial_n;
317}
318
319
320// Simple function to compute "n choose k", aka the binomial coefficient.
321template <typename T>
322T binomial(T n, T k)
323{
324 T ret = 1;
325
326 // Binomial function is "symmetric" in k, C(n, k) = C(n, n-k).
327 if (k > n - k)
328 k = n - k;
329
330 // Compute n * (n-1) * ... * (n-k+1) / (k * (k-1) * ... * 1)
331 for (T i = 0; i < k; ++i)
332 {
333 ret *= (n - i);
334 ret /= (i + 1);
335 }
336
337 return ret;
338}
339
340
344template <typename T>
345void deallocate (std::vector<T> & vec)
346{
347 std::vector<T>().swap(vec);
348}
349
350
351// When looking for a complicated suffix to a filename, we only want
352// to consider the base name, without any preceding path name.
353// "/tmp/foo.e25ad0/mesh.msh" is not ExodusII.
354std::string_view basename_of(const std::string & fullname);
355
356
360bool contains(std::string_view superstring,
361 std::string_view substring);
362
363
367bool ends_with(std::string_view superstring,
368 std::string_view suffix);
369
370
371// Utility functions useful when dealing with complex numbers.
372
373#ifdef LIBMESH_USE_COMPLEX_NUMBERS
374
380std::string complex_filename (std::string basename,
381 unsigned int r_o_c=0);
382
386void prepare_complex_data (const std::vector<Complex> & source,
387 std::vector<Real> & real_part,
388 std::vector<Real> & imag_part);
389
390#endif // #ifdef LIBMESH_USE_COMPLEX_NUMBERS
391
392
396int mkdir(const char* pathname);
397
398
406std::string unzip_file (std::string_view name);
407
408
418{
419public:
420
425 explicit
426 ReverseBytes (const bool dr);
427
432 template <typename T>
433 T operator () (T & data) const;
434
435private:
436
440 bool reverse () const { return _do_reverse; }
441
445 const bool _do_reverse;
446};
447
448
449
450// ReverseBytes inline members
451inline
453 _do_reverse (rb)
454{}
455
456
457template <typename T>
458inline
460{
461 // Possibly reverse the byte ordering
462 if (this->reverse())
463 {
464 unsigned char * b = (unsigned char *) &data;
465
466 int i=0;
467 int j=(sizeof(T) - 1);
468
469 while (i < j)
470 {
471 std::swap (b[i], b[j]);
472 i++; j--;
473 }
474 }
475
476 return data;
477}
478
479
480
486{
492 using is_transparent = void;
493
498 template <class T>
499 bool operator()(const std::unique_ptr<T> & a, const std::unique_ptr<T> & b) const
500 {
501 return a.get() < b.get();
502 }
503
507 template <class T>
508 bool operator()(const std::unique_ptr<T> & a, const T * const & b) const
509 {
510 return a.get() < b;
511 }
512
516 template <class T>
517 bool operator()(const T * const & a, const std::unique_ptr<T> & b) const
518 {
519 return a < b.get();
520 }
521};
522
523} // namespace Utility
524
525} // namespace libMesh
526
527#endif // LIBMESH_UTILITY_H
This Functor simply takes an object and reverses its byte representation.
Definition utility.h:418
T operator()(T &data) const
Functor.
Definition utility.h:459
ReverseBytes(const bool dr)
Constructor.
Definition utility.h:452
Helper struct for enabling template metaprogramming/SFINAE.
Definition utility.h:66
static auto test(const U *u) -> decltype(std::cout<< *u)
static auto test(...) -> std::false_type
static const Real b
T binomial(T n, T k)
Definition utility.h:322
T pow(const T &x)
Definition utility.h:296
unsigned int factorial(unsigned int n)
A simple implementation of the factorial.
Definition utility.h:305
int mkdir(const char *pathname)
Create a directory.
Definition utility.C:152
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
The STL provides std::binary_search() which returns true or false depending on whether the searched-f...
Definition utility.h:233
Map::mapped_type & map_find(Map &map, const Key &key, const char *filename, int line_number)
-Wdangling-reference was nowhere near ready to add to -Wall in gcc 13.
Definition utility.h:105
Vector::reference & vector_at(Vector &vec, typename Vector::size_type i, const char *filename, int line_number)
A replacement for std::vector::at(i) which is meant to be used with a macro, and, unlike at(),...
Definition utility.h:192
void deallocate(std::vector< T > &vec)
A convenient method to truly empty a vector using the "swap trick".
Definition utility.h:345
bool contains(std::string_view superstring, std::string_view substring)
Look for a substring within a string.
Definition utility.C:205
std::string system_info()
Definition utility.C:63
std::string complex_filename(std::string basename, unsigned int r_o_c=0)
Definition utility.C:119
void prepare_complex_data(const std::vector< Complex > &source, std::vector< Real > &real_part, std::vector< Real > &imag_part)
Prepare complex data for writing.
Definition utility.C:133
bool ends_with(std::string_view superstring, std::string_view suffix)
Look for a substring at the very end of a string.
Definition utility.C:213
std::string_view basename_of(const std::string &fullname)
Definition utility.C:108
std::string unzip_file(std::string_view name)
Create an unzipped copy of a bz2 or xz file, returning the name of the now-unzipped file that can be ...
Definition utility.C:164
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
Struct which defines a custom comparison object that can be used with std::sets of std::unique_ptrs.
Definition utility.h:486
void is_transparent
As of C++14, std::set::find() can be a templated overload.
Definition utility.h:492
bool operator()(const std::unique_ptr< T > &a, const T *const &b) const
operator< comparison when rhs is a dumb pointer
Definition utility.h:508
bool operator()(const std::unique_ptr< T > &a, const std::unique_ptr< T > &b) const
This is already what the default operator< comparison for std::unique_ptrs does, we are not adding an...
Definition utility.h:499
bool operator()(const T *const &a, const std::unique_ptr< T > &b) const
operator< comparison when lhs is a dumb pointer
Definition utility.h:517
static T apply(const T &)
Definition utility.h:290
static T apply(const T &x)
Definition utility.h:285
static T apply(const T &x)
Definition utility.h:274
An efficient template instantiation for raising to an arbitrary integer power.
Definition utility.h:255
static T apply(const T &x)
Definition utility.h:256
static const bool value
Definition xdr_io.C:55