cstring_iterator
От: igna Россия  
Дата: 11.07.11 14:22
Оценка:
Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:

template <class OutputIterator>
void copy_cstring(char const* s, OutputIterator oi)
{
    copy(cstring_iterator(s), cstring_iterator(), oi);
}


Boost смотрел, не нашел. Хорошо запрятали (как например implicit_cast), плохо смотрел, или авторам не до таких мелочей?

В общем нужно приблизительно вот что:

class cstring_iterator : public iterator<forward_iterator_tag, char> {
    char const* ptr_;
    char value_;

    void read_value()
    {
        value_ = *ptr_;
        if (!value_)
            ptr_ = 0;
    }
public:
    explicit cstring_iterator(char const* const s)
        : ptr_ (s)
    {
        read_value();
    }
    cstring_iterator()
        : ptr_ (0)
    {}
    char operator*()
    {
        return value_;
    }
    cstring_iterator& operator++()
    {
        ++ptr_;
        read_value();
        return *this;
    }
    cstring_iterator operator++(int)
    {
        cstring_iterator tmp;
        operator++();
        return tmp;
    }
    friend bool operator==(cstring_iterator const& x, cstring_iterator const& y)
    {
        return x.ptr_ == y.ptr_;
    }
    friend bool operator!=(cstring_iterator const& x, cstring_iterator const& y)
    {
        return !operator==(x, y);
    }
};
Re: cstring_iterator
От: c-smile Канада http://terrainformatica.com
Дата: 11.07.11 15:20
Оценка:
Здравствуйте, igna, Вы писали:

Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++.
Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?
Re[2]: cstring_iterator
От: _nn_ www.nemerleweb.com
Дата: 11.07.11 15:45
Оценка:
Здравствуйте, c-smile, Вы писали:

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


CS>Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++.

CS>Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?

Получится такой простой универсальный код:
template <class InputPointer, class OutputIterator>
void copy_cstring(InputPointer s, OutputIterator oi)
{
    while (*s)
    {
        *oi = *s;
        ++oi;
        ++s;
    }
}


Но тогда нет begin и end
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: cstring_iterator
От: wander  
Дата: 11.07.11 20:36
Оценка: 1 (1) +1
Здравствуйте, igna, Вы писали:

I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:


здесь
Re[2]: cstring_iterator
От: igna Россия  
Дата: 12.07.11 05:51
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Или я не понял или ты только что описал банальный указатель const char* и его встроенный operator++.

CS>Только зачем этот весь огород? Чисто чтоб было как у пацанов в boost?

Чтобы как в STL. И чтобы использовать алгоритмы оттуда.
Re[2]: cstring_iterator
От: igna Россия  
Дата: 12.07.11 08:41
Оценка:
Здравствуйте, wander, Вы писали:

W>здесь


Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL. Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.
Re[3]: cstring_iterator
От: wander  
Дата: 12.07.11 09:44
Оценка:
Здравствуйте, igna, Вы писали:

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


W>>здесь


I>Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL. Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.


Алгоритмы можно и стандартные использовать. ИМХО, range только дополняет их. boost::iterator_range видел?

Нашелся еще вот такой исходник. Что-то подобное встречалось и с использованием range, с ходу не нашел примера.
Re[4]: cstring_iterator
От: igna Россия  
Дата: 12.07.11 10:08
Оценка:
Здравствуйте, wander, Вы писали:

W>Алгоритмы можно и стандартные использовать. ИМХО, range только дополняет их. boost::iterator_range видел?


W>Нашелся еще вот такой исходник. Что-то подобное встречалось и с использованием range, с ходу не нашел примера.


Прошу прощения, можно сначала один вопрос прежде чем я снова начну искать в Bopost.Range. Мне cstring_iterator или cstring_range все-равно придется самому писать?
Re: cstring_iterator
От: Alexander G Украина  
Дата: 12.07.11 14:02
Оценка: 1 (1) +1
Здравствуйте, igna, Вы писали:

I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:


I>
I>template <class OutputIterator>
I>void copy_cstring(char const* s, OutputIterator oi)
I>{
I>    copy(cstring_iterator(s), cstring_iterator(), oi);
I>}
I>


Насколько я вижу, можно написать наследник boost::iterator_adaptor перекрыв только метод equal, это не очень много кода.
Русский военный корабль идёт ко дну!
Re[3]: cstring_iterator
От: jazzer Россия Skype: enerjazzer
Дата: 13.07.11 03:48
Оценка:
Здравствуйте, igna, Вы писали:

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


W>>здесь


I>Спасибо, я понял так, что нужно использовать алгоритмы Boost.Range взамен алгоритмов STL


Необязательно, хоть и удобно.
Можно юзать вот так:
std::for_each( boost::begin(xxx), boost::end(xxx), yyy );

где xxx — это любой совместимый Forward Iterator Range, включая std::pair<const char*,const char*>.

I>Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.

вышеупомянутая std::pair — это оно и есть.
Ну и as_literal(), as_array() тоже их генерят (только у последнего будет ноль заключительный еще):
http://www.boost.org/doc/libs/1_47_0/libs/range/doc/html/range/reference/concept_implementation/semantics/functions.html
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: cstring_iterator
От: igna Россия  
Дата: 13.07.11 04:49
Оценка:
Здравствуйте, jazzer, Вы писали:

I>>Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.


J>вышеупомянутая std::pair — это оно и есть.

