suanPan
🧮 An Open Source, Parallel and Heterogeneous Finite Element Analysis Framework
Loading...
Searching...
No Matches
utility.h
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2026 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program 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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17
18#ifndef UTILITY_H
19#define UTILITY_H
20
21#include <concepts>
22#include <set>
23#include <suanPan.h>
24#ifdef __cpp_lib_execution
25#include <execution>
26#endif
27
28namespace suanpan {
29 template<typename T> constexpr const T& middle(const std::vector<T>& container) { return container[container.size() / 2]; }
30
31 template<sp_i IT, std::invocable<IT> F> void for_each(const IT start, const IT end, F&& FN) {
32#ifdef SUANPAN_MT
33 static tbb::affinity_partitioner ap;
34 tbb::parallel_for(start, end, std::forward<F>(FN), ap);
35#else
36 for(IT I = start; I < end; ++I) FN(I);
37#endif
38 }
39
40 template<sp_i IT, std::invocable<IT> F> void for_each(const IT end, F&& FN) { return for_each(static_cast<IT>(0), end, std::forward<F>(FN)); }
41
42 template<typename T> constexpr T max_element(T start, T end) {
43#ifdef __cpp_lib_execution
44 return std::max_element(std::execution::par, start, end);
45#else
46 return std::max_element(start, end);
47#endif
48 }
49
50 template<typename T> [[maybe_unused]] const std::vector<T>& unique(std::vector<T>& container) {
51 std::sort(container.begin(), container.end());
52 container.erase(std::unique(container.begin(), container.end()), container.end());
53 container.shrink_to_fit();
54 return container;
55 }
56
57 template<class Container, class Handler> requires requires(Container x) { x.begin(); x.end(); } auto all_of(Container& target, Handler&& func) {
58 return std::all_of(
59#ifdef __cpp_lib_execution
60 std::execution::par,
61#endif
62 target.begin(), target.end(), std::forward<Handler>(func)
63 );
64 }
65
66 template<class Container, class Handler> requires requires(Container x) { x.begin(); x.end(); } auto none_of(Container& target, Handler&& func) {
67 return std::none_of(
68#ifdef __cpp_lib_execution
69 std::execution::par,
70#endif
71 target.begin(), target.end(), std::forward<Handler>(func)
72 );
73 }
74
75 template<class Container, class Handler> requires requires(Container x) { x.begin(); x.end(); } auto any_of(Container& target, Handler&& func) {
76 return std::any_of(
77#ifdef __cpp_lib_execution
78 std::execution::par,
79#endif
80 target.begin(), target.end(), std::forward<Handler>(func)
81 );
82 }
83
84 template<typename T> constexpr T& hacker(const T& I) { return const_cast<T&>(I); }
85
86 template<typename T> constexpr T*& hacker(const T* const& I) { return const_cast<T*&>(I); }
87
88 template<typename T> requires std::signed_integral<T> || std::floating_point<T> constexpr T sign(const T I) { return (I > T(0)) - (I < T(0)); }
89
90 template<std::floating_point T> constexpr T clamp(const T c, T a, T b) {
91 if(a > b) std::swap(a, b);
92 return std::max(a, std::min(b, c));
93 }
94
95 template<std::floating_point T> constexpr T clamp_unit(const T c) { return clamp(c, T(0), T(1)); }
96
97 template<std::floating_point T> bool approx_equal(const T x, const T y, int ulp = 2) { return std::fabs(x - y) <= std::numeric_limits<T>::epsilon() * std::fabs(x + y) * ulp || std::fabs(x - y) < std::numeric_limits<T>::min(); }
98
99 unsigned long long binomial(unsigned long long, unsigned long long);
100
101 char to_upper(char);
102 char to_lower(char);
103
104 void to_upper(std::string&);
105 void to_lower(std::string&);
106 std::string to_upper(const std::string&);
107 std::string to_lower(const std::string&);
108 std::string to_upper(std::string&&);
109 std::string to_lower(std::string&&);
110
111 namespace expression {
112 std::vector<std::pair<std::string, unsigned>> split(std::string_view variable_string);
113 } // namespace expression
114} // namespace suanpan
115
116template<typename T> bool get_input(std::istringstream& stream, T& output) { return static_cast<bool>(stream >> output); }
117
118template<typename T> bool get_input(std::istringstream& stream, Col<T>& output) {
119 for(auto& item : output)
120 if(!get_input(stream, item)) return false;
121 return true;
122}
123
124template<typename T, typename... U> bool get_input(std::istringstream& stream, T& output, U&... rest) { return get_input(stream, output) && get_input(stream, rest...); }
125
126template<typename... Ts> bool get_input(std::istringstream& stream, std::tuple<Ts...>& output) {
127 return std::apply([&](auto&... items) { return get_input(stream, items...); }, output);
128}
129
130template<typename T> auto get_remaining(std::istringstream& stream) {
131 std::vector<T> output;
132 T value;
133 while(get_input(stream, value)) output.emplace_back(value);
134 return output;
135}
136
137template<typename T> auto get_remaining_as_set(std::istringstream& stream) {
138 std::set<T> output;
139 T value;
140 while(get_input(stream, value)) output.insert(value);
141 return output;
142}
143
144template<typename T1, typename T2, typename... Ts> auto get_remaining(std::istringstream& stream) {
145 std::tuple<std::vector<T1>, std::vector<T2>, std::vector<Ts>...> output;
146 std::tuple<T1, T2, Ts...> temp;
147 while(get_input(stream, temp)) std::apply([&](auto&... containers) { std::apply([&](auto&&... items) { ((containers.emplace_back(items)), ...); }, temp); }, output);
148 return output;
149}
150
151template<typename... Ts> auto get_remaining_as_tuple(std::istringstream& stream) {
152 std::vector<std::tuple<Ts...>> output;
153 std::tuple<Ts...> temp;
154 while(get_input(stream, temp)) output.emplace_back(temp);
155 return output;
156}
157
158template<typename T> T get_input(std::istringstream& stream) {
159 T output{};
160 stream >> output;
161 return output;
162}
163
164void ignore_whitespace(std::istringstream&);
165
166template<typename T> bool get_optional_input(std::istringstream& stream, T& output) { return stream.eof() || get_input(stream, output); }
167
168template<typename T> bool get_optional_input(std::istringstream& stream, Col<T>& output) {
169 for(auto& item : output)
170 if(!stream.eof() && !get_input(stream, item)) return false;
171 return true;
172}
173
174template<typename T, typename... U> bool get_optional_input(std::istringstream& stream, T& output, U&... rest) { return stream.eof() || (get_input(stream, output) && get_optional_input(stream, rest...)); }
175
176std::string get_remaining(std::istringstream&);
177
178bool is_equal(char, char);
179bool is_equal(int, char);
180bool is_equal(std::string_view, std::string_view);
181
182template<typename... S> bool is_equal_any(std::string_view a, S... rest) { return (is_equal(a, rest) || ...); }
183
184bool if_startswith(std::string_view, std::string_view);
185
186bool if_contain(const std::string&, const char*);
187bool if_contain(const std::string&, const std::string&);
188
189bool is_true(std::string_view);
190bool is_false(std::string_view);
191
192bool is_integer(const std::string&);
193
194double perturb(double, double = 1E-5);
195
196#endif
Storage< T >::iterator end(Storage< T > &S)
Definition Storage.hpp:211
std::vector< std::pair< std::string, unsigned > > split(std::string_view variable_string)
Definition utility.cpp:70
Definition SparseMatMAGMA.hpp:43
auto any_of(Container &target, Handler &&func)
Definition utility.h:75
const std::vector< T > & unique(std::vector< T > &container)
Definition utility.h:50
auto all_of(Container &target, Handler &&func)
Definition utility.h:57
bool approx_equal(const T x, const T y, int ulp=2)
Definition utility.h:97
char to_lower(char)
Definition utility.cpp:38
constexpr T sign(const T I)
Definition utility.h:88
unsigned long long binomial(unsigned long long, unsigned long long)
Definition utility.cpp:22
constexpr T clamp(const T c, T a, T b)
Definition utility.h:90
auto none_of(Container &target, Handler &&func)
Definition utility.h:66
char to_upper(char)
Definition utility.cpp:36
constexpr T max_element(T start, T end)
Definition utility.h:42
void for_each(const IT start, const IT end, F &&FN)
Definition utility.h:31
constexpr T & hacker(const T &I)
Definition utility.h:84
constexpr const T & middle(const std::vector< T > &container)
Definition utility.h:29
constexpr T clamp_unit(const T c)
Definition utility.h:95
bool if_startswith(std::string_view, std::string_view)
Definition utility.cpp:110
void ignore_whitespace(std::istringstream &)
Definition utility.cpp:93
bool is_integer(const std::string &)
Definition utility.cpp:127
bool is_equal(char, char)
Definition utility.cpp:104
bool get_optional_input(std::istringstream &stream, T &output)
Definition utility.h:166
bool get_input(std::istringstream &stream, T &output)
Definition utility.h:116
auto get_remaining(std::istringstream &stream)
Definition utility.h:130
bool is_equal_any(std::string_view a, S... rest)
Definition utility.h:182
auto get_remaining_as_set(std::istringstream &stream)
Definition utility.h:137
auto get_remaining_as_tuple(std::istringstream &stream)
Definition utility.h:151
double perturb(double, double=1E-5)
Definition utility.cpp:129
bool is_true(std::string_view)
Definition utility.cpp:123
bool is_false(std::string_view)
Definition utility.cpp:125
bool if_contain(const std::string &, const char *)
Definition utility.cpp:119