Как я могу перебирать строку в 128-битных кусках?

у меня есть функция, которая работает на 128-битных блоков данных с произвольной длиной строки. Если строка не делится на блоки по 128 бит, она будет дополнена соответственно.

цель состоит в том, чтобы преобразовать данные в строке, которая подается в функцию.

Я изначально думал о петле через строку такой:

//This might have stupid errors.  Hopefully it stillg gets the point across.
for (int i = 0; i < strn.size(); i += 16)
{
    string block = strn.substr(i, i + 15);
    strn.replace(i, i + 15, block);
}

Я думаю, это сработает, но я думаю, что должен быть более элегантный способ сделать это. Одна идея это пришло на ум, чтобы инкапсулировать strn в классе и реализовать свой собственный итератор, который может читать его содержимое в 128-битных кусках. Это привлекательно, потому что конструктор может обрабатывать заполнение, а некоторые из функций, которые я сейчас использую, могут быть приватными, что позволяет избежать возможного неправильного использования. Кажется ли это плодотворным подходом? Если да, то как можно реализовать свой собственный итератор? Подробные объяснения приветствуются, так как я очень неопытный с C++.

несколько есть другие, возможно, лучшие, подходы?

спасибо!

2 ответов


существует много подходов. Один из самых простых и понятных был бы таким:: вы можете создать свой собственный тип размером ровно 128 бит; простой struct сделает работу.

typedef struct
{
    char buf[16];
} _128bit;

и используйте его для итерации по вашей строке. Приведите начало строки к этому типу структуры:_128bit* start = (_128bit*)buffer; и начните итерацию с ним, используя арифметику интегрального указателя. Все операции на start будет работать с точки зрения его размера. Е. Г. ,start++ двинет 128 битов вперед; start-- переместит 128 бит назад. Как только вы окажетесь в нужной позиции, переделайте ее на нужный тип и выполните свои манипуляции.


Я бы, вероятно, сделал это с итераторами, а не индексированием, все еще используя свой собственный цикл for:

const int NUM_BITS_IN_CHUNK = 128;
const int CHUNK_SIZE = NUM_BITS_IN_CHUNK / CHAR_BIT;

for(std::string::const_iterator iter = str.begin(); iter < str.end(); iter += CHUNK_SIZE)
{
    your_func(iter, iter + CHUNK_SIZE);
}

код boost:: iterator_adaptor будет выглядеть примерно так. Обратите внимание, что я получаю только четыре байта на кусок вместо 16 для простоты в Примере.:

#include <iostream>
#include <string>

#include <boost/iterator_adaptors.hpp>

struct string_chunk_iterator : public boost::iterator_adaptor<string_chunk_iterator, std::string::const_iterator>
{
    string_chunk_iterator(const std::string::const_iterator& base) : iterator_adaptor(base) { }

private:
    friend class boost::iterator_core_access;
    void increment() { this->base_reference() = this->base() + 4; }
    void advance(typename iterator_adaptor::difference_type n)
    {
        this->base_reference() = this->base() + (4 * n);
    }
};

int main()
{
    const std::string tester(20, 'A');

    string_chunk_iterator iter(tester.begin());
    string_chunk_iterator str_end(tester.end());

    for(; iter != str_end; ++iter)
    {
        std::string chunk(&*iter, &*(iter + 1));

        std::cout << chunk << std::endl;
    }

    return 0;
}