xref: /glogg/src/utils.h (revision 2493b5088b3bfba37bb262be238a7a80526d8ebf)
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 
27*2493b508SNicolas Bonnefon // Line number are unsigned 32 bits for now.
28*2493b508SNicolas Bonnefon typedef uint32_t LineNumber;
29*2493b508SNicolas 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 
85bb02e0acSNicolas Bonnefon // Represents a position in a file (line, column)
86bb02e0acSNicolas Bonnefon class FilePosition
87bb02e0acSNicolas Bonnefon {
88bb02e0acSNicolas Bonnefon   public:
89bb02e0acSNicolas Bonnefon     FilePosition()
90bb02e0acSNicolas Bonnefon     { line_ = -1; column_ = -1; }
91bb02e0acSNicolas Bonnefon     FilePosition( qint64 line, int column )
92bb02e0acSNicolas Bonnefon     { line_ = line; column_ = column; }
93bb02e0acSNicolas Bonnefon 
94bb02e0acSNicolas Bonnefon     qint64 line() const { return line_; }
95bb02e0acSNicolas Bonnefon     int column() const { return column_; }
96bb02e0acSNicolas Bonnefon 
97bb02e0acSNicolas Bonnefon   private:
98bb02e0acSNicolas Bonnefon     qint64 line_;
99bb02e0acSNicolas Bonnefon     int column_;
100bb02e0acSNicolas Bonnefon };
101bb02e0acSNicolas Bonnefon 
102f09fa651SNicolas Bonnefon #ifndef HAVE_MAKE_UNIQUE
103f09fa651SNicolas Bonnefon #include <memory>
104f09fa651SNicolas Bonnefon 
105f09fa651SNicolas Bonnefon namespace std {
106f09fa651SNicolas Bonnefon template<typename T, typename... Args>
107f09fa651SNicolas Bonnefon std::unique_ptr<T> make_unique(Args&&... args) {
108f09fa651SNicolas Bonnefon         return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
109f09fa651SNicolas Bonnefon }
110f09fa651SNicolas Bonnefon }
111f09fa651SNicolas Bonnefon #endif
112f09fa651SNicolas Bonnefon 
113dfb2a39cSNicolas Bonnefon #ifndef HAVE_OVERRIDE
114dfb2a39cSNicolas Bonnefon #define override
115dfb2a39cSNicolas Bonnefon #endif
116dfb2a39cSNicolas Bonnefon 
1179ba963cbSNicolas Bonnefon #ifndef HAVE_HTONS
1189ba963cbSNicolas Bonnefon inline uint16_t glogg_htons( uint16_t hostshort )
1199ba963cbSNicolas Bonnefon {
1209ba963cbSNicolas Bonnefon     static const uint16_t test_value = 0xABCD;
1219ba963cbSNicolas Bonnefon     if ( *( reinterpret_cast<const uint8_t*>( &test_value ) ) == 0xCD ) {
1229ba963cbSNicolas Bonnefon         uint16_t result = ( hostshort & 0x00FF ) << 8;
1239ba963cbSNicolas Bonnefon         result |= ( hostshort & 0xFF00 ) >> 8;
1249ba963cbSNicolas Bonnefon 
1259ba963cbSNicolas Bonnefon         return result;
1269ba963cbSNicolas Bonnefon     }
1279ba963cbSNicolas Bonnefon     else {
1289ba963cbSNicolas Bonnefon         return hostshort;
1299ba963cbSNicolas Bonnefon     }
1309ba963cbSNicolas Bonnefon }
1319ba963cbSNicolas Bonnefon #endif
1329ba963cbSNicolas Bonnefon 
133bb02e0acSNicolas Bonnefon #endif
134