FireSTARR
Loading...
Searching...
No Matches
Util.h
1/* Copyright (c) Queen's Printer for Ontario, 2020. */
2/* Copyright (c) His Majesty the King in Right of Canada as represented by the Minister of Natural Resources, 2021-2025. */
3
4/* SPDX-License-Identifier: AGPL-3.0-or-later */
5
6#pragma once
7#include "stdafx.h"
8#include <string>
9#include <unordered_map>
10#include <utility>
11#include <vector>
12
13#ifndef TIFFTAG_GDAL_NODATA
14#define TIFFTAG_GDAL_NODATA 42113
15#endif
16
23TIFF* GeoTiffOpen(const char* const filename, const char* const mode);
24
28int sxprintf(char* buffer, size_t N, const char* format, va_list* args);
29int sxprintf(char* buffer, size_t N, const char* format, ...);
34template <std::size_t N>
35int sxprintf(char (&buffer)[N], const char* format, va_list* args)
36{
37 // printf("int sxprintf(char (&buffer)[N], const char* format, va_list* args)\n");
38 return sxprintf(&buffer[0], N, format, args);
39}
40template <std::size_t N>
41int sxprintf(char (&buffer)[N], const char* format, ...)
42{
43 // printf("int sxprintf(char (&buffer)[N], const char* format, ...)\n");
44 va_list args;
45 va_start(args, format);
46 auto r = sxprintf(buffer, format, &args);
47 va_end(args);
48 return r;
49}
50
51namespace fs
52{
53namespace util
54{
62template <typename T>
63[[nodiscard]] DurationSize to_time(const T day, const int hour) noexcept
64{
65 return day + hour / (1.0 * DAY_HOURS);
66}
72[[nodiscard]] constexpr DurationSize to_time(const size_t t_index) noexcept
73{
74 return static_cast<DurationSize>(t_index) / DAY_HOURS;
75}
83template <typename T>
84[[nodiscard]] size_t time_index(const T day, const int hour) noexcept
85{
86 return static_cast<size_t>(day) * DAY_HOURS + hour;
87}
95template <typename T>
96[[nodiscard]] size_t time_index(const T day,
97 const int hour,
98 const Day min_date) noexcept
99{
100 return time_index(day, hour) - static_cast<size_t>(DAY_HOURS) * min_date;
101}
107[[nodiscard]] constexpr size_t time_index(const DurationSize time) noexcept
108{
109 return static_cast<size_t>(time * DAY_HOURS);
110}
117[[nodiscard]] constexpr size_t time_index(const DurationSize time,
118 const Day min_date) noexcept
119{
120 return time_index(time) - static_cast<size_t>(DAY_HOURS) * min_date;
121}
128template <class T>
129[[nodiscard]] T no_convert(int value, int) noexcept
130{
131 return static_cast<T>(value);
132}
138[[nodiscard]] constexpr MathSize fix_radians(const MathSize theta)
139{
140 if (theta > M_2_X_PI)
141 {
142 return theta - M_2_X_PI;
143 }
144 if (theta < 0)
145 {
146 return theta + M_2_X_PI;
147 }
148 return theta;
149}
155[[nodiscard]] constexpr MathSize to_radians(const MathSize degrees) noexcept
156{
157 return fix_radians(degrees / M_RADIANS_TO_DEGREES);
158}
159// only calculate this once and reuse it
163static constexpr MathSize RAD_360 = to_radians(360);
167static constexpr MathSize RAD_270 = to_radians(270);
171static constexpr MathSize RAD_180 = to_radians(180);
175static constexpr MathSize RAD_090 = to_radians(90);
181[[nodiscard]] constexpr MathSize to_degrees(const MathSize radians)
182{
183 return fix_radians(radians) * M_RADIANS_TO_DEGREES;
184}
190[[nodiscard]] constexpr MathSize to_heading(const MathSize azimuth)
191{
192 return fix_radians(azimuth + RAD_180);
193}
204template <class Elem,
205 class Traits,
206 class Alloc>
207std::basic_istream<Elem, Traits>& getline(
208 std::basic_istream<Elem, Traits>* stream,
209 std::basic_string<Elem, Traits, Alloc>* str,
210 const Elem delimiter)
211{
212 // make template so we can use pointers directly
213 return getline(*stream, *str, delimiter);
214}
220[[nodiscard]] bool directory_exists(const char* dir) noexcept;
226[[nodiscard]] bool file_exists(const char* path) noexcept;
234void read_directory(const bool for_files,
235 const string& name,
236 vector<string>* v,
237 const string& match);
244void read_directory(const string& name,
245 vector<string>* v,
246 const string& match);
253void read_directory(const bool for_files,
254 const string& name,
255 vector<string>* v);
261void read_directory(const string& name, vector<string>* v);
268[[nodiscard]] vector<string> find_rasters(const string& dir, int year);
273void make_directory(const char* dir) noexcept;
278void make_directory_recursive(const char* dir) noexcept;
284template <class T>
285[[nodiscard]] inline constexpr MathSize sq(const T& x)
286{
287 return static_cast<MathSize>(x) * static_cast<MathSize>(x);
288}
296template <unsigned int N, class T>
297[[nodiscard]] constexpr T pow_int(const T& base)
298{
299 // https://stackoverflow.com/questions/16443682/c-power-of-integer-template-meta-programming
300 return N == 0
301 ? 1
302 : N % 2 == 0
303 ? pow_int<N / 2, T>(base) * pow_int<N / 2, T>(base)
304 : base * pow_int<(N - 1) / 2, T>(base) * pow_int<(N - 1) / 2, T>(base);
305}
312template <unsigned int N, class T>
313[[nodiscard]] constexpr T bit_mask()
314{
315 return static_cast<T>(pow_int<N, int64_t>(2) - 1);
316}
323template <unsigned int N>
324[[nodiscard]] MathSize round_to_precision(const MathSize value) noexcept
325{
326 // HACK: this can't actually make the value be the precision we want due to
327 // floating point storage, but we can round it to what it would be if it were
328 // that precision
329 static const auto b = pow_int<N, int64_t>(10);
330 return round(value * b) / b;
331}
341tm to_tm(const int year,
342 const int month,
343 const int day,
344 const int hour,
345 const int minute);
352DurationSize to_time(const tm& t);
362DurationSize to_time(const int year,
363 const int month,
364 const int day,
365 const int hour,
366 const int minute);
373void read_date(istringstream* iss, string* str, tm* t);
378{
382 atomic<size_t> count_;
386 string for_what_;
387public:
388 ~UsageCount();
393 explicit UsageCount(string for_what) noexcept;
394 UsageCount(UsageCount&& rhs) noexcept = delete;
395 UsageCount(const UsageCount& rhs) noexcept = delete;
396 UsageCount& operator=(UsageCount&& rhs) noexcept = delete;
397 UsageCount& operator=(const UsageCount& rhs) noexcept = delete;
402 UsageCount& operator++() noexcept;
403};
404// https://stackoverflow.com/questions/15843525/how-do-you-insert-the-value-in-a-sorted-vector
412template <typename T>
413[[nodiscard]] typename std::vector<T>::iterator
414 insert_sorted(std::vector<T>* vec, T const& item)
415{
416 return vec->insert(std::upper_bound(vec->begin(), vec->end(), item), item);
417}
424template <typename T>
425void insert_unique(std::vector<T>* vec, T const& item)
426{
427 const auto i = std::lower_bound(vec->begin(), vec->end(), item);
428 if (i == vec->end() || *i != item)
429 {
430 vec->insert(i, item);
431 }
432}
433}
445template <typename T, typename V>
446T binary_find(const T lower,
447 const T upper,
448 const MathSize value,
449 const std::function<V(T)>& fct)
450{
451 const auto mid = lower + (upper - lower) / 2;
452 if (lower == upper)
453 {
454 return lower;
455 }
456 if (fct(mid) < value)
457 {
458 return binary_find(lower, mid, value, fct);
459 }
460 return binary_find(mid + 1, upper, value, fct);
461}
472template <typename T, typename V>
473T binary_find_checked(const T lower,
474 const T upper,
475 const MathSize value,
476 const std::function<V(T)>& fct)
477{
478 if (fct(lower) < value)
479 {
480 return lower;
481 }
482 if (fct(upper) >= value)
483 {
484 return upper;
485 }
486 return binary_find(lower, upper, value, fct);
487}
495void month_and_day(const int year, const size_t day_of_year, size_t* month, size_t* day_of_month);
501[[nodiscard]] bool is_leap_year(const int year);
508[[nodiscard]] string make_timestamp(const int year, const DurationSize time);
515[[nodiscard]] inline MathSize ellipse_angle(const MathSize length_to_breadth,
516 const MathSize theta)
517{
518 return (util::fix_radians(
519 atan2(sin(theta) / length_to_breadth,
520 cos(theta))));
521}
522}
Provides the ability to determine how many times something is used during a simulation.
Definition Util.h:378
UsageCount & operator++() noexcept
Increment operator.
Definition Util.cpp:230
UsageCount(string for_what) noexcept
Constructor.
Definition Util.cpp:226
atomic< size_t > count_
How many times this has been used.
Definition Util.h:382
string for_what_
What this is tracking usage of.
Definition Util.h:386
Definition util.py:1