diff --git a/Sources/Plasma/Apps/plPageOptimizer/main.cpp b/Sources/Plasma/Apps/plPageOptimizer/main.cpp index 11d794d2..eabd4e25 100644 --- a/Sources/Plasma/Apps/plPageOptimizer/main.cpp +++ b/Sources/Plasma/Apps/plPageOptimizer/main.cpp @@ -61,6 +61,9 @@ int main(int argc, char* argv[]) plResManager* resMgr = new plResManager; hsgResMgr::Init(resMgr); #ifndef _DEBUG + } catch (std::exception &e) { + printf(" ***crashed on init: %s\n", e.what()); + return 2; } catch (...) { puts(" ***crashed on init"); return 2; @@ -75,6 +78,10 @@ int main(int argc, char* argv[]) optimizer.Optimize(); } #ifndef _DEBUG + catch (std::exception &e) { + printf(" ***crashed on optimizing: %s\n", e.what()); + return 2; + } catch (...) { puts(" ***crashed on optimizing"); return 2; @@ -92,6 +99,9 @@ int main(int argc, char* argv[]) hsgResMgr::Shutdown(); #ifndef _DEBUG + } catch (std::exception &e) { + printf(" ***crashed on shutdown: %s\n", e.what()); + return 2; } catch (...) { puts(" ***crashed on shutdown"); return 2; diff --git a/Sources/Plasma/CoreLib/CMakeLists.txt b/Sources/Plasma/CoreLib/CMakeLists.txt index 21abff68..759e6384 100644 --- a/Sources/Plasma/CoreLib/CMakeLists.txt +++ b/Sources/Plasma/CoreLib/CMakeLists.txt @@ -14,6 +14,7 @@ set(CoreLib_SOURCES hsBounds.cpp hsCpuID.cpp hsCritSect.cpp + hsExceptions.cpp hsExceptionStack.cpp hsFastMath.cpp hsGeometry3.cpp @@ -59,6 +60,7 @@ set(CoreLib_HEADERS hsCpuID.h hsCritSect.h hsExceptions.h + hsExceptionStack.h hsFastMath.h hsGeometry3.h hsHashTable.h diff --git a/Sources/Plasma/CoreLib/HeadSpin.h b/Sources/Plasma/CoreLib/HeadSpin.h index 98de089a..c31d9876 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.h +++ b/Sources/Plasma/CoreLib/HeadSpin.h @@ -130,6 +130,22 @@ typedef int32_t hsError; # define hsDeprecated(message) #endif +#ifdef HAVE_OVERRIDE +# define HS_OVERRIDE override +# define HS_FINAL final +#else +# define HS_OVERRIDE +# define HS_FINAL +#endif + +#ifdef HAVE_NOEXCEPT +# define HS_NOEXCEPT noexcept +# define HS_NOEXCEPT_IF(cond) noexcept(cond) +#else +# define HS_NOEXCEPT throw() +# define HS_NOEXCEPT_IF(cond) +#endif + //====================================== // Endian swap funcitions //====================================== diff --git a/Sources/Plasma/CoreLib/hsExceptionStack.cpp b/Sources/Plasma/CoreLib/hsExceptionStack.cpp index 4e9d47b7..44eadd19 100644 --- a/Sources/Plasma/CoreLib/hsExceptionStack.cpp +++ b/Sources/Plasma/CoreLib/hsExceptionStack.cpp @@ -48,4 +48,4 @@ void hsExceptionStack::FreeInstance() { delete fExceptionStack; fExceptionStack = nil; -} \ No newline at end of file +} diff --git a/Sources/Plasma/CoreLib/hsExceptions.cpp b/Sources/Plasma/CoreLib/hsExceptions.cpp new file mode 100644 index 00000000..cbb81069 --- /dev/null +++ b/Sources/Plasma/CoreLib/hsExceptions.cpp @@ -0,0 +1,22 @@ +#include "hsExceptions.h" + +#include + +hsException::hsException(hsErrorEnum error, long param) HS_NOEXCEPT + : fError(error), fParam(param) +{ + static const char *kErrorNames[] = { + "kNo_hsError", + "kNilParam_hsError", + "kBadParam_hsError", + "kInternal_hsError", + "kOS_hsError" + }; + static_assert(arrsize(kErrorNames) == hsErrorEnum_MAX, + "kErrorNames not in sync with hsErrorEnum"); + + if (fError >= 0 && fError < hsErrorEnum_MAX) + snprintf(fWhat, arrsize(fWhat), "%s (%ld)", kErrorNames[fError], fParam); + else + snprintf(fWhat, arrsize(fWhat), "Unknown hsException error %d (%ld)", fError, fParam); +} diff --git a/Sources/Plasma/CoreLib/hsExceptions.h b/Sources/Plasma/CoreLib/hsExceptions.h index 09697e37..47b5a525 100644 --- a/Sources/Plasma/CoreLib/hsExceptions.h +++ b/Sources/Plasma/CoreLib/hsExceptions.h @@ -43,64 +43,52 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #define hsExceptionDefined #include "HeadSpin.h" - -// #define HS_NO_EXCEPTIONS -- this will turn off execptions you might want -// to do it with -D or equivalent instead of here since who knows who includes this. - - +#include enum hsErrorEnum { kNo_hsError, - kBadAlloc_hsError, kNilParam_hsError, kBadParam_hsError, kInternal_hsError, - kOS_hsError + kOS_hsError, + hsErrorEnum_MAX }; ////////////////////////////////////////////////////////////////////////////// -class hsException { +class hsException : public std::exception { public: hsErrorEnum fError; - long fParam; - - hsException(hsErrorEnum error, long param = 0) : fError(error), fParam(param) {} -}; + long fParam; + char fWhat[64]; -class hsBadAllocException : public hsException { -public: - hsBadAllocException() : hsException(kBadAlloc_hsError) {} + hsException(hsErrorEnum error, long param = 0) HS_NOEXCEPT; + const char *what() const HS_NOEXCEPT HS_OVERRIDE { return fWhat; } }; class hsNilParamException : public hsException { public: - hsNilParamException() : hsException(kNilParam_hsError) {} + hsNilParamException() HS_NOEXCEPT : hsException(kNilParam_hsError) {} }; class hsBadParamException : public hsException { public: - hsBadParamException() : hsException(kBadParam_hsError) {} + hsBadParamException() HS_NOEXCEPT : hsException(kBadParam_hsError) {} }; class hsInternalException : public hsException { public: - hsInternalException() : hsException(kInternal_hsError) {} + hsInternalException() HS_NOEXCEPT : hsException(kInternal_hsError) {} }; class hsOSException : public hsException { public: - hsOSException(long error) : hsException(kOS_hsError, error) {} + hsOSException(long error) HS_NOEXCEPT : hsException(kOS_hsError, error) {} }; ///////////////////////////////////////////////////////////////////////////////// -#ifndef HS_NO_EXCEPTIONS -#define hsThrow(a) {hsAssert(0,#a);throw a;} -#define hsCatch(a) catch (a) -#define hsCatch2(a,b) catch (a b) - -#define hsTry try +#define hsThrow(a) { hsAssert(0,#a); throw a; } inline void hsThrowIfNilParam(const void* p) { @@ -165,48 +153,4 @@ inline void hsThrowIfFalse(bool condition, const char message[]) } } -#else -#define hsThrow(a) {hsAssert(0,#a);} -#define hsCatch(a) if(0) -#define hsCatch2(a,b) if(0) -#define hsTry - -inline void hsThrowIfNilParam(const void* p) -{ - hsAssert(p!=nil,"hsThrowIfNilParam"); -} - -inline void hsThrowIfBadParam(bool trueIfBadParam) -{ - hsAssert(!trueIfBadParam,"hsThrowIfBadParam"); -} - -inline void hsThrowIfOSErr(long osErr) -{ - hsAssert(osErr==0,"hsThrowIfOSErr"); -} - -inline void hsThrowIfTrue(bool condition) -{ - hsAssert(!condition,"hsThrowIfTrue"); -} - -inline void hsThrowIfFalse(bool condition) -{ - hsAssert(condition,"hsThrowIfFalse"); -} - -inline void hsThrowIfTrue(bool condition, const char message[]) -{ - hsAssert(!condition,message); -} - -inline void hsThrowIfFalse(bool condition, const char message[]) -{ - hsAssert(condition,message); -} - - -#endif - #endif diff --git a/Sources/Plasma/CoreLib/hsMemory.cpp b/Sources/Plasma/CoreLib/hsMemory.cpp index a0d934ae..fdd18685 100644 --- a/Sources/Plasma/CoreLib/hsMemory.cpp +++ b/Sources/Plasma/CoreLib/hsMemory.cpp @@ -110,44 +110,6 @@ void HSMemory::Clear(void* m, uint32_t byteLen) ////////////////////////////////////////////////////////////////////////////////////// -#if 0 -template T* hsSoftNew(T*& obj) -{ - try { - obj = new T; - } - catch (...) { - obj = nil; - } - return obj; -} - -inline template T* hsSoftNew(T*& obj, unsigned count) -{ - try { - obj = new T[count]; - } - catch (...) { - obj = nil; - } - return obj; -} -#endif - -void* HSMemory::SoftNew(uint32_t size) -{ - uint32_t* p; - - hsTry { - p = new uint32_t[(size + 3) >> 2]; - } hsCatch(...) { - p = nil; - } - return p; -} - -////////////////////////////////////////////////////////////////////////////////////// - struct hsPrivateChunk { hsPrivateChunk* fNext; char* fAvailableAddr; @@ -222,19 +184,6 @@ void* hsChunkAllocator::Allocate(uint32_t size, const void* data) return addr; } -void* hsChunkAllocator::SoftAllocate(uint32_t size, const void* data) -{ - void* addr; - - hsTry { - addr = this->Allocate(size, data); - } - hsCatch(...) { - addr = nil; - } - return addr; -} - ////////////////////////////////////////////////////////////////////////////////////// struct hsAppenderHead { diff --git a/Sources/Plasma/CoreLib/hsMemory.h b/Sources/Plasma/CoreLib/hsMemory.h index 32f7877d..0b5d8c5e 100644 --- a/Sources/Plasma/CoreLib/hsMemory.h +++ b/Sources/Plasma/CoreLib/hsMemory.h @@ -56,8 +56,6 @@ public: static void* New(uint32_t size); static void Delete(void* block); static void* Copy(uint32_t length, const void* source); - - static void* SoftNew(uint32_t size); // returns nil if can't allocate }; /////////////////////////////////////////////////////////////////////////////////////////// @@ -110,8 +108,7 @@ public: void Reset(); void SetChunkSize(uint32_t size); - void* Allocate(uint32_t size, const void* data = nil); // throws if fails - void* SoftAllocate(uint32_t size, const void* data = nil); // returns nil if fails + void* Allocate(uint32_t size, const void* data = nil); }; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Sources/Plasma/CoreLib/plString.cpp b/Sources/Plasma/CoreLib/plString.cpp index c55ea7ed..de339fdb 100644 --- a/Sources/Plasma/CoreLib/plString.cpp +++ b/Sources/Plasma/CoreLib/plString.cpp @@ -489,23 +489,23 @@ plUnicodeBuffer plString::GetUnicodeArray() const return result; } -int plString::ToInt(int base) const +int plString::ToInt(int base) const HS_NOEXCEPT { return static_cast(strtol(c_str(), nullptr, base)); } -unsigned int plString::ToUInt(int base) const +unsigned int plString::ToUInt(int base) const HS_NOEXCEPT { return static_cast(strtoul(c_str(), nullptr, base)); } -float plString::ToFloat() const +float plString::ToFloat() const HS_NOEXCEPT { // strtof is C99, which MS doesn't support... return (float)strtod(c_str(), nullptr); } -double plString::ToDouble() const +double plString::ToDouble() const HS_NOEXCEPT { return strtod(c_str(), nullptr); } @@ -550,7 +550,7 @@ plString plString::IFormat(const char *fmt, va_list vptr) return plString::FromUtf8(buffer, chars); } -ssize_t plString::Find(char ch, CaseSensitivity sense) const +ssize_t plString::Find(char ch, CaseSensitivity sense) const HS_NOEXCEPT { if (sense == kCaseSensitive) { const char *cp = strchr(c_str(), ch); @@ -566,7 +566,7 @@ ssize_t plString::Find(char ch, CaseSensitivity sense) const } } -ssize_t plString::FindLast(char ch, CaseSensitivity sense) const +ssize_t plString::FindLast(char ch, CaseSensitivity sense) const HS_NOEXCEPT { if (IsEmpty()) return -1; @@ -586,7 +586,7 @@ ssize_t plString::FindLast(char ch, CaseSensitivity sense) const } } -ssize_t plString::Find(const char *str, CaseSensitivity sense) const +ssize_t plString::Find(const char *str, CaseSensitivity sense) const HS_NOEXCEPT { if (!str || !str[0]) return -1; diff --git a/Sources/Plasma/CoreLib/plString.h b/Sources/Plasma/CoreLib/plString.h index fe68b3b5..65eefe3a 100644 --- a/Sources/Plasma/CoreLib/plString.h +++ b/Sources/Plasma/CoreLib/plString.h @@ -95,11 +95,11 @@ private: unsigned int fRefs; const _Ch *fStringData; - StringRef(const _Ch *data) + StringRef(const _Ch *data) HS_NOEXCEPT : fRefs(1), fStringData(data) { } - inline void AddRef() { ++fRefs; } - inline void DecRef() + inline void AddRef() HS_NOEXCEPT { ++fRefs; } + inline void DecRef() HS_NOEXCEPT { if (--fRefs == 0) { delete [] fStringData; @@ -114,14 +114,14 @@ private: }; size_t fSize; - bool IHaveACow() const { return fSize >= SSO_CHARS; } + bool IHaveACow() const HS_NOEXCEPT { return fSize >= SSO_CHARS; } public: /** Construct an empty string buffer. */ - plStringBuffer() : fSize(0) { memset(fShort, 0, sizeof(fShort)); } + plStringBuffer() HS_NOEXCEPT : fSize(0) { memset(fShort, 0, sizeof(fShort)); } /** Copy constructor - adds a reference to the copied buffer */ - plStringBuffer(const plStringBuffer<_Ch> ©) : fSize(copy.fSize) + plStringBuffer(const plStringBuffer<_Ch> ©) HS_NOEXCEPT : fSize(copy.fSize) { memcpy(fShort, copy.fShort, sizeof(fShort)); if (IHaveACow()) @@ -129,7 +129,7 @@ public: } /** Move constructor */ - plStringBuffer(plStringBuffer<_Ch> &&move) : fSize(move.fSize) + plStringBuffer(plStringBuffer<_Ch> &&move) HS_NOEXCEPT : fSize(move.fSize) { memcpy(fShort, move.fShort, sizeof(fShort)); move.fSize = 0; @@ -154,7 +154,7 @@ public: /** Destructor. The ref-counted data will only be freed if no other * string buffers still reference it. */ - ~plStringBuffer<_Ch>() + ~plStringBuffer<_Ch>() HS_NOEXCEPT { if (IHaveACow()) fData->DecRef(); @@ -163,7 +163,7 @@ public: /** Assignment operator. Changes the reference to point to the * buffer in \a copy. */ - plStringBuffer<_Ch> &operator=(const plStringBuffer<_Ch> ©) + plStringBuffer<_Ch> &operator=(const plStringBuffer<_Ch> ©) HS_NOEXCEPT { if (copy.IHaveACow()) copy.fData->AddRef(); @@ -176,7 +176,7 @@ public: } /** Move assignment operator */ - plStringBuffer<_Ch> &operator=(plStringBuffer<_Ch> &&move) + plStringBuffer<_Ch> &operator=(plStringBuffer<_Ch> &&move) HS_NOEXCEPT { if (IHaveACow()) fData->DecRef(); @@ -188,17 +188,17 @@ public: } /** Returns a pointer to the referenced string buffer. */ - const _Ch *GetData() const { return IHaveACow() ? fData->fStringData : fShort; } + const _Ch *GetData() const HS_NOEXCEPT { return IHaveACow() ? fData->fStringData : fShort; } /** Returns the number of characters (not including the '\0') in the * referenced string buffer. */ - size_t GetSize() const { return fSize; } + size_t GetSize() const HS_NOEXCEPT { return fSize; } /** Cast operator. This is a shortcut for not needing to call GetData on * buffer objects passed to methods or objects expecting a C-style string. */ - operator const _Ch *() const { return GetData(); } + operator const _Ch *() const HS_NOEXCEPT { return GetData(); } /** Create a writable buffer for \a size characters. * From Haxxia with love! This will release the current string buffer @@ -266,7 +266,7 @@ public: public: /** Construct a valid, empty string. */ - plString() { } + plString() HS_NOEXCEPT { } /** Construct a string from a C-style string. * \note This constructor expects the input to be UTF-8 encoded. For @@ -286,19 +286,19 @@ public: plString(char (&literal)[_Sz]) { IConvertFromUtf8(literal, STRLEN_AUTO); } /** Copy constructor. */ - plString(const plString ©) : fUtf8Buffer(copy.fUtf8Buffer) { } + plString(const plString ©) HS_NOEXCEPT : fUtf8Buffer(copy.fUtf8Buffer) { } /** Move constructor. */ - plString(plString &&move) : fUtf8Buffer(std::move(move.fUtf8Buffer)) { } + plString(plString &&move) HS_NOEXCEPT : fUtf8Buffer(std::move(move.fUtf8Buffer)) { } /** Copy constructor from plStringBuffer. * \note This constructor expects the input to be UTF-8 encoded. For * conversion from ISO-8859-1 8-bit data, use FromIso8859_1(). */ - plString(const plStringBuffer &init) { operator=(init); } + plString(const plStringBuffer &init) HS_NOEXCEPT { operator=(init); } /** Move constructor from plStringBuffer. */ - plString(plStringBuffer &&init) { operator=(std::move(init)); } + plString(plStringBuffer &&init) HS_NOEXCEPT { operator=(std::move(init)); } /** Construct a string from expanded Unicode data. */ plString(const plUnicodeBuffer &init) { IConvertFromUtf32(init.GetData(), init.GetSize()); } @@ -315,10 +315,10 @@ public: plString &operator=(char (&literal)[_Sz]) { IConvertFromUtf8(literal, STRLEN_AUTO); return *this; } /** Assignment operator. Same as plString(const plString &). */ - plString &operator=(const plString ©) { fUtf8Buffer = copy.fUtf8Buffer; return *this; } + plString &operator=(const plString ©) HS_NOEXCEPT { fUtf8Buffer = copy.fUtf8Buffer; return *this; } /** Assignment operator. Same as plString(plString &&). */ - plString &operator=(plString &&move) { fUtf8Buffer = std::move(move.fUtf8Buffer); return *this; } + plString &operator=(plString &&move) HS_NOEXCEPT { fUtf8Buffer = std::move(move.fUtf8Buffer); return *this; } /** Assignment operator. Same as plString(const plStringBuffer &). */ plString &operator=(const plStringBuffer &init); @@ -384,17 +384,17 @@ public: * expecting C-style string pointers. If this string is empty, returns * \a substitute instead. */ - const char *c_str(const char *substitute = "") const + const char *c_str(const char *substitute = "") const HS_NOEXCEPT { return IsEmpty() ? substitute : fUtf8Buffer.GetData(); } /** Return the byte at position \a position. Note that this may be in * the middle of a UTF-8 sequence -- if you want an actual Unicode * character, use the buffer returned from GetUnicodeArray() instead. */ - char CharAt(size_t position) const { return c_str()[position]; } + char CharAt(size_t position) const HS_NOEXCEPT { return c_str()[position]; } /** Returns the internal UTF-8 data buffer object. */ - plStringBuffer ToUtf8() const { return fUtf8Buffer; } + plStringBuffer ToUtf8() const HS_NOEXCEPT { return fUtf8Buffer; } /** Convert this string's data to a UTF-16 string buffer. */ plStringBuffer ToUtf16() const; @@ -421,10 +421,10 @@ public: /** Returns the size in number of bytes (excluding the null-terminator) of * this string. */ - size_t GetSize() const { return fUtf8Buffer.GetSize(); } + size_t GetSize() const HS_NOEXCEPT { return fUtf8Buffer.GetSize(); } /** Returns \c true if this string is empty (""). */ - bool IsEmpty() const { return fUtf8Buffer.GetSize() == 0; } + bool IsEmpty() const HS_NOEXCEPT { return fUtf8Buffer.GetSize() == 0; } /** Returns \c true if this string is "null". Currently, this is just * a synonym for IsEmpty(), as plString makes no distinction between @@ -432,27 +432,27 @@ public: * \todo Evaluate whether Plasma actually needs to distinguish between * empty and NULL strings. Ideally, only IsEmpty should be required. */ - bool IsNull() const { return IsEmpty(); } + bool IsNull() const HS_NOEXCEPT { return IsEmpty(); } /** Convert the string data to an integer in base \a base. * If base is set to 0, this function behaves like strtol, which checks * for hex or octal prefixes (e.g. 0777 or 0x1234), and assumes base 10 * if none are found. */ - int ToInt(int base = 0) const; + int ToInt(int base = 0) const HS_NOEXCEPT; /** Convert the string to an unsigned integer in base \a base. * If base is set to 0, this function behaves like strtoul, which checks * for hex or octal prefixes (e.g. 0777 or 0x1234), and assumes base 10 * if none are found. */ - unsigned int ToUInt(int base = 0) const; + unsigned int ToUInt(int base = 0) const HS_NOEXCEPT; /** Convert the string to a floating point value. */ - float ToFloat() const; + float ToFloat() const HS_NOEXCEPT; /** Convert the string to a double precision floating point value. */ - double ToDouble() const; + double ToDouble() const HS_NOEXCEPT; /** Construct a plString using a printf-like format string. * This function should be called inside of other vararg functions, @@ -470,7 +470,7 @@ public: * \li \p \<0 - this string is lexicographically less than \a str * \li \p \>0 - this string is lexicographically greater than \a str */ - int Compare(const plString &str, CaseSensitivity sense = kCaseSensitive) const + int Compare(const plString &str, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT { return (sense == kCaseSensitive) ? strcmp(c_str(), str.c_str()) : stricmp(c_str(), str.c_str()); @@ -482,7 +482,7 @@ public: * \li \p \<0 - this string is lexicographically less than \a str * \li \p \>0 - this string is lexicographically greater than \a str */ - int Compare(const char *str, CaseSensitivity sense = kCaseSensitive) const + int Compare(const char *str, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT { return (sense == kCaseSensitive) ? strcmp(c_str(), str ? str : "") : stricmp(c_str(), str ? str : ""); @@ -492,7 +492,7 @@ public: * string with \a str. * \sa Compare(const plString &, CaseSensitivity) const */ - int CompareN(const plString &str, size_t count, CaseSensitivity sense = kCaseSensitive) const + int CompareN(const plString &str, size_t count, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT { return (sense == kCaseSensitive) ? strncmp(c_str(), str.c_str(), count) : strnicmp(c_str(), str.c_str(), count); @@ -502,58 +502,58 @@ public: * string with \a str. * \sa Compare(const char *, CaseSensitivity) const */ - int CompareN(const char *str, size_t count, CaseSensitivity sense = kCaseSensitive) const + int CompareN(const char *str, size_t count, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT { return (sense == kCaseSensitive) ? strncmp(c_str(), str ? str : "", count) : strnicmp(c_str(), str ? str : "", count); } /** Shortcut for Compare(str, kCaseInsensitive). */ - int CompareI(const plString &str) const { return Compare(str, kCaseInsensitive); } + int CompareI(const plString &str) const HS_NOEXCEPT { return Compare(str, kCaseInsensitive); } /** Shortcut for Compare(str, kCaseInsensitive). */ - int CompareI(const char *str) const { return Compare(str, kCaseInsensitive); } + int CompareI(const char *str) const HS_NOEXCEPT { return Compare(str, kCaseInsensitive); } /** Shortcut for CompareN(str, kCaseInsensitive). */ - int CompareNI(const plString &str, size_t count) const { return CompareN(str, count, kCaseInsensitive); } + int CompareNI(const plString &str, size_t count) const HS_NOEXCEPT { return CompareN(str, count, kCaseInsensitive); } /** Shortcut for CompareN(str, kCaseInsensitive). */ - int CompareNI(const char *str, size_t count) const { return CompareN(str, count, kCaseInsensitive); } + int CompareNI(const char *str, size_t count) const HS_NOEXCEPT { return CompareN(str, count, kCaseInsensitive); } /** Operator overload for use in containers which depend on \c std::less. */ - bool operator<(const plString &other) const { return Compare(other) < 0; } + bool operator<(const plString &other) const HS_NOEXCEPT { return Compare(other) < 0; } /** Test if this string contains the same string data as \a other. */ - bool operator==(const char *other) const { return Compare(other) == 0; } + bool operator==(const char *other) const HS_NOEXCEPT { return Compare(other) == 0; } /** Test if this string contains the same string data as \a other. */ - bool operator==(const plString &other) const { return Compare(other) == 0; } + bool operator==(const plString &other) const HS_NOEXCEPT { return Compare(other) == 0; } /** Inverse of operator==(const char *) const. */ - bool operator!=(const char *other) const { return Compare(other) != 0; } + bool operator!=(const char *other) const HS_NOEXCEPT { return Compare(other) != 0; } /** Inverse of operator==(const plString &) const. */ - bool operator!=(const plString &other) const { return Compare(other) != 0; } + bool operator!=(const plString &other) const HS_NOEXCEPT { return Compare(other) != 0; } /** Find the index (in bytes) of the first instance of \a ch in this string. * \return -1 if the character was not found. */ - ssize_t Find(char ch, CaseSensitivity sense = kCaseSensitive) const; + ssize_t Find(char ch, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT; /** Find the index (in bytes) of the last instance of \a ch in this string. * \return -1 if the character was not found. */ - ssize_t FindLast(char ch, CaseSensitivity sense = kCaseSensitive) const; + ssize_t FindLast(char ch, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT; /** Find the index (in bytes) of the first instance of \a str in this string. * \return -1 if the substring was not found. */ - ssize_t Find(const char *str, CaseSensitivity sense = kCaseSensitive) const; + ssize_t Find(const char *str, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT; /** Find the index (in bytes) of the first instance of \a str in this string. * \return -1 if the substring was not found. */ - ssize_t Find(const plString &str, CaseSensitivity sense = kCaseSensitive) const + ssize_t Find(const plString &str, CaseSensitivity sense = kCaseSensitive) const HS_NOEXCEPT { return Find(str.c_str(), sense); } /** Check that this string matches the specified regular expression. @@ -645,7 +645,7 @@ public: { // TODO: This doesn't really use enough bits to be useful when // size_t is 64-bits. - size_t operator()(const plString& str) const + size_t operator()(const plString& str) const HS_NOEXCEPT { size_t hash = 0; for (size_t i = 0; i < str.GetSize(); ++i) { @@ -660,7 +660,7 @@ public: } protected: - virtual char fetch_char(const plString& str, size_t index) const + virtual char fetch_char(const plString& str, size_t index) const HS_NOEXCEPT { return str.CharAt(index); } }; @@ -670,21 +670,21 @@ public: struct hash_i : public hash { protected: - virtual char fetch_char(const plString& str, size_t index) const + char fetch_char(const plString& str, size_t index) const HS_NOEXCEPT HS_FINAL HS_OVERRIDE { return tolower(str.CharAt(index)); } }; /** Functor which compares two strings case-insensitively for sorting. */ struct less_i { - bool operator()(const plString &_L, const plString &_R) const + bool operator()(const plString &_L, const plString &_R) const HS_NOEXCEPT { return _L.Compare(_R, kCaseInsensitive) < 0; } }; /** Functor which compares two strings case-insensitively for equality. */ struct equal_i { - bool operator()(const plString &_L, const plString &_R) const + bool operator()(const plString &_L, const plString &_R) const HS_NOEXCEPT { return _L.Compare(_R, kCaseInsensitive) == 0; } }; @@ -715,16 +715,16 @@ public: /** Construct a new empty string stream. The first STRING_STACK_SIZE * bytes are allocated on the stack for further efficiency. */ - plStringStream() : fBufSize(STRING_STACK_SIZE), fLength(0) { } + plStringStream() HS_NOEXCEPT : fBufSize(STRING_STACK_SIZE), fLength(0) { } /** Destructor, frees any allocated heap memory owned by the stream. */ - ~plStringStream() { if (ICanHasHeap()) delete [] fBuffer; } + ~plStringStream() HS_NOEXCEPT { if (ICanHasHeap()) delete [] fBuffer; } plStringStream(const plStringStream &) = delete; plStringStream &operator=(const plStringStream &) = delete; /** Move operator */ - plStringStream(plStringStream &&move) + plStringStream(plStringStream &&move) HS_NOEXCEPT : fBufSize(move.fBufSize), fLength(move.fLength) { memcpy(fShort, move.fShort, sizeof(fShort)); @@ -732,7 +732,7 @@ public: } /** Move assignment operator. */ - plStringStream &operator=(plStringStream &&move) + plStringStream &operator=(plStringStream &&move) HS_NOEXCEPT { memcpy(fShort, move.fShort, sizeof(fShort)); fBufSize = move.fBufSize; @@ -780,13 +780,13 @@ public: /** Returns a pointer to the beginning of the stream buffer. * \warning This pointer is not null-terminated. */ - const char *GetRawBuffer() const + const char *GetRawBuffer() const HS_NOEXCEPT { return ICanHasHeap() ? fBuffer : fShort; } /** Return the size (in bytes) of the stream's data. */ - size_t GetLength() const { return fLength; } + size_t GetLength() const HS_NOEXCEPT { return fLength; } /** Convert the stream's data to a UTF-8 string. */ plString GetString() const { return plString::FromUtf8(GetRawBuffer(), fLength); } @@ -796,7 +796,7 @@ public: * with as much space as it had before, making this method more * useful for re-using string streams in loops. */ - void Truncate() { fLength = 0; } + void Truncate() HS_NOEXCEPT { fLength = 0; } private: union { @@ -805,7 +805,7 @@ private: }; size_t fBufSize, fLength; - bool ICanHasHeap() const { return fBufSize > STRING_STACK_SIZE; } + bool ICanHasHeap() const HS_NOEXCEPT { return fBufSize > STRING_STACK_SIZE; } }; /** \p strlen implementation for plUniChar based C-style string buffers. */ diff --git a/Sources/Plasma/PubUtilLib/plAudio/plEAXEffects.cpp b/Sources/Plasma/PubUtilLib/plAudio/plEAXEffects.cpp index 5feb43ff..9a0b4d7e 100644 --- a/Sources/Plasma/PubUtilLib/plAudio/plEAXEffects.cpp +++ b/Sources/Plasma/PubUtilLib/plAudio/plEAXEffects.cpp @@ -150,7 +150,13 @@ bool plEAXListener::Init( void ) SetGlobalEAXProperty(DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ROOM, &lRoom, sizeof( unsigned int )); } - catch ( ... ) + catch (std::exception &e) + { + plStatusLog::AddLineS("audio.log", "Unable to set EAX Property Set (%s), disabling EAX...", e.what()); + plgAudioSys::EnableEAX(false); + return false; + } + catch (...) { plStatusLog::AddLineS("audio.log", "Unable to set EAX Property Set, disabling EAX..."); plgAudioSys::EnableEAX(false); diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp index 5485995c..e690c71e 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp @@ -158,14 +158,16 @@ bool plAvBrainHuman::Apply(double timeNow, float elapsed) fWalkingStrategy->SetTurnStrength(IGetTurnStrength(timeNow)); RunStandardBehaviors(timeNow, elapsed); fWalkingStrategy->RecalcVelocity(timeNow, elapsed, (fPreconditions & plHBehavior::kBehaviorTypeNeedsRecalcMask)); - + plArmatureBrain::Apply(timeNow, elapsed); #ifndef _DEBUG - } catch (...) - { + } catch (std::exception &e) { + plStatusLog *log = plAvatarMgr::GetInstance()->GetLog(); + log->AddLineF("plAvBrainHuman::Apply - exception caught: %s", e.what()); + } catch (...) { // just catch all the crashes on exit... plStatusLog *log = plAvatarMgr::GetInstance()->GetLog(); - log->AddLine("plAvBrainHuman::Apply - crash caught"); + log->AddLine("plAvBrainHuman::Apply - exception caught"); } #endif diff --git a/Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h b/Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h index 01bc12a1..8069d4c6 100644 --- a/Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h +++ b/Sources/Plasma/PubUtilLib/plGImage/plDynamicTextMap.h @@ -130,9 +130,9 @@ class plDynamicTextMap : public plMipmap virtual uint8_t GetNumLevels( void ) const { return 1; } - void Colorize() override { } - plMipmap *Clone() const override; - void CopyFrom(const plMipmap *source) override; + void Colorize() HS_OVERRIDE { } + plMipmap *Clone() const HS_OVERRIDE; + void CopyFrom(const plMipmap *source) HS_OVERRIDE; /// Operations to perform on the text block diff --git a/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp b/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp index 90770fd5..e998e089 100644 --- a/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp +++ b/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp @@ -1475,7 +1475,13 @@ bool plFont::LoadFromFNTStream( hsStream *stream ) ICalcFontAscent(); return true; } - catch( ... ) + catch (std::exception &e) + { + printf("Exception caught in plFont::LoadFromFNTStream: %s\n", e.what()); + IClear(); + return false; + } + catch (...) { // Somehow we crashed converting! IClear(); @@ -2092,7 +2098,14 @@ bool plFont::LoadFromBDF( const plFileName &path, plBDFConvertCallback *callb } } } - catch( ... ) + catch (std::exception &e) + { + printf("Exception caught in plFont::LoadFromBDF: %s\n", e.what()); + IClear(); + fclose(fp); + return false; + } + catch (...) { IClear(); fclose( fp ); diff --git a/Sources/Plasma/PubUtilLib/plGImage/plJPEG.cpp b/Sources/Plasma/PubUtilLib/plGImage/plJPEG.cpp index e592a010..1df89465 100644 --- a/Sources/Plasma/PubUtilLib/plGImage/plJPEG.cpp +++ b/Sources/Plasma/PubUtilLib/plGImage/plJPEG.cpp @@ -73,7 +73,7 @@ static char jpegmsg[JMSG_LENGTH_MAX]; static void plJPEG_error_exit( j_common_ptr cinfo ) { (*cinfo->err->format_message) ( cinfo, jpegmsg ); - throw ( false ); + throw false; } static void plJPEG_emit_message( j_common_ptr cinfo, int msg_level ) { @@ -134,7 +134,7 @@ plMipmap *plJPEG::IRead( hsStream *inStream ) /// Read in the JPEG header if ( inStream->GetEOF() == 0 ) - throw( false ); + throw false; /// Wonderful limitation of mixing our streams with IJL--it wants either a filename /// or a memory buffer. Since we can't give it the former, we have to read the entire @@ -142,11 +142,6 @@ plMipmap *plJPEG::IRead( hsStream *inStream ) /// have to write/read a length of said buffer. Such is life, I guess... jpegSourceSize = inStream->ReadLE32(); jpegSourceBuffer = new uint8_t[ jpegSourceSize ]; - if( jpegSourceBuffer == nil ) - { - // waah. - ERREXIT1( &cinfo, JERR_OUT_OF_MEMORY, 0 ); - } inStream->Read( jpegSourceSize, jpegSourceBuffer ); jpeg_mem_src( &cinfo, jpegSourceBuffer, jpegSourceSize ); @@ -183,11 +178,6 @@ plMipmap *plJPEG::IRead( hsStream *inStream ) /// Construct a new mipmap to hold everything newMipmap = new plMipmap( cinfo.output_width, cinfo.output_height, plMipmap::kRGB32Config, 1, plMipmap::kJPEGCompression ); - if( newMipmap == nil || newMipmap->GetImage() == nil ) - { - ERREXIT1( &cinfo, JERR_OUT_OF_MEMORY, 0 ); - } - /// Set up to read in to that buffer we now have JSAMPROW jbuffer; int row_stride = cinfo.output_width * cinfo.output_components; @@ -216,7 +206,7 @@ plMipmap *plJPEG::IRead( hsStream *inStream ) // Sometimes life just sucks ISwapRGBAComponents( (uint32_t *)newMipmap->GetImage(), newMipmap->GetWidth() * newMipmap->GetHeight() ); } - catch( ... ) + catch (...) { delete newMipmap; newMipmap = nil; @@ -282,10 +272,6 @@ bool plJPEG::IWrite( plMipmap *source, hsStream *outStream ) // Create a buffer to hold the data jpgBufferSize = source->GetWidth() * source->GetHeight() * 3; jpgBuffer = new uint8_t[ jpgBufferSize ]; - if( jpgBuffer == nil ) - { - ERREXIT1( &cinfo, JERR_OUT_OF_MEMORY, 0 ); - } uint8_t *bufferAddr = jpgBuffer; unsigned long bufferSize = jpgBufferSize; @@ -338,7 +324,7 @@ bool plJPEG::IWrite( plMipmap *source, hsStream *outStream ) outStream->WriteLE32( bufferSize ); outStream->Write( bufferSize, bufferAddr ); } - catch( ... ) + catch (...) { result = false; } diff --git a/Sources/Plasma/PubUtilLib/plGImage/plPNG.cpp b/Sources/Plasma/PubUtilLib/plGImage/plPNG.cpp index 9e8c3253..1e091251 100644 --- a/Sources/Plasma/PubUtilLib/plGImage/plPNG.cpp +++ b/Sources/Plasma/PubUtilLib/plGImage/plPNG.cpp @@ -95,21 +95,21 @@ plMipmap* plPNG::IRead(hsStream* inStream) png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { - throw(false); + throw false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - throw(false); + throw false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - throw(false); + throw false; } // Assign delegate function for reading from hsStream @@ -169,10 +169,8 @@ plMipmap* plPNG::IRead(hsStream* inStream) delete [] row_ptrs; } } catch (...) { - if (newMipmap != NULL) { - delete newMipmap; - newMipmap = NULL; - } + delete newMipmap; + newMipmap = nullptr; } return newMipmap; @@ -200,14 +198,14 @@ bool plPNG::IWrite(plMipmap* source, hsStream* outStream) png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { - throw(false); + throw false; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - throw(false); + throw false; } // Assign delegate function for writing to hsStream diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h index 0e13a7b5..a9cb101c 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h @@ -237,7 +237,7 @@ private: int ISendGameMessage(plMessage* msg); void IDisableNet (); - void ICreateStatusLog() const override; + void ICreateStatusLog() const HS_OVERRIDE; public: plNetClientMgr(); @@ -265,7 +265,7 @@ public: void SendApplyAvatarCustomizationsMsg(const plKey msgReceiver, bool netPropagate=true, bool localPropagate=true); // plLoggable - bool Log(const plString& str) const override; + bool Log(const plString& str) const HS_OVERRIDE; // setters void SetIniAuthServer(const char * value) { fIniAuthServer=value;} diff --git a/Sources/Plasma/PubUtilLib/plSDL/plSDLMgr.cpp b/Sources/Plasma/PubUtilLib/plSDL/plSDLMgr.cpp index 9c802815..c936f21a 100644 --- a/Sources/Plasma/PubUtilLib/plSDL/plSDLMgr.cpp +++ b/Sources/Plasma/PubUtilLib/plSDL/plSDLMgr.cpp @@ -191,7 +191,19 @@ int plSDLMgr::Read(hsStream* s, plSDL::DescriptorList* dl) delete sd; // well that sucked } } - catch(...) + catch (std::exception &e) + { + if (fNetApp) + { + hsLogEntry(fNetApp->DebugMsg("Something bad happened while reading SDLMgr data: %s", e.what())); + } + else + { + DebugMsg("Something bad happened while reading SDLMgr data: %s", e.what()); + } + return 0; + } + catch (...) { if (fNetApp) { diff --git a/Sources/Plasma/PubUtilLib/plSDL/plStateDataRecord.cpp b/Sources/Plasma/PubUtilLib/plSDL/plStateDataRecord.cpp index ccf7718c..1d5cc025 100644 --- a/Sources/Plasma/PubUtilLib/plSDL/plStateDataRecord.cpp +++ b/Sources/Plasma/PubUtilLib/plSDL/plStateDataRecord.cpp @@ -274,9 +274,16 @@ bool plStateDataRecord::Read(hsStream* s, float timeConvert, uint32_t readOption } } } - catch(...) + catch (std::exception &e) { - hsAssert( false, + hsAssert(false, + plFormat("Something bad happened ({}) while reading simple var data, desc:{}", + e.what(), fDescriptor ? fDescriptor->GetName() : "?").c_str()); + return false; + } + catch (...) + { + hsAssert(false, plFormat("Something bad happened while reading simple var data, desc:{}", fDescriptor ? fDescriptor->GetName() : "?").c_str()); return false; @@ -308,9 +315,16 @@ bool plStateDataRecord::Read(hsStream* s, float timeConvert, uint32_t readOption } } } - catch(...) + catch (std::exception &e) + { + hsAssert(false, + plFormat("Something bad happened ({}) while reading nested var data, desc:{}", + e.what(), fDescriptor ? fDescriptor->GetName() : "?").c_str()); + return false; + } + catch (...) { - hsAssert( false, + hsAssert(false, plFormat("Something bad happened while reading nested var data, desc:{}", fDescriptor ? fDescriptor->GetName() : "?").c_str()); return false; diff --git a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h index 991765ad..ddf356a9 100644 --- a/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h +++ b/Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h @@ -159,7 +159,7 @@ class plStatusLog : public plLog ~plStatusLog(); - bool AddLine(const plString& line) override; + bool AddLine(const plString& line) HS_OVERRIDE; bool AddLine( const char *line, uint32_t color = kWhite ); diff --git a/Sources/Tools/plFontConverter/plFontConverter.cpp b/Sources/Tools/plFontConverter/plFontConverter.cpp index 8dec0c85..381cc14c 100644 --- a/Sources/Tools/plFontConverter/plFontConverter.cpp +++ b/Sources/Tools/plFontConverter/plFontConverter.cpp @@ -350,12 +350,12 @@ class plMyBDFCallback : public plBDFConvertCallback public: plMyBDFCallback(QWidget *parent) : fProgress(parent) { } - virtual void NumChars(uint16_t chars) override + void NumChars(uint16_t chars) HS_OVERRIDE { fProgress.SetRange(chars); } - virtual void CharDone() override + void CharDone() HS_OVERRIDE { fPoint++; fProgress.SetValue(fPoint); @@ -498,7 +498,7 @@ class NumListValidator : public QValidator public: NumListValidator(QObject *parent = nullptr) : QValidator(parent) { } - virtual State validate(QString &input, int &pos) const override + State validate(QString &input, int &pos) const HS_OVERRIDE { for (int ch = 0; ch < input.size(); ++ch) { diff --git a/Sources/Tools/plLocalizationEditor/plAddDlgs.cpp b/Sources/Tools/plLocalizationEditor/plAddDlgs.cpp index f9180642..216084d7 100644 --- a/Sources/Tools/plLocalizationEditor/plAddDlgs.cpp +++ b/Sources/Tools/plLocalizationEditor/plAddDlgs.cpp @@ -59,7 +59,7 @@ class AlphaNumericValidator : public QValidator public: AlphaNumericValidator(QObject *parent = nullptr) : QValidator(parent) { } - virtual State validate(QString &input, int &pos) const override + State validate(QString &input, int &pos) const HS_OVERRIDE { for (int ch = 0; ch < input.size(); ++ch) { diff --git a/Sources/Tools/plResBrowser/plResBrowser.h b/Sources/Tools/plResBrowser/plResBrowser.h index 9372db17..1cd2c783 100644 --- a/Sources/Tools/plResBrowser/plResBrowser.h +++ b/Sources/Tools/plResBrowser/plResBrowser.h @@ -43,6 +43,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #define _plResBrowser_h #include +#include "HeadSpin.h" class plResBrowser : public QMainWindow { @@ -55,8 +56,8 @@ public: void SetWindowTitle(const QString &title); protected: - virtual void dragEnterEvent(QDragEnterEvent *event) override; - virtual void dropEvent(QDropEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) HS_OVERRIDE; + void dropEvent(QDropEvent *event) HS_OVERRIDE; private slots: void OpenFile(); diff --git a/cmake/CompilerChecks.cmake b/cmake/CompilerChecks.cmake index 11be0d74..6248e38f 100644 --- a/cmake/CompilerChecks.cmake +++ b/cmake/CompilerChecks.cmake @@ -40,8 +40,7 @@ endif() # Check for CPUID headers try_compile(HAVE_CPUID ${PROJECT_BINARY_DIR} - ${PROJECT_SOURCE_DIR}/cmake/check_cpuid.cpp - OUTPUT_VARIABLE OUTPUT) + ${PROJECT_SOURCE_DIR}/cmake/check_cpuid.cpp) if(HAVE_CPUID) message("CPUID header found -- using hardware math acceleration when available") else() @@ -51,17 +50,22 @@ endif() # Look for a supported "deprecated" attribute specifier. try_compile(HAVE_CXX14_DEPRECATED_ATTR ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/check_deprecated_attribute.cpp - COMPILE_DEFINITIONS -DTRY_ATTRIBUTE - OUTPUT_VARIABLE OUTPUT) + COMPILE_DEFINITIONS -DTRY_ATTRIBUTE) try_compile(HAVE_GCC_DEPRECATED_ATTR ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/check_deprecated_attribute.cpp - COMPILE_DEFINITIONS -DTRY_GCC_ATTR - OUTPUT_VARIABLE OUTPUT) + COMPILE_DEFINITIONS -DTRY_GCC_ATTR) # Look for C++11 constexpr support try_compile(HAVE_CONSTEXPR ${PROJECT_BINARY_DIR} - ${PROJECT_SOURCE_DIR}/cmake/check_constexpr.cpp - OUTPUT_VARIABLE OUTPUT) + ${PROJECT_SOURCE_DIR}/cmake/check_constexpr.cpp) + +# Look for C++11 override/final specifiers +try_compile(HAVE_OVERRIDE ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR}/cmake/check_override.cpp) + +# Look for C++11 noexcept specifier +try_compile(HAVE_NOEXCEPT ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR}/cmake/check_noexcept.cpp) configure_file(${PROJECT_SOURCE_DIR}/cmake/hsCompilerSpecific.h.cmake ${PROJECT_BINARY_DIR}/hsCompilerSpecific.h) diff --git a/cmake/check_noexcept.cpp b/cmake/check_noexcept.cpp new file mode 100644 index 00000000..a1c5691f --- /dev/null +++ b/cmake/check_noexcept.cpp @@ -0,0 +1,7 @@ +void doesnt_throw() noexcept { } + +int main(int, char **) +{ + doesnt_throw(); + return 0; +} diff --git a/cmake/check_override.cpp b/cmake/check_override.cpp new file mode 100644 index 00000000..b6c70f66 --- /dev/null +++ b/cmake/check_override.cpp @@ -0,0 +1,26 @@ +class Base +{ +public: + virtual ~Base() { } + virtual void virtual_function() = 0; +}; + +class Override : public Base +{ +public: + void virtual_function() override { } +}; + +class Final : public Override +{ +public: + void virtual_function() final { } +}; + +int main(int, char **) +{ + Final klass; + klass.virtual_function(); + + return 0; +} diff --git a/cmake/hsCompilerSpecific.h.cmake b/cmake/hsCompilerSpecific.h.cmake index 242c4cf1..665e5500 100644 --- a/cmake/hsCompilerSpecific.h.cmake +++ b/cmake/hsCompilerSpecific.h.cmake @@ -52,5 +52,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #cmakedefine HAVE_GCC_DEPRECATED_ATTR #cmakedefine HAVE_CONSTEXPR +#cmakedefine HAVE_OVERRIDE +#cmakedefine HAVE_NOEXCEPT #endif