Здравствуйте, 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, Вы писали:
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: