github.com/ethereum/go-ethereum@v1.16.1/common/range.go (about) 1 // Copyright 2025 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package common 18 19 import ( 20 "iter" 21 ) 22 23 // Range represents a range of integers. 24 type Range[T uint32 | uint64] struct { 25 first, afterLast T 26 } 27 28 // NewRange creates a new range based of first element and number of elements. 29 func NewRange[T uint32 | uint64](first, count T) Range[T] { 30 return Range[T]{first, first + count} 31 } 32 33 // First returns the first element of the range. 34 func (r Range[T]) First() T { 35 return r.first 36 } 37 38 // Last returns the last element of the range. This panics for empty ranges. 39 func (r Range[T]) Last() T { 40 if r.first == r.afterLast { 41 panic("last item of zero length range is not allowed") 42 } 43 return r.afterLast - 1 44 } 45 46 // AfterLast returns the first element after the range. This allows obtaining 47 // information about the end part of zero length ranges. 48 func (r Range[T]) AfterLast() T { 49 return r.afterLast 50 } 51 52 // Count returns the number of elements in the range. 53 func (r Range[T]) Count() T { 54 return r.afterLast - r.first 55 } 56 57 // IsEmpty returns true if the range is empty. 58 func (r Range[T]) IsEmpty() bool { 59 return r.first == r.afterLast 60 } 61 62 // Includes returns true if the given element is inside the range. 63 func (r Range[T]) Includes(v T) bool { 64 return v >= r.first && v < r.afterLast 65 } 66 67 // SetFirst updates the first element of the list. 68 func (r *Range[T]) SetFirst(v T) { 69 r.first = v 70 if r.afterLast < r.first { 71 r.afterLast = r.first 72 } 73 } 74 75 // SetAfterLast updates the end of the range by specifying the first element 76 // after the range. This allows setting zero length ranges. 77 func (r *Range[T]) SetAfterLast(v T) { 78 r.afterLast = v 79 if r.afterLast < r.first { 80 r.first = r.afterLast 81 } 82 } 83 84 // SetLast updates last element of the range. 85 func (r *Range[T]) SetLast(v T) { 86 r.SetAfterLast(v + 1) 87 } 88 89 // Intersection returns the intersection of two ranges. 90 func (r Range[T]) Intersection(q Range[T]) Range[T] { 91 i := Range[T]{first: max(r.first, q.first), afterLast: min(r.afterLast, q.afterLast)} 92 if i.first > i.afterLast { 93 return Range[T]{} 94 } 95 return i 96 } 97 98 // Union returns the union of two ranges. Panics for gapped ranges. 99 func (r Range[T]) Union(q Range[T]) Range[T] { 100 if max(r.first, q.first) > min(r.afterLast, q.afterLast) { 101 panic("cannot create union; gap between ranges") 102 } 103 return Range[T]{first: min(r.first, q.first), afterLast: max(r.afterLast, q.afterLast)} 104 } 105 106 // Iter iterates all integers in the range. 107 func (r Range[T]) Iter() iter.Seq[T] { 108 return func(yield func(T) bool) { 109 for i := r.first; i < r.afterLast; i++ { 110 if !yield(i) { 111 break 112 } 113 } 114 } 115 }