J>Ну и as_literal(), as_array() тоже их генерят (только у последнего будет ноль заключительный еще):
J>http://www.boost.org/doc/libs/1_47_0/libs/range/doc/html/range/reference/concept_implementation/semantics/functions.html

Они все предварительно измеряют длину строки, верно?
Re: cstring_iterator
От: ioni Россия  
Дата: 13.07.11 06:23
Оценка:
Здравствуйте, igna, Вы писали:

I>Нужен итератор по знакам/символам строки заканчивающейся нулем (без предварительного измерения длины строки), который будет использоваться примерно так:

вы фактически и написали что вам тербуется
я бы подкорректировал так

template < typename TChar >
struct const_string_iterator : public std::iterator< std::forward_iterator_tag, TChar>
{
    TChar const* str_;
    explicit const_string_iterator( TChar const* str ) : str_( str )
    {
    }
    const_string_iterator( ) : str_( 0 )
    {
    }
    TChar operator* ()
    {
        return (str_ == 0) ? 0 : *str_;
    }
    const_string_iterator& operator++()
    {
        if(str_ != 0)
        {
            ++str_;
            if(*str_ == 0) str_ = 0;
        }
        return *this;
    }
    const_string_iterator operator++(int)
    {
        const_string_iterator tmp;
        operator++();
        return tmp;
    }
    friend bool operator==(const_string_iterator const& x, const_string_iterator const& y)
    {
        return x.str_ == y.str_;
    }

    friend bool operator!=(const_string_iterator const& x, const_string_iterator const& y)
    {
        return !operator==(x, y);
    }
};

typedef const_string_iterator< char > char_string_iterator;
typedef const_string_iterator< wchar_t > wchar_string_iterator;

//////////////////////////////////////////////////////////////////////////
int main(int argc, _TCHAR* argv[])
{
    const char* str = {"abcdefghijklmniop"};
    std::copy( char_string_iterator(str), char_string_iterator(), std::ostream_iterator<char>(std::cout, "\n") );
    return 0;
}
Re[5]: cstring_iterator
От: jazzer Россия Skype: enerjazzer
Дата: 13.07.11 06:57
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

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


I>>>Хорошо, только чего-то подобного cstring_range я в Boost.Range не нашел.


J>>вышеупомянутая std::pair — это оно и есть.

J>>Ну и as_literal(), as_array() тоже их генерят (только у последнего будет ноль заключительный еще):
J>>http://www.boost.org/doc/libs/1_47_0/libs/range/doc/html/range/reference/concept_implementation/semantics/functions.html

I>Они все предварительно измеряют длину строки, верно?


иначе random access не получить

но as_array() не должен измерять, просто должен взять весь массив как есть.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: cstring_iterator
От: _nn_ www.nemerleweb.com
Дата: 13.07.11 07:04
Оценка: 1 (1)
Здравствуйте, jazzer, Вы писали:

J>иначе random access не получить


Автору поста очевидно нужен Input/Output итератор, а не Random Access.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: cstring_iterator
От: igna Россия  
Дата: 13.07.11 08:14
Оценка:
Здравствуйте, jazzer, Вы писали:

J>иначе random access не получить


Мне достаточно получить итератор ввода.

J>но as_array() не должен измерять, просто должен взять весь массив как есть.


В моем примере использования того, что нужно, массива нет, так char const*.

Но все-равно за ответ спасибо, нет значит в бусте, того что мне надо в готовом виде.
Re[2]: cstring_iterator
От: igna Россия  
Дата: 13.07.11 08:42
Оценка:
Здравствуйте, ioni, Вы писали:

I>я бы подкорректировал так


У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.

Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.
Re[3]: cstring_iterator
От: ioni Россия  
Дата: 13.07.11 12:51
Оценка:
Здравствуйте, 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
Re[3]: cstring_iterator
От: ioni Россия  
Дата: 13.07.11 12:54
Оценка:
Здравствуйте, igna, Вы писали:

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


I>>я бы подкорректировал так


I>У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.


I>Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.


точно
сейчас поправлю
Re[3]: cstring_iterator
От: ioni Россия  
Дата: 13.07.11 12:59
Оценка:
Здравствуйте, igna, Вы писали:

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


I>>я бы подкорректировал так


I>У тебя ошибка, в случае пустой строки выводится завершающий строку '\0'.


I>Не стану утверждать, что у меня ошибок нет; как раз для того, чтобы не выискивать их, и хотел воспользоваться готовым решением. А нафигачить горы непроверенного и неотлаженного кода вдоль и поперек по диагонали я тоже могу. Но не хочу.


испрвленный конструктор

    explicit const_string_iterator( TChar const* str ) : str_( str )
    {
        if( str_ != 0 && *str_ == 0 ) str_ = 0;
    }
Re[4]: cstring_iterator
От: igna Россия  
Дата: 13.07.11 14:17
Оценка:
Здравствуйте, ioni, Вы писали:

I>испрвленный конструктор


I>    explicit const_string_iterator( TChar const* str ) : str_( str )
I>    {
I>        if( str_ != 0 && *str_ == 0 ) str_ = 0;
I>    }


Хорошо, едем дальше. Проверка str_ != 0 в операторах разыменовывания и инкрементирования in release mode не нужна, поскольку сингулярный итератор разыменовывать и инкрементировать запрещено.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.