xref: /aosp_15_r20/external/skia/src/sksl/SkSLPosition.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 Google LLC.
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 SKSL_POSITION
9 #define SKSL_POSITION
10 
11 #include "include/core/SkTypes.h"
12 
13 #include <cstdint>
14 #include <string_view>
15 
16 namespace SkSL {
17 
18 class Position {
19 public:
Position()20     Position()
21         : fStartOffset(-1)
22         , fLength(0) {}
23 
Range(int startOffset,int endOffset)24     static Position Range(int startOffset, int endOffset) {
25         SkASSERT(startOffset <= endOffset);
26         SkASSERT(startOffset <= kMaxOffset);
27         int length = endOffset - startOffset;
28         Position result;
29         result.fStartOffset = startOffset;
30         result.fLength = length <= 0xFF ? length : 0xFF;
31         return result;
32     }
33 
valid()34     bool valid() const {
35         return fStartOffset != -1;
36     }
37 
38     int line(std::string_view source) const;
39 
startOffset()40     int startOffset() const {
41         SkASSERT(this->valid());
42         return fStartOffset;
43     }
44 
endOffset()45     int endOffset() const {
46         SkASSERT(this->valid());
47         return fStartOffset + fLength;
48     }
49 
50     // Returns the position from this through, and including the entirety of, end.
rangeThrough(Position end)51     Position rangeThrough(Position end) const {
52         if (fStartOffset == -1 || end.fStartOffset == -1) {
53             return *this;
54         }
55         SkASSERTF(this->startOffset() <= end.startOffset() && this->endOffset() <= end.endOffset(),
56                 "Invalid range: (%d-%d) - (%d-%d)\n", this->startOffset(), this->endOffset(),
57                 end.startOffset(), end.endOffset());
58         return Range(this->startOffset(), end.endOffset());
59     }
60 
61     // Returns a position representing the character immediately after this position
after()62     Position after() const {
63         int endOffset = this->endOffset();
64         return Range(endOffset, endOffset + 1);
65     }
66 
67     bool operator==(const Position& other) const {
68         return fStartOffset == other.fStartOffset && fLength == other.fLength;
69     }
70 
71     bool operator!=(const Position& other) const {
72         return !(*this == other);
73     }
74 
75     bool operator>(const Position& other) const {
76         return fStartOffset > other.fStartOffset;
77     }
78 
79     bool operator>=(const Position& other) const {
80         return fStartOffset >= other.fStartOffset;
81     }
82 
83     bool operator<(const Position& other) const {
84         return fStartOffset < other.fStartOffset;
85     }
86 
87     bool operator<=(const Position& other) const {
88         return fStartOffset <= other.fStartOffset;
89     }
90 
91     static constexpr int kMaxOffset = 0x7FFFFF;
92 
93 private:
94     int32_t fStartOffset : 24;
95     uint32_t fLength : 8;
96 };
97 
98 struct ForLoopPositions {
99     Position initPosition = Position();
100     Position conditionPosition = Position();
101     Position nextPosition = Position();
102 };
103 
104 } // namespace SkSL
105 
106 #endif
107