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.
lookupLineNumber(const T & list,qint64 lineNumber,int * foundIndex)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 enum class Encoding {
86 ENCODING_AUTO = 0,
87 ENCODING_ISO_8859_1,
88 ENCODING_UTF8,
89 ENCODING_UTF16LE,
90 ENCODING_UTF16BE,
91 ENCODING_CP1251,
92 ENCODING_CP1252,
93 ENCODING_BIG5,
94 ENCODING_GB18030,
95 ENCODING_SHIFT_JIS,
96 ENCODING_KOI8R,
97 ENCODING_MAX,
98 };
99
100 // Represents a position in a file (line, column)
101 class FilePosition
102 {
103 public:
FilePosition()104 FilePosition()
105 { line_ = -1; column_ = -1; }
FilePosition(qint64 line,int column)106 FilePosition( qint64 line, int column )
107 { line_ = line; column_ = column; }
108
line()109 qint64 line() const { return line_; }
column()110 int column() const { return column_; }
111
112 private:
113 qint64 line_;
114 int column_;
115 };
116
117 template<typename Iterator>
lookupLineNumber(Iterator begin,Iterator end,LineNumber lineNum)118 LineNumber lookupLineNumber( Iterator begin, Iterator end, LineNumber lineNum )
119 {
120 LineNumber lineIndex = 0;
121 Iterator lowerBound = std::lower_bound( begin, end, lineNum );
122 if ( lowerBound != end ) {
123 lineIndex = std::distance(begin, lowerBound);
124 }
125 else if (begin != end) {
126 lineIndex = begin->lineNumber();
127 }
128 return lineIndex;
129 }
130
131 #ifndef HAVE_MAKE_UNIQUE
132 #include <memory>
133
134 namespace std {
135 template<typename T, typename... Args>
make_unique(Args &&...args)136 std::unique_ptr<T> make_unique(Args&&... args) {
137 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
138 }
139 }
140 #endif
141
142 #ifndef HAVE_OVERRIDE
143 #define override
144 #endif
145
146 #endif
147