Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : /* 7 : * This header file contains C++ language helpers used by every class 8 : * in the system. DO NOT add anything here that can be thought of as a 9 : * library or that requires the inclusion on header files. 10 : */ 11 : #ifndef __UTIL_H__ 12 : #define __UTIL_H__ 13 : 14 : #include <boost/function.hpp> 15 : 16 : #define DISALLOW_COPY_AND_ASSIGN(_Class) \ 17 : _Class(const _Class &); \ 18 : _Class& operator=(const _Class &) 19 : 20 : 21 : #ifdef NDEBUG 22 : #define CHECK_INVARIANT(Cond) \ 23 : do { \ 24 : if (!(Cond)) { \ 25 : LOG(WARN, "Invariant failed: " ## Cond); \ 26 : return false; \ 27 : } \ 28 : } while (0) 29 : #else 30 : #define CHECK_INVARIANT(Cond) \ 31 : do { \ 32 : assert(Cond); \ 33 : } while (0) 34 : #endif 35 : 36 : template <typename IntType> 37 760972 : bool BitIsSet(IntType value, size_t bit) { 38 760972 : return (value & (1 << bit)) != 0; 39 : } 40 : 41 : template <typename IntType> 42 21750 : void SetBit(IntType &value, size_t bit) { 43 21750 : value |= (1 << bit); 44 21750 : } 45 : 46 : template <typename IntType> 47 21786 : void ClearBit(IntType &value, size_t bit) { 48 21786 : value &= ~(1 << bit); 49 21786 : } 50 : 51 : class ModuleInitializer { 52 : public: 53 1556 : ModuleInitializer(boost::function<void(void)> func) { 54 1556 : (func)(); 55 1556 : } 56 : }; 57 : 58 : // This two levels of indirection is necessary because otherwise preprocessor 59 : // will not expand __LINE__ after ## operator 60 : #define TOKENPASTE(x, y) x ## y 61 : #define TOKENPASTE2(x, y) TOKENPASTE(x, y) 62 : #define MODULE_INITIALIZER(Func) \ 63 : static ModuleInitializer TOKENPASTE2(init_, __LINE__)(Func); 64 : 65 : #define BOOL_KEY_COMPARE(x, y) \ 66 : do { \ 67 : if ((x) < (y)) return true; \ 68 : if ((y) < (x)) return false; \ 69 : } while (false) 70 : 71 : #define KEY_COMPARE(x, y) \ 72 : do { \ 73 : if ((x) < (y)) return -1; \ 74 : if ((y) < (x)) return 1; \ 75 : } while (false) 76 : 77 : // Compare sorted vectors of pointers. 78 : template <class InputIterator, class CompareOp> 79 1966241 : int STLSortedCompare(InputIterator first1, InputIterator last1, 80 : InputIterator first2, InputIterator last2, 81 : CompareOp op) { 82 1966241 : InputIterator iter1 = first1; 83 1966241 : InputIterator iter2 = first2; 84 2300237 : while (iter1 != last1 && iter2 != last2) { 85 368469 : int result = op(*iter1, *iter2); 86 368471 : if (result != 0) { 87 34475 : return result; 88 : } 89 333996 : ++iter1; 90 333996 : ++iter2; 91 : } 92 1931770 : if (iter1 != last1) { 93 12519 : return 1; 94 : } 95 1919251 : if (iter2 != last2) { 96 2733 : return -1; 97 : } 98 1916520 : return 0; 99 : } 100 : 101 : template <typename Container> 102 4971110 : void STLDeleteValues(Container *container) { 103 4971110 : typename Container::iterator next; 104 13906389 : for (typename Container::iterator iter = container->begin(); 105 13906347 : iter != container->end(); iter = next) { 106 8935167 : next = iter; 107 8935167 : ++next; 108 8935154 : delete *iter; 109 : } 110 4970961 : container->clear(); 111 4970889 : } 112 : 113 : // Delete all the elements of a map. 114 : template <typename Container> 115 387313 : void STLDeleteElements(Container *container) { 116 387313 : typename Container::iterator next; 117 2359674 : for (typename Container::iterator iter = container->begin(); 118 2359674 : iter != container->end(); iter = next) { 119 1972361 : next = iter; 120 1972361 : ++next; 121 1972361 : delete iter->second; 122 : } 123 387312 : container->clear(); 124 387312 : } 125 : 126 : // Check if key exist in collection 127 : template <typename Collection, typename T> 128 : bool STLKeyExists(const Collection &col, const T &key) { 129 : return col.find(key) != col.end(); 130 : } 131 : 132 : template <typename T> 133 : class custom_ptr { 134 : public: 135 : custom_ptr(boost::function<void(T *)> deleter, T *ptr = 0) 136 : : deleter_(deleter), ptr_(ptr) { 137 : assert(deleter_ != NULL); 138 : } 139 : ~custom_ptr() { 140 : if (ptr_ != NULL) { 141 : (deleter_)(ptr_); 142 : } 143 : } 144 : T *get() const { 145 : return ptr_; 146 : } 147 : T *operator->() const { 148 : return ptr_; 149 : } 150 : void reset(T *ptr = 0) { 151 : if (ptr_ != NULL) { 152 : (deleter_)(ptr_); 153 : } 154 : ptr_ = ptr; 155 : } 156 : T *release() { 157 : T *ptr = ptr_; 158 : ptr_ = NULL; 159 : return ptr; 160 : } 161 : private: 162 : boost::function<void(T *)> deleter_; 163 : T *ptr_; 164 : }; 165 : 166 : template <class KeyType, template <class> class SmartPointer> 167 : struct SmartPointerComparator { 168 0 : bool operator()( const SmartPointer<KeyType> lhs, 169 : const SmartPointer<KeyType> rhs) const { 170 0 : KeyType *left = lhs.get(); 171 0 : KeyType *right = rhs.get(); 172 0 : return (*left).IsLess(*right); 173 : } 174 : }; 175 : 176 : #endif /* UTIL_H_ */