diff --git a/README.md b/README.md index 5b332e5..ae38061 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,22 @@ OctaSTD is a collection of C++ utilities to aid the upcoming OctaForge C++ API. It provides containers (dynamic arrays etc) as well as other utilities. + +It utilizes C++11. It also implements equivalents of certain C++14 library +features that are possible to implement with the C++11 language. It does not +go beyond C++11 level when it comes to core language features. + +## Supported compilers + +Compiler | Version +-------- | ------- +gcc/g++ | 4.8+ +clang | 3.4+ +MSVC++ | 2015+ + +Other C++11 compliant compilers might work as well. OctaSTD does not utilize +compiler specific extensions except certain builtin type traits - to implement +traits that are not normally possible to implement without compiler support. + +OctaSTD does not provide fallbacks for those traits. The compiler is expected +to support these builtins. So far the 3 above-mentioned compilers support them. diff --git a/octa/traits.h b/octa/traits.h index 542e927..1741272 100644 --- a/octa/traits.h +++ b/octa/traits.h @@ -19,24 +19,13 @@ */ namespace octa { - /* removers */ - - 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 RemoveConstVolatile { - typedef typename RemoveVolatile::type>::type type; - }; + template struct RemoveConstVolatile; /* integral constant */ template struct IntegralConstant { - static constexpr const T value = val; + static constexpr T value = val; typedef T value_type; typedef IntegralConstant type; @@ -48,7 +37,7 @@ namespace octa { typedef IntegralConstant true_t; typedef IntegralConstant false_t; - template constexpr const T IntegralConstant::value; + template constexpr T IntegralConstant::value; /* is void */ @@ -179,15 +168,11 @@ namespace octa { !IsFundamental::value > {}; - /* is pointer to member function */ - - template struct IsMemberFunctionPointer: true_t {}; - /* is pointer to member */ template struct IsMemberPointerBase: false_t {}; template - struct IsMemberPointerBase: true_t {}; + struct IsMemberPointerBase: true_t {}; template struct IsMemberPointer: IsMemberPointerBase< @@ -196,10 +181,28 @@ namespace octa { /* is pointer to member object */ - template struct IsMemberObjectPointer: IntegralConstant::value && !IsMemberFunctionPointer::value) + template struct IsMemberObjectPointerBase: false_t {}; + + template + struct IsMemberObjectPointerBase: IntegralConstant::value > {}; + template struct IsMemberObjectPointer: + IsMemberObjectPointerBase::type> {}; + + /* is pointer to member function */ + + template struct IsMemberFunctionPointerBase: false_t {}; + + template + struct IsMemberFunctionPointerBase: IntegralConstant::value + > {}; + + template struct IsMemberFunctionPointer: + IsMemberFunctionPointerBase::type> {}; + /* is reference */ template struct IsReference: IntegralConstant::value > {}; + /* is trivially copyable */ + + template + struct IsTriviallyCopyable: IntegralConstant::type>::value + > {}; + + /* is trivial */ + + template struct IsTriviallyDefaultConstructible; + + template + struct IsTrivial: IntegralConstant::value && IsTriviallyDefaultConstructible::value) + > {}; + + /* has virtual destructor */ + + template + struct HasVirtualDestructor: IntegralConstant {}; + + /* is trivially constructible */ + + template + struct IsTriviallyConstructible: false_t {}; + + template + struct IsTriviallyConstructible: IntegralConstant {}; + + template + struct IsTriviallyConstructible: IntegralConstant {}; + + template + struct IsTriviallyConstructible: IntegralConstant {}; + + template + struct IsTriviallyConstructible: IntegralConstant {}; + + /* is trivially default constructible */ + + template + struct IsTriviallyDefaultConstructible: IsTriviallyConstructible {}; + + /* is trivially copy constructible */ + + template struct AddLvalueReference; + + template + struct IsTriviallyCopyConstructible: IsTriviallyConstructible::type + > {}; + + /* is trivially move constructible */ + + template + struct IsTriviallyMoveConstructible: IsTriviallyConstructible::type + > {}; + + /* is trivially assignable */ + + template + struct IsTriviallyAssignable: false_t {}; + + template + struct IsTriviallyAssignable: IntegralConstant {}; + + template + struct IsTriviallyAssignable: IntegralConstant {}; + + template + struct IsTriviallyAssignable: IntegralConstant {}; + + template + struct IsTriviallyAssignable: IntegralConstant {}; + + /* is trivially copy assignable */ + + template struct AddLvalueReference; + + template + struct IsTriviallyCopyAssignable: IsTriviallyAssignable::type + > {}; + + /* is trivially move assignable */ + + template + struct IsTriviallyMoveAssignable: IsTriviallyAssignable::type + > {}; + + /* is trivially destructible */ + + template + struct IsTriviallyDestructible: IntegralConstant {}; + + /* is nothrow constructible */ + + template + struct IsNothrowConstructible: false_t {}; + + template + struct IsNothrowConstructible: IntegralConstant {}; + + template + struct IsNothrowConstructible: IntegralConstant {}; + + template + struct IsNothrowConstructible: IntegralConstant {}; + + template + struct IsNothrowConstructible: IntegralConstant {}; + + /* is nothrow default constructible */ + + template + struct IsNothrowDefaultConstructible: IsNothrowConstructible {}; + + /* is nothrow copy constructible */ + + template struct AddLvalueReference; + + template + struct IsNothrowCopyConstructible: IsNothrowConstructible::type + > {}; + + /* is nothrow move constructible */ + + template + struct IsNothrowMoveConstructible: IsNothrowConstructible::type + > {}; + + /* is nothrow assignable */ + + template + struct IsNothrowAssignable: false_t {}; + + template + struct IsNothrowAssignable: IntegralConstant {}; + + template + struct IsNothrowAssignable: IntegralConstant {}; + + template + struct IsNothrowAssignable: IntegralConstant {}; + + template + struct IsNothrowAssignable: IntegralConstant {}; + + /* is nothrow copy assignable */ + + template struct AddLvalueReference; + + template + struct IsNothrowCopyAssignable: IsNothrowAssignable::type + > {}; + + /* is nothrow move assignable */ + + template + struct IsNothrowMoveAssignable: IsNothrowAssignable::type + > {}; + /* is base of */ template @@ -330,6 +535,50 @@ namespace octa { template struct Rank: IntegralConstant::value + 1> {}; + /* remove const, volatile, cv */ + + 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 RemoveConstVolatile { + typedef typename RemoveVolatile::type>::type type; + }; + + /* add const, volatile, cv */ + + template::value + || IsFunction::value || IsConst::value> + struct AddConstBase { typedef T type; }; + + template struct AddConstBase { + typedef const T type; + }; + + template struct AddConst { + typedef typename AddConstBase::type type; + }; + + template::value + || IsFunction::value || IsVolatile::value> + struct AddVolatileBase { typedef T type; }; + + template struct AddVolatileBase { + typedef volatile T type; + }; + + template struct AddVolatile { + typedef typename AddVolatileBase::type type; + }; + + template + struct AddConstVolatile { + typedef typename AddConst::type>::type type; + }; + /* remove reference */ template using RemoveReference = internal::RemoveReference; @@ -388,6 +637,147 @@ namespace octa { typedef typename RemoveAllExtents::type type; }; + /* make (un)signed + * + * this is bad, but i don't see any better way + * shamelessly copied from graphitemaster @ neothyne + */ + + namespace internal { + template struct TypeList { + typedef T first; + typedef U rest; + }; + + /* not a type */ + struct NAT { + NAT() = delete; + NAT(const NAT &) = delete; + NAT &operator=(const NAT &) = delete; + ~NAT() = delete; + }; + + typedef TypeList>>>> stypes; + + typedef TypeList>>>> utypes; + + template + struct TypeFindFirst; + + template + struct TypeFindFirst, N, true> { + typedef T type; + }; + + template + struct TypeFindFirst, N, false> { + typedef typename TypeFindFirst::type type; + }; + + template::type>::value, + bool = IsVolatile::type>::value + > struct ApplyConstVolatile { + typedef U type; + }; + + template + struct ApplyConstVolatile { /* const */ + typedef const U type; + }; + + template + struct ApplyConstVolatile { /* volatile */ + typedef volatile U type; + }; + + template + struct ApplyConstVolatile { /* const volatile */ + typedef const volatile U type; + }; + + template + struct ApplyConstVolatile { /* const */ + typedef const U &type; + }; + + template + struct ApplyConstVolatile { /* volatile */ + typedef volatile U &type; + }; + + template + struct ApplyConstVolatile { /* const volatile */ + typedef const volatile U &type; + }; + + template::value || IsEnum::value> + struct MakeSigned {}; + + template::value || IsEnum::value> + struct MakeUnsigned {}; + + template + struct MakeSigned { + typedef typename TypeFindFirst::type type; + }; + + template + struct MakeUnsigned { + typedef typename TypeFindFirst::type type; + }; + + template<> struct MakeSigned {}; + template<> struct MakeSigned { typedef schar type; }; + template<> struct MakeSigned { typedef schar type; }; + template<> struct MakeSigned { typedef short type; }; + template<> struct MakeSigned { typedef short type; }; + template<> struct MakeSigned { typedef int type; }; + template<> struct MakeSigned { typedef int type; }; + template<> struct MakeSigned { typedef long type; }; + template<> struct MakeSigned { typedef long type; }; + template<> struct MakeSigned { typedef llong type; }; + template<> struct MakeSigned { typedef llong type; }; + + template<> struct MakeUnsigned {}; + template<> struct MakeUnsigned { typedef uchar type; }; + template<> struct MakeUnsigned { typedef uchar type; }; + template<> struct MakeUnsigned { typedef ushort type; }; + template<> struct MakeUnsigned { typedef ushort type; }; + template<> struct MakeUnsigned { typedef uint type; }; + template<> struct MakeUnsigned { typedef uint type; }; + template<> struct MakeUnsigned { typedef ulong type; }; + template<> struct MakeUnsigned { typedef ulong type; }; + template<> struct MakeUnsigned { typedef ullong type; }; + template<> struct MakeUnsigned { typedef ullong type; }; + } + + template struct MakeSigned { + typedef typename internal::ApplyConstVolatile::type + >::type + >::type type; + }; + + template struct MakeUnsigned { + typedef typename internal::ApplyConstVolatile::type + >::type + >::type type; + }; + + /* common type */ + /* conditional */ template @@ -461,6 +851,87 @@ namespace octa { >::type >::type type; }; + + /* common type */ + + template struct CommonType; + + template struct CommonType { + typedef Decay type; + }; + + template struct CommonType { + typedef Decay() : declval())> type; + }; + + template + struct CommonType { + typedef typename CommonType::type, V...>::type type; + }; + + /* aligned storage */ + + namespace internal { + template struct AlignedStorageTest { + union type { + uchar data[N]; + max_align_t align; + }; + }; + }; + + template::type) + > struct AlignedStorage { + struct type { + alignas(A) uchar data[N]; + }; + }; + + /* aligned union */ + + namespace internal { + template struct AlignMax; + + template struct AlignMax { + static constexpr size_t value = N; + }; + + template struct AlignMax { + static constexpr size_t value = (N1 > N2) ? N1 : N2; + }; + + template + struct AlignMax { + static constexpr size_t value + = AlignMax::value, N...>::value; + }; + } + + template struct AlignedUnion { + static constexpr size_t alignment_value + = internal::AlignMax::value; + + struct type { + alignas(alignment_value) uchar data[internal::AlignMax::value]; + }; + }; + + /* underlying type */ + + template::value> struct UnderlyingTypeBase; + + template struct UnderlyingTypeBase { + typedef typename Conditional::value, + typename MakeSigned::type, + typename MakeUnsigned::type + >::type type; + }; + + template struct UnderlyingType { + typedef typename UnderlyingTypeBase::type type; + }; } #endif \ No newline at end of file