xref: /glogg/src/utils.h (revision dfb2a39cb717e84f8a91ff75f7d49658243c4ca1)
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 
27bb02e0acSNicolas Bonnefon // Use a bisection method to find the given line number
28bb02e0acSNicolas Bonnefon // in a sorted list.
29bb02e0acSNicolas Bonnefon // The T type must be a container containing elements that
30bb02e0acSNicolas Bonnefon // implement the lineNumber() member.
31bb02e0acSNicolas Bonnefon // Returns true if the lineNumber is found, false if not
32bb02e0acSNicolas Bonnefon // foundIndex is the index of the found number or the index
33bb02e0acSNicolas Bonnefon // of the closest greater element.
34bb02e0acSNicolas Bonnefon template <typename T> bool lookupLineNumber(
35bb02e0acSNicolas Bonnefon         const T& list, qint64 lineNumber, int* foundIndex )
36bb02e0acSNicolas Bonnefon {
37bb02e0acSNicolas Bonnefon     int minIndex = 0;
38bb02e0acSNicolas Bonnefon     int maxIndex = list.size() - 1;
39bb02e0acSNicolas Bonnefon     // If the list is not empty
40bb02e0acSNicolas Bonnefon     if ( maxIndex - minIndex >= 0 ) {
41bb02e0acSNicolas Bonnefon         // First we test the ends
42bb02e0acSNicolas Bonnefon         if ( list[minIndex].lineNumber() == lineNumber ) {
43bb02e0acSNicolas Bonnefon             *foundIndex = minIndex;
44bb02e0acSNicolas Bonnefon             return true;
45bb02e0acSNicolas Bonnefon         }
46bb02e0acSNicolas Bonnefon         else if ( list[maxIndex].lineNumber() == lineNumber ) {
47bb02e0acSNicolas Bonnefon             *foundIndex = maxIndex;
48bb02e0acSNicolas Bonnefon             return true;
49bb02e0acSNicolas Bonnefon         }
50bb02e0acSNicolas Bonnefon 
51bb02e0acSNicolas Bonnefon         // Then we test the rest
52bb02e0acSNicolas Bonnefon         while ( (maxIndex - minIndex) > 1 ) {
53bb02e0acSNicolas Bonnefon             const int tryIndex = (minIndex + maxIndex) / 2;
54bb02e0acSNicolas Bonnefon             const qint64 currentMatchingNumber =
55bb02e0acSNicolas Bonnefon                 list[tryIndex].lineNumber();
56bb02e0acSNicolas Bonnefon             if ( currentMatchingNumber > lineNumber )
57bb02e0acSNicolas Bonnefon                 maxIndex = tryIndex;
58bb02e0acSNicolas Bonnefon             else if ( currentMatchingNumber < lineNumber )
59bb02e0acSNicolas Bonnefon                 minIndex = tryIndex;
60bb02e0acSNicolas Bonnefon             else if ( currentMatchingNumber == lineNumber ) {
61bb02e0acSNicolas Bonnefon                 *foundIndex = tryIndex;
62bb02e0acSNicolas Bonnefon                 return true;
63bb02e0acSNicolas Bonnefon             }
64bb02e0acSNicolas Bonnefon         }
65bb02e0acSNicolas Bonnefon 
66bb02e0acSNicolas Bonnefon         // If we haven't found anything...
67bb02e0acSNicolas Bonnefon         // ... end of the list or before the next
68bb02e0acSNicolas Bonnefon         if ( lineNumber > list[maxIndex].lineNumber() )
69bb02e0acSNicolas Bonnefon             *foundIndex = maxIndex + 1;
70bb02e0acSNicolas Bonnefon         else if ( lineNumber > list[minIndex].lineNumber() )
71bb02e0acSNicolas Bonnefon             *foundIndex = minIndex + 1;
72bb02e0acSNicolas Bonnefon         else
73bb02e0acSNicolas Bonnefon             *foundIndex = minIndex;
74bb02e0acSNicolas Bonnefon     }
75bb02e0acSNicolas Bonnefon     else {
76bb02e0acSNicolas Bonnefon         *foundIndex = 0;
77bb02e0acSNicolas Bonnefon     }
78bb02e0acSNicolas Bonnefon 
79bb02e0acSNicolas Bonnefon     return false;
80bb02e0acSNicolas Bonnefon }
81bb02e0acSNicolas Bonnefon 
82bb02e0acSNicolas Bonnefon // Represents a position in a file (line, column)
83bb02e0acSNicolas Bonnefon class FilePosition
84bb02e0acSNicolas Bonnefon {
85bb02e0acSNicolas Bonnefon   public:
86bb02e0acSNicolas Bonnefon     FilePosition()
87bb02e0acSNicolas Bonnefon     { line_ = -1; column_ = -1; }
88bb02e0acSNicolas Bonnefon     FilePosition( qint64 line, int column )
89bb02e0acSNicolas Bonnefon     { line_ = line; column_ = column; }
90bb02e0acSNicolas Bonnefon 
91bb02e0acSNicolas Bonnefon     qint64 line() const { return line_; }
92bb02e0acSNicolas Bonnefon     int column() const { return column_; }
93bb02e0acSNicolas Bonnefon 
94bb02e0acSNicolas Bonnefon   private:
95bb02e0acSNicolas Bonnefon     qint64 line_;
96bb02e0acSNicolas Bonnefon     int column_;
97bb02e0acSNicolas Bonnefon };
98bb02e0acSNicolas Bonnefon 
99f09fa651SNicolas Bonnefon #ifndef HAVE_MAKE_UNIQUE
100f09fa651SNicolas Bonnefon #include <memory>
101f09fa651SNicolas Bonnefon 
102f09fa651SNicolas Bonnefon namespace std {
103f09fa651SNicolas Bonnefon template<typename T, typename... Args>
104f09fa651SNicolas Bonnefon std::unique_ptr<T> make_unique(Args&&... args) {
105f09fa651SNicolas Bonnefon         return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
106f09fa651SNicolas Bonnefon }
107f09fa651SNicolas Bonnefon }
108f09fa651SNicolas Bonnefon #endif
109f09fa651SNicolas Bonnefon 
110*dfb2a39cSNicolas Bonnefon #ifndef HAVE_OVERRIDE
111*dfb2a39cSNicolas Bonnefon #define override
112*dfb2a39cSNicolas Bonnefon #endif
113*dfb2a39cSNicolas Bonnefon 
114bb02e0acSNicolas Bonnefon #endif
115