Advertisement
bueddl

printf impl using c++ templates

May 24th, 2016
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.06 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <type_traits>
  4.  
  5. void _pf_seek_direct_out(const char *&format)
  6. {
  7.     for (; *format != '\0'; ++format) {
  8.         if (*format == '%') {
  9.             switch (*++format) {
  10.             case '%':
  11.                 std::cout << '%';
  12.                 break;
  13.  
  14.             default:
  15.                 return;
  16.             }
  17.         } else {
  18.             std::cout << *format;
  19.         }
  20.     }
  21. }
  22.  
  23. void _pf_output_format(const char *&format)
  24. {
  25.     /* Flags */
  26.     bool stop = false;
  27.     do {
  28.         switch (*format) {
  29.         case '#':
  30.             std::cout << std::showbase;
  31.             break;
  32.  
  33.         case '0':
  34.             std::cout << std::setfill('0');
  35.             break;
  36.  
  37.         case '-':
  38.             std::cout << std::left;
  39.             std::cout << std::setfill(' ');
  40.             break;
  41.  
  42.         case ' ':
  43.             std::cout << std::setfill(' ');
  44.             break;
  45.  
  46.         case '+':
  47.             std::cout << std::showpos;
  48.             break;
  49.  
  50.         default:
  51.             stop = true;
  52.             break;
  53.         }
  54.         format++;
  55.     } while (!stop);
  56.  
  57.     format--;
  58.  
  59.     /* Field width */
  60.     int num = 0;
  61.     while ('0' <= *format && *format <= '9') {
  62.         num *= 10;
  63.         num += *format++ - '0';
  64.     }
  65.     if (num)
  66.         std::cout << std::setw(num);
  67.  
  68.     /* Precision */
  69.     if (*format == '.') {
  70.         int num = 0;
  71.         while ('0' <= *format && *format <= '9') {
  72.             num *= 10;
  73.             num += *format++ - '0';
  74.         }
  75.         std::cout << std::setprecision(num);
  76.     }
  77. }
  78.  
  79. template<typename T, typename ...Ts>
  80. void printf(const char *format, T arg, Ts... args)
  81. {
  82.     static_assert(std::is_integral<T>::value, "Implementation for integral types");
  83.  
  84.     // Seek normal text
  85.     _pf_seek_direct_out(format);
  86.  
  87.     // Apply output format settings
  88.     _pf_output_format(format);
  89.  
  90.     // Conversion specifiers
  91.     switch (*format++) {
  92.     case 'd':
  93.     case 'i':
  94.         std::cout << std::dec;
  95.         break;
  96.  
  97.     case 'O':
  98.         std::cout << std::uppercase;
  99.         /* Fall-through */
  100.     case 'o':
  101.         std::cout << std::oct;
  102.         break;
  103.  
  104.     case 'X':
  105.         std::cout << std::uppercase;
  106.         /* Fall-through */
  107.     case 'x':
  108.         std::cout << std::hex;
  109.         break;
  110.  
  111.     default:
  112.         ; /* Errör :c */
  113.     }
  114.  
  115.     std::cout << arg;
  116.  
  117.     printf(format, args...);
  118. }
  119.  
  120. int main()
  121. {
  122.     printf("Das ist der %d. Test mit %X Format Anweisungen drinne: %08x, %-10d!\n", 123, 4, 0xff, 12345);
  123.  
  124.     return 0;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement