xref: /glogg/src/utils.h (revision 048334c92fb4b86ebbabc7471f7313a1cc515c10)
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.
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:
104bb02e0acSNicolas Bonnefon     FilePosition()
105bb02e0acSNicolas Bonnefon     { line_ = -1; column_ = -1; }
106bb02e0acSNicolas Bonnefon     FilePosition( qint64 line, int column )
107bb02e0acSNicolas Bonnefon     { line_ = line; column_ = column; }
108bb02e0acSNicolas Bonnefon 
109bb02e0acSNicolas Bonnefon     qint64 line() const { return line_; }
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>
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>
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