rapidyaml  0.7.1
parse and emit YAML, and do it fast
Get number of digits

Functions

template<class T >
auto c4::digits_dec (T v) noexcept -> typename std::enable_if< sizeof(T)==1u, unsigned >::type
 decimal digits for 8 bit integers More...
 
template<class T >
unsigned c4::digits_hex (T v) noexcept
 return the number of digits required to encode an hexadecimal number. More...
 
template<class T >
unsigned c4::digits_bin (T v) noexcept
 return the number of digits required to encode a binary number. More...
 
template<class T >
unsigned c4::digits_oct (T v_) noexcept
 return the number of digits required to encode an octal number. More...
 

Detailed Description

Note
At first sight this code may look heavily branchy and therefore inefficient. However, measurements revealed this to be the fastest among the alternatives.
See also
https://github.com/biojppm/c4core/pull/77

Function Documentation

◆ digits_dec()

template<class T >
auto c4::digits_dec ( v) -> typename std::enable_if<sizeof(T) == 1u, unsigned>::type
inlinenoexcept

decimal digits for 8 bit integers

decimal digits for 64 bit integers

decimal digits for 32 bit integers

decimal digits for 16 bit integers

Definition at line 441 of file charconv.hpp.

443 {
444  C4_STATIC_ASSERT(std::is_integral<T>::value);
445  C4_ASSERT(v >= 0);
446  return ((v >= 100) ? 3u : ((v >= 10) ? 2u : 1u));
447 }

Referenced by c4::itoa(), c4::utoa(), c4::write_dec(), and c4::write_dec_unchecked().

◆ digits_hex()

template<class T >
unsigned c4::digits_hex ( v)
inlinenoexcept

return the number of digits required to encode an hexadecimal number.

Definition at line 524 of file charconv.hpp.

525 {
526  C4_STATIC_ASSERT(std::is_integral<T>::value);
527  C4_ASSERT(v >= 0);
528  return v ? 1u + (msb((typename std::make_unsigned<T>::type)v) >> 2u) : 1u;
529 }

Referenced by c4::itoa(), c4::utoa(), c4::write_hex(), and c4::write_hex_unchecked().

◆ digits_bin()

template<class T >
unsigned c4::digits_bin ( v)
inlinenoexcept

return the number of digits required to encode a binary number.

Definition at line 533 of file charconv.hpp.

534 {
535  C4_STATIC_ASSERT(std::is_integral<T>::value);
536  C4_ASSERT(v >= 0);
537  return v ? 1u + msb((typename std::make_unsigned<T>::type)v) : 1u;
538 }

Referenced by c4::itoa(), c4::utoa(), c4::write_bin(), and c4::write_bin_unchecked().

◆ digits_oct()

template<class T >
unsigned c4::digits_oct ( v_)
inlinenoexcept

return the number of digits required to encode an octal number.

Definition at line 542 of file charconv.hpp.

543 {
544  // TODO: is there a better way?
545  C4_STATIC_ASSERT(std::is_integral<T>::value);
546  C4_ASSERT(v_ >= 0);
547  using U = typename
548  std::conditional<sizeof(T) <= sizeof(unsigned),
549  unsigned,
550  typename std::make_unsigned<T>::type>::type;
551  U v = (U) v_; // safe because we require v_ >= 0
552  unsigned __n = 1;
553  const unsigned __b2 = 64u;
554  const unsigned __b3 = __b2 * 8u;
555  const unsigned long __b4 = __b3 * 8u;
556  while(true)
557  {
558  if(v < 8u)
559  return __n;
560  if(v < __b2)
561  return __n + 1;
562  if(v < __b3)
563  return __n + 2;
564  if(v < __b4)
565  return __n + 3;
566  v /= (U) __b4;
567  __n += 4;
568  }
569 }

Referenced by c4::itoa(), c4::utoa(), c4::write_oct(), and c4::write_oct_unchecked().