@Xiran

Как написать итератор для цифр числа?

Во общем, итератор мне нужен для того, чтобы итерировать по цифрам чисел в разных системах счисления.
Я хочу, чтобы интерфейс у него был как у std::ostream_iterator.
Это бы было прям идеально.
Но, я не знаю:
1. Как оформить итератор конца
2. Как следить за лайфтаймом объектов без контейнера
Хотелось бы, например, делать вот так:
std::vector<int> number { DigitsIterator<int> { n, 10 }, DigitsIterator<int> { } };

Прошу описать, как подобные "бесконтейнерные" итераторы пишутся.
  • Вопрос задан
  • 120 просмотров
Решения вопроса 1
@vanyamba-electronics
Примерно так.
#include <iostream>

using namespace std;

template <typename _T>
class digitstream
{
protected:
    _T m_value;
public:
    digitstream(const _T& val) :
        m_value(val)
    {
    }
    class const_iterator 
    {
    protected:
        _T m_value;
        unsigned int m_base;
        unsigned int m_pos;
    public:
        const_iterator(const _T& val, unsigned int base) :
            m_value(val),
            m_base(base)
        {
            m_pos = 0;
            if (m_base != 0) {
                if (m_value < m_base)
                    return;
                _T rest = m_value;
                do {
                    rest = rest / m_base;
                    m_pos++;
                }
                while (rest >= m_base);
            }
        }
        const_iterator(const const_iterator& src) :
            m_value(src.m_value),
            m_base(src.m_base),
            m_pos(src.m_pos)
        {
        }
        char operator * () const {
            if (m_base != 0) {
                _T rest = m_value;
                for (int n = 0; n < m_pos; ++n)
                    rest = rest / m_base;
                _T result = rest % m_base;
                if (result > 9)
                    return 'A' + result - 10;
                return '0' + result;
            }
            return '0';
        }
        const_iterator& operator ++() {
            --m_pos;
            return *this;
        }
        const_iterator& operator --() {
            ++m_pos;
            return *this;
        }
        bool operator ==(const const_iterator& cmp) const {
            if (cmp.m_value == 0 && cmp.m_base == 0 && m_pos == -1)
                return true;
            return false;
        }
        bool operator !=(const const_iterator& cmp) const {
            return ! operator ==(cmp);
        }
    };
    const_iterator begin(unsigned int base) const {
        return const_iterator(m_value, base);
    }
    const_iterator end() const {
        return const_iterator(0, 0);
    }
    class reverse_iterator
    {
    protected:
        _T m_value;
        unsigned int m_base;
        unsigned int m_pos;
    public:
        reverse_iterator(const _T& val, unsigned int base) :
            m_value(val),
            m_base(base),
            m_pos(0)
        {
        }
        reverse_iterator(const reverse_iterator& src) :
            m_value(src.m_value),
            m_base(src.m_base),
            m_pos(src.m_pos)
        {
        }
        char operator * () const {
            if (m_base != 0) {
                _T rest = m_value;
                for (int n = 0; n < m_pos; ++n)
                    rest = rest / m_base;
                _T result = rest % m_base;
                if (result > 9)
                    return 'A' + result - 10;
                return '0' + result;
            }
            return '0';
        }
        reverse_iterator& operator ++() {
            ++m_pos;
            return *this;
        }
        reverse_iterator& operator --() {
            --m_pos;
            return *this;
        }
        bool operator ==(const reverse_iterator& cmp) const {
            if (cmp.m_value == 0 && cmp.m_base == 0 && m_base != 0) {
                 _T rest = m_value;
                for (int n = 0; n < m_pos; ++n)
                    rest = rest / m_base;
                if (rest == 0)
                    return true;
            }
            return false;
        }
        bool operator !=(const reverse_iterator& cmp) const {
            return ! operator ==(cmp);
        }
    };
    reverse_iterator rbegin(unsigned int base) const {
        return reverse_iterator(m_value, base);
    }
    reverse_iterator rend() const {
        return reverse_iterator(0, 0);
    }
};

int main()
{
    digitstream<int> ds(0xFADE372F);
    for (digitstream<int>::const_iterator it = ds.begin(16); it != ds.end(); ++it)
        cout << *it;
    cout << endl;
    for (digitstream<int>::reverse_iterator rit = ds.rbegin(16); rit != ds.rend(); ++rit)
        cout << *rit;
    cout << endl;

    return 0;
}

Ссылка на Online GDB.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы