1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
15 #include <unordered_set>
17 #include <vpu/utils/containers.hpp>
18 #include <vpu/utils/handle.hpp>
19 #include <vpu/utils/optional.hpp>
29 template <class Iterator>
30 class IterRange final {
32 using value_type = typename Iterator::value_type;
34 using iterator = Iterator;
35 using const_iterator = Iterator;
37 inline IterRange() = default;
38 inline IterRange(const IterRange&) = default;
39 inline IterRange& operator=(const IterRange&) = default;
40 inline IterRange(IterRange&&) = default;
41 inline IterRange& operator=(IterRange&&) = default;
43 template <class It1, class It2>
44 inline IterRange(It1&& b, It2&& e) : _begin(std::forward<It1>(b)), _end(std::forward<It2>(e)) {}
46 inline Iterator begin() const { return _begin; }
47 inline Iterator end() const { return _end; }
49 Iterator cbegin() const { return _begin; }
50 Iterator cend() const { return _end; }
59 template <class Iterator>
60 inline impl::IterRange<Iterator> iterRange(const Iterator& begin, const Iterator& end) {
61 return impl::IterRange<Iterator>(begin, end);
63 template <class Iterator>
64 inline impl::IterRange<Iterator> iterRange(Iterator&& begin, Iterator&& end) {
65 return impl::IterRange<Iterator>(std::move(begin), std::move(end));
75 class ContRange final {
77 using value_type = typename Cont::value_type;
79 using iterator = typename Cont::iterator;
80 using const_iterator = typename Cont::const_iterator;
82 inline ContRange() = default;
83 inline ContRange(const ContRange&) = default;
84 inline ContRange& operator=(const ContRange&) = default;
85 inline ContRange(ContRange&&) = default;
86 inline ContRange& operator=(ContRange&&) = default;
88 inline explicit ContRange(const Cont& cont) : _cont(&cont) {}
90 inline const_iterator begin() const {
91 assert(_cont != nullptr);
92 return _cont->begin();
94 inline const_iterator end() const {
95 assert(_cont != nullptr);
99 inline const_iterator cbegin() const {
100 assert(_cont != nullptr);
101 return _cont->begin();
103 inline const_iterator cend() const {
104 assert(_cont != nullptr);
109 const Cont* _cont = nullptr;
114 template <class Cont>
115 inline impl::ContRange<Cont> contRange(const Cont& cont) {
116 return impl::ContRange<Cont>(cont);
125 template <class BaseRange, class MapOp>
126 class MapRange final {
128 class Iterator final {
130 using base_iterator = typename BaseRange::const_iterator;
131 using base_iterator_value = decltype(*base_iterator());
133 using map_op_value = typename std::result_of<MapOp(base_iterator_value)>::type;
135 using value_type = typename std::decay<map_op_value>::type;
136 using pointer = value_type*;
137 using reference = value_type&;
139 using iterator_category = std::input_iterator_tag;
140 using difference_type = std::ptrdiff_t;
142 inline Iterator() = default;
143 inline Iterator(const Iterator&) = default;
144 inline Iterator& operator=(const Iterator&) = default;
145 inline Iterator(Iterator&&) = default;
146 inline Iterator& operator=(Iterator&&) = default;
149 inline Iterator(BI&& cur, BI&& end, const MapOp& op) :
150 _cur(std::forward<typename std::remove_reference<BI>::type>(cur)),
151 _end(std::forward<typename std::remove_reference<BI>::type>(end)),
155 inline const value_type& operator*() const {
156 assert(_cur != _end);
157 _curValue = (*_op)(*_cur);
158 return _curValue.get();
161 inline Iterator& operator++() {
166 inline bool operator==(const Iterator& other) const {
167 return _cur == other._cur;
169 inline bool operator!=(const Iterator& other) const {
170 return _cur != other._cur;
176 const MapOp* _op = nullptr;
178 mutable Optional<value_type> _curValue;
181 using base_iterator = typename BaseRange::const_iterator;
182 using base_iterator_value = decltype(*base_iterator());
184 using map_op_value = typename std::result_of<MapOp(base_iterator_value)>::type;
186 using value_type = typename std::decay<map_op_value>::type;
188 using iterator = Iterator;
189 using const_iterator = Iterator;
191 inline MapRange() = default;
192 inline MapRange(const MapRange&) = default;
193 inline MapRange& operator=(const MapRange&) = default;
194 inline MapRange(MapRange&&) = default;
195 inline MapRange& operator=(MapRange&&) = default;
197 template <class _B, class _M>
198 inline MapRange(_B&& base, _M&& op) :
199 _base(std::forward<typename std::remove_reference<_B>::type>(base)),
200 _op(std::forward<typename std::remove_reference<_M>::type>(op)) {
203 inline Iterator begin() const { return Iterator(_base.begin(), _base.end(), _op); }
204 inline Iterator end() const { return Iterator(_base.end(), _base.end(), _op); }
206 inline Iterator cbegin() const { return Iterator(_base.begin(), _base.end(), _op); }
207 inline Iterator cend() const { return Iterator(_base.end(), _base.end(), _op); }
216 template <class BaseRange, class MapOp>
217 inline impl::MapRange<typename std::decay<BaseRange>::type, typename std::decay<MapOp>::type>
218 mapRange(BaseRange&& base, MapOp&& op) {
219 return impl::MapRange<typename std::decay<BaseRange>::type, typename std::decay<MapOp>::type>(
220 std::forward<typename std::remove_reference<BaseRange>::type>(base),
221 std::forward<typename std::remove_reference<MapOp>::type>(op));
223 template <class MapOp, class BaseRange>
224 inline impl::MapRange<typename std::decay<BaseRange>::type, MapOp> mapRange(BaseRange&& base) {
225 return impl::MapRange<typename std::remove_reference<BaseRange>::type, MapOp>(
226 std::forward<typename std::remove_reference<BaseRange>::type>(base),
236 template <class BaseRange, class FilterOp>
237 class FilterRange final {
239 class Iterator final {
241 using base_iterator = typename BaseRange::const_iterator;
242 using base_iterator_value = decltype(*base_iterator());
244 using value_type = typename std::decay<base_iterator_value>::type;
245 using pointer = value_type*;
246 using reference = value_type&;
248 using iterator_category = std::input_iterator_tag;
249 using difference_type = std::ptrdiff_t;
251 inline Iterator() = default;
252 inline Iterator(const Iterator&) = default;
253 inline Iterator& operator=(const Iterator&) = default;
254 inline Iterator(Iterator&&) = default;
255 inline Iterator& operator=(Iterator&&) = default;
258 inline Iterator(BI&& cur, BI&& end, const FilterOp& op) :
259 _cur(std::forward<typename std::remove_reference<BI>::type>(cur)),
260 _end(std::forward<typename std::remove_reference<BI>::type>(end)),
265 inline const value_type& operator*() const {
266 assert(_cur != _end);
268 return _curValue.get();
271 inline Iterator& operator++() {
277 inline bool operator==(const Iterator& other) const {
278 return _cur == other._cur;
280 inline bool operator!=(const Iterator& other) const {
281 return _cur != other._cur;
285 inline void advance() {
286 while (_cur != _end) {
288 if ((*_op)(_curValue.get())) {
298 const FilterOp* _op = nullptr;
300 mutable Optional<value_type> _curValue;
303 using value_type = typename BaseRange::value_type;
305 using iterator = Iterator;
306 using const_iterator = Iterator;
308 inline FilterRange() = default;
309 inline FilterRange(const FilterRange&) = default;
310 inline FilterRange& operator=(const FilterRange&) = default;
311 inline FilterRange(FilterRange&&) = default;
312 inline FilterRange& operator=(FilterRange&&) = default;
314 template <class _B, class _F>
315 inline FilterRange(_B&& base, _F&& op) :
316 _base(std::forward<typename std::remove_reference<_B>::type>(base)),
317 _op(std::forward<typename std::remove_reference<_F>::type>(op)) {
320 inline Iterator begin() const { return Iterator(_base.begin(), _base.end(), _op); }
321 inline Iterator end() const { return Iterator(_base.end(), _base.end(), _op); }
323 inline Iterator cbegin() const { return Iterator(_base.begin(), _base.end(), _op); }
324 inline Iterator cend() const { return Iterator(_base.end(), _base.end(), _op); }
333 template <class BaseRange, class FilterOp>
334 inline impl::FilterRange<typename std::decay<BaseRange>::type, typename std::decay<FilterOp>::type>
335 filterRange(BaseRange&& base, FilterOp&& op) {
337 FilterRange<typename std::decay<BaseRange>::type, typename std::decay<FilterOp>::type>(
338 std::forward<typename std::remove_reference<BaseRange>::type>(base),
339 std::forward<typename std::remove_reference<FilterOp>::type>(op));
341 template <class FilterOp, class BaseRange>
342 inline impl::FilterRange<typename std::decay<BaseRange>::type, FilterOp> filterRange(BaseRange&& base) {
343 return impl::FilterRange<typename std::decay<BaseRange>::type, FilterOp>(
344 std::forward<typename std::remove_reference<BaseRange>::type>(base),
348 struct NonNull final {
351 inline bool operator()(const Ptr& ptr) const {
352 return ptr != nullptr;
356 struct PtrToHandle final {
357 template <typename T>
358 inline Handle<T> operator()(const std::shared_ptr<T>& ptr) const {
359 return Handle<T>(ptr);
367 template <class Range>
368 inline std::vector<typename std::decay<typename Range::value_type>::type> toVector(const Range& range, int capacity = 0) {
369 std::vector<typename std::decay<typename Range::value_type>::type> out;
371 out.reserve(capacity);
373 for (const auto& item : range) {
374 out.emplace_back(item);
379 template <class Range>
380 inline SmallVector<typename std::decay<typename Range::value_type>::type> toSmallVector(const Range& range, int capacity = 0) {
381 SmallVector<typename std::decay<typename Range::value_type>::type> out;
383 out.reserve(capacity);
385 for (const auto& item : range) {
386 out.emplace_back(item);