Created
July 24, 2019 00:39
-
-
Save B1Z0N/92e6787407e04fb5b7440dcd39f57345 to your computer and use it in GitHub Desktop.
c++ template traits implemented for better understanding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <utility> | |
//*********************TRANSFORMATION*TRAITS*************************** | |
// Remove reference | |
template <typename T> | |
struct RemoveReferenceT | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
struct RemoveReferenceT<T&> | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
struct RemoveReferenceT < T&& > | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
using RemoveReference = typename RemoveReferenceT<T>::type; | |
// Add lvalue reference | |
template <typename T> | |
struct AddLValueReferenceT { | |
using type = T&; | |
}; | |
template <> | |
struct AddLValueReferenceT<void> { | |
using type = void; | |
}; | |
template <> | |
struct AddLValueReferenceT<const void> { | |
using type = void const; | |
}; | |
template <> | |
struct AddLValueReferenceT<void volatile> { | |
using type = void volatile; | |
}; | |
template <> | |
struct AddLValueReferenceT<const void volatile> { | |
using type = void const volatile; | |
}; | |
template <typename T> | |
using AddLValueReference = typename AddLValueReferenceT<T>::type; | |
// Add rvalue reference | |
template <typename T> | |
struct AddRValueReferenceT { | |
using type = T &&; | |
}; | |
template <> | |
struct AddRValueReferenceT<void> { | |
using type = void; | |
}; | |
template <> | |
struct AddRValueReferenceT<const void> { | |
using type = void const; | |
}; | |
template <> | |
struct AddRValueReferenceT<void volatile> { | |
using type = void volatile; | |
}; | |
template <> | |
struct AddRValueReferenceT<const void volatile> { | |
using type = void const volatile; | |
}; | |
template <typename T> | |
using AddRValueReference = typename AddRValueReferenceT<T>::type; | |
// Remove const | |
template <typename T> | |
struct RemoveConstT | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
struct RemoveConstT<const T> | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
using RemoveConst = typename RemoveConstT<T>::type; | |
// Add const not neede, we can use const T for any T | |
// Remove volatile | |
template <typename T> | |
struct RemoveVolatileT | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
struct RemoveVolatileT<volatile T> | |
{ | |
using type = T; | |
}; | |
template <typename T> | |
using RemoveVolatile = typename RemoveVolatileT<T>::type; | |
// Remove CV | |
template <typename T> | |
struct RemoveCVT : RemoveConstT<RemoveVolatile<T>> { }; | |
template <typename T> | |
using RemoveCV = typename RemoveCVT<T>::type; | |
// Decay | |
template <typename T> | |
struct DecayT : RemoveCVT<T> { }; | |
template <typename T> | |
struct DecayT<T[]> | |
{ | |
using type = T*; | |
}; | |
template <typename T, std::size_t N> | |
struct DecayT<T[N]> | |
{ | |
using type = T*; | |
}; | |
template <typename R, typename... Args> | |
struct DecayT<R( Args... )> | |
{ | |
using type = R (*) ( Args... ); | |
}; | |
/** | |
* Specialization for C-style varargs | |
*/ | |
template<typename R, typename... Args> | |
struct DecayT<R( Args..., ... )> | |
{ | |
using type = R (*)(Args..., ...); | |
}; | |
template <typename T> | |
using Decay = typename DecayT<T>::type; | |
//*********************PREDICATE*TRAITS*************************** | |
// Utility true and false types | |
template <bool val> | |
struct BoolConstant | |
{ | |
using type = BoolConstant<val>; | |
static constexpr bool value = val; | |
}; | |
using Falsetype = BoolConstant<false>; | |
using Truetype = BoolConstant<true>; | |
// Is same type? | |
template <typename T1, typename T2> | |
struct IsSameT : Falsetype { }; | |
template <typename T> | |
struct IsSameT<T, T> : Truetype { }; | |
template <typename T1, typename T2> | |
constexpr bool IsSame = IsSameT<T1, T2>::value; | |
//*********************PREDICATE*TRAITS*************************** | |
// PlusResult | |
template <typename T1, typename T2> | |
struct PlusResultT | |
{ | |
using type = decltype( std::declval<T1>() + std::declval<T2>() ); | |
}; | |
template <typename T1, typename T2> | |
using PlusResult = typename PlusResultT<T1, T2>::type; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment