xref: /glogg/src/utils.h (revision f869e41d2c129cd0f2f3eccb5e9d0d80a5998201)
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 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_MAX,
94 };
95 
96 // Represents a position in a file (line, column)
97 class FilePosition
98 {
99   public:
100     FilePosition()
101     { line_ = -1; column_ = -1; }
102     FilePosition( qint64 line, int column )
103     { line_ = line; column_ = column; }
104 
105     qint64 line() const { return line_; }
106     int column() const { return column_; }
107 
108   private:
109     qint64 line_;
110     int column_;
111 };
112 
113 template<typename Iterator>
114 LineNumber lookupLineNumber( Iterator begin, Iterator end, LineNumber lineNum )
115 {
116     LineNumber lineIndex = 0;
117     Iterator lowerBound = std::lower_bound( begin, end, lineNum );
118     if ( lowerBound != end ) {
119         lineIndex = std::distance(begin, lowerBound);
120     }
121     else if (begin != end) {
122         lineIndex = begin->lineNumber();
123     }
124     return lineIndex;
125 }
126 
127 #ifndef HAVE_MAKE_UNIQUE
128 #include <memory>
129 
130 namespace std {
131 template<typename T, typename... Args>
132 std::unique_ptr<T> make_unique(Args&&... args) {
133         return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
134 }
135 }
136 #endif
137 
138 #ifndef HAVE_OVERRIDE
139 #define override
140 #endif
141 
142 #endif
143