/**************************************************************************************************************************** Basic.h This library provides function templates to better support C++ functional programming across platforms. Based on Vlpp library (https://github.com/vczh-libraries/Vlpp) and Marcus Rugger functional-vlpp library (https://github.com/marcusrugger/functional-vlpp) Built by Khoi Hoang (https://github.com/khoih-prog/functional-vlpp) Licensed under MIT license Original author Vczh Library++ 3.0 Developer: Zihan Chen(vczh) Framework::Basic Classes: NotCopyable : Object inherits from this type cannot be copied Error : Error, unlike exception, is not encouraged to catch Object : Base class of all classes Macros: CHECK_ERROR(CONDITION,DESCRIPTION) : Assert, throws an Error if failed CHECK_FAIL(DESCRIPTION) : Force an assert failure SCOPE_VARIABLE(TYPE,VARIABLE,VALUE){ ... } : Scoped variable Version: 1.0.2 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 13/02/2019 Initial coding, testing and supporting AVR architecture 1.0.1 K Hoang 01/03/2020 Add support for STM32 and all other architectures. 1.0.2 K Hoang 21/02/2021 Clear compiler warnings *****************************************************************************************************************************/ #pragma once #ifndef VCZH_BASIC #define VCZH_BASIC #ifdef VCZH_CHECK_MEMORY_LEAKS #define _CRTDBG_MAP_ALLOC #include #include #define VCZH_CHECK_MEMORY_LEAKS_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) #define new VCZH_CHECK_MEMORY_LEAKS_NEW #endif #include #include #define abstract #define __thiscall #define __forceinline inline #define _I8_MIN ((vint8_t)0x80) #define _I8_MAX ((vint8_t)0x7F) #define _UI8_MAX ((vuint8_t)0xFF) #define _I16_MIN ((vint16_t)0x8000) #define _I16_MAX ((vint16_t)0x7FFF) #define _UI16_MAX ((vuint16_t)0xFFFF) #define _I32_MIN ((vint32_t)0x80000000) #define _I32_MAX ((vint32_t)0x7FFFFFFF) #define _UI32_MAX ((vuint32_t)0xFFFFFFFF) #define _I64_MIN ((vint64_t)0x8000000000000000L) #define _I64_MAX ((vint64_t)0x7FFFFFFFFFFFFFFFL) #define _UI64_MAX ((vuint64_t)0xFFFFFFFFFFFFFFFFL) #define L_(x) L__(x) #define L__(x) L ## x namespace vl { typedef int8_t vint8_t; typedef uint8_t vuint8_t; typedef int16_t vint16_t; typedef uint16_t vuint16_t; typedef int32_t vint32_t; typedef uint32_t vuint32_t; typedef int64_t vint64_t; typedef uint64_t vuint64_t; /// Signed interface whose size is equal to sizeof(void*). typedef vint32_t vint; /// Signed interface whose size is equal to sizeof(void*). typedef vint32_t vsint; /// Unsigned interface whose size is equal to sizeof(void*). typedef vuint32_t vuint; /// Signed interger representing position. typedef vint64_t pos_t; #define ITOA_S _itoa_s #define ITOW_S _itow_s #define I64TOA_S _i64toa_s #define I64TOW_S _i64tow_s #define UITOA_S _ui64toa_s #define UITOW_S _ui64tow_s #define UI64TOA_S _ui64toa_s #define UI64TOW_S _ui64tow_s //#define INCRC(x) (__sync_add_and_fetch(x, 1)) //#define DECRC(x) (__sync_sub_and_fetch(x, 1)) #define INCRC(x) (++(*x)) #define DECRC(x) (--(*x)) /*********************************************************************** NotCopyable Base Class ***********************************************************************/ class NotCopyable { private: NotCopyable(const NotCopyable&) { } NotCopyable& operator=(const NotCopyable&) { return *this; } public: NotCopyable() { } }; #define SCOPE_VARIABLE(TYPE, VARIABLE, VALUE)\ if(bool __scope_variable_flag__=true)\ for(TYPE VARIABLE = VALUE;__scope_variable_flag__;__scope_variable_flag__=false) /*********************************************************************** Type Traits ***********************************************************************/ template struct RemoveReference { typedef T Type; }; template struct RemoveReference { typedef T Type; }; template struct RemoveReference < T&& > { typedef T Type; }; template struct RemoveConst { typedef T Type; }; template struct RemoveConst { typedef T Type; }; template struct RemoveVolatile { typedef T Type; }; template struct RemoveVolatile { typedef T Type; }; template struct RemoveCVR { typedef T Type; }; template struct RemoveCVR { typedef typename RemoveCVR::Type Type; }; template struct RemoveCVR < T&& > { typedef typename RemoveCVR::Type Type; }; template struct RemoveCVR { typedef typename RemoveCVR::Type Type; }; template struct RemoveCVR { typedef typename RemoveCVR::Type Type; }; template typename RemoveReference::Type&& MoveValue(T&& value) { return (typename RemoveReference::Type&&)value; } template T&& ForwardValue(typename RemoveReference::Type&& value) { return (T&&)value; } template T&& ForwardValue(typename RemoveReference::Type& value) { return (T&&)value; } template struct TypeTuple { }; /*********************************************************************** Object Base Class ***********************************************************************/ /// Base type of all classes. class Object { public: virtual ~Object() { } }; /// Type for storing a value to wherever requiring a [T:vl.Ptr`1] to [T:vl.Object]. /// Type of the value. template class ObjectBox : public Object { private: T object; public: /// Box a value. /// The value to box. ObjectBox(const T& _object) : object(_object) { } /// Box a movable value. /// The value to box. ObjectBox(T&& _object) : object(MoveValue(_object)) { } /// Copy a box. /// The box. ObjectBox(const ObjectBox& value) : object(value.object) { } /// Move a box. /// The box. ObjectBox(ObjectBox&& value) : object(MoveValue(value.object)) { } /// Box a value. /// The boxed value. /// The value to box. ObjectBox& operator=(const T& _object) { object = _object; return *this; } /// Copy a box. /// The boxed value. /// The box. ObjectBox& operator=(const ObjectBox& value) { object = value.object; return *this; } /// Move a box. /// The boxed value. /// The box. ObjectBox& operator=(ObjectBox&& value) { object = MoveValue(value.object); return *this; } /// Unbox the value. /// The original value. const T& Unbox() { return object; } }; /// Type for optionally storing a value. /// Type of the value. template class Nullable { private: T* object; public: /// Create a null value. Nullable() : object(0) { } /// Create a non-null value. /// The value to copy. Nullable(const T& value) : object(new T(value)) { } /// Create a non-null value. /// The value to move. Nullable(T&& value) : object(new T(MoveValue(value))) { } /// Copy a nullable value. /// The nullable value to copy. Nullable(const Nullable& nullable) : object(nullable.object ? new T(*nullable.object) : 0) { } /// Move a nullable value. /// The nullable value to move. Nullable(Nullable&& nullable) : object(nullable.object) { nullable.object = 0; } ~Nullable() { if (object) { delete object; object = 0; } } /// Create a non-null value. /// The created nullable value. /// The value to copy. Nullable& operator=(const T& value) { if (object) { delete object; object = 0; } object = new T(value); return *this; } /// Copy a nullable value. /// The created nullable value. /// The nullable value to copy. Nullable& operator=(const Nullable& nullable) { if (this != &nullable) { if (object) { delete object; object = 0; } if (nullable.object) { object = new T(*nullable.object); } } return *this; } /// Move a nullable value. /// The created nullable value. /// The nullable value to move. Nullable& operator=(Nullable&& nullable) { if (this != &nullable) { if (object) { delete object; object = 0; } object = nullable.object; nullable.object = 0; } return *this; } static bool Equals(const Nullable& a, const Nullable& b) { return a.object ? b.object ? *a.object == *b.object : false : b.object ? false : true; } static vint Compare(const Nullable& a, const Nullable& b) { return a.object ? b.object ? (*a.object == *b.object ? 0 : *a.object < *b.object ? -1 : 1) : 1 : b.object ? -1 : 0; } bool operator==(const Nullable& nullable)const { return Equals(*this, nullable); } bool operator!=(const Nullable& nullable)const { return !Equals(*this, nullable); } bool operator<(const Nullable& nullable)const { return Compare(*this, nullable) < 0; } bool operator<=(const Nullable& nullable)const { return Compare(*this, nullable) <= 0; } bool operator>(const Nullable& nullable)const { return Compare(*this, nullable) > 0; } bool operator>=(const Nullable& nullable)const { return Compare(*this, nullable) >= 0; } /// Convert the nullable value to a bool value. /// Returns true if it is not null. operator bool()const { return object != 0; } /// Unbox the value. This operation will cause an access violation of it is null. /// The original value. const T& Value()const { return *object; } }; template union BinaryRetriver { T t; char binary[sizeof(T) > minSize ? sizeof(T) : minSize]; }; /*********************************************************************** Configuration Type Traits ***********************************************************************/ /// Get the index type of a value for containers. /// Type of the value. template struct KeyType { public: /// The index type of a value for containers. typedef T Type; /// Convert a value to its index type. /// The corresponding index value. /// The value. static T GetKeyValue(const T& value) { return value; } }; /// Test is a type a Plain-Old-Data type for containers. /// The type to test. template struct POD { /// Returns true if the type is a Plain-Old-Data type. static const bool Result = false; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; template<>struct POD { static const bool Result = true; }; templatestruct POD { static const bool Result = true; }; templatestruct POD { static const bool Result = true; }; templatestruct POD < T&& > { static const bool Result = true; }; templatestruct POD { static const bool Result = true; }; templatestruct POD { static const bool Result = POD::Result; }; templatestruct POD { static const bool Result = POD::Result; }; templatestruct POD { static const bool Result = POD::Result; }; templatestruct POD { static const bool Result = POD::Result; }; /*********************************************************************** Interface Class ***********************************************************************/ /// Base type of all interfaces. All interface types are encouraged to be virtual inherited. class Interface : private NotCopyable { public: virtual ~Interface() { } }; /*********************************************************************** Type Extraction Class ***********************************************************************/ struct YesType {}; struct NoType {}; template struct AcceptType { }; template struct AcceptType { typedef T Type; }; template struct YesNoAnd { typedef NoType Type; }; template<> struct YesNoAnd { typedef YesType Type; }; template struct YesNoOr { typedef YesType Type; }; template<> struct YesNoOr { typedef NoType Type; }; template struct AcceptValue { static const bool Result = false; }; template<> struct AcceptValue { static const bool Result = true; }; template T ValueOf(); template struct PointerConvertable { static YesType Test(TTo* value); static NoType Test(void* value); typedef decltype(Test(ValueOf())) YesNoType; }; template struct ReturnConvertable { static YesType Test(TTo&& value); static NoType Test(...); typedef decltype(Test(ValueOf < TFrom&& > ())) YesNoType; }; template struct ReturnConvertable { typedef YesType YesNoType; }; template struct ReturnConvertable { typedef NoType YesNoType; }; template<> struct ReturnConvertable { typedef YesType YesNoType; }; template struct AcceptAlways { typedef T Type; }; template struct RequiresConvertable { static YesType Test(TTo* value); static NoType Test(void* value); typedef decltype(Test((TFrom*)0)) YesNoType; }; } // namespace vl #endif // VCZH_BASIC