diff --git a/Misc/Misc.vcxproj b/Misc/Misc.vcxproj
index 7e2973b1..76714140 100644
--- a/Misc/Misc.vcxproj
+++ b/Misc/Misc.vcxproj
@@ -24,13 +24,13 @@
- Application
+ StaticLibrary
true
v110
MultiByte
- Application
+ StaticLibrary
true
v110
MultiByte
diff --git a/Misc/Utilities.cpp b/Misc/Utilities.cpp
index c3046aeb..502541b2 100644
--- a/Misc/Utilities.cpp
+++ b/Misc/Utilities.cpp
@@ -5,23 +5,25 @@
#include "Utilities.h"
#include
-#include
using ::std::vector;
using ::std::string;
+using ::std::wstring;
namespace Utility
{
// PRIVATE STATIC ////////////////////////////////////////////////////
namespace PrivateStatic
{
- const ::std::locale systemDefaultLocale = ::std::locale();
+ const ::std::locale system_default_locale = ::std::locale();
}
// STRING ////////////////////////////////////////////////////////////
namespace String
{
- vector & split( vector &output, const string &str, char delim, string::size_type offset )
+ // string
+
+ vector & Split( vector &output, const string &str, char delim, string::size_type offset )
{
if( str.length() > 0 )
{
@@ -42,13 +44,13 @@ namespace Utility
{
if( delimPos > offset )
output.push_back( str.substr( offset, delimPos - offset ) );
- String::split( output, str, delim, delimPos + 1 );
+ String::Split( output, str, delim, delimPos + 1 );
}
}
return output;
}
- vector & split( vector &output, const string &str, const string &delim, string::size_type offset )
+ vector & Split( vector &output, const string &str, const string &delim, string::size_type offset )
{
if( str.length() > 0 )
{
@@ -62,13 +64,13 @@ namespace Utility
{
if( delimPos > offset )
output.push_back( str.substr( offset, delimPos - offset ) );
- String::split( output, str, delim, delimPos + delim.length() );
+ String::Split( output, str, delim, delimPos + delim.length() );
}
}
return output;
}
- vector & split( vector &output, const string &str, const vector &delim, string::size_type offset )
+ vector & Split( vector &output, const string &str, const vector &delim, string::size_type offset )
{
if( str.length() > 0 )
{
@@ -94,13 +96,13 @@ namespace Utility
{
if( firstDelimPos > offset )
output.push_back( str.substr( offset, firstDelimPos - offset ) );
- String::split( output, str, delim, firstDelimPos + delim[delimRef].length() );
+ String::Split( output, str, delim, firstDelimPos + delim[delimRef].length() );
}
}
return output;
}
- string trim( const string &str )
+ string Trim( const string &str )
{
string::size_type first = 0,
last = str.length();
@@ -128,7 +130,7 @@ namespace Utility
return str.substr( first, (++last) - first );
}
- string & toLowerCase( string &output, const string &str )
+ string & ToLowerCase( string &output, const string &str )
{
int length = (int)str.length();
output.resize( length );
@@ -137,7 +139,7 @@ namespace Utility
return output;
}
- string & toLowerCase( string &str )
+ string & ToLowerCase( string &str )
{
int length = (int)str.length();
for( int i = 0; i < length; ++i )
@@ -145,7 +147,7 @@ namespace Utility
return str;
}
- string & toUpperCase( string &output, const string &str )
+ string & ToUpperCase( string &output, const string &str )
{
int length = (int)str.length();
output.resize( length );
@@ -154,7 +156,7 @@ namespace Utility
return output;
}
- string & toUpperCase( string &str )
+ string & ToUpperCase( string &str )
{
int length = (int)str.length();
for( int i = 0; i < length; ++i )
@@ -162,14 +164,14 @@ namespace Utility
return str;
}
- string & extractDirPath( string &output, const string &file, char dirDelimeter )
+ string & ExtractDirPath( string &output, const string &file, char dirDelimeter )
{
string d = " ";
d[0] = dirDelimeter;
- return String::extractDirPath( output, file, d );
+ return String::ExtractDirPath( output, file, d );
}
- string & extractDirPath( string &output, const string &file, const string &dirDelimeter )
+ string & ExtractDirPath( string &output, const string &file, const string &dirDelimeter )
{
string::size_type end = file.find_last_of( dirDelimeter );
if( end == string::npos )
@@ -185,7 +187,7 @@ namespace Utility
return output;
}
- string & replaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
+ string & ReplaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
{
string::size_type i = offset;
while( true )
@@ -197,12 +199,94 @@ namespace Utility
}
return str;
}
+
+ // wstring
+
+ vector & Split( vector &output, const wstring &str, char delim, wstring::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ while( offset < str.length() ) // trim
+ {
+ if( str[offset] == delim )
+ ++offset;
+ else break;
+ }
+
+ wstring::size_type delimPos = str.find_first_of( delim, offset );
+ if( delimPos == wstring::npos )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( delimPos > offset )
+ output.push_back( str.substr( offset, delimPos - offset ) );
+ String::Split( output, str, delim, delimPos + 1 );
+ }
+ }
+ return output;
+ }
+
+ vector & Split( vector &output, const wstring &str, const wstring &delim, wstring::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ wstring::size_type delimPos = str.find_first_of( delim, offset );
+ if( delimPos == wstring::npos )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( delimPos > offset )
+ output.push_back( str.substr( offset, delimPos - offset ) );
+ String::Split( output, str, delim, delimPos + delim.length() );
+ }
+ }
+ return output;
+ }
+
+ vector & Split( vector &output, const wstring &str, const vector &delim, wstring::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ wstring::size_type firstDelimPos = str.length(), delimPos;
+
+ vector::size_type numDelims = delim.size(), delimRef = 0;
+ for( vector::size_type i = 0; i < numDelims ; ++i )
+ {
+ delimPos = str.find_first_of( delim[i], offset );
+ if( delimPos != wstring::npos ) if( delimPos < firstDelimPos )
+ {
+ delimRef = i;
+ firstDelimPos = delimPos;
+ }
+ }
+
+ if( firstDelimPos == str.length() )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( firstDelimPos > offset )
+ output.push_back( str.substr( offset, firstDelimPos - offset ) );
+ String::Split( output, str, delim, firstDelimPos + delim[delimRef].length() );
+ }
+ }
+ return output;
+ }
+
}
// STREAM ////////////////////////////////////////////////////////////
namespace Stream
{
- float* readFloats( float *output, ::std::istream &input, unsigned int numFloats )
+ float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats )
{
string str;
for( unsigned int i = 0; i < numFloats; ++i )
diff --git a/Misc/Utilities.h b/Misc/Utilities.h
index aa9128c3..ba6e0c3a 100644
--- a/Misc/Utilities.h
+++ b/Misc/Utilities.h
@@ -11,69 +11,241 @@
#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
{
- // note to self: add a whitespaceSplit method?
- ::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 );
+ // 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 );
+ float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats );
}
namespace StaticArray
{
- template
- inline unsigned int numElementsOf( const ElementType(&)[num] )
+ 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( ElementType &elementA, ElementType &elementB, ElementType &swapSpace )
+ template
+ inline void Swap( ScalarType &elementA, ScalarType &elementB, ScalarType &swapSpace )
{ swapSpace = elementA; elementA = elementB; elementB = swapSpace; }
- template
- inline void swap( ElementType &elementA, ElementType &elementB )
- { ElementType swapSpace; swap( elementA, 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 )
+ inline ValueType Abs( const ValueType &value )
{ return value < 0 ? value * -1 : value; }
template
- inline ValueType max( const ValueType &valueA, const ValueType &valueB )
+ inline ValueType Max( const ValueType &valueA, const ValueType &valueB )
{ return valueA > valueB ? valueA : valueB; }
template
- inline ValueType min( const ValueType &valueA, const ValueType &valueB )
+ inline ValueType Min( const ValueType &valueA, const ValueType &valueB )
{ return valueA < valueB ? valueA : valueB; }
template
- inline ValueType radian( const ValueType °ree )
+ 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 )
+ 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); }
}
}