A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
sequence-number.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2008-2010 INESC Porto
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19 //
20 
21 #ifndef NS3_SEQ_NUM_H
22 #define NS3_SEQ_NUM_H
23 
24 #include <limits>
25 #include <iostream>
26 #include <stdint.h>
27 
28 namespace ns3 {
29 
51 template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
53 {
54 public:
56  : m_value (0)
57  {}
58 
63  explicit SequenceNumber (NUMERIC_TYPE value)
64  : m_value (value)
65  {}
66 
72  : m_value (value.m_value)
73  {}
74 
81  {
82  m_value = value;
83  return *this;
84  }
85 
92  {
93  m_value = value.m_value;
94  return *this;
95  }
96 
97 #if 0
98  // a SequenceNumber implicitly converts to a plain number, but not the other way around
99  operator NUMERIC_TYPE () const
100  {
101  return m_value;
102  }
103 #endif
104 
109  NUMERIC_TYPE GetValue () const
110  {
111  return m_value;
112  }
113 
119  {
120  m_value++;
121  return *this;
122  }
123 
129  {
131  m_value++;
132  return retval;
133  }
134 
140  {
141  m_value--;
142  return *this;
143  }
144 
150  {
152  m_value--;
153  return retval;
154  }
155 
162  {
163  m_value += value;
164  return *this;
165  }
166 
173  {
174  m_value -= value;
175  return *this;
176  }
177 
184  {
186  }
187 
194  {
196  }
197 
204  {
206  }
207 
214  {
215  static const NUMERIC_TYPE maxValue = std::numeric_limits<NUMERIC_TYPE>::max ();
216  static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
217  if (m_value > other.m_value)
218  {
219  NUMERIC_TYPE diff = m_value - other.m_value;
220  if (diff < halfMaxValue)
221  {
222  return static_cast<SIGNED_TYPE> (diff);
223  }
224  else
225  {
226  // |------------|------------|
227  // ==== ===
228  // ^ ^
229  // other.m_value m_value
230  return -(static_cast<SIGNED_TYPE> (maxValue - m_value + 1 + other.m_value));
231  }
232  }
233  else
234  {
235  NUMERIC_TYPE diff = other.m_value - m_value;
236  if (diff < halfMaxValue)
237  {
238  // |------------|------------|
239  // ========
240  // ^ ^
241  // m_value other.m_value
242  return -(static_cast<SIGNED_TYPE> (diff));
243  }
244  else
245  {
246  // |------------|------------|
247  // ==== ===
248  // ^ ^
249  // m_value other.m_value
250  return static_cast<SIGNED_TYPE> (maxValue - other.m_value + 1 + m_value);
251  }
252  }
253  }
254 
268  {
269  static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
270 
271  return (((m_value > other.m_value) && (m_value - other.m_value) <= halfMaxValue)
272  || ((other.m_value > m_value) && (other.m_value - m_value) > halfMaxValue));
273  }
274 
281  {
282  return (m_value == other.m_value);
283  }
284 
291  {
292  return (m_value != other.m_value);
293  }
294 
300  bool operator <= (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
301  {
302  return (!this->operator> (other));
303  }
304 
311  {
312  return (this->operator> (other) || this->operator== (other));
313  }
314 
320  bool operator < (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other) const
321  {
322  return !this->operator> (other) && m_value != other.m_value;
323  }
324 
331  template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
332  friend std::ostream & operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
333 
340  template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
341  friend std::istream & operator >> (std::istream &is, const SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
342 
343 private: // unimplemented operators
349  bool operator ! () const;
356  SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> operator<< (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
358  int operator* ();
359  //SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>* operator& ();
360 
361 private:
362  NUMERIC_TYPE m_value;
363 };
364 
365 template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
366 std::ostream &
367 operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &val)
368 {
369  os << val.m_value;
370  return os;
371 }
372 
373 template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
374 std::istream & operator >> (std::istream &is, const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &val)
375 {
376  is >> val.m_value;
377  return is;
378 }
379 
380 
383 
384 } // namespace ns3
385 
386 #endif /* NS3_SEQ_NUM_H */
387 
388 
bool operator!=(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &other) const
Inequality operator for comparing sequence numbers.
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:49
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
bool operator&&(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
bool operator||(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
bool operator==(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &other) const
Equality operator for comparing sequence number.
bool operator>(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &other) const
Here is the critical part, how the comparison is made taking into account wrap-around.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator/(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
bool operator!() const
SequenceNumber< uint32_t, int32_t > SequenceNumber32
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator&(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator^(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
bool operator>=(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &other) const
Greater than or equal operator for comparing sequence numbers.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator+(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &other) const
Operator defining addition of two sequence numbers.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > & operator=(NUMERIC_TYPE value)
Constructs a SequenceNumber from an assignment of given value.
SequenceNumber(SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > const &value)
Constructs a SequenceNumber from a copy.
Generic "sequence number" class.
SequenceNumber< uint16_t, int16_t > SequenceNumber16
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > & operator+=(SIGNED_TYPE value)
Plus equals operator.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator|(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator%(const SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > &b) const
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator++()
Prefix increment operator.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator~() const
friend std::istream & operator>>(std::istream &is, const SequenceNumber< NUMERIC_TYPE2, SIGNED_TYPE2 > &val)
For loading sequence number from input streams.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator--()
Prefix decrement operator.
SequenceNumber(NUMERIC_TYPE value)
Constructs a SequenceNumber with the given value.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > & operator-=(SIGNED_TYPE value)
Minus equals operator.
SequenceNumber< NUMERIC_TYPE, SIGNED_TYPE > operator-(SIGNED_TYPE delta) const
Subtraction operator for subtracting numeric value from sequence number.