///////////////////////////////////////////////////////////////////// // Utility Collection of Miscellanious Handy Functions // © Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #pragma once #ifndef UTILITIES_H #define UTILITIES_H #include #include #include #include #include namespace Utility { namespace Memory { template struct UniquePointer { public: UniquePointer( Type *assignedMemory = NULL ); ~UniquePointer(); UniquePointer & operator = ( Type *assignedMemory ); UniquePointer & operator = ( const UniquePointer &donor ); operator Type* (); operator const Type* () const; Type * operator -> (); const Type * operator -> () const; template Type & operator [] ( Index i ); template const Type & operator [] ( Index i ) const; operator bool () const; Type* Release(); bool haveOwnership() const; private: mutable Type *ownedMemory; }; // IMPLEMENTATIONS //////////////////////////////////////////////// template UniquePointer::UniquePointer( Type *assignedMemory ) { this->ownedMemory = assignedMemory; } template UniquePointer::~UniquePointer() { if( this->ownedMemory ) delete this->ownedMemory; } template UniquePointer & UniquePointer::operator = ( Type *assignedMemory ) { if( this->ownedPointer ) delete this->ownedMemory; this->ownedMemory = assignedMemory; return *this; } template UniquePointer & UniquePointer::operator = ( const UniquePointer &donor ) { if( this->ownedMemory ) delete this->ownedMemory; this->ownedMemory = donor.ownedMemory; donor.ownedMemory = NULL; return *this; } template UniquePointer::operator Type* () { return this->ownedMemory; } template UniquePointer::operator const Type* () const { return this->ownedMemory; } template Type * UniquePointer::operator -> () { return this->ownedMemory; } template const Type * UniquePointer::operator -> () const { return this->ownedMemory; } template template Type & UniquePointer::operator [] ( Index i ) { return this->ownedMemory[i]; } template template const Type & UniquePointer::operator [] ( Index i ) const { return this->ownedMemory[i]; } template UniquePointer::operator bool() const { return this->ownedMemory != NULL; } template Type* UniquePointer::Release() { Type *copy = this->ownedMemory; this->ownedMemory = NULL; return copy; } template inline bool UniquePointer::haveOwnership() const { return this->operator bool(); } } namespace String { // string ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 ); ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 ); ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 ); ::std::string Trim( const ::std::string &str ); ::std::string & ToLowerCase( ::std::string &output, const ::std::string &str ); ::std::string & ToLowerCase( ::std::string &str ); ::std::string & ToUpperCase( ::std::string &output, const ::std::string &str ); ::std::string & ToUpperCase( ::std::string &str ); ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter ); ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter ); ::std::string & ReplaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos ); // wstring ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, char delim, ::std::wstring::size_type offset = 0 ); ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::wstring &delim, ::std::wstring::size_type offset = 0 ); ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::vector<::std::wstring> &delim, ::std::wstring::size_type offset = 0 ); } namespace Stream { float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats ); } namespace StaticArray { template inline unsigned int NumElementsOf( const ScalarType(&)[num] ) { return num; } template inline ScalarType & FirstElementOf( ScalarType (&arr)[num] ) { return arr[0]; } template inline ScalarType & LastElementOf( ScalarType (&arr)[num] ) { return arr[num-1]; } } namespace Element { template inline void Swap( ScalarType &elementA, ScalarType &elementB, ScalarType &swapSpace ) { swapSpace = elementA; elementA = elementB; elementB = swapSpace; } template inline void Swap( ScalarType &elementA, ScalarType &elementB ) { ScalarType swapSpace; Swap( elementA, elementB, swapSpace ); } } namespace Value { using ::std::numeric_limits; template inline ValueType Abs( const ValueType &value ) { return value < 0 ? value * -1 : value; } template inline ValueType Max( const ValueType &valueA, const ValueType &valueB ) { return valueA > valueB ? valueA : valueB; } template inline ValueType Min( const ValueType &valueA, const ValueType &valueB ) { return valueA < valueB ? valueA : valueB; } template inline ValueType Average( const ValueType &valueA, const ValueType &valueB ) { return (valueA + valueB) * 0.5f; } template inline ValueType AverageWithDelta( const ValueType &origin, const ValueType &delta ) { return origin + (delta * 0.5f); } template inline ValueType Radian( const ValueType °ree ) { return degree * (3.1415926535897932384626433832795f / 180.0f); } template inline ValueType Degree( const ValueType &radian ) { return radian * (180.0f / 3.1415926535897932384626433832795f); } // SPECIALIZATIONS ////////////////////////////////////////// template<> inline char Average( const char &valueA, const char &valueB ) { return (valueA + valueB) >> 1; } template<> inline unsigned char Average( const unsigned char &valueA, const unsigned char &valueB ) { return (valueA + valueB) >> 1; } template<> inline int Average( const int &valueA, const int &valueB ) { return (valueA + valueB) >> 1; } template<> inline unsigned int Average( const unsigned int &valueA, const unsigned int &valueB ) { return (valueA + valueB) >> 1; } template<> inline long Average( const long &valueA, const long &valueB ) { return (valueA + valueB) >> 1; } template<> inline unsigned long Average( const unsigned long &valueA, const unsigned long &valueB ) { return (valueA + valueB) >> 1; } template<> inline long long Average( const long long &valueA, const long long &valueB ) { return (valueA + valueB) >> 1; } template<> inline unsigned long long Average( const unsigned long long &valueA, const unsigned long long &valueB ) { return (valueA + valueB) >> 1; } template<> inline char AverageWithDelta( const char &origin, const char &delta ) { return origin + (delta >> 1); } template<> inline unsigned char AverageWithDelta( const unsigned char &origin, const unsigned char &delta ) { return origin + (delta >> 1); } template<> inline int AverageWithDelta( const int &origin, const int &delta ) { return origin + (delta >> 1); } template<> inline unsigned int AverageWithDelta( const unsigned int &origin, const unsigned int &delta ) { return origin + (delta >> 1); } template<> inline long AverageWithDelta( const long &origin, const long &delta ) { return origin + (delta >> 1); } template<> inline unsigned long AverageWithDelta( const unsigned long &origin, const unsigned long &delta ) { return origin + (delta >> 1); } template<> inline long long AverageWithDelta( const long long &origin, const long long &delta ) { return origin + (delta >> 1); } template<> inline unsigned long long AverageWithDelta( const unsigned long long &origin, const unsigned long long &delta ) { return origin + (delta >> 1); } } } #endif