elBase.h

/******************************************************************************** * Elgrint base header * Elgrint library, version 1.0 * Created by Dimitry Rotstein * Copyright(C) 2013 by Miranor * Description: * - Defines atomic/elementary types, constants, global functions, and macros * for general use in all Elgrint modules * *******************************************************************************/ #ifndef MIRANOR_ELGRINT_BASE #define MIRANOR_ELGRINT_BASE #include <limits.h> // Helps determine IntN and UIntN #include <math.h> // Often useful #include <time.h> // 'clock' is used often #ifdef _VCPP_COMPILER #pragma warning(disable : 4355) // Allow 'this' in init lists (used extensively) #endif namespace Elgrint { ///////////////////////////////////////////////////////////////////////////////// /////////////////////// Atomic types (8/16/32/64 bits) ////////////////////////// ///////////////////////////////////////////////////////////////////////////////// // Define Int8/UInt8 #if UCHAR_MAX == 0xFF typedef signed char Int8; typedef unsigned char UInt8; #else #error Unable to identify an 8-bit type #endif // Define Int16/UInt16 #if USHRT_MAX == 0xFFFF typedef signed short Int16; typedef unsigned short UInt16; #elif UINT_MAX == 0xFFFF typedef signed int Int16; typedef unsigned int UInt16; #elif ULONG_MAX == 0xFFFF typedef signed long Int16; typedef unsigned long UInt16; #else #error Unable to identify a 16-bit type #endif // Define Int32/UInt32 #if USHRT_MAX == 0xFFFFFFFF typedef signed short Int32; typedef unsigned short UInt32; #elif UINT_MAX == 0xFFFFFFFF typedef signed int Int32; typedef unsigned int UInt32; #elif ULONG_MAX == 0xFFFFFFFF typedef signed long Int32; typedef unsigned long UInt32; #else #error Unable to identify a 32-bit type #endif // Define Int64/UInt64 #if UINT_MAX == 0xFFFFFFFFFFFFFFFF typedef signed int Int64; typedef unsigned int UInt64; #elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF typedef signed long Int64; typedef unsigned long UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif ///////////////////////////////////////////////////////////////////////////////// //////////////////////// Elementary types (atomic-based) //////////////////////// ///////////////////////////////////////////////////////////////////////////////// // MNum: large enough to enumerate all addressable memory #if defined _WIN64 typedef UInt64 MNum; #elif defined _WIN32 typedef UInt32 MNum; #else typedef UInt64 MNum; #endif typedef UInt64 MFileSize; // For MFile (MNum may not be large enough) typedef UInt32 MLocusElem; // For MLocus (external for simplicity) typedef double MSizeElem; // For MSize/MRect (external for simplicity) typedef double MPointElem; // For MPoint/MRect (external for simplicity) ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////// Elementary constants ////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// const UInt32 None = 0x7FFF7F7F; const UInt32 Auto = 0x7FFF7F7E; const UInt32 Same = 0x7FFF7F7D; const UInt32 Zero = 0; const MNum MaxNum = MNum(-1); const MNum MaxNoticeID = UInt32(-1); const MNum MaxTimerID = 2000000000; const MNum MinTimerDelay = 10; const MNum MaxTimerDelay = 2000000000; // ~23.1 days const MFileSize MaxFileSize = MFileSize(-1); ///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Functions /////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// // The 'IsValid' function detects invalid values: None/Auto/Same, and // derived (e.g. NoneRect). Can also be used in other cases, e.g. for MWindow // Note: IsValid(float) is defined below because it uses M_PARAM_CHECK // inline bool IsValid(const Int8& n) { return (n&0xF0) != 0x70; } inline bool IsValid(const UInt8& n) { return (n&0xF0) != 0x70; } inline bool IsValid(const Int16& n) { return (n&0xFFF0) != 0x7F70; } inline bool IsValid(const UInt16& n) { return (n&0xFFF0) != 0x7F70; } inline bool IsValid(const Int32& n) { return (n&0xFFFFFFF0) != 0x7FFF7F70; } inline bool IsValid(const UInt32& n) { return (n&0xFFFFFFF0) != 0x7FFF7F70; } inline bool IsValid(const Int64& n) { return (n&0x00FFFFFFF0) != 0x007FFF7F70; } inline bool IsValid(const UInt64& n) { return (n&0x00FFFFFFF0) != 0x007FFF7F70; } inline bool IsValid(const double& n) { return n<0x007FFF7F70 || n>0x007FFF7F7F; } inline bool IsValid(const long double& n) { return n<0x007FFF7F70 || n>0x007FFF7F7F; } inline bool IsValid(const char& ch) { return ch >= 1 && ch <= 127; } // The 'IsPlainType' functions allow MVector and MFile to operate noticeably // faster, yet safely, for any type T, which satisfies all of the following // conditions: // - Does not allocate memory // - Does not contain pointers/references (directly or indirectly) // - Assignment operator can handle any garbage value // - Has empty d-tor or no d-tor at all (i.e. d-tor can be skipped without problems) // - Does not use "this" pointer explicitly, or doesn't have one at all // // All types are assumed to be non-plain for safety reasons, unless explicitly // specified otherwise, by a specialization of IsPlainType function, as done for // all built-in types below. You can define additional IsPlainType specializations // for any type which satisfies the above conditions. If you're not sure that // it does, then do NOT redefine IsPlainType template <class T> inline bool IsPlainType() { return false; } // Universal version template<> inline bool IsPlainType<signed char> () { return true; } template<> inline bool IsPlainType<unsigned char> () { return true; } template<> inline bool IsPlainType<signed short> () { return true; } template<> inline bool IsPlainType<unsigned short> () { return true; } template<> inline bool IsPlainType<signed int> () { return true; } template<> inline bool IsPlainType<unsigned int> () { return true; } template<> inline bool IsPlainType<signed long> () { return true; } template<> inline bool IsPlainType<unsigned long> () { return true; } template<> inline bool IsPlainType<signed long long> () { return true; } template<> inline bool IsPlainType<unsigned long long>() { return true; } template<> inline bool IsPlainType<float> () { return true; } template<> inline bool IsPlainType<double> () { return true; } template<> inline bool IsPlainType<long double> () { return true; } template<> inline bool IsPlainType<bool> () { return true; } template<> inline bool IsPlainType<char> () { return true; } // Max/Min returns a reference to the largest/smallest value of the two template <class T> inline const T& Max(const T& a, const T& b) { return b<a?a:b; } template <class T> inline const T& Min(const T& a, const T& b) { return a<b?a:b; } // If 'val' is out of ['minVal','maxVal'] range, return the closest value 'val' // within this range. If 'minVal' > 'maxVal', returns 'maxVal' for any 'val' // template <class T> inline const T& ToRange(const T& val, const T& minVal, const T& maxVal) { return Min(Max(val,minVal),maxVal); } // Swaps two values (specialized for collections using their 'swapWith' methods) // template <class T> inline void Swap(T& a, T& b) { T tmp = a; a = b; b = tmp; } // Returns true iff bit number 'b' in 'src' is set // template <class N> inline bool IsBit(const N& src, UInt8 b) { return b < sizeof(N)*8 && (src & (N(1)<<b)) != 0; } // Extracts bit sequence from bit number 'b1' through 'b2' and returns the integer // value of a number composed of the extracted bits. // template <class N> inline N GetBits(N src, UInt8 b1, UInt8 b2) { const UInt8 LAST_BIT = sizeof(N)*8 - 1; b2 = Min(b2, LAST_BIT); if (b1 > b2) return 0; src <<= (LAST_BIT-b2); src >>= (LAST_BIT-b2+b1); return src; } ///////////////////////////////////////////////////////////////////////////////// ////////////////////////////// Assertion macros ///////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// // // M_ASSERT - standard assertion for internal consistency checks // M_PARAM_CHECK - similar to M_ASSERT, but generates a more user-friendly output // on assertion failure. Used on arguments of public functions extern bool assertRaised; // Prevents stack overflow due to assertion within assertion // Must be defined in RELEASE mode as well, because it's used in the 'catch' statements struct _MAssertionRecord { const char* condStr; const char* filename; int lineNum; _MAssertionRecord(const char* acondStr, const char* afilename, int alineNum) : condStr(acondStr), filename(afilename), lineNum(alineNum) {} }; #ifdef _DEBUG #define M_PARAM_CHECK(cond,msg) \ { if (!(cond) && !assertRaised) \ { assertRaised = true; throw _MAssertionRecord(msg, __FILE__, __LINE__); } \ } #define M_ASSERT(cond) \ { if (!(cond) && !assertRaised) \ { assertRaised = true; throw _MAssertionRecord(#cond, __FILE__, __LINE__); } \ } #else #define M_PARAM_CHECK(cond,msg) #define M_ASSERT(cond) #endif

...

Miranor Home | About Miranor | About Elgrint | Create account | Login | Account settings | Contact Us | Privacy Policy | Site map

© Copyright 2014 by Miranor. All rights reserved. By using this site you agree to the Terms of Use.

Page last updated on August 10th, 2014.