File: range.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (158 lines) | stat: -rw-r--r-- 5,585 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GFX_RANGE_RANGE_H_
#define UI_GFX_RANGE_RANGE_H_

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <iosfwd>
#include <limits>
#include <string>

#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#include "ui/gfx/range/gfx_range_export.h"

#if BUILDFLAG(IS_APPLE)
#if __OBJC__
#import <Foundation/Foundation.h>
#else
typedef struct _NSRange NSRange;
#endif
#endif  // BUILDFLAG(IS_APPLE)

namespace gfx {

// This class represents either a forward range [min, max) or a reverse range
// (max, min]. |start_| is always the first of these and |end_| the second; as a
// result, the range is forward if (start_ <= end_).  The zero-width range
// [val, val) is legal, contains and intersects itself, and is contained by and
// intersects any nonempty range [min, max) where min <= val < max.
class GFX_RANGE_EXPORT Range {
 public:
  // Creates an empty range {0,0}.
  constexpr Range() : Range(0) {}

  // Initializes the range with a start and end.
  constexpr Range(size_t start, size_t end)
      : start_(base::checked_cast<uint32_t>(start)),
        end_(base::checked_cast<uint32_t>(end)) {}

  // Initializes the range with the same start and end positions.
  constexpr explicit Range(size_t position) : Range(position, position) {}

  // Platform constructors.
#if BUILDFLAG(IS_APPLE)
  // Constructs a Range from a NSRange.
  // CHECKs if NSRange is out of the maximum bound of Range.
  explicit Range(const NSRange& range);
  // Constructs a Range from a NSRange.
  // Returns InvalidRange() if NSRange is out of the maximum bound of Range.
  static Range FromPossiblyInvalidNSRange(const NSRange& range);
#endif

  // Returns a range that is invalid, which is {UINT32_MAX,UINT32_MAX}.
  static constexpr Range InvalidRange() {
    return Range(std::numeric_limits<uint32_t>::max());
  }

  // Checks if the range is valid through comparison to InvalidRange().  If this
  // is not valid, you must not call start()/end().
  constexpr bool IsValid() const { return *this != InvalidRange(); }

  // Ensures that the direction of this range matches the direction of the
  // provided range, reversing this range if necessary. Returns a reference to
  // `this` to allow method chaining.
  Range& MatchDirection(const Range& other) {
    if (is_reversed() != other.is_reversed()) {
      std::swap(start_, end_);
    }
    return *this;
  }

  // Getters and setters.
  constexpr size_t start() const { return start_; }
  void set_start(size_t start) { start_ = base::checked_cast<uint32_t>(start); }

  constexpr size_t end() const { return end_; }
  void set_end(size_t end) { end_ = base::checked_cast<uint32_t>(end); }

  // Returns the absolute value of the length.
  constexpr size_t length() const { return GetMax() - GetMin(); }

  constexpr bool is_reversed() const { return start() > end(); }
  constexpr bool is_empty() const { return start() == end(); }

  // Returns the minimum and maximum values.
  constexpr size_t GetMin() const {
    return start() < end() ? start() : end();
  }
  constexpr size_t GetMax() const {
    return start() > end() ? start() : end();
  }

  constexpr bool operator==(const Range& other) const = default;
  constexpr auto operator<=>(const Range& other) const = default;
  constexpr bool EqualsIgnoringDirection(const Range& other) const {
    return GetMin() == other.GetMin() && GetMax() == other.GetMax();
  }

  // Returns true if this range intersects the specified |range|.
  constexpr bool Intersects(const Range& range) const {
    return Intersect(range).IsValid();
  }

  // Returns true if this range contains the specified |range|.
  constexpr bool Contains(const Range& range) const {
    return range.IsBoundedBy(*this) &&
           // A non-empty range doesn't contain the range [max, max).
           (range.GetMax() != GetMax() || range.is_empty() == is_empty());
  }

  // Returns true if this range is contained by the specified |range| or it is
  // an empty range and ending the range |range|.
  constexpr bool IsBoundedBy(const Range& range) const {
    return IsValid() && range.IsValid() && GetMin() >= range.GetMin() &&
           GetMax() <= range.GetMax();
  }

  // Computes the intersection of this range with the given |range|.
  // If they don't intersect, it returns an InvalidRange().
  // The returned range is always empty or forward (never reversed).
  constexpr Range Intersect(const Range& range) const {
    const size_t min = std::max(GetMin(), range.GetMin());
    const size_t max = std::min(GetMax(), range.GetMax());
    return (min < max || Contains(range) || range.Contains(*this))
               ? Range(min, max)
               : InvalidRange();
  }

#if BUILDFLAG(IS_APPLE)
  // Constructs a Range from a NSRange.
  // CHECKs if NSRange is out of the maximum bound of Range.
  Range& operator=(const NSRange& range);

  // NSRange does not store the directionality of a range, so if this
  // is_reversed(), the range will get flipped when converted to an NSRange.
  NSRange ToNSRange() const;
#endif
  // GTK+ has no concept of a range.

  std::string ToString() const;

 private:
  // Note: we use uint32_t instead of size_t because this struct is sent over
  // IPC which could span 32 & 64 bit processes.
  uint32_t start_;
  uint32_t end_;
};

GFX_RANGE_EXPORT std::ostream& operator<<(std::ostream& os, const Range& range);

}  // namespace gfx

#endif  // UI_GFX_RANGE_RANGE_H_