00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique 00002 00003 // This file is part of Qolyester. 00004 00005 // Qolyester is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 00010 // Qolyester is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 00026 00027 #ifndef QOLYESTER_UTL_SEQNUM_HH 00028 # define QOLYESTER_UTL_SEQNUM_HH 1 00029 00030 # include <sys/types.h> 00031 00032 namespace olsr { 00033 00034 namespace utl { 00035 00036 namespace internal { 00037 00038 //******************************************************* 00039 //* Static type information and metaprogramming tools * 00040 //******************************************************* 00041 00042 template <typename T> struct maxvalue_trait {}; 00043 00044 # define DECLARE_MAX_TRAIT(Type,Max) \ 00045 template <> struct maxvalue_trait<Type> { static const Type value = (Max); } 00046 00047 DECLARE_MAX_TRAIT(int8_t, 127); 00048 DECLARE_MAX_TRAIT(u_int8_t, 255); 00049 DECLARE_MAX_TRAIT(int16_t, 32767); 00050 DECLARE_MAX_TRAIT(u_int16_t, 65535); 00051 DECLARE_MAX_TRAIT(int32_t, 2147483647); 00052 DECLARE_MAX_TRAIT(u_int32_t, 4294967295U); 00053 00054 template <typename T> struct assert_unsigned {}; 00055 00056 # define DECLARE_UNSIGNED(Type) \ 00057 template <> struct assert_unsigned<Type> { struct this_type_is_not_unsigned; } 00058 00059 DECLARE_UNSIGNED(u_int8_t); 00060 DECLARE_UNSIGNED(u_int16_t); 00061 DECLARE_UNSIGNED(u_int32_t); 00062 00063 # define ASSERT_UNSIGNED(Type) \ 00064 typedef typename internal::assert_unsigned<Type>::this_type_is_not_unsigned _unsigned_dummy_t 00065 00066 } // namespace internal 00067 00068 //***************************************************** 00069 //* Seqnum class for sequence number implementation * 00070 //***************************************************** 00071 00080 template <typename T> 00081 class Seqnum { 00082 typedef Seqnum<T> This; // Convenience definition 00083 ASSERT_UNSIGNED(T); // Static assertion 00084 public: 00085 00086 // Default and copy constructors 00087 Seqnum() : 00088 _value(0) 00089 {} 00090 00091 Seqnum(const This& other) : 00092 _value(other._value) 00093 {} 00094 00095 Seqnum(const T& other) : 00096 _value(other) 00097 {} 00098 00099 // Comparators 00100 bool 00101 operator>(const This& rhs) const { 00102 if (_value > rhs._value && _value - rhs._value <= This::_halfmax) 00103 return true; 00104 if (rhs._value > _value && rhs._value - _value > This::_halfmax) 00105 return true; 00106 return false; 00107 } 00108 00109 bool 00110 operator<(const This& rhs) const { 00111 if (rhs._value > _value && rhs._value - _value <= This::_halfmax) 00112 return true; 00113 if (_value > rhs._value && _value - rhs._value > This::_halfmax) 00114 return true; 00115 return false; 00116 } 00117 00118 bool 00119 operator==(const This& rhs) const { 00120 return _value == rhs._value; 00121 } 00122 00123 bool 00124 operator>=(const This& rhs) const { 00125 return *this > rhs || *this == rhs; 00126 } 00127 00128 bool 00129 operator<=(const This& rhs) const { 00130 return *this < rhs || *this == rhs; 00131 } 00132 00133 // Pre- and post-incrementors 00134 This& 00135 operator++() { 00136 ++_value; 00137 return *this; 00138 } 00139 00140 This 00141 operator++(int) { 00142 This tmp(*this); 00143 ++*this; 00144 return tmp; 00145 } 00146 00147 // Cast to base value type operator 00148 operator T() const { 00149 return _value; 00150 } 00151 00152 // Reset operator (just in case) 00153 void 00154 reset() { 00155 _value = 0; 00156 } 00157 00158 private: 00159 T _value; 00160 static const T _halfmax = internal::maxvalue_trait<T>::value / 2; 00161 }; 00162 00163 } // namespace utl 00164 00165 typedef utl::Seqnum<u_int16_t> seqnum_t; 00166 00167 } // namespace olsr 00168 00169 #endif // ! QOLYESTER_UTL_SEQNUM_HH