rapidyaml  0.10.0
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 434 of file charconv.hpp.

436 {
437  C4_STATIC_ASSERT(std::is_integral<T>::value);
438  C4_ASSERT(v >= 0);
439  return ((v >= 100) ? 3u : ((v >= 10) ? 2u : 1u));
440 }

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 517 of file charconv.hpp.

518 {
519  C4_STATIC_ASSERT(std::is_integral<T>::value);
520  C4_ASSERT(v >= 0);
521  return v ? 1u + (msb((typename std::make_unsigned<T>::type)v) >> 2u) : 1u;
522 }

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 526 of file charconv.hpp.

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

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 535 of file charconv.hpp.

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

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