///////////////////////////////////////////////////////////////////// // Utility Collection of Miscellanious Handy Functions // © Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #ifndef UTILITIES_H #define UTILITIES_H #include #include #include #include #include namespace Utility { namespace DynamicMemory { /// If dynamicInstance is not NULL, then delete template void SafeDeleteInstance( Type *dynamicInstance ); /// If dynamicArray is not NULL, then delete [] template void SafeDeleteArray( Type dynamicArray[] ); template struct UniquePointer { /// Wrapper to safely transfer dynamic ownership/responsibility public: /// Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. /// If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer( Type *assignedInstance = NULL ); /// Will auto delete assigned dynamic instance. ~UniquePointer(); /// Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. /// If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer & operator = ( Type *assignedInstance ); /// Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. /// If donor had nothing, is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer & operator = ( const UniquePointer &donor ); /// Access the assigned dynamic instance. Will crash if nothing there operator Type* (); /// Access the assigned dynamic instance. Will crash if nothing there operator const Type* () const; /// Access members of the assigned dynamic instance. Will crash if nothing there Type * operator -> (); /// Access members of the assigned dynamic instance. Will crash if nothing there const Type * operator -> () const; /// If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. operator bool () const; /// This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete. Type* Release(); /// (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. bool HaveOwnership() const; private: mutable Type *ownedInstance; }; template struct UniqueArray { /// Wrapper to safely transfer dynamic ownership/responsibility public: /// Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. /// If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray( Type assignedArray[] = NULL ); /// Will auto delete assigned dynamic array. ~UniqueArray(); /// Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. /// If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray & operator = ( Type assignedArray[] ); /// Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. /// If donor had nothing, is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray & operator = ( const UniqueArray &donor ); /// Accesses the instance at index i of this UniqeArray's owned dynamic array. /// Will crash if out-of-bound or there is no assigned array. template Type & operator [] ( Index i ); /// Accesses the instance at index i of this UniqeArray's owned dynamic array. /// Will crash if out-of-bound or there is no assigned array. template const Type & operator [] ( Index i ) const; /// If true, this UniqueArray have a current ownership/responsibility of a dynamic instance. operator bool () const; /// This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete. Type* Release(); /// (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array. bool HaveOwnership() const; private: mutable Type *ownedArray; }; } 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); } } } #include "Utilities-InlineImpl.h" #endif