/* * Created by Brett Terpstra 6920201 on 14/10/22. * Copyright (c) Brett Terpstra 2022 All Rights Reserved * * This file is used to include common standard library headers * There are some things {String, Maps} that I use a lot * Plus common defines that might be useful in the future. * */ #ifndef STEP_2_STD_H #define STEP_2_STD_H /** * includes */ #include #include #include "logging.h" #include #include #include #include #include #include #include #include #include #include #define RTAssert(condition) static_cast (condition) ? void(0) : throw std::runtime_error("Assert Failed!"); /** * defines */ #define RAYTRACING_VERSION_MAJOR 0 #define RAYTRACING_VERSION_MINOR 0 #define RAYTRACING_VERSION_PATCH 1 #define RAYTRACING_VERSION_STRING "0.0.1" /** * Constants */ const double infinity = std::numeric_limits::infinity(); const double ninfinity = -std::numeric_limits::infinity(); // PI, to a large # of digits const double PI = 3.1415926535897932385; // very small number const double EPSILON = 0.0000001; /** * classes */ static inline double degreeeToRadian(double deg) { return deg * PI / 180.0; } constexpr unsigned long GLOBAL_SEED = 691l * 691l * 691l; namespace Raytracing { struct Signals { bool haltExecution{false}; bool pauseRaytracing{false}; bool haltRaytracing{false}; }; class AlignedAllocator { private: public: // not sure if this actually provides a performance benefit. Testing is inconclusive template static T* allocateCacheAligned(int number = 1) { void* allocatedSpace = aligned_alloc(64, sizeof(T) * number); return new(allocatedSpace) T[number]; } }; class Random { private: std::random_device rd; // obtain a random number from hardware std::mt19937 gen; std::uniform_real_distribution doubleDistr{0, 1}; std::uniform_int_distribution longDistr{0, 1}; std::uniform_int_distribution ulongDistr{0, 1}; public: Random(): gen(std::mt19937(GLOBAL_SEED)) {} Random(double min, double max): gen(std::mt19937(GLOBAL_SEED)), doubleDistr{min, max}, longDistr{(long) min, (long) max}, ulongDistr{(unsigned long) min, (unsigned long) max} {} Random(long min, long max): gen(std::mt19937(GLOBAL_SEED)), doubleDistr{(double) min, (double) max}, longDistr{(long) min, (long) max}, ulongDistr{(unsigned long) min, (unsigned long) max} {} Random(unsigned long min, unsigned long max): gen(std::mt19937(GLOBAL_SEED)), doubleDistr{(double) min, (double) max}, longDistr{(long) min, (long) max}, ulongDistr{(unsigned long) min, (unsigned long) max} {} double getDouble() { return doubleDistr(gen); } long getLong() { return longDistr(gen); } unsigned long getULong() { return ulongDistr(gen); } }; class String { public: /** * Converts the string into lower case * @param s string to lower case * @return a string copy that is all lower case */ static inline std::string toLowerCase(const std::string& s) { std::stringstream str; std::for_each( s.begin(), s.end(), [&str](unsigned char ch) { str << (char) std::tolower(ch); } ); return str.str(); } /** * Converts the string into upper case * @param s string to upper case * @return a string copy that is all upper case */ static inline std::string toUpperCase(const std::string& s) { std::stringstream str; std::for_each( s.begin(), s.end(), [&str](unsigned char ch) { str << (char) std::toupper(ch); } ); return str.str(); } /** * @return the standard string of time.now */ static inline std::string getTimeString() { auto t = std::time(nullptr); auto now = std::localtime(&t); std::stringstream timeString; timeString << (1900 + now->tm_year); timeString << "-"; timeString << (1 + now->tm_mon); timeString << "-"; timeString << now->tm_mday; timeString << " "; timeString << now->tm_hour; timeString << ":"; timeString << now->tm_min; timeString << ":"; timeString << now->tm_sec; return timeString.str(); } // taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c // extended to return a vector static inline std::vector split(std::string s, const std::string& delim) { size_t pos = 0; std::vector tokens; while ((pos = s.find(delim)) != std::string::npos) { auto token = s.substr(0, pos); tokens.push_back(token); s.erase(0, pos + delim.length()); } tokens.push_back(s); return tokens; } // taken from https://stackoverflow.com/questions/216823/how-to-trim-an-stdstring // would've preferred to use boost lib but instructions said to avoid external libs // trim from start (in place) static inline std::string& ltrim(std::string& s) { s.erase( s.begin(), std::find_if( s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); } )); return s; } // trim from end (in place) static inline std::string& rtrim(std::string& s) { s.erase( std::find_if( s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); } ).base(), s.end()); return s; } // trim from both ends (in place) static inline std::string& trim(std::string& s) { ltrim(s); rtrim(s); return s; } // trim from start (copying) static inline std::string ltrim_copy(std::string s) { ltrim(s); return s; } // trim from end (copying) static inline std::string rtrim_copy(std::string s) { rtrim(s); return s; } // trim from both ends (copying) static inline std::string trim_copy(std::string s) { trim(s); return s; } }; } static Raytracing::Random rnd{}; static inline double getRandomDouble() { return rnd.getDouble(); } static inline double clamp(double val, double min, double max) { if (val < min) return min; if (val > max) return max; return val; } #endif //STEP_2_STD_H