Publishing 2019 R2 content (#223)
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / include / vpu / utils / range.hpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #pragma once
6
7 #include <cassert>
8
9 #include <type_traits>
10 #include <iterator>
11 #include <utility>
12 #include <vector>
13 #include <memory>
14 #include <functional>
15 #include <unordered_set>
16
17 #include <vpu/utils/containers.hpp>
18 #include <vpu/utils/handle.hpp>
19 #include <vpu/utils/optional.hpp>
20
21 namespace vpu {
22
23 //
24 // IterRange
25 //
26
27 namespace impl {
28
29 template <class Iterator>
30 class IterRange final {
31 public:
32     using value_type = typename Iterator::value_type;
33
34     using iterator = Iterator;
35     using const_iterator = Iterator;
36
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;
42
43     template <class It1, class It2>
44     inline IterRange(It1&& b, It2&& e) : _begin(std::forward<It1>(b)), _end(std::forward<It2>(e)) {}
45
46     inline Iterator begin() const { return _begin; }
47     inline Iterator end() const { return _end; }
48
49     Iterator cbegin() const { return _begin; }
50     Iterator cend() const { return _end; }
51
52 private:
53     Iterator _begin;
54     Iterator _end;
55 };
56
57 }  // namespace impl
58
59 template <class Iterator>
60 inline impl::IterRange<Iterator> iterRange(const Iterator& begin, const Iterator& end) {
61     return impl::IterRange<Iterator>(begin, end);
62 }
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));
66 }
67
68 //
69 // ContRange
70 //
71
72 namespace impl {
73
74 template <class Cont>
75 class ContRange final {
76 public:
77     using value_type = typename Cont::value_type;
78
79     using iterator = typename Cont::iterator;
80     using const_iterator = typename Cont::const_iterator;
81
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;
87
88     inline explicit ContRange(const Cont& cont) : _cont(&cont) {}
89
90     inline const_iterator begin() const {
91         assert(_cont != nullptr);
92         return _cont->begin();
93     }
94     inline const_iterator end() const {
95         assert(_cont != nullptr);
96         return _cont->end();
97     }
98
99     inline const_iterator cbegin() const {
100         assert(_cont != nullptr);
101         return _cont->begin();
102     }
103     inline const_iterator cend() const {
104         assert(_cont != nullptr);
105         return _cont->end();
106     }
107
108 private:
109     const Cont* _cont = nullptr;
110 };
111
112 }  // namespace impl
113
114 template <class Cont>
115 inline impl::ContRange<Cont> contRange(const Cont& cont) {
116     return impl::ContRange<Cont>(cont);
117 }
118
119 //
120 // MapRange
121 //
122
123 namespace impl {
124
125 template <class BaseRange, class MapOp>
126 class MapRange final {
127 public:
128     class Iterator final {
129     public:
130         using base_iterator = typename BaseRange::const_iterator;
131         using base_iterator_value = decltype(*base_iterator());
132
133         using map_op_value = typename std::result_of<MapOp(base_iterator_value)>::type;
134
135         using value_type = typename std::decay<map_op_value>::type;
136         using pointer = value_type*;
137         using reference = value_type&;
138
139         using iterator_category = std::input_iterator_tag;
140         using difference_type = std::ptrdiff_t;
141
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;
147
148         template <class BI>
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)),
152                 _op(&op) {
153         }
154
155         inline const value_type& operator*() const {
156             assert(_cur != _end);
157             _curValue = (*_op)(*_cur);
158             return _curValue.get();
159         }
160
161         inline Iterator& operator++() {
162             ++_cur;
163             return *this;
164         }
165
166         inline bool operator==(const Iterator& other) const {
167             return _cur == other._cur;
168         }
169         inline bool operator!=(const Iterator& other) const {
170             return _cur != other._cur;
171         }
172
173     private:
174         base_iterator _cur;
175         base_iterator _end;
176         const MapOp* _op = nullptr;
177
178         mutable Optional<value_type> _curValue;
179     };
180
181     using base_iterator = typename BaseRange::const_iterator;
182     using base_iterator_value = decltype(*base_iterator());
183
184     using map_op_value = typename std::result_of<MapOp(base_iterator_value)>::type;
185
186     using value_type = typename std::decay<map_op_value>::type;
187
188     using iterator = Iterator;
189     using const_iterator = Iterator;
190
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;
196
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)) {
201     }
202
203     inline Iterator begin() const { return Iterator(_base.begin(), _base.end(), _op); }
204     inline Iterator end() const { return Iterator(_base.end(), _base.end(), _op); }
205
206     inline Iterator cbegin() const { return Iterator(_base.begin(), _base.end(), _op); }
207     inline Iterator cend() const { return Iterator(_base.end(), _base.end(), _op); }
208
209 private:
210     BaseRange _base;
211     MapOp _op;
212 };
213
214 }  // namespace impl
215
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));
222 }
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),
227         MapOp());
228 }
229
230 //
231 // FilterRange
232 //
233
234 namespace impl {
235
236 template <class BaseRange, class FilterOp>
237 class FilterRange final {
238 public:
239     class Iterator final {
240     public:
241         using base_iterator = typename BaseRange::const_iterator;
242         using base_iterator_value = decltype(*base_iterator());
243
244         using value_type = typename std::decay<base_iterator_value>::type;
245         using pointer = value_type*;
246         using reference = value_type&;
247
248         using iterator_category = std::input_iterator_tag;
249         using difference_type = std::ptrdiff_t;
250
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;
256
257         template <class BI>
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)),
261                 _op(&op) {
262             advance();
263         }
264
265         inline const value_type& operator*() const {
266             assert(_cur != _end);
267             _curValue = *_cur;
268             return _curValue.get();
269         }
270
271         inline Iterator& operator++() {
272             ++_cur;
273             advance();
274             return *this;
275         }
276
277         inline bool operator==(const Iterator& other) const {
278             return _cur == other._cur;
279         }
280         inline bool operator!=(const Iterator& other) const {
281             return _cur != other._cur;
282         }
283
284     private:
285         inline void advance() {
286             while (_cur != _end) {
287                 _curValue = *_cur;
288                 if ((*_op)(_curValue.get())) {
289                     break;
290                 }
291                 ++_cur;
292             }
293         }
294
295     private:
296         base_iterator _cur;
297         base_iterator _end;
298         const FilterOp* _op = nullptr;
299
300         mutable Optional<value_type> _curValue;
301     };
302
303     using value_type = typename BaseRange::value_type;
304
305     using iterator = Iterator;
306     using const_iterator = Iterator;
307
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;
313
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)) {
318     }
319
320     inline Iterator begin() const { return Iterator(_base.begin(), _base.end(), _op); }
321     inline Iterator end() const { return Iterator(_base.end(), _base.end(), _op); }
322
323     inline Iterator cbegin() const { return Iterator(_base.begin(), _base.end(), _op); }
324     inline Iterator cend() const { return Iterator(_base.end(), _base.end(), _op); }
325
326 private:
327     BaseRange _base;
328     FilterOp _op;
329 };
330
331 }  // namespace impl
332
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) {
336     return impl::
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));
340 }
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),
345         FilterOp());
346 }
347
348 struct NonNull final {
349 public:
350     template <class Ptr>
351     inline bool operator()(const Ptr& ptr) const {
352         return ptr != nullptr;
353     }
354 };
355
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);
360     }
361 };
362
363 //
364 // toVector
365 //
366
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;
370     if (capacity > 0) {
371         out.reserve(capacity);
372     }
373     for (const auto& item : range) {
374         out.emplace_back(item);
375     }
376     return out;
377 }
378
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;
382     if (capacity > 0) {
383         out.reserve(capacity);
384     }
385     for (const auto& item : range) {
386         out.emplace_back(item);
387     }
388     return out;
389 }
390
391 }  // namespace vpu