Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 12:31
Оценка:
Можно ли как-то преобразовать целое в строку во время компиляции, хочется использовать что-то такое:
template<int N>
class SomeClass
{
  #pragma message(IntToString<N>)
  //...
}

Сам не смог...Спасибо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re: Int to string compile time.
От: rg45 СССР  
Дата: 24.12.09 12:59
Оценка:
Здравствуйте, ankorol, Вы писали:

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

A>
A>template<int N>
A>class SomeClass
A>{
A>  #pragma message(IntToString<N>)
A>  //...
A>}
A>

A>Сам не смог...Спасибо.

Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 13:05
Оценка:
Здравствуйте, rg45, Вы писали:

R>Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.


Ваша правда, так не получится, а если чисто теоретически такое преобразование можно сделать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: Int to string compile time.
От: nen777w  
Дата: 24.12.09 13:14
Оценка:
R>>Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.
A>Ваша правда, так не получится, а если чисто теоретически такое преобразование можно сделать?

#define I2S( val ) #val
const char *p = I2S(45);


Так? Или Я вопроса не понял.
Re[3]: Int to string compile time.
От: Тот кто сидит в пруду Россия  
Дата: 24.12.09 13:17
Оценка:
Здравствуйте, ankorol, Вы писали:

R>>Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.


A>Ваша правда, так не получится, а если чисто теоретически такое преобразование можно сделать?


Теоретически можно например во время компиляции заполнить статический массив char строкой, содержащей текстовое представление числовой константы времени компиляции. Практически это будет жутко замедлять компиляцию и вообще кажется смысла не имеет.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 13:19
Оценка:
Здравствуйте, nen777w, Вы писали:

N>
N>#define I2S( val ) #val
N>const char *p = I2S(45);
N>


N>Так? Или Я вопроса не понял.


const int N=45;
const char *p = I2S(N);// p =="N" а хочется 45
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[4]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 13:24
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Теоретически можно например во время компиляции заполнить статический массив char строкой, содержащей текстовое представление числовой константы времени компиляции. Практически это будет жутко замедлять компиляцию и вообще кажется смысла не имеет.


А можно пример кода.
Ну приминение можно придумать — например я хочу иметь для своей специализации шаблона
template<int N>
{
   static char *str_presentation;
}

в str_presentation значени N что бы во время вывода на экран или еще куда-то время на перевод числа в строку.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[5]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 13:28
Оценка:
A>в str_presentation значени N что бы во время вывода на экран или еще куда-то время на перевод числа в строку не тратить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: Int to string compile time.
От: rg45 СССР  
Дата: 24.12.09 13:55
Оценка: 9 (2)
Здравствуйте, ankorol, Вы писали:

A>Здравствуйте, rg45, Вы писали:


R>>Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.


A>Ваша правда, так не получится, а если чисто теоретически такое преобразование можно сделать?


Упрощенно, для иллюстрации идеи, ниже показано как это можно реализовать. Если сделать еще пару-тройку танцевальных движений с бубном, то можно обобщить реализацию на целочисленный тип произвольного размера и убрать не значашие нули в начале строки.
template<int N> struct Exp10 { enum { value = Exp10<N-1>::value * 10 }; };
template<> struct Exp10<0> { enum { value = 1 }; };

template<int N, int Pos>
struct SymbolAt 
{ 
  static const char value = N / Exp10<Pos>::value % 10 + '0';
};

template<int N>
struct IntToString
{
  static const char value[];
};

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

