Архитектурная акустика/Реализация/IteratorAdapterConditional
< Архитектурная акустика | Реализация
Перейти к навигации
Перейти к поиску
Версия от 00:37, 9 января 2018; Андрей Чусов (обсуждение | вклад) (Новая страница: «{{class|Архитектурная акустика/Реализация/IteratorAdapterConditional}} {{example_begin}} <source lang="cpp"> #include "collection_…»)
Реализует прямой итератор, который на каждой итерации проверяет выполнение условия, заданного предикатом, и, если условие не выполняется, осуществляет переход к следующему элементу до тех пор, пока не будет выполнено условие, или итератор не перейдет в состояние, при котором дальнейшие переходы запрещены.
template <class _BaseIterator, class _Predicate, class _IsDeref>
class IteratorAdapterConditional;
_BaseIterator | Тип преобразуемого адаптером итератора. Должен удовлетворять требованиям ForwardIterator. |
_Predicate | Тип предиката, при перечислении осуществляющего проверку условия остановки переходов. Предикат должен принимать единственный параметр, который может быть:
Вызов предиката должен быть однозначен и соответствовать только одному из вышеупомянутых случаев, поэтому в качестве предиката не допускается использование шаблонов или обобщенных лямбда-выражений. Также предикат должен удовлетворять требованиям CopyConstructible и CopyAssignable. |
_IsDeref | Предикат, проверяющий возможность перехода итератором _BaseIterator к следующему элементу путем инкремента. Тип должен удовлетворять требованиям CopyConstructible и CopyAssignable. |
Открытые типы
Тип | Описание |
---|---|
iterator | Тип _BaseIterator. |
iterator_category | Категория итератора. Тип эквивалентен std::forward_iterator_tag. |
value_type | Тип typename std::iterator_traits<iterator>::value_type . |
reference | Тип typename std::iterator_traits<iterator>::reference . |
pointer | Тип typename std::iterator_traits<iterator>::pointer . |
difference_type | Тип typename std::iterator_traits<iterator>::difference_type . |
predicate | Тип предиката необходимости перехода. Тип эквивалентен _Predicate. |
iterator_predicate | Тип предиката возможности перехода. Тип эквивалентен _IsDeref. |
Открытые методы
Метод | Описание |
---|---|
(конструкторы) | Конструкторы класса IteratorAdapterConditional. |
operator= | Операторы присваивания. |
operator* | Оператор разыменовывания. |
operator-> | Оператор косвенного доступа к элементам. |
operator++ | Переход итератора к следующему элементу, удовлетворяющему предикату IteratorAdapterConditional::predicate. |
operator== | Проверка на эквивалентность итераторов. |
operator!= | Проверка на неэквивалентность итераторов. |
base | Возвращает адаптируемый итератор в текущей позиции. |
adaptation_base | Возвращает текущий корневой адаптированный, возможно цепочкой адаптеров, итератор. |
Пример
#include "collection_base.h"
#include <array>
#include <iostream>
using namespace Chusov::Math;
template <class Container>
std::array<int, 20 * 10> extract_even_range_for(const Container& cont)
{
std::vector<std::thread> vecThreads;
std::array<int, 20 * 10> EvenValues;
for (unsigned i = 0; i < std::thread::hardware_concurrency(); ++i)
vecThreads.emplace_back([&vecThreads, i, &cont, &EvenValues]()
{
for (auto&& v :
adapt_iterator_range<IteratorAdapterConditional>(
adapt_iterator_range<IteratorAdapterForStep>(
Chusov::Memory::make_iterator_range(make_iterator_adapter<IteratorAdapter2D>(cont.crbegin()) + i, cont.crend()),
std::thread::hardware_concurrency(),
adapt_iterator_range<IteratorAdapter2D>(cont.crbegin(), cont.crend())
),
[](int x) -> bool {return (x & 1) == 0; },
//or: [](IteratorAdapterForStep<IteratorAdapter2D<Matrix<int>::const_reverse_iterator>> _it) -> bool {return (*_it & 1) == 0;},
//or: [](IteratorAdapter2D<Matrix<int>::const_reverse_iterator> _it) -> bool {return (*_it & 1) == 0;},
[&cont](auto _it) -> bool {return _it.adaptation_base() != cont.crend(); }
//or: [&cont](IteratorAdapterForStep<IteratorAdapter2D<Matrix<int>::const_reverse_iterator>> it) -> bool {return it != cont.crend();}
)
)
EvenValues[20 * 10 - v / 2] = v;
});
for (auto&& thr : vecThreads)
thr.join();
return EvenValues;
}
template <class Container>
std::array<int, 20 * 10> extract_even_direct_for(const Container& cont)
{
std::vector<std::thread> vecThreads;
std::array<int, 20 * 10> EvenValues;
for (unsigned i = 0; i < std::thread::hardware_concurrency(); ++i)
vecThreads.emplace_back([&vecThreads, i, &cont, &EvenValues]()
{
for (auto it = make_iterator_adapter<IteratorAdapterConditional>(
make_iterator_adapter<IteratorAdapterForStep>(
i,
std::thread::hardware_concurrency(),
adapt_iterator_range<IteratorAdapter2D>(cont.crbegin(), cont.crend())
),
//generic lambda causes ambiguity: should it pass an iterator or a value here
[](IteratorAdapterForStep<IteratorAdapter2D<Matrix<int>::const_reverse_iterator>> _it) -> bool {return (*_it & 1) == 0; },
[&cont](auto _it) -> bool {return _it.adaptation_base() != cont.crend(); }
); it.adaptation_base() != make_iterator_adapter<IteratorAdapter2D>(cont.crend()); ++it)
EvenValues[20 * 10 - *it / 2] = *it;
});
for (auto&& thr : vecThreads)
thr.join();
return EvenValues;
}
int main(int argc, char** argv)
{
auto m2 = Matrix<int>(0, 20, 20);
auto x = 1;
for (auto&& v : adapt_iterator_range<IteratorAdapter2D>(m2.begin(), m2.end()))
v = x++;
auto rng_based = extract_even_range_for(m2);
std::cout << "\nElements of an array with even elements of a matrix put in parallel in reverse order (range-for based).\n";
for (auto val:rng_based)
std::cout << val << "\t";
std::cout << "\n";
auto direct_based = extract_even_direct_for(m2);
for (auto val : direct_based)
std::cout << val << "\t";
std::cout << "\n";
return 0;
}