1d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka/* 2d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * Copyright (C) 2017 The Android Open Source Project 3d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * 4d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 5d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * you may not use this file except in compliance with the License. 6d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * You may obtain a copy of the License at 7d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * 8d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 9d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * 10d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * Unless required by applicable law or agreed to in writing, software 11d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 12d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * See the License for the specific language governing permissions and 14d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka * limitations under the License. 15d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka */ 16d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 17d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka#ifndef MINIKIN_RANGE_H 18d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka#define MINIKIN_RANGE_H 19d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 20366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka#include <algorithm> 21524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka#include <limits> 22366f57fb4efd0ddf5d48cd232cd88d3777517ea2Seigo Nonaka#include <utility> 23524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka 24d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakanamespace minikin { 25d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 26d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka// An undirected range. 27d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakaclass Range { 28d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakapublic: 29524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka static constexpr uint32_t NOWHERE = std::numeric_limits<uint32_t>::max(); 30524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka 31d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // start must be smaller than or equal to end otherwise the behavior is undefined. 32d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka Range(uint32_t start, uint32_t end) : mStart(start), mEnd(end) {} 3356f8ea51818c682991c1e700e07f93e26167ed89Seigo Nonaka Range() : Range(NOWHERE, NOWHERE) {} 34d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 35d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka Range(const Range&) = default; 36d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka Range& operator=(const Range&) = default; 37d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 38524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka static Range invalidRange() { return Range(NOWHERE, NOWHERE); } 39524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka inline bool isValid() const { return mStart != NOWHERE && mEnd != NOWHERE; } 40524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka 416c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline uint32_t getStart() const { return mStart; } // inclusive 42d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline void setStart(uint32_t start) { mStart = start; } // inclusive 43d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 446c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline uint32_t getEnd() const { return mEnd; } // exclusive 45d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline void setEnd(uint32_t end) { mEnd = end; } // exclusive 46d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 47d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline uint32_t getLength() const { return mEnd - mStart; } 48d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 49d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline bool isEmpty() const { return mStart == mEnd; } 50d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 51d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline uint32_t toRangeOffset(uint32_t globalPos) const { return globalPos - mStart; } 52d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline uint32_t toGlobalOffset(uint32_t rangePos) const { return mStart + rangePos; } 53d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 54d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // The behavior is undefined if pos is out of range. 55d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline std::pair<Range, Range> split(uint32_t pos) const { 56d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka return std::make_pair(Range(mStart, pos), Range(pos, mEnd)); 57d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka } 58d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 59d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline bool contains(const Range& other) const { 60d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka return mStart <= other.mStart && other.mEnd <= mEnd; 61d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka } 62d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 63d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // Returns true if the pos is in this range. 64d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // For example, 65d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // const Range range(1, 2); // 1 is inclusive, 2 is exclusive. 66d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // range.contains(0); // false 67d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // range.contains(1); // true 68d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // range.contains(2); // false 696c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline bool contains(uint32_t pos) const { return mStart <= pos && pos < mEnd; } 70d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 71524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka // Returns true if left and right intersect. 72524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka inline static bool intersects(const Range& left, const Range& right) { 73524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka return left.isValid() && right.isValid() && left.mStart < right.mEnd && 74524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka right.mStart < left.mEnd; 75524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka } 763da4269e6097e0dafdb438c760dafdde13feda95Seigo Nonaka inline static Range intersection(const Range& left, const Range& right) { 773da4269e6097e0dafdb438c760dafdde13feda95Seigo Nonaka return Range(std::max(left.mStart, right.mStart), std::min(left.mEnd, right.mEnd)); 783da4269e6097e0dafdb438c760dafdde13feda95Seigo Nonaka } 79524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka 80524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka // Returns merged range. This method assumes left and right are not invalid ranges and they have 81524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka // an intersection. 82524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka static Range merge(const Range& left, const Range& right) { 83524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka return Range({std::min(left.mStart, right.mStart), std::max(left.mEnd, right.mEnd)}); 84524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka } 85524d294be051584e5506e5a4ad6ec70471bf4c08Seigo Nonaka 8656f8ea51818c682991c1e700e07f93e26167ed89Seigo Nonaka inline bool operator==(const Range& o) const { return mStart == o.mStart && mEnd == o.mEnd; } 8756f8ea51818c682991c1e700e07f93e26167ed89Seigo Nonaka 8856f8ea51818c682991c1e700e07f93e26167ed89Seigo Nonaka inline bool operator!=(const Range& o) const { return !(*this == o); } 8956f8ea51818c682991c1e700e07f93e26167ed89Seigo Nonaka 90d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakaprivate: 91d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka // Helper class for "for (uint32_t i : range)" style for-loop. 92d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka class RangeIterator { 93d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka public: 94d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka RangeIterator(uint32_t pos) : mPos(pos) {} 95d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 96d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline bool operator!=(const RangeIterator& o) const { return o.mPos != mPos; } 97d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline uint32_t operator*() const { return mPos; } 986c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka inline RangeIterator& operator++() { 996c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka mPos++; 1006c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka return *this; 1016c8722e217ff5238f0b849152d7936959a728103Seigo Nonaka } 102d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 103d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka private: 104d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka uint32_t mPos; 105d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka }; 106d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 107d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakapublic: 108d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline RangeIterator begin() const { return RangeIterator(mStart); } 109d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka inline RangeIterator end() const { return RangeIterator(mEnd); } 110d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 111d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonakaprivate: 112d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka uint32_t mStart; 113d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka uint32_t mEnd; 114d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka}; 115d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 116d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka} // namespace minikin 117d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka 118d565f7d88018f09a740ff6cf26cb2b068139c784Seigo Nonaka#endif // MINIKIN_RANGE_H 119