Re: Танцы с бубном :)
От: rg45 СССР  
Дата: 24.12.09 23:25
Оценка: 38 (5)
Здравствуйте, ankorol, Вы писали:

A>Можно ли как-то преобразовать целое в строку во время компиляции?...


Азарт разыгрался, захотелось решить задачку без сторонних библиотек. В этой версии отбрасываются незначащие нулевые разряды и правильно обрабатываются отрицательные числа и нуль. Реализация, конечно, несколько сложнее, чем здесь
Автор: rg45
Дата: 24.12.09
:
enum Signs { negative, positive };

template<int n> struct Abs { static const unsigned value = n < 0 ? -n : n; };

template<int n> struct Sign { static const Signs value = n < 0 ? negative : positive; };

template<unsigned n> struct DigitsCount { enum { value = DigitsCount<n/10>::value + 1 }; };
template<> struct DigitsCount<0> { enum { value = 0 }; };

template<unsigned n, int pos, bool outOfRange> struct CheckedLittleEndianSymbolAt { static const char value = 0; }; 
template<unsigned n, int pos> struct CheckedLittleEndianSymbolAt<n, pos, false> 
  { static const char value =  CheckedLittleEndianSymbolAt<n / 10, pos - 1, false>::value; }; 
template<unsigned n> struct CheckedLittleEndianSymbolAt<n, 0, false> { static const char value = '0' + n%10; }; 

template<unsigned n, int pos> struct LittleEndianSymbolAt : CheckedLittleEndianSymbolAt<n, pos, pos < 0> { };

template<Signs sign, unsigned absValue, int pos> struct SymbolOfSignedAt;
template<unsigned n, int pos> struct SymbolOfSignedAt<negative, n, pos> : SymbolOfSignedAt<positive, n, pos - 1> { };
template<unsigned n> struct SymbolOfSignedAt<negative, n, 0> { static const char value = '-';  };
template<unsigned n, int pos> struct SymbolOfSignedAt<positive, n, pos> : LittleEndianSymbolAt<n, DigitsCount<n>::value-pos-1> { };
template<> struct SymbolOfSignedAt<positive, 0, 0> { static const char value = '0';  };

template<int n, int pos> struct SymbolAt : SymbolOfSignedAt<Sign<n>::value, Abs<n>::value, pos> { };

template<int n> struct IntToString { static const char value[]; };
template<int n> const char IntToString<n>::value[] = 
{
  SymbolAt<n,0>::value, SymbolAt<n,1>::value, SymbolAt<n,2>::value, SymbolAt<n,3>::value,  
  SymbolAt<n,4>::value, SymbolAt<n,5>::value, SymbolAt<n,6>::value, SymbolAt<n,7>::value,  
  SymbolAt<n,8>::value, SymbolAt<n,9>::value, SymbolAt<n,10>::value, SymbolAt<n,12>::value,  
};

Теперь нужно убедиться, что мы получаем эти строки именно во время компиляции. Для этого достаточно проверить, что мы можем этими строковыми значениями параметризовать шаблоны:
#include <iostream>

template<const char* str>
struct CompileTimeString
{
  static void print() { std::cout << str << std::endl; }
};

int main()
{
  CompileTimeString<IntToString<123>::value>::print(); //Output: 123
  CompileTimeString<IntToString<0>::value>::print(); //Output: 0
  CompileTimeString<IntToString<-1234567>::value>::print(); //Output: -1234567
}
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.