/*
* xSF - Common functions
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
* Last modification on 2014-09-17
*
* Partially based on the vio*sf framework
*/
#pragma once
#include <limits>
#include <fstream>
#include <string>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdint>
// Code from http://learningcppisfun.blogspot.com/2010/04/comparing-floating-point-numbers.html
template<typename T> inline bool fEqual(T x, T y, int N = 1)
{
T diff = std::abs(x - y);
T tolerance = N * std::numeric_limits<T>::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<char *>(bytes), 4);
return Get32BitsLE(bytes);
}
// This gets the directory for the path, including the final forward/backward slash
template<typename T> inline std::basic_string<T> ExtractDirectoryFromPath(const std::basic_string<T> &fullPath)
{
auto lastSlash = fullPath.rfind('\\');
if (lastSlash == std::basic_string<T>::npos)
lastSlash = fullPath.rfind('/');
return lastSlash != std::basic_string<T>::npos ? fullPath.substr(0, lastSlash + 1) : std::basic_string<T>();
}
// This gets the filename for the path
template<typename T> inline std::basic_string<T> ExtractFilenameFromPath(const std::basic_string<T> &fullPath)
{
auto lastSlash = fullPath.rfind('\\');
if (lastSlash == std::basic_string<T>::npos)
lastSlash = fullPath.rfind('/');
return lastSlash != std::basic_string<T>::npos ? fullPath.substr(lastSlash + 1) : std::basic_string<T>();
}
// Code from the following answer on Stack Overflow:
// http://stackoverflow.com/a/15479212
template<typename T> inline T NextHighestPowerOf2(T value)
{
if (value < 1)
return 1;
--value;
for (size_t i = 1; i < sizeof(T) * std::numeric_limits<unsigned char>::digits; i <<= 1)
value |= value >> i;
return value + 1;
}
// Clamp a value between a minimum and maximum value
template<typename T1, typename T2> 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 _MSC_VER
inline bool FileExists(const std::wstring &filename)
{
std::ifstream file(filename.c_str());
return !!file;
}
#endif