xref: /glogg/src/utils.h (revision 209000a64813870d3d6a4fc0d1af7898cc8c37ca)
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 
85*209000a6SNicolas Bonnefon enum class Encoding {
86*209000a6SNicolas Bonnefon     ENCODING_AUTO = 0,
87*209000a6SNicolas Bonnefon     ENCODING_ISO_8859_1,
88*209000a6SNicolas Bonnefon     ENCODING_UTF8,
89*209000a6SNicolas Bonnefon     ENCODING_UTF16LE,
90*209000a6SNicolas Bonnefon     ENCODING_UTF16BE,
91*209000a6SNicolas Bonnefon     ENCODING_CP1251,
92*209000a6SNicolas Bonnefon     ENCODING_CP1252,
93*209000a6SNicolas Bonnefon     ENCODING_MAX,
94*209000a6SNicolas Bonnefon };
95*209000a6SNicolas Bonnefon 
96bb02e0acSNicolas Bonnefon // Represents a position in a file (line, column)
97bb02e0acSNicolas Bonnefon class FilePosition
98bb02e0acSNicolas Bonnefon {
99bb02e0acSNicolas Bonnefon   public:
100bb02e0acSNicolas Bonnefon     FilePosition()
101bb02e0acSNicolas Bonnefon     { line_ = -1; column_ = -1; }
102bb02e0acSNicolas Bonnefon     FilePosition( qint64 line, int column )
103bb02e0acSNicolas Bonnefon     { line_ = line; column_ = column; }
104bb02e0acSNicolas Bonnefon 
105bb02e0acSNicolas Bonnefon     qint64 line() const { return line_; }
106bb02e0acSNicolas Bonnefon     int column() const { return column_; }
107bb02e0acSNicolas Bonnefon 
108bb02e0acSNicolas Bonnefon   private:
109bb02e0acSNicolas Bonnefon     qint64 line_;
110bb02e0acSNicolas Bonnefon     int column_;
111bb02e0acSNicolas Bonnefon };
112bb02e0acSNicolas Bonnefon 
113f09fa651SNicolas Bonnefon #ifndef HAVE_MAKE_UNIQUE
114f09fa651SNicolas Bonnefon #include <memory>
115f09fa651SNicolas Bonnefon 
116f09fa651SNicolas Bonnefon namespace std {
117f09fa651SNicolas Bonnefon template<typename T, typename... Args>
118f09fa651SNicolas Bonnefon std::unique_ptr<T> make_unique(Args&&... args) {
119f09fa651SNicolas Bonnefon         return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
120f09fa651SNicolas Bonnefon }
121f09fa651SNicolas Bonnefon }
122f09fa651SNicolas Bonnefon #endif
123f09fa651SNicolas Bonnefon 
124dfb2a39cSNicolas Bonnefon #ifndef HAVE_OVERRIDE
125dfb2a39cSNicolas Bonnefon #define override
126dfb2a39cSNicolas Bonnefon #endif
127dfb2a39cSNicolas Bonnefon 
128bb02e0acSNicolas Bonnefon #endif
129