24template<
typename... Ts>
26 using ReturnTuple = std::tuple<Ts&...>;
30 using value_type = ReturnTuple;
31 using difference_type = ptrdiff_t;
32 using pointer = value_type*;
33 using reference = value_type;
34 using iterator_category = std::input_iterator_tag;
35 constexpr Iterator(
const SkZip*
zip,
size_t index) : fZip{
zip}, fIndex{index} { }
36 constexpr Iterator(
const Iterator& that) : Iterator{ that.fZip, that.fIndex } { }
37 constexpr Iterator& operator++() { ++fIndex;
return *
this; }
38 constexpr Iterator operator++(
int) { Iterator tmp(*
this); operator++();
return tmp; }
39 constexpr bool operator==(
const Iterator& rhs)
const {
return fIndex == rhs.fIndex; }
40 constexpr bool operator!=(
const Iterator& rhs)
const {
return fIndex != rhs.fIndex; }
41 constexpr reference
operator*() {
return (*fZip)[fIndex]; }
42 friend constexpr difference_type
operator-(Iterator lhs, Iterator rhs) {
43 return lhs.fIndex - rhs.fIndex;
47 const SkZip*
const fZip =
nullptr;
52 inline static constexpr T* nullify =
nullptr;
55 constexpr SkZip() : fPointers{nullify<Ts>...}, fSize{0} {}
56 constexpr SkZip(
size_t) =
delete;
64 template <
typename U,
typename T>
69 template<
typename... Us,
70 typename = std::enable_if<std::conjunction<CanConvertToConst<Us, Ts>...>
::value>>
72 : fPointers(that.
data())
73 , fSize{that.
size()} { }
75 constexpr ReturnTuple
operator[](
size_t i)
const {
return this->index(
i);}
76 constexpr size_t size()
const {
return fSize; }
77 constexpr bool empty()
const {
return this->
size() == 0; }
78 constexpr ReturnTuple
front()
const {
return this->index(0); }
79 constexpr ReturnTuple
back()
const {
return this->index(this->
size() - 1); }
80 constexpr Iterator
begin()
const {
return Iterator{
this, 0}; }
81 constexpr Iterator
end()
const {
return Iterator{
this, this->
size()}; }
82 template<
size_t I>
constexpr auto get()
const {
83 return SkSpan(std::get<I>(fPointers), fSize);
85 constexpr std::tuple<Ts*...>
data()
const {
return fPointers; }
88 if (n == 0) {
return SkZip(); }
89 return SkZip{n, fPointers};
93 if (n == 0) {
return SkZip(); }
94 return SkZip{n, this->pointersAt(fSize - n)};
104 constexpr SkZip(
size_t n,
const std::tuple<Ts*...>& pointers)
105 : fPointers{pointers}
108 constexpr ReturnTuple index(
size_t i)
const {
111 return indexDetail(
i, std::make_index_sequence<
sizeof...(Ts)>{});
114 template<std::size_t... Is>
115 constexpr ReturnTuple indexDetail(
size_t i, std::index_sequence<Is...>)
const {
116 return ReturnTuple((std::get<Is>(fPointers))[
i]...);
119 std::tuple<Ts*...> pointersAt(
size_t i)
const {
122 return pointersAtDetail(
i, std::make_index_sequence<
sizeof...(Ts)>{});
125 template<std::size_t... Is>
126 constexpr std::tuple<Ts*...> pointersAtDetail(
size_t i, std::index_sequence<Is...>)
const {
127 return std::tuple<Ts*...>{&(std::get<Is>(fPointers))[
i]...};
130 std::tuple<Ts*...> fPointers;
135 template<
typename T>
struct DecayPointer{
139 template<
typename T>
using DecayPointerT =
typename DecayPointer<T>::type;
141 template<
typename C>
struct ContiguousMemory { };
142 template<
typename T>
struct ContiguousMemory<
T*> {
143 using value_type =
T;
144 static constexpr value_type*
Data(
T* t) {
return t; }
145 static constexpr size_t Size(
T*
s) {
return SIZE_MAX; }
147 template<
typename T,
size_t N>
struct ContiguousMemory<
T(&)[
N]> {
148 using value_type =
T;
149 static constexpr value_type*
Data(
T(&t)[
N]) {
return t; }
150 static constexpr size_t Size(
T(&)[
N]) {
return N; }
154 template<
typename T>
struct ContiguousMemory<
SkSpan<
T>> {
155 using value_type =
T;
160 template<
typename C>
struct ContiguousMemory<
C&> {
161 using value_type =
typename std::remove_pointer<decltype(std::declval<C>().data())>
::type;
162 static constexpr value_type*
Data(
C& c) {
return c.data(); }
163 static constexpr size_t Size(
C& c) {
return c.size(); }
165 template<
typename C>
using Span = ContiguousMemory<DecayPointerT<C>>;
166 template<
typename C>
using ValueType =
typename Span<C>::value_type;
168 template<
typename C,
typename... Ts>
struct PickOneSize { };
169 template <
typename T,
typename... Ts>
struct PickOneSize<
T*, Ts...> {
170 static constexpr size_t Size(
T* t, Ts... ts) {
174 template <
typename T,
typename... Ts,
size_t N>
struct PickOneSize<
T(&)[
N], Ts...> {
175 static constexpr size_t Size(
T(&)[
N], Ts...) {
return N; }
177 template<
typename T,
typename... Ts>
struct PickOneSize<
SkSpan<
T>, Ts...> {
180 template<
typename C,
typename... Ts>
struct PickOneSize<
C&, Ts...> {
181 static constexpr size_t Size(
C& c, Ts...) {
return c.size(); }
185 template<
typename... Ts>
189 size_t size = PickOneSize<DecayPointerT<Ts>...>
::Size(std::forward<Ts>(ts)...);
193 size_t minSize = SIZE_MAX;
208template<
typename... Ts>
211template<
typename... Ts>
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
constexpr auto SkMakeZip(Ts &&... ts)
SkZip(size_t size, Ts *... ts) -> SkZip< Ts... >
static constexpr auto MakeZip(Ts &&... ts)
constexpr SkZip last(size_t n) const
constexpr size_t size() const
constexpr SkZip(const SkZip< Us... > &that)
constexpr SkZip first(size_t n) const
typename std::integral_constant< bool, std::is_convertible< U *, T * >::value &&sizeof(U)==sizeof(T)>::type CanConvertToConst
constexpr SkZip(const SkZip &that)=default
constexpr Iterator begin() const
constexpr SkZip subspan(size_t offset, size_t count) const
constexpr ReturnTuple operator[](size_t i) const
constexpr bool empty() const
constexpr ReturnTuple back() const
constexpr Iterator end() const
constexpr std::tuple< Ts *... > data() const
constexpr SkZip(size_t)=delete
constexpr SkZip(size_t size, Ts *... ts)
constexpr auto get() const
constexpr ReturnTuple front() const
constexpr SkZip & operator=(const SkZip &that)=default
static float max(float r, float g, float b)
static float min(float r, float g, float b)
struct PathData * Data(SkPath *path)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
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)
constexpr Color operator*(T value, const Color &c)