Skip to content

Instantly share code, notes, and snippets.

@schaumb
Created April 26, 2022 17:11
Show Gist options
  • Save schaumb/7896ce5ca1a7edd6ffb0e5184f3c24d8 to your computer and use it in GitHub Desktop.
Save schaumb/7896ce5ca1a7edd6ffb0e5184f3c24d8 to your computer and use it in GitHub Desktop.
add_long, remove_long, has_long type traits
#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