/* * xSF - Common functions * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com] * Last modification on 2014-09-24 * * Partially based on the vio*sf framework */ #pragma once #include #include #if defined(_WIN32) && !defined(_MSC_VER) # include "fstream_wfopen.h" #endif #include #define _USE_MATH_DEFINES #include #include #include #include #include "convert.h" // Code from http://learningcppisfun.blogspot.com/2010/04/comparing-floating-point-numbers.html template inline bool fEqual(T x, T y, int N = 1) { T diff = std::abs(x - y); T tolerance = N * std::numeric_limits::epsilon(); return diff <= tolerance * std::abs(x) && diff <= tolerance * std::abs(y); } inline uint32_t Get32BitsLE(const uint8_t *input) { return input[0] | (input[1] << 8) | (input[2] << 16) | (input[3] << 24); } inline uint32_t Get32BitsLE(std::ifstream &input) { uint8_t bytes[4]; input.read(reinterpret_cast(bytes), 4); return Get32BitsLE(bytes); } // This gets the directory for the path, including the final forward/backward slash template inline std::basic_string ExtractDirectoryFromPath(const std::basic_string &fullPath) { auto lastSlash = fullPath.rfind('\\'); if (lastSlash == std::basic_string::npos) lastSlash = fullPath.rfind('/'); return lastSlash != std::basic_string::npos ? fullPath.substr(0, lastSlash + 1) : std::basic_string(); } // This gets the filename for the path template inline std::basic_string ExtractFilenameFromPath(const std::basic_string &fullPath) { auto lastSlash = fullPath.rfind('\\'); if (lastSlash == std::basic_string::npos) lastSlash = fullPath.rfind('/'); return lastSlash != std::basic_string::npos ? fullPath.substr(lastSlash + 1) : std::basic_string(); } // Code from the following answer on Stack Overflow: // http://stackoverflow.com/a/15479212 template inline T NextHighestPowerOf2(T value) { if (value < 1) return 1; --value; for (size_t i = 1; i < sizeof(T) * std::numeric_limits::digits; i <<= 1) value |= value >> i; return value + 1; } // Clamp a value between a minimum and maximum value template inline void clamp(T1 &valueToClamp, const T2 &minValue, const T2 &maxValue) { if (valueToClamp < minValue) valueToClamp = minValue; else if (valueToClamp > maxValue) valueToClamp = maxValue; } inline bool FileExists(const std::string &filename) { std::ifstream file(filename.c_str()); return !!file; } #ifdef _WIN32 inline bool FileExists(const std::wstring &filename) { #ifdef _MSC_VER std::ifstream file(filename.c_str()); #else ifstream_wfopen file(filename.c_str()); #endif return !!file; } #endif inline void CopyToString(const std::wstring &src, wchar_t *dst) { wcscpy(dst, src.c_str()); } inline void CopyToString(const std::string &src, wchar_t *dst) { wcscpy(dst, ConvertFuncs::StringToWString(src).c_str()); } inline void CopyToString(const std::string &src, char *dst) { strcpy(dst, src.c_str()); } inline void CopyToString(const std::wstring &src, char *dst) { strcpy(dst, ConvertFuncs::WStringToString(src).c_str()); }