Skip to content

Instantly share code, notes, and snippets.

@kachsheev
Created November 25, 2017 18:41
Show Gist options
  • Save kachsheev/b9bf4a9b9d9d59166c614d8031d9ec9a to your computer and use it in GitHub Desktop.
Save kachsheev/b9bf4a9b9d9d59166c614d8031d9ec9a to your computer and use it in GitHub Desktop.
Get count signs in integer
// 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