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 // Represents a position in a file (line, column) 86 class FilePosition 87 { 88 public: 89 FilePosition() 90 { line_ = -1; column_ = -1; } 91 FilePosition( qint64 line, int column ) 92 { line_ = line; column_ = column; } 93 94 qint64 line() const { return line_; } 95 int column() const { return column_; } 96 97 private: 98 qint64 line_; 99 int column_; 100 }; 101 102 #ifndef HAVE_MAKE_UNIQUE 103 #include <memory> 104 105 namespace std { 106 template<typename T, typename... Args> 107 std::unique_ptr<T> make_unique(Args&&... args) { 108 return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 109 } 110 } 111 #endif 112 113 #ifndef HAVE_OVERRIDE 114 #define override 115 #endif 116 117 #ifndef HAVE_HTONS 118 inline uint16_t glogg_htons( uint16_t hostshort ) 119 { 120 static const uint16_t test_value = 0xABCD; 121 if ( *( reinterpret_cast<const uint8_t*>( &test_value ) ) == 0xCD ) { 122 uint16_t result = ( hostshort & 0x00FF ) << 8; 123 result |= ( hostshort & 0xFF00 ) >> 8; 124 125 return result; 126 } 127 else { 128 return hostshort; 129 } 130 } 131 #endif 132 133 #endif 134