Coverage Report

Created: 2025-06-24 08:20

/src/skia/src/core/SkEnumerate.h
Line
Count
Source
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
16
template <typename Iter, typename C = std::monostate>
17
class SkEnumerate {
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
959k
    static constexpr auto MakeResult(size_t i, Captured&& v) {
24
959k
        if constexpr (is_tuple<Captured>::value) {
25
957k
            return std::tuple_cat(std::tuple<size_t>{i}, v);
26
957k
        } else {
27
            // Capture v by reference instead of by value by using std::tie.
28
1.91k
            return std::tuple_cat(std::tuple<size_t>{i}, std::tie(v));
29
1.91k
        }
30
959k
    }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::MakeResult(unsigned long, std::__1::tuple<unsigned short const&, SkPoint const&>&&)
Line
Count
Source
23
957k
    static constexpr auto MakeResult(size_t i, Captured&& v) {
24
957k
        if constexpr (is_tuple<Captured>::value) {
25
957k
            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
957k
    }
SkEnumerate<SkPoint*, std::__1::monostate>::MakeResult(unsigned long, SkPoint&)
Line
Count
Source
23
1.91k
    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
1.91k
        } else {
27
            // Capture v by reference instead of by value by using std::tie.
28
1.91k
            return std::tuple_cat(std::tuple<size_t>{i}, std::tie(v));
29
1.91k
        }
30
1.91k
    }
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
22.3k
        constexpr Iterator(ptrdiff_t index, Iter it) : fIndex{index}, fIt{it} { }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::Iterator::Iterator(long, SkZip<unsigned short const, SkPoint const>::Iterator)
Line
Count
Source
41
22.1k
        constexpr Iterator(ptrdiff_t index, Iter it) : fIndex{index}, fIt{it} { }
SkEnumerate<SkPoint*, std::__1::monostate>::Iterator::Iterator(long, SkPoint*)
Line
Count
Source
41
218
        constexpr Iterator(ptrdiff_t index, Iter it) : fIndex{index}, fIt{it} { }
42
957k
        constexpr Iterator(const Iterator&) = default;
43
959k
        constexpr Iterator operator++() { ++fIndex; ++fIt; return *this; }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::Iterator::operator++()
Line
Count
Source
43
957k
        constexpr Iterator operator++() { ++fIndex; ++fIt; return *this; }
SkEnumerate<SkPoint*, std::__1::monostate>::Iterator::operator++()
Line
Count
Source
43
1.91k
        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
970k
        constexpr bool operator!=(const Iterator& rhs) const { return fIt != rhs.fIt; }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::Iterator::operator!=(SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::Iterator const&) const
Line
Count
Source
46
968k
        constexpr bool operator!=(const Iterator& rhs) const { return fIt != rhs.fIt; }
SkEnumerate<SkPoint*, std::__1::monostate>::Iterator::operator!=(SkEnumerate<SkPoint*, std::__1::monostate>::Iterator const&) const
Line
Count
Source
46
2.02k
        constexpr bool operator!=(const Iterator& rhs) const { return fIt != rhs.fIt; }
47
959k
        constexpr reference operator*() { return MakeResult(fIndex, *fIt); }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::Iterator::operator*()
Line
Count
Source
47
957k
        constexpr reference operator*() { return MakeResult(fIndex, *fIt); }
SkEnumerate<SkPoint*, std::__1::monostate>::Iterator::operator*()
Line
Count
Source
47
1.91k
        constexpr reference operator*() { return MakeResult(fIndex, *fIt); }
48
49
    private:
50
        ptrdiff_t fIndex;
51
        Iter fIt;
52
    };
53
54
public:
55
109
    constexpr SkEnumerate(Iter begin, Iter end) : SkEnumerate{0, begin, end} {}
56
    explicit constexpr SkEnumerate(C&& c)
57
11.0k
            : fCollection{std::move(c)}
58
11.0k
            , fBeginIndex{0}
59
11.0k
            , fBegin{std::begin(fCollection)}
60
11.0k
            , 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
11.1k
    constexpr Iterator begin() const { return Iterator{fBeginIndex, fBegin}; }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::begin() const
Line
Count
Source
67
11.0k
    constexpr Iterator begin() const { return Iterator{fBeginIndex, fBegin}; }
SkEnumerate<SkPoint*, std::__1::monostate>::begin() const
Line
Count
Source
67
109
    constexpr Iterator begin() const { return Iterator{fBeginIndex, fBegin}; }
68
11.1k
    constexpr Iterator end() const { return Iterator{fBeginIndex + this->ssize(), fEnd}; }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::end() const
Line
Count
Source
68
11.0k
    constexpr Iterator end() const { return Iterator{fBeginIndex + this->ssize(), fEnd}; }
SkEnumerate<SkPoint*, std::__1::monostate>::end() const
Line
Count
Source
68
109
    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
11.1k
    constexpr ptrdiff_t ssize() const { return std::distance(fBegin,  fEnd); }
SkEnumerate<SkZip<unsigned short const, SkPoint const>::Iterator, SkZip<unsigned short const, SkPoint const> >::ssize() const
Line
Count
Source
71
11.0k
    constexpr ptrdiff_t ssize() const { return std::distance(fBegin,  fEnd); }
SkEnumerate<SkPoint*, std::__1::monostate>::ssize() const
Line
Count
Source
71
109
    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
89
private:
90
    constexpr SkEnumerate(ptrdiff_t beginIndex, Iter begin, Iter end)
91
109
        : fBeginIndex{beginIndex}
92
109
        , fBegin(begin)
93
109
        , fEnd(end) {}
94
95
    C fCollection;
96
    const ptrdiff_t fBeginIndex;
97
    Iter fBegin;
98
    Iter fEnd;
99
};
100
101
template <typename C, typename Iter = decltype(std::begin(std::declval<C>()))>
102
109
inline constexpr SkEnumerate<Iter> SkMakeEnumerate(C& c) {
103
109
    return SkEnumerate<Iter>{std::begin(c), std::end(c)};
104
109
}
105
template <typename C, typename Iter = decltype(std::begin(std::declval<C>()))>
106
11.0k
inline constexpr SkEnumerate<Iter, C> SkMakeEnumerate(C&& c) {
107
11.0k
    return SkEnumerate<Iter, C>{std::forward<C>(c)};
108
11.0k
}
109
110
template <class T, std::size_t N, typename Iter = decltype(std::begin(std::declval<T(&)[N]>()))>
111
inline constexpr SkEnumerate<Iter> SkMakeEnumerate(T (&a)[N]) {
112
    return SkEnumerate<Iter>{std::begin(a), std::end(a)};
113
}
114
#endif  // SkEnumerate_DEFINED