xref: /glogg/src/utils.h (revision bb02e0acf44ddb4e4f83d6127a1e488789162922)
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