//Использование:
#include <iostream>
int main()
{
  std::cout << IntToString<123>::value << std::endl;
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Int to string compile time.
От: Тот кто сидит в пруду Россия  
Дата: 24.12.09 14:02
Оценка:
Здравствуйте, ankorol, Вы писали:

ТКС>>Теоретически можно например во время компиляции заполнить статический массив char строкой, содержащей текстовое представление числовой константы времени компиляции. Практически это будет жутко замедлять компиляцию и вообще кажется смысла не имеет.


A>А можно пример кода.


Давайте так: вы напишете 2 рекурсивную функция которая вычисляет n-й символ в строковом представлении целого числа, если n превышает длину строки — возвращает 0. А я ваш код в компайлтайм переведу

A>Ну приминение можно придумать — например я хочу иметь для своей специализации шаблона

A>
A>template<int N>
A>{
A>   static char *str_presentation;
A>}
A>

A>в str_presentation значени N что бы во время вывода на экран или еще куда-то время на перевод числа в строку.

Ну а что мешает в рантайме ее заполнить?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 14:03
Оценка:
Спасибо! Супер! Мне нехватало этого шага с инициализацией строки символами через запятую, всё пытался конкатенировать строки. Танцевальные движения с бубном попробую сам придумать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: Int to string compile time.
От: Basil2 Россия https://starostin.msk.ru
Дата: 24.12.09 14:05
Оценка:
Здравствуйте, ankorol, Вы писали:

R>>Не получится потому, что директивы #pragma обрабатываются еще до компиляции препроцессором.


A>Ваша правда, так не получится, а если чисто теоретически такое преобразование можно сделать?


С точки зрения теории, по идее, нельзя.
Шаблоны допускает инициализацию только интегральных типов, куда ни string, ни char* не попадают.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[6]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 14:07
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:


ТКС>Давайте так: вы напишете 2 рекурсивную функция которая вычисляет n-й символ в строковом представлении целого числа, если n превышает длину строки — возвращает 0. А я ваш код в компайлтайм переведу


rg45 уже написал не рекурсивную версию.

ТКС>Ну а что мешает в рантайме ее заполнить?


Ничто не мешает, это просто я себе придумал такое упражнение-извращение с шаблонами, ничего общего с реальной жизнью это не имеет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re: Int to string compile time.
От: Alexey F  
Дата: 24.12.09 14:09
Оценка: 83 (6) :)
Здравствуйте, ankorol, Вы писали:

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

[...skip...]

Можно
Чуть не успел — опередили здесь
Автор: rg45
Дата: 24.12.09


И всё таки: берём boost::mpl::string (можно сделать собственную, упрощённую реализацию; также boost::mpl::push_front, boost::mpl::c_str, boost::mpl::empty) и boost::mpl::if_ (элементарно делается):
#include <boost/mpl/string.hpp>
#include <boost/mpl/if.hpp>

namespace aux {
    template< std::size_t N, class Str = boost::mpl::string<> >
    struct to_string_helper {
        enum {
            ansiiDigitMask = 0x30,
            symbol = ansiiDigitMask bitor ( N % 10 )
        };

        typedef typename to_string_helper<
            N / 10,
            typename boost::mpl::push_front< Str, boost::mpl::char_<symbol> >::type
        >::type type;
    };


    template<class Str>
    struct to_string_helper<0, Str> {
        enum { zero = '0' };

        typedef typename boost::mpl::if_<
            typename boost::mpl::empty<Str>::type,
            boost::mpl::string<zero>,
            Str
        >::type type;

    };
}


template<std::size_t N>
struct size_t_to_string {
    typedef typename aux::to_string_helper<N>::type type;
};



namespace aux {
    template<int N, bool isNegative>
    struct to_int_helper {
        typedef typename size_t_to_string<N>::type type;
    };


    template<int N>
    struct to_int_helper<N, true> {
        enum { negativeSign = '-' };

        typedef typename boost::mpl::push_front<
            typename size_t_to_string<-N>::type,
            boost::mpl::char_<negativeSign>
        >::type type;
    };
}


template<int N>
struct int_to_string {
    typedef typename aux::to_int_helper<N, N < 0>::type type;
};


template<class Str>
inline char const* to_c_string () {
    return boost::mpl::c_str<typename Str::type>::value;
}


Проверка:
struct Some {
    typedef int_to_string<-42>::type Value1;
};


int main () {
    puts ( to_c_string<Some::Value1> () );
    puts ( to_c_string< size_t_to_string<123> > () );
    puts ( to_c_string< int_to_string<-123> > () );
}


