@@ -586,258 +586,6 @@ size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_
586586 return j ;
587587}
588588
589- /*--- integer to string conversions --*/
590-
591- /* All conversion functions:
592- - require a destination array `buf` of sufficient length
593- - write the string representation at the beginning of `buf`
594- - null terminate the string
595- - return the string length
596- */
597-
598- /* 2 <= base <= 36 */
599- char const digits36 [36 ] = {
600- '0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,
601- 'a' ,'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,
602- 'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,
603- 'u' ,'v' ,'w' ,'x' ,'y' ,'z'
604- };
605-
606-
607- #define USE_SPECIAL_RADIX_10 1 // special case base 10 radix conversions
608- #define USE_SINGLE_CASE_FAST 1 // special case single digit numbers
609-
610- /* using u32toa_shift variant */
611-
612- #define gen_digit (buf , c ) if (is_be()) \
613- buf = (buf >> 8) | ((uint64_t)(c) << ((sizeof(buf) - 1) * 8)); \
614- else \
615- buf = (buf << 8) | (c)
616-
617- static size_t u7toa_shift (char dest [minimum_length (8 )], uint32_t n )
618- {
619- size_t len = 1 ;
620- uint64_t buf = 0 ;
621- while (n >= 10 ) {
622- uint32_t quo = n % 10 ;
623- n /= 10 ;
624- gen_digit (buf , '0' + quo );
625- len ++ ;
626- }
627- gen_digit (buf , '0' + n );
628- memcpy (dest , & buf , sizeof buf );
629- return len ;
630- }
631-
632- static size_t u07toa_shift (char dest [minimum_length (8 )], uint32_t n , size_t len )
633- {
634- size_t i ;
635- dest += len ;
636- dest [7 ] = '\0' ;
637- for (i = 7 ; i -- > 1 ;) {
638- uint32_t quo = n % 10 ;
639- n /= 10 ;
640- dest [i ] = (char )('0' + quo );
641- }
642- dest [i ] = (char )('0' + n );
643- return len + 7 ;
644- }
645-
646- size_t u32toa (char buf [minimum_length (11 )], uint32_t n )
647- {
648- #ifdef USE_SINGLE_CASE_FAST /* 10% */
649- if (n < 10 ) {
650- buf [0 ] = (char )('0' + n );
651- buf [1 ] = '\0' ;
652- return 1 ;
653- }
654- #endif
655- #define TEN_POW_7 10000000
656- if (n >= TEN_POW_7 ) {
657- uint32_t quo = n / TEN_POW_7 ;
658- n %= TEN_POW_7 ;
659- size_t len = u7toa_shift (buf , quo );
660- return u07toa_shift (buf , n , len );
661- }
662- return u7toa_shift (buf , n );
663- }
664-
665- size_t u64toa (char buf [minimum_length (21 )], uint64_t n )
666- {
667- if (likely (n < 0x100000000 ))
668- return u32toa (buf , n );
669-
670- size_t len ;
671- if (n >= TEN_POW_7 ) {
672- uint64_t n1 = n / TEN_POW_7 ;
673- n %= TEN_POW_7 ;
674- if (n1 >= TEN_POW_7 ) {
675- uint32_t quo = n1 / TEN_POW_7 ;
676- n1 %= TEN_POW_7 ;
677- len = u7toa_shift (buf , quo );
678- len = u07toa_shift (buf , n1 , len );
679- } else {
680- len = u7toa_shift (buf , n1 );
681- }
682- return u07toa_shift (buf , n , len );
683- }
684- return u7toa_shift (buf , n );
685- }
686-
687- size_t i32toa (char buf [minimum_length (12 )], int32_t n )
688- {
689- if (likely (n >= 0 ))
690- return u32toa (buf , n );
691-
692- buf [0 ] = '-' ;
693- return 1 + u32toa (buf + 1 , - (uint32_t )n );
694- }
695-
696- size_t i64toa (char buf [minimum_length (22 )], int64_t n )
697- {
698- if (likely (n >= 0 ))
699- return u64toa (buf , n );
700-
701- buf [0 ] = '-' ;
702- return 1 + u64toa (buf + 1 , - (uint64_t )n );
703- }
704-
705- /* using u32toa_radix_length variant */
706-
707- static uint8_t const radix_shift [64 ] = {
708- 0 , 0 , 1 , 0 , 2 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
709- 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
710- 5 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
711- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
712- };
713-
714- size_t u32toa_radix (char buf [minimum_length (33 )], uint32_t n , unsigned base )
715- {
716- int shift ;
717-
718- #ifdef USE_SPECIAL_RADIX_10
719- if (likely (base == 10 ))
720- return u32toa (buf , n );
721- #endif
722- if (n < base ) {
723- buf [0 ] = digits36 [n ];
724- buf [1 ] = '\0' ;
725- return 1 ;
726- }
727- shift = radix_shift [base & 63 ];
728- if (shift ) {
729- uint32_t mask = (1 << shift ) - 1 ;
730- size_t len = (32 - clz32 (n ) + shift - 1 ) / shift ;
731- size_t last = n & mask ;
732- char * end = buf + len ;
733- n >>= shift ;
734- * end -- = '\0' ;
735- * end -- = digits36 [last ];
736- while (n >= base ) {
737- size_t quo = n & mask ;
738- n >>= shift ;
739- * end -- = digits36 [quo ];
740- }
741- * end = digits36 [n ];
742- return len ;
743- } else {
744- size_t len = 2 ;
745- size_t last = n % base ;
746- n /= base ;
747- uint32_t nbase = base ;
748- while (n >= nbase ) {
749- nbase *= base ;
750- len ++ ;
751- }
752- char * end = buf + len ;
753- * end -- = '\0' ;
754- * end -- = digits36 [last ];
755- while (n >= base ) {
756- size_t quo = n % base ;
757- n /= base ;
758- * end -- = digits36 [quo ];
759- }
760- * end = digits36 [n ];
761- return len ;
762- }
763- }
764-
765- size_t u64toa_radix (char buf [minimum_length (65 )], uint64_t n , unsigned base )
766- {
767- int shift ;
768-
769- #ifdef USE_SPECIAL_RADIX_10
770- if (likely (base == 10 ))
771- return u64toa (buf , n );
772- #endif
773- shift = radix_shift [base & 63 ];
774- if (shift ) {
775- if (n < base ) {
776- buf [0 ] = digits36 [n ];
777- buf [1 ] = '\0' ;
778- return 1 ;
779- }
780- uint64_t mask = (1 << shift ) - 1 ;
781- size_t len = (64 - clz64 (n ) + shift - 1 ) / shift ;
782- size_t last = n & mask ;
783- char * end = buf + len ;
784- n >>= shift ;
785- * end -- = '\0' ;
786- * end -- = digits36 [last ];
787- while (n >= base ) {
788- size_t quo = n & mask ;
789- n >>= shift ;
790- * end -- = digits36 [quo ];
791- }
792- * end = digits36 [n ];
793- return len ;
794- } else {
795- if (likely (n < 0x100000000 ))
796- return u32toa_radix (buf , n , base );
797- size_t last = n % base ;
798- n /= base ;
799- uint64_t nbase = base ;
800- size_t len = 2 ;
801- while (n >= nbase ) {
802- nbase *= base ;
803- len ++ ;
804- }
805- char * end = buf + len ;
806- * end -- = '\0' ;
807- * end -- = digits36 [last ];
808- while (n >= base ) {
809- size_t quo = n % base ;
810- n /= base ;
811- * end -- = digits36 [quo ];
812- }
813- * end = digits36 [n ];
814- return len ;
815- }
816- }
817-
818- size_t i32toa_radix (char buf [minimum_length (34 )], int32_t n , unsigned int base )
819- {
820- if (likely (n >= 0 ))
821- return u32toa_radix (buf , n , base );
822-
823- buf [0 ] = '-' ;
824- return 1 + u32toa_radix (buf + 1 , - (uint32_t )n , base );
825- }
826-
827- size_t i64toa_radix (char buf [minimum_length (66 )], int64_t n , unsigned int base )
828- {
829- if (likely (n >= 0 ))
830- return u64toa_radix (buf , n , base );
831-
832- buf [0 ] = '-' ;
833- return 1 + u64toa_radix (buf + 1 , - (uint64_t )n , base );
834- }
835-
836- #undef gen_digit
837- #undef TEN_POW_7
838- #undef USE_SPECIAL_RADIX_10
839- #undef USE_SINGLE_CASE_FAST
840-
841589/*---- sorting with opaque argument ----*/
842590
843591typedef void (* exchange_f )(void * a , void * b , size_t size );
0 commit comments