Created
November 25, 2017 18:41
-
-
Save kachsheev/b9bf4a9b9d9d59166c614d8031d9ec9a to your computer and use it in GitHub Desktop.
Get count signs in integer
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
// define | |
template< | |
Types::ullong_t MIN, Types::ullong_t MAX | |
, SizeTraits::SizeType BUFFER_SIZE | |
> | |
struct NumberChecker | |
{ | |
template<typename IntType> | |
static inline SizeTraits::SizeType get(IntType value); | |
}; | |
template<SizeTraits::SizeType BUFFER_SIZE> | |
struct NumberChecker< | |
Types::ullong_t(999999999999999999ULL), Types::ullong_t(9999999999999999999ULL) | |
, BUFFER_SIZE | |
> | |
{ | |
template<typename IntType> | |
static inline SizeTraits::SizeType get(IntType value); | |
}; | |
template<typename T, bool SIGNED> | |
struct BufferSize | |
{ | |
static inline SizeTraits::SizeType get(T integer); | |
}; | |
template<typename T> | |
struct BufferSize<T, false> | |
{ | |
static inline SizeTraits::SizeType get(T integer); | |
}; | |
// implementation | |
template<Types::ullong_t MIN, Types::ullong_t MAX, SizeTraits::SizeType BUFFER_SIZE> | |
template<typename IntType> | |
inline SizeTraits::SizeType | |
NumberChecker<MIN, MAX, BUFFER_SIZE>::get(IntType value) | |
{ | |
if (MIN <= value && value <= MAX) | |
return BUFFER_SIZE; | |
else | |
return NumberChecker< | |
MAX, MAX * Types::ullong_t(10) + Types::ullong_t(9) | |
, BUFFER_SIZE + SizeTraits::SizeType(1) | |
>::get(value); | |
} | |
template<SizeTraits::SizeType BUFFER_SIZE> | |
template<typename IntType> | |
inline SizeTraits::SizeType NumberChecker< | |
Types::ullong_t(999999999999999999ULL), Types::ullong_t(9999999999999999999ULL) | |
, BUFFER_SIZE>::get(IntType value) | |
{ | |
constexpr Types::ullong_t MIN = Types::ullong_t(999999999999999999ULL); | |
constexpr Types::ullong_t MAX = Types::ullong_t(9999999999999999999ULL); | |
if (MIN <= value && value <= MAX) | |
return BUFFER_SIZE; | |
else | |
return BUFFER_SIZE + 1; | |
} | |
template<typename IntType, bool SIGNED> | |
SizeTraits::SizeType BufferSize<IntType, SIGNED>::get(IntType integer) | |
{ | |
SizeTraits::SizeType signedValue = 0; | |
if (integer < 0) | |
{ | |
++signedValue; | |
integer *= -1; | |
} | |
typename MakeUnsigned<IntType>::Type value = integer; | |
return signedValue + NumberChecker<0ULL, 9ULL, 1>::get(value); | |
} | |
template<typename IntType> | |
SizeTraits::SizeType BufferSize<IntType, false>::get(IntType integer) | |
{ | |
return NumberChecker<0ULL, 9ULL, 1>::get(integer); | |
} | |
template<typename IntType> | |
SizeTraits::SizeType bufferSize(IntType integer) | |
{ | |
return BufferSize<IntType>::get(integer); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment