1bb02e0acSNicolas Bonnefon /*
2bb02e0acSNicolas Bonnefon * Copyright (C) 2011, 2013 Nicolas Bonnefon and other contributors
3bb02e0acSNicolas Bonnefon *
4bb02e0acSNicolas Bonnefon * This file is part of glogg.
5bb02e0acSNicolas Bonnefon *
6bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify
7bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by
8bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or
9bb02e0acSNicolas Bonnefon * (at your option) any later version.
10bb02e0acSNicolas Bonnefon *
11bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful,
12bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of
13bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14bb02e0acSNicolas Bonnefon * GNU General Public License for more details.
15bb02e0acSNicolas Bonnefon *
16bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License
17bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18bb02e0acSNicolas Bonnefon */
19bb02e0acSNicolas Bonnefon
20bb02e0acSNicolas Bonnefon #ifndef UTILS_H
21bb02e0acSNicolas Bonnefon #define UTILS_H
22bb02e0acSNicolas Bonnefon
23f09fa651SNicolas Bonnefon #include <QtGlobal>
24f09fa651SNicolas Bonnefon
25f09fa651SNicolas Bonnefon #include "config.h"
26f09fa651SNicolas Bonnefon
272493b508SNicolas Bonnefon // Line number are unsigned 32 bits for now.
282493b508SNicolas Bonnefon typedef uint32_t LineNumber;
292493b508SNicolas Bonnefon
30bb02e0acSNicolas Bonnefon // Use a bisection method to find the given line number
31bb02e0acSNicolas Bonnefon // in a sorted list.
32bb02e0acSNicolas Bonnefon // The T type must be a container containing elements that
33bb02e0acSNicolas Bonnefon // implement the lineNumber() member.
34bb02e0acSNicolas Bonnefon // Returns true if the lineNumber is found, false if not
35bb02e0acSNicolas Bonnefon // foundIndex is the index of the found number or the index
36bb02e0acSNicolas Bonnefon // of the closest greater element.
lookupLineNumber(const T & list,qint64 lineNumber,int * foundIndex)37bb02e0acSNicolas Bonnefon template <typename T> bool lookupLineNumber(
38bb02e0acSNicolas Bonnefon const T& list, qint64 lineNumber, int* foundIndex )
39bb02e0acSNicolas Bonnefon {
40bb02e0acSNicolas Bonnefon int minIndex = 0;
41bb02e0acSNicolas Bonnefon int maxIndex = list.size() - 1;
42bb02e0acSNicolas Bonnefon // If the list is not empty
43bb02e0acSNicolas Bonnefon if ( maxIndex - minIndex >= 0 ) {
44bb02e0acSNicolas Bonnefon // First we test the ends
45bb02e0acSNicolas Bonnefon if ( list[minIndex].lineNumber() == lineNumber ) {
46bb02e0acSNicolas Bonnefon *foundIndex = minIndex;
47bb02e0acSNicolas Bonnefon return true;
48bb02e0acSNicolas Bonnefon }
49bb02e0acSNicolas Bonnefon else if ( list[maxIndex].lineNumber() == lineNumber ) {
50bb02e0acSNicolas Bonnefon *foundIndex = maxIndex;
51bb02e0acSNicolas Bonnefon return true;
52bb02e0acSNicolas Bonnefon }
53bb02e0acSNicolas Bonnefon
54bb02e0acSNicolas Bonnefon // Then we test the rest
55bb02e0acSNicolas Bonnefon while ( (maxIndex - minIndex) > 1 ) {
56bb02e0acSNicolas Bonnefon const int tryIndex = (minIndex + maxIndex) / 2;
57bb02e0acSNicolas Bonnefon const qint64 currentMatchingNumber =
58bb02e0acSNicolas Bonnefon list[tryIndex].lineNumber();
59bb02e0acSNicolas Bonnefon if ( currentMatchingNumber > lineNumber )
60bb02e0acSNicolas Bonnefon maxIndex = tryIndex;
61bb02e0acSNicolas Bonnefon else if ( currentMatchingNumber < lineNumber )
62bb02e0acSNicolas Bonnefon minIndex = tryIndex;
63bb02e0acSNicolas Bonnefon else if ( currentMatchingNumber == lineNumber ) {
64bb02e0acSNicolas Bonnefon *foundIndex = tryIndex;
65bb02e0acSNicolas Bonnefon return true;
66bb02e0acSNicolas Bonnefon }
67bb02e0acSNicolas Bonnefon }
68bb02e0acSNicolas Bonnefon
69bb02e0acSNicolas Bonnefon // If we haven't found anything...
70bb02e0acSNicolas Bonnefon // ... end of the list or before the next
71bb02e0acSNicolas Bonnefon if ( lineNumber > list[maxIndex].lineNumber() )
72bb02e0acSNicolas Bonnefon *foundIndex = maxIndex + 1;
73bb02e0acSNicolas Bonnefon else if ( lineNumber > list[minIndex].lineNumber() )
74bb02e0acSNicolas Bonnefon *foundIndex = minIndex + 1;
75bb02e0acSNicolas Bonnefon else
76bb02e0acSNicolas Bonnefon *foundIndex = minIndex;
77bb02e0acSNicolas Bonnefon }
78bb02e0acSNicolas Bonnefon else {
79bb02e0acSNicolas Bonnefon *foundIndex = 0;
80bb02e0acSNicolas Bonnefon }
81bb02e0acSNicolas Bonnefon
82bb02e0acSNicolas Bonnefon return false;
83bb02e0acSNicolas Bonnefon }
84bb02e0acSNicolas Bonnefon
85209000a6SNicolas Bonnefon enum class Encoding {
86209000a6SNicolas Bonnefon ENCODING_AUTO = 0,
87209000a6SNicolas Bonnefon ENCODING_ISO_8859_1,
88209000a6SNicolas Bonnefon ENCODING_UTF8,
89209000a6SNicolas Bonnefon ENCODING_UTF16LE,
90209000a6SNicolas Bonnefon ENCODING_UTF16BE,
91209000a6SNicolas Bonnefon ENCODING_CP1251,
92209000a6SNicolas Bonnefon ENCODING_CP1252,
93*048334c9SSeerauber ENCODING_BIG5,
94*048334c9SSeerauber ENCODING_GB18030,
95*048334c9SSeerauber ENCODING_SHIFT_JIS,
96*048334c9SSeerauber ENCODING_KOI8R,
97209000a6SNicolas Bonnefon ENCODING_MAX,
98209000a6SNicolas Bonnefon };
99209000a6SNicolas Bonnefon
100bb02e0acSNicolas Bonnefon // Represents a position in a file (line, column)
101bb02e0acSNicolas Bonnefon class FilePosition
102bb02e0acSNicolas Bonnefon {
103bb02e0acSNicolas Bonnefon public:
FilePosition()104bb02e0acSNicolas Bonnefon FilePosition()
105bb02e0acSNicolas Bonnefon { line_ = -1; column_ = -1; }
FilePosition(qint64 line,int column)106bb02e0acSNicolas Bonnefon FilePosition( qint64 line, int column )
107bb02e0acSNicolas Bonnefon { line_ = line; column_ = column; }
108bb02e0acSNicolas Bonnefon
line()109bb02e0acSNicolas Bonnefon qint64 line() const { return line_; }
column()110bb02e0acSNicolas Bonnefon int column() const { return column_; }
111bb02e0acSNicolas Bonnefon
112bb02e0acSNicolas Bonnefon private:
113bb02e0acSNicolas Bonnefon qint64 line_;
114bb02e0acSNicolas Bonnefon int column_;
115bb02e0acSNicolas Bonnefon };
116bb02e0acSNicolas Bonnefon
1173ff6c941SAnton Filimonov template<typename Iterator>
lookupLineNumber(Iterator begin,Iterator end,LineNumber lineNum)1183ff6c941SAnton Filimonov LineNumber lookupLineNumber( Iterator begin, Iterator end, LineNumber lineNum )
1193ff6c941SAnton Filimonov {
1203ff6c941SAnton Filimonov LineNumber lineIndex = 0;
1213ff6c941SAnton Filimonov Iterator lowerBound = std::lower_bound( begin, end, lineNum );
1223ff6c941SAnton Filimonov if ( lowerBound != end ) {
1233ff6c941SAnton Filimonov lineIndex = std::distance(begin, lowerBound);
1243ff6c941SAnton Filimonov }
1253ff6c941SAnton Filimonov else if (begin != end) {
1263ff6c941SAnton Filimonov lineIndex = begin->lineNumber();
1273ff6c941SAnton Filimonov }
1283ff6c941SAnton Filimonov return lineIndex;
1293ff6c941SAnton Filimonov }
1303ff6c941SAnton Filimonov
131f09fa651SNicolas Bonnefon #ifndef HAVE_MAKE_UNIQUE
132f09fa651SNicolas Bonnefon #include <memory>
133f09fa651SNicolas Bonnefon
134f09fa651SNicolas Bonnefon namespace std {
135f09fa651SNicolas Bonnefon template<typename T, typename... Args>
make_unique(Args &&...args)136f09fa651SNicolas Bonnefon std::unique_ptr<T> make_unique(Args&&... args) {
137f09fa651SNicolas Bonnefon return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
138f09fa651SNicolas Bonnefon }
139f09fa651SNicolas Bonnefon }
140f09fa651SNicolas Bonnefon #endif
141f09fa651SNicolas Bonnefon
142dfb2a39cSNicolas Bonnefon #ifndef HAVE_OVERRIDE
143dfb2a39cSNicolas Bonnefon #define override
144dfb2a39cSNicolas Bonnefon #endif
145dfb2a39cSNicolas Bonnefon
146bb02e0acSNicolas Bonnefon #endif
147