rapidyaml  0.16.0
parseandemitYAML,anddoitfast
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

template<class T >
auto c4::digits_dec ( T  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 432 of file charconv.hpp.

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

434 {
435  C4_STATIC_ASSERT(std::is_integral<T>::value);
436  C4_ASSERT(v >= 0);
437  return ((v >= 100) ? 3u : ((v >= 10) ? 2u : 1u));
438 }
template<class T >
unsigned c4::digits_hex ( T  v)
inlinenoexcept

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

Definition at line 529 of file charconv.hpp.

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

530 {
531  C4_STATIC_ASSERT(std::is_integral<T>::value);
532  C4_ASSERT(v >= 0);
533  return v ? 1u + (msb((typename std::make_unsigned<T>::type)v) >> 2u) : 1u;
534 }
template<class T >
unsigned c4::digits_bin ( T  v)
inlinenoexcept

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

Definition at line 538 of file charconv.hpp.

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

539 {
540  C4_STATIC_ASSERT(std::is_integral<T>::value);
541  C4_ASSERT(v >= 0);
542  return v ? 1u + msb((typename std::make_unsigned<T>::type)v) : 1u;
543 }
template<class T >
unsigned c4::digits_oct ( T  v_)
inlinenoexcept

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

Definition at line 547 of file charconv.hpp.

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

548 {
549  // TODO: is there a better way?
550  C4_STATIC_ASSERT(std::is_integral<T>::value);
551  C4_ASSERT(v_ >= 0);
552  using U = typename std::conditional<sizeof(T) <= sizeof(unsigned),
553  unsigned,
554  typename std::make_unsigned<T>::type>::type;
555  U v = (U) v_; // safe because we require v_ >= 0 // NOLINT
556  uint32_t n_ = 1;
557  enum : U {
558  b2_ = 64u,
559  b3_ = 64u * 8u,
560  b4_ = 64u * 8u * 8u,
561  };
562  while(true)
563  {
564  if(v < 8u)
565  return n_;
566  else if(v < b2_)
567  return n_ + 1;
568  else if(v < b3_)
569  return n_ + 2;
570  else if(v < b4_)
571  return n_ + 3;
572  v /= (U) b4_;
573  n_ += 4;
574  }
575 }