Created
April 26, 2022 17:11
-
-
Save schaumb/7896ce5ca1a7edd6ffb0e5184f3c24d8 to your computer and use it in GitHub Desktop.
add_long, remove_long, has_long type traits
This file contains hidden or 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 <type_traits> | |
namespace bxlx { | |
namespace impl { | |
template<typename T, typename = void> | |
struct add_long { | |
using type = T; | |
}; | |
template<> | |
struct add_long<char> { | |
using type = char; | |
}; | |
template<> | |
struct add_long<int> { | |
using type = long int; | |
}; | |
template<> | |
struct add_long<long int> { | |
using type = long long int; | |
}; | |
template<typename T> | |
struct add_long<T, std::enable_if_t<std::is_const_v<T>>> { | |
using type = std::add_const_t<typename add_long<std::remove_const_t<T>>::type>; | |
}; | |
template<typename T> | |
struct add_long<T, std::enable_if_t<!std::is_const_v<T> && std::is_volatile_v<T>>> { | |
using type = std::add_volatile_t<typename add_long<std::remove_volatile_t<T>>::type>; | |
}; | |
template<typename T> | |
struct add_long<T, std::enable_if_t<!std::is_const_v<T> && !std::is_volatile_v<T> && std::is_unsigned_v<T>>> { | |
using type = std::make_unsigned_t<typename add_long<std::make_signed_t<T>>::type>; | |
}; | |
template<typename T, typename = void> | |
struct remove_long { | |
using type = T; | |
}; | |
template<> | |
struct remove_long<char> { | |
using type = char; | |
}; | |
template<> | |
struct remove_long<long int> { | |
using type = int; | |
}; | |
template<> | |
struct remove_long<long long int> { | |
using type = long int; | |
}; | |
template<typename T> | |
struct remove_long<T, std::enable_if_t<std::is_const_v<T>>> { | |
using type = std::add_const_t<typename remove_long<std::remove_const_t<T>>::type>; | |
}; | |
template<typename T> | |
struct remove_long<T, std::enable_if_t<!std::is_const_v<T> && std::is_volatile_v<T>>> { | |
using type = std::add_volatile_t<typename remove_long<std::remove_volatile_t<T>>::type>; | |
}; | |
template<typename T> | |
struct remove_long<T, std::enable_if_t<!std::is_const_v<T> && !std::is_volatile_v<T> && std::is_unsigned_v<T>>> { | |
using type = std::make_unsigned_t<typename remove_long<std::make_signed_t<T>>::type>; | |
}; | |
} | |
template<typename T> | |
using add_long = impl::add_long<T>; | |
template<typename T> | |
using remove_long = impl::remove_long<T>; | |
template<typename T> | |
using has_long = std::bool_constant<!std::is_same_v<remove_long<T>, T>>; | |
template<typename T> | |
using add_long_t = typename add_long<T>::type; | |
template<typename T> | |
using remove_long_t = typename remove_long<T>::type; | |
template<typename T> | |
[[maybe_unused]] | |
constexpr static inline auto has_long_v = has_long<T>::value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment