matf-rg-engine 1.0.0
Base for project for the Computer Graphics course at Faculty of Mathematics, University of Belgrade
Loading...
Searching...
No Matches
Utils.hpp
Go to the documentation of this file.
1
6#ifndef MATF_RG_PROJECT_UTILS_HPP
7#define MATF_RG_PROJECT_UTILS_HPP
8
9#include <format>
10#include <source_location>
11#include <vector>
12#include <mutex>
13#include <filesystem>
14#include <functional>
15#include <unordered_set>
16#include <type_traits>
17
19template<class... Ts>
20struct overloaded : Ts... {
21 using Ts::operator()...;
22};
23
24template<class... Ts>
25overloaded(Ts...) -> overloaded<Ts...>;
26
27template<typename Func>
28struct DeferImpl {
29 DeferImpl(Func f) : f(f) {
30 }
31
32 ~DeferImpl() {
33 f();
34 }
35
36 Func f;
37};
38
39struct MakeDeferImpl {
40};
41
42template<typename Func>
43DeferImpl<Func> operator<<(MakeDeferImpl, Func f) {
44 return DeferImpl(f);
45}
46#define STR(a) #a
47#define CONCAT_IMPL(a, b) a##b
48#define CONCAT(a, b) CONCAT_IMPL(a, b)
50
63#define defer auto CONCAT(defer_stmt_, __LINE__) = MakeDeferImpl() << [&]
64
68#define range(container) std::begin(container), std::end(container)
69
73#define crange(container) std::cbegin(container), std::cend(container)
74
75namespace engine::util {
79 void tracing_on();
80
84 void tracing_off();
85
96 void trace(std::source_location location = std::source_location::current());
97
103 std::string read_text_file(const std::filesystem::path &path);
104
116 template<typename Action>
117 void once(Action action) {
118 static std::once_flag once;
119 std::call_once(once, action);
120 };
121
125 namespace alg {
132 template<typename Container, typename T>
133 bool contains(const Container &container, const T &value) {
134 if constexpr (requires { container.contains(value); }) {
135 return container.contains(value);
136 } else {
137 return std::find(std::cbegin(container), std::cend(container), value) != std::cend(container);
138 }
139 }
140
148 template<typename It, typename Adjacent>
149 void topological_sort(It first, It last, Adjacent adjacent) {
150 using ElementType = std::remove_reference_t<decltype(*first)>;
151 std::unordered_set<ElementType> visited;
152 std::vector<ElementType> stack;
153
154 auto visit = [&](auto& self, ElementType &current) mutable -> void {
155 visited.emplace(current);
156 for (auto next: adjacent(current)) {
157 if (!visited.contains(next)) {
158 self(self, next);
159 }
160 }
161 stack.push_back(current);
162 };
163
164
165 auto it = first;
166 while (it != last) {
167 if (!visited.contains(*it)) {
168 visit(visit, *it);
169 }
170 ++it;
171 }
172 std::move(stack.rbegin(), stack.rend(), first);
173 }
174
183 template<typename It, typename Adjacent, typename OutputIt = std::nullptr_t>
184 bool has_cycle(It first, It last, Adjacent adjacent, OutputIt cycle_output = nullptr) {
185 using ElementType = std::remove_reference_t<decltype(*first)>;
186 std::unordered_set<ElementType> visited;
187 std::unordered_set<ElementType> path;
188 auto visit = [&](auto& self, ElementType &current) mutable -> bool {
189 visited.emplace(current);
190 path.emplace(current);
191 for (ElementType &next: adjacent(current)) {
192 if (!visited.contains(next) && self(self, next)) {
193 return true;
194 }
195 if (path.contains(next)) {
196 return true;
197 }
198 }
199 path.erase(current);
200 return false;
201 };
202
203 for (auto root = first; root != last; ++root) {
204 if (!visited.contains(*root) && visit(visit, *root)) {
205 if constexpr (!std::is_same_v<OutputIt, std::nullptr_t>) {
206 std::move(path.begin(), path.end(), cycle_output);
207 };
208 return true;
209 }
210 }
211 return false;
212 }
213 } // namespace alg
214
215 namespace ds {
216 }
217} // namespace engine
218
219#endif//MATF_RG_PROJECT_UTILS_HPP
void topological_sort(It first, It last, Adjacent adjacent)
Topologically sorts a directed acyclic graph represented by a range and an adjacent function....
Definition Utils.hpp:149
bool has_cycle(It first, It last, Adjacent adjacent, OutputIt cycle_output=nullptr)
Checks if a graph represented by a range and an adjacent function has a cycle.
Definition Utils.hpp:184
bool contains(const Container &container, const T &value)
Checks if a container contains a value. Shorthand for std::find.
Definition Utils.hpp:133
Definition App.hpp:9
void tracing_on()
Turns on tracing.
Definition Utils.cpp:12
void tracing_off()
Turns off tracing.
Definition Utils.cpp:16
std::string read_text_file(const std::filesystem::path &path)
Reads a text file.
Definition Utils.cpp:101
void once(Action action)
Calls an action once.
Definition Utils.hpp:117
void trace(std::source_location location=std::source_location::current())
Traces a function call.
Definition Utils.cpp:20