Здравствуйте, igna, Вы писали:
I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:
Здравствуйте, igna, Вы писали:
I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:
I>
Здравствуйте, igna, Вы писали:
I>В типичном случае это разыменование будет соптимизировано, поскольку где-то неподалеку будет находиться еще одно разыменование от оператора разыменования. А вот сравнение с нулем в типичном случае сравнения несингулярных итераторов соптимизировать будет нельзя.
Если считать сравнения, то сравнение с нулём всё равно будет, в данном случае с нулевым символом. Нужно смотреть результат компиляции, чтобы сказать точно, что быдет лучше.
AG>>Хорошего random access iterator из этой идеи не получится. Для random access iterator требуется операция distance, она будет за линейное время при наличии сингулярного итератора.
I>Это не так, ты же знаешь, что символы строки хранятся непрерывно, значит смело можешь вычитать. Даже проверка на 0 in release mode не нужна, поскольку сингулярный итератор в качестве аргумента distance использовать нельзя.
Здравствуйте, Alexander G, Вы писали:
AG>Если считать сравнения, то сравнение с нулём всё равно будет, в данном случае с нулевым символом. Нужно смотреть результат компиляции, чтобы сказать точно, что быдет лучше.
Смотрим результат компиляции:
increment
$LL45@main:
movsx ecx, cl
inc edx
add eax, ecx
mov cl, BYTE PTR [edx]
test cl, cl
jne SHORT $LL45@main
equal
$LL41@main:
mov cl, BYTE PTR [edx]
test cl, cl
sete bl
test bl, bl
jne SHORT $LN76@main
movsx ecx, cl
add eax, ecx
inc edx
jmp SHORT $LL41@main
$LN76@main:
Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:
Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++.
Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, igna, Вы писали:
CS>Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++. CS>Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?
Здравствуйте, c-smile, Вы писали:
CS>Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++. CS>Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?
Чтобы как в STL. И чтобы использовать алгоритмы оттуда.
Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL. Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, wander, Вы писали:
W>>здесь
I>Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL. Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.
Алгоритмы можно и стандартные использовать. ИМХО, range только дополняет их. boost::iterator_range видел?
Нашелся еще вот такой исходник. Что-то подобное встречалось и с использованием range, с ходу не нашел примера.
Здравствуйте, wander, Вы писали:
W>Алгоритмы можно и стандартные использовать. ИМХО, range только дополняет их. boost::iterator_range видел?
W>Нашелся еще вот такой исходник. Что-то подобное встречалось и с использованием range, с ходу не нашел примера.
Прошу прощения, можно сначала один вопрос прежде чем я снова начну искать в Bopost.Range. Мне cstring_iterator или cstring_range все-равно придется самому писать?
Здравствуйте, igna, Вы писали:
I>Здравствуйте, wander, Вы писали:
W>>здесь
I>Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL
Необязательно, хоть и удобно.
Можно юзать вот так:
Здравствуйте, igna, Вы писали:
I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:
вы фактически и написали что вам тербуется
я бы подкорректировал так
Здравствуйте, ioni, Вы писали:
I>я бы подкорректировал так
У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.
Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, ioni, Вы писали:
I>>я бы подкорректировал так
I>У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.
I>Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.
Я проверял нет
int main()
{
const char* str = {"abcdefghijklmniop"};
// std::copy( char_string_iterator(str), char_string_iterator(), std::ostream_iterator<char>(std::cout, "\n") );
size_t len = 0;
char_string_iterator i = char_string_iterator(str), e =char_string_iterator();
for(; i != e; ++i)
{
char ch = *i;
++len;
}
std::cout << strlen(str) << " " << len;
return 0;
}
17 17
Здравствуйте, igna, Вы писали:
I>Здравствуйте, ioni, Вы писали:
I>>я бы подкорректировал так
I>У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.
I>Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, ioni, Вы писали:
I>>я бы подкорректировал так
I>У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.
I>Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.
Хорошо, едем дальше. Проверка str_ != 0 в операторах разыменовывания и инкрементирования in release mode не нужна, поскольку сингулярный итератор разыменовывать и инкрементировать запрещено.
Здравствуйте, igna, Вы писали:
I>Хорошо, едем дальше. Проверка str_ != 0 в операторах разыменовывания и инкрементирования in release mode не нужна, поскольку сингулярный итератор разыменовывать и инкрементировать запрещено.
да пожалуй вы правы
валидность указателя надо проверять до
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, ioni, Вы писали:
I>>да пожалуй вы правы I>>валидность указателя надо проверять до
AG>Ещё, operator* () должен возвращать ссылку.
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, ioni, Вы писали:
I>>согласен I>>но вообще то не собирается
AG>Всё собирается. Исправил ошибку, вот:
AG>http://codepad.org/7HVj94bg
нет ничего совершенного
Логически это именно то, что надо, но может оказаться неоптимальным в некоторых случаях; например, если сравниваются два несингулярных итератора. Если достаточен forward iterator, лучше все же обнулять указатель сразу как только он устанавливается на конец строки. (Мест таких два: в конструкторе и в операторе инкрементирования, поэтому проверку и обнуление имеет смысл вынести в отдельную функцию.)
А вот если нужен random access iterator, то может быть и так, как ты предложил, хотя я бы подумал еще, не лучше ли сохранять указатель на последний символ/знак строки перед обнулением указателя, чтобы оператор декрементирования мог восстановить его. Правда тогда в итераторе потребуется еще одно поле.
В любом случае библиотека общего назначения должна бы иметь оба эти итератора для строки заканчивающейся нулем: один как forward iterator, второй как random access iterator.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Alexander G, Вы писали:
AG>>А, ну да. Может переопределить не increment, а equal, как я ранее предложил:
I>
I>Логически это именно то, что надо, но может оказаться неоптимальным в некоторых случаях; например, если сравниваются два несингулярных итератора.
Я думаю, цикл с диапазоном из двух несингулярных итераторов в случае такого equal оптимальнее.
В случае проверки в increment будет разыменование. В случае проверки в equal выполнится последняя ветка, которая ничего не разыменует.
I>А вот если нужен random access iterator, то может быть и так, как ты предложил, хотя я бы подумал еще, не лучше ли сохранять указатель на последний символ/знак строки перед обнулением указателя, чтобы оператор декрементирования мог восстановить его. Правда тогда в итераторе потребуется еще одно поле.
Хорошего random access iterator из этой идеи не получится. Для random access iterator требуется операция distance, она будет за линейное время при наличии сингулярного итератора. Даже хорошего bidirectional не получится — past-the-end должен быть декрементируемым, это не сработает для cstring_iterator, изначально сконструированного сингулярным.
I>В любом случае библиотека общего назначения должна бы иметь оба эти итератора для строки заканчивающейся нулем: один как forward iterator, второй как random access iterator.
Должна библиотека общего назначения включать такие микрооптимизации?
Здравствуйте, Alexander G, Вы писали:
AG>В случае проверки в increment будет разыменование.
В типичном случае это разыменование будет соптимизировано, поскольку где-то неподалеку будет находиться еще одно разыменование от оператора разыменования. А вот сравнение с нулем в типичном случае сравнения несингулярных итераторов соптимизировать будет нельзя.
AG>Хорошего random access iterator из этой идеи не получится. Для random access iterator требуется операция distance, она будет за линейное время при наличии сингулярного итератора.
Это не так, ты же знаешь, что символы строки хранятся непрерывно, значит смело можешь вычитать. Даже проверка на 0 in release mode не нужна, поскольку сингулярный итератор в качестве аргумента distance использовать нельзя.
Здравствуйте, igna, Вы писали:
AG>>Если считать сравнения, то сравнение с нулём всё равно будет, в данном случае с нулевым символом. Нужно смотреть результат компиляции, чтобы сказать точно, что быдет лучше.
I>Смотрим результат компиляции:
Вот теперь вижу, хотя физический смысл использования регистра bl неясен