Flutter Engine
The Flutter Engine
SkEnumerate.h
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkEnumerate_DEFINED
9#define SkEnumerate_DEFINED
10
11#include <cstddef>
12#include <iterator>
13#include <tuple>
14#include <variant>
15
16template <typename Iter, typename C = std::monostate>
18 using Captured = decltype(*std::declval<Iter>());
19 template <typename> struct is_tuple : std::false_type {};
20 template <typename... T> struct is_tuple<std::tuple<T...>> : std::true_type {};
21
22 // v must be a r-value to bind to temporary non-const references.
23 static constexpr auto MakeResult(size_t i, Captured&& v) {
24 if constexpr (is_tuple<Captured>::value) {
25 return std::tuple_cat(std::tuple<size_t>{i}, v);
26 } else {
27 // Capture v by reference instead of by value by using std::tie.
28 return std::tuple_cat(std::tuple<size_t>{i}, std::tie(v));
29 }
30 }
31
32 using Result = decltype(MakeResult(0, std::declval<Captured>()));
33
34 class Iterator {
35 public:
36 using value_type = Result;
37 using difference_type = ptrdiff_t;
38 using pointer = value_type*;
39 using reference = value_type;
40 using iterator_category = std::input_iterator_tag;
41 constexpr Iterator(ptrdiff_t index, Iter it) : fIndex{index}, fIt{it} { }
42 constexpr Iterator(const Iterator&) = default;
43 constexpr Iterator operator++() { ++fIndex; ++fIt; return *this; }
44 constexpr Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
45 constexpr bool operator==(const Iterator& rhs) const { return fIt == rhs.fIt; }
46 constexpr bool operator!=(const Iterator& rhs) const { return fIt != rhs.fIt; }
47 constexpr reference operator*() { return MakeResult(fIndex, *fIt); }
48
49 private:
50 ptrdiff_t fIndex;
51 Iter fIt;
52 };
53
54public:
55 constexpr SkEnumerate(Iter begin, Iter end) : SkEnumerate{0, begin, end} {}
56 explicit constexpr SkEnumerate(C&& c)
57 : fCollection{std::move(c)}
58 , fBeginIndex{0}
59 , fBegin{std::begin(fCollection)}
60 , fEnd{std::end(fCollection)} { }
61 constexpr SkEnumerate(const SkEnumerate& that) = default;
62 constexpr SkEnumerate& operator=(const SkEnumerate& that) {
63 fBegin = that.fBegin;
64 fEnd = that.fEnd;
65 return *this;
66 }
67 constexpr Iterator begin() const { return Iterator{fBeginIndex, fBegin}; }
68 constexpr Iterator end() const { return Iterator{fBeginIndex + this->ssize(), fEnd}; }
69 constexpr bool empty() const { return fBegin == fEnd; }
70 constexpr size_t size() const { return std::distance(fBegin, fEnd); }
71 constexpr ptrdiff_t ssize() const { return std::distance(fBegin, fEnd); }
72 constexpr SkEnumerate first(size_t n) {
73 SkASSERT(n <= this->size());
74 ptrdiff_t deltaEnd = this->ssize() - n;
75 return SkEnumerate{fBeginIndex, fBegin, std::prev(fEnd, deltaEnd)};
76 }
77 constexpr SkEnumerate last(size_t n) {
78 SkASSERT(n <= this->size());
79 ptrdiff_t deltaBegin = this->ssize() - n;
80 return SkEnumerate{fBeginIndex + deltaBegin, std::next(fBegin, deltaBegin), fEnd};
81 }
82 constexpr SkEnumerate subspan(size_t offset, size_t count) {
83 SkASSERT(offset < this->size());
84 SkASSERT(count <= this->size() - offset);
85 auto newBegin = std::next(fBegin, offset);
86 return SkEnumerate(fBeginIndex + offset, newBegin, std::next(newBegin, count));
87 }
88
89private:
90 constexpr SkEnumerate(ptrdiff_t beginIndex, Iter begin, Iter end)
91 : fBeginIndex{beginIndex}
92 , fBegin(begin)
93 , fEnd(end) {}
94
95 C fCollection;
96 const ptrdiff_t fBeginIndex;
97 Iter fBegin;
98 Iter fEnd;
99};
100
101template <typename C, typename Iter = decltype(std::begin(std::declval<C>()))>
102inline constexpr SkEnumerate<Iter> SkMakeEnumerate(C& c) {
103 return SkEnumerate<Iter>{std::begin(c), std::end(c)};
104}
105template <typename C, typename Iter = decltype(std::begin(std::declval<C>()))>
107 return SkEnumerate<Iter, C>{std::forward<C>(c)};
108}
109
110template <class T, std::size_t N, typename Iter = decltype(std::begin(std::declval<T(&)[N]>()))>
111inline constexpr SkEnumerate<Iter> SkMakeEnumerate(T (&a)[N]) {
112 return SkEnumerate<Iter>{std::begin(a), std::end(a)};
113}
114#endif // SkEnumerate_DEFINED
int count
Definition: FontMgrTest.cpp:50
static float next(float f)
static float prev(float f)
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkEnumerate< Iter > SkMakeEnumerate(C &c)
Definition: SkEnumerate.h:102
#define N
Definition: beziers.cpp:19
constexpr Iterator begin() const
Definition: SkEnumerate.h:67
constexpr SkEnumerate last(size_t n)
Definition: SkEnumerate.h:77
constexpr SkEnumerate subspan(size_t offset, size_t count)
Definition: SkEnumerate.h:82
constexpr ptrdiff_t ssize() const
Definition: SkEnumerate.h:71
constexpr SkEnumerate & operator=(const SkEnumerate &that)
Definition: SkEnumerate.h:62
constexpr SkEnumerate(C &&c)
Definition: SkEnumerate.h:56
constexpr Iterator end() const
Definition: SkEnumerate.h:68
constexpr SkEnumerate(const SkEnumerate &that)=default
constexpr bool empty() const
Definition: SkEnumerate.h:69
constexpr SkEnumerate first(size_t n)
Definition: SkEnumerate.h:72
constexpr size_t size() const
Definition: SkEnumerate.h:70
constexpr SkEnumerate(Iter begin, Iter end)
Definition: SkEnumerate.h:55
static const char * begin(const StringSlice &s)
Definition: editor.cpp:252
struct MyStruct a[10]
uint8_t value
bool operator==(C p1, const scoped_nsprotocol< C > &p2)
bool operator!=(C p1, const scoped_nsprotocol< C > &p2)
constexpr Color operator*(T value, const Color &c)
Definition: color.h:911
Definition: ref_ptr.h:256
#define T
Definition: precompiler.cc:65
SeparatedVector2 offset