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