1*bb02e0acSNicolas Bonnefon /* 2*bb02e0acSNicolas Bonnefon * Copyright (C) 2011, 2013 Nicolas Bonnefon and other contributors 3*bb02e0acSNicolas Bonnefon * 4*bb02e0acSNicolas Bonnefon * This file is part of glogg. 5*bb02e0acSNicolas Bonnefon * 6*bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify 7*bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by 8*bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or 9*bb02e0acSNicolas Bonnefon * (at your option) any later version. 10*bb02e0acSNicolas Bonnefon * 11*bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful, 12*bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*bb02e0acSNicolas Bonnefon * GNU General Public License for more details. 15*bb02e0acSNicolas Bonnefon * 16*bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License 17*bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18*bb02e0acSNicolas Bonnefon */ 19*bb02e0acSNicolas Bonnefon 20*bb02e0acSNicolas Bonnefon #ifndef UTILS_H 21*bb02e0acSNicolas Bonnefon #define UTILS_H 22*bb02e0acSNicolas Bonnefon 23*bb02e0acSNicolas Bonnefon // Use a bisection method to find the given line number 24*bb02e0acSNicolas Bonnefon // in a sorted list. 25*bb02e0acSNicolas Bonnefon // The T type must be a container containing elements that 26*bb02e0acSNicolas Bonnefon // implement the lineNumber() member. 27*bb02e0acSNicolas Bonnefon // Returns true if the lineNumber is found, false if not 28*bb02e0acSNicolas Bonnefon // foundIndex is the index of the found number or the index 29*bb02e0acSNicolas Bonnefon // of the closest greater element. 30*bb02e0acSNicolas Bonnefon template <typename T> bool lookupLineNumber( 31*bb02e0acSNicolas Bonnefon const T& list, qint64 lineNumber, int* foundIndex ) 32*bb02e0acSNicolas Bonnefon { 33*bb02e0acSNicolas Bonnefon int minIndex = 0; 34*bb02e0acSNicolas Bonnefon int maxIndex = list.size() - 1; 35*bb02e0acSNicolas Bonnefon // If the list is not empty 36*bb02e0acSNicolas Bonnefon if ( maxIndex - minIndex >= 0 ) { 37*bb02e0acSNicolas Bonnefon // First we test the ends 38*bb02e0acSNicolas Bonnefon if ( list[minIndex].lineNumber() == lineNumber ) { 39*bb02e0acSNicolas Bonnefon *foundIndex = minIndex; 40*bb02e0acSNicolas Bonnefon return true; 41*bb02e0acSNicolas Bonnefon } 42*bb02e0acSNicolas Bonnefon else if ( list[maxIndex].lineNumber() == lineNumber ) { 43*bb02e0acSNicolas Bonnefon *foundIndex = maxIndex; 44*bb02e0acSNicolas Bonnefon return true; 45*bb02e0acSNicolas Bonnefon } 46*bb02e0acSNicolas Bonnefon 47*bb02e0acSNicolas Bonnefon // Then we test the rest 48*bb02e0acSNicolas Bonnefon while ( (maxIndex - minIndex) > 1 ) { 49*bb02e0acSNicolas Bonnefon const int tryIndex = (minIndex + maxIndex) / 2; 50*bb02e0acSNicolas Bonnefon const qint64 currentMatchingNumber = 51*bb02e0acSNicolas Bonnefon list[tryIndex].lineNumber(); 52*bb02e0acSNicolas Bonnefon if ( currentMatchingNumber > lineNumber ) 53*bb02e0acSNicolas Bonnefon maxIndex = tryIndex; 54*bb02e0acSNicolas Bonnefon else if ( currentMatchingNumber < lineNumber ) 55*bb02e0acSNicolas Bonnefon minIndex = tryIndex; 56*bb02e0acSNicolas Bonnefon else if ( currentMatchingNumber == lineNumber ) { 57*bb02e0acSNicolas Bonnefon *foundIndex = tryIndex; 58*bb02e0acSNicolas Bonnefon return true; 59*bb02e0acSNicolas Bonnefon } 60*bb02e0acSNicolas Bonnefon } 61*bb02e0acSNicolas Bonnefon 62*bb02e0acSNicolas Bonnefon // If we haven't found anything... 63*bb02e0acSNicolas Bonnefon // ... end of the list or before the next 64*bb02e0acSNicolas Bonnefon if ( lineNumber > list[maxIndex].lineNumber() ) 65*bb02e0acSNicolas Bonnefon *foundIndex = maxIndex + 1; 66*bb02e0acSNicolas Bonnefon else if ( lineNumber > list[minIndex].lineNumber() ) 67*bb02e0acSNicolas Bonnefon *foundIndex = minIndex + 1; 68*bb02e0acSNicolas Bonnefon else 69*bb02e0acSNicolas Bonnefon *foundIndex = minIndex; 70*bb02e0acSNicolas Bonnefon } 71*bb02e0acSNicolas Bonnefon else { 72*bb02e0acSNicolas Bonnefon *foundIndex = 0; 73*bb02e0acSNicolas Bonnefon } 74*bb02e0acSNicolas Bonnefon 75*bb02e0acSNicolas Bonnefon return false; 76*bb02e0acSNicolas Bonnefon } 77*bb02e0acSNicolas Bonnefon 78*bb02e0acSNicolas Bonnefon // Represents a position in a file (line, column) 79*bb02e0acSNicolas Bonnefon class FilePosition 80*bb02e0acSNicolas Bonnefon { 81*bb02e0acSNicolas Bonnefon public: 82*bb02e0acSNicolas Bonnefon FilePosition() 83*bb02e0acSNicolas Bonnefon { line_ = -1; column_ = -1; } 84*bb02e0acSNicolas Bonnefon FilePosition( qint64 line, int column ) 85*bb02e0acSNicolas Bonnefon { line_ = line; column_ = column; } 86*bb02e0acSNicolas Bonnefon 87*bb02e0acSNicolas Bonnefon qint64 line() const { return line_; } 88*bb02e0acSNicolas Bonnefon int column() const { return column_; } 89*bb02e0acSNicolas Bonnefon 90*bb02e0acSNicolas Bonnefon private: 91*bb02e0acSNicolas Bonnefon qint64 line_; 92*bb02e0acSNicolas Bonnefon int column_; 93*bb02e0acSNicolas Bonnefon }; 94*bb02e0acSNicolas Bonnefon 95*bb02e0acSNicolas Bonnefon #endif 96