Сгенерированный код в релизе — один mov. В debug-е — вызов ф-ции, в которой будет этот mov
Re[5]: Int to string compile time.
От: rg45 СССР  
Дата: 24.12.09 14:11
Оценка:
Здравствуйте, ankorol, Вы писали:

A>Спасибо! Супер! Мне нехватало этого шага с инициализацией строки символами через запятую, всё пытался конкатенировать строки. Танцевальные движения с бубном попробую сам придумать.


Интересно будет посмотреть конечную реализацию.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 14:25
Оценка:
Здравствуйте, rg45, Вы писали:

R>Интересно будет посмотреть конечную реализацию.

template<int N> struct Exp10 { enum { value = Exp10<N-1>::value * 10 }; };
template<> struct Exp10<0> { enum { value = 1 }; };

template<int N>
class NumberLength
{
public:
    enum{value = NumberLength<N/10>::value+1};
};

template<>
class NumberLength<0>
{
public:
    enum{value = 0};
};

template<int N, int Pos>
struct SymbolAt 
{ 
    static const char value = N / Exp10<Pos>::value % 10 + '0';
};

template<int N>
struct SymbolAt<N,-1> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-2> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-3> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-4> 
{ 
    static const char value = 0;
};
template<int N>
struct SymbolAt<N,-5> 
{ 
    static const char value = 0;
};
template<int N>
struct SymbolAt<N,-6> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-7> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-8> 
{ 
    static const char value = 0;
};

template<int N>
struct SymbolAt<N,-9> 
{ 
    static const char value = 0;
};
template<int N>
struct IntToString
{
    static const char value[];
};

template<int N>
const char IntToString<N>::value[] = 
{ 
    SymbolAt<N,NumberLength<N>::value-1>::value,
    SymbolAt<N,NumberLength<N>::value-2>::value,
    SymbolAt<N,NumberLength<N>::value-3>::value,
    SymbolAt<N,NumberLength<N>::value-4>::value,
    SymbolAt<N,NumberLength<N>::value-5>::value,
    SymbolAt<N,NumberLength<N>::value-6>::value,
    SymbolAt<N,NumberLength<N>::value-7>::value,
    SymbolAt<N,NumberLength<N>::value-8>::value,
    SymbolAt<N,NumberLength<N>::value-9>::value,
};

template<>
const char IntToString<0>::value[] ={'0',0} ;
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[7]: Int to string compile time.
От: Alexey F  
Дата: 24.12.09 14:32
Оценка:
Здравствуйте, ankorol, Вы писали:

[...skip...]

Может, int на unsigned сменить?
Отрицательные числа не обрабатываются:
int main () {
    puts ( IntToString<3278>::value );
    puts ( IntToString<-3278>::value );
}


3278
-.)(

Re[8]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 14:45
Оценка:
Здравствуйте, Alexey F, Вы писали:

АF>Может, int на unsigned сменить?


Да, надо бы сменить... или допилять что-бы отрицательные корректно обрабатывались
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[7]: Int to string compile time.
От: Тот кто сидит в пруду Россия  
Дата: 24.12.09 14:49
Оценка:
Здравствуйте, ankorol, Вы писали:

ТКС>>Давайте так: вы напишете 2 рекурсивную функция которая вычисляет n-й символ в строковом представлении целого числа, если n превышает длину строки — возвращает 0. А я ваш код в компайлтайм переведу


A>rg45 уже написал не рекурсивную версию.


Exp10 у него, естественно, рекурсивная. Не рекурсивно такие вещи на шаблонах не делаются.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[8]: Int to string compile time.
От: ankorol Украина  
Дата: 24.12.09 14:51
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Exp10 у него, естественно, рекурсивная. Не рекурсивно такие вещи на шаблонах не делаются.

Ну это вспомогательный класс. Его тоже можно заполнить специализациями вручную до каких-то разумных приделов.
Но согласен очень много чего в метапрограммировании на С++ рекурсивное...
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.