A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
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>
52
class
SequenceNumber
53
{
54
public
:
55
SequenceNumber
()
56
:
m_value
(0)
57
{}
58
63
explicit
SequenceNumber
(NUMERIC_TYPE value)
64
:
m_value
(value)
65
{}
66
67
// copy contructor
68
SequenceNumber
(
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
const
&value)
69
:
m_value
(value.
m_value
)
70
{}
71
72
// assignment from a plain number
73
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator=
(NUMERIC_TYPE value)
74
{
75
m_value
= value;
76
return
*
this
;
77
}
78
79
// assignment from a sequence number
80
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator=
(
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
const
&value)
81
{
82
m_value
= value.
m_value
;
83
return
*
this
;
84
}
85
86
#if 0
87
// a SequenceNumber implicitly converts to a plain number, but not the other way around
88
operator
NUMERIC_TYPE ()
const
89
{
90
return
m_value
;
91
}
92
#endif
93
98
NUMERIC_TYPE
GetValue
()
const
99
{
100
return
m_value
;
101
}
102
103
// prefix ++
104
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator++
()
105
{
106
m_value
++;
107
return
*
this
;
108
}
109
110
// postfix ++
111
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator++
(
int
)
112
{
113
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
retval (
m_value
);
114
m_value
++;
115
return
retval;
116
}
117
118
// prefix --
119
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator--
()
120
{
121
m_value
--;
122
return
*
this
;
123
}
124
125
// postfix --
126
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator--
(
int
)
127
{
128
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
retval (
m_value
);
129
m_value
--;
130
return
retval;
131
}
132
133
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator+=
(SIGNED_TYPE value)
134
{
135
m_value
+= value;
136
return
*
this
;
137
}
138
139
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator-=
(SIGNED_TYPE value)
140
{
141
m_value
-= value;
142
return
*
this
;
143
}
144
145
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator +
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
146
{
147
return
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
(
m_value
+ other.
m_value
);
148
}
149
150
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator +
(SIGNED_TYPE delta)
const
151
{
152
return
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
(
m_value
+ delta);
153
}
154
155
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator -
(SIGNED_TYPE delta)
const
156
{
157
return
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
(
m_value
- delta);
158
}
159
160
SIGNED_TYPE
operator -
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
161
{
162
static
const
NUMERIC_TYPE maxValue = std::numeric_limits<NUMERIC_TYPE>::max ();
163
static
const
NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
164
if
(
m_value
> other.
m_value
)
165
{
166
NUMERIC_TYPE diff =
m_value
- other.
m_value
;
167
if
(diff < halfMaxValue)
168
{
169
return
static_cast<
SIGNED_TYPE
>
(diff);
170
}
171
else
172
{
173
// |------------|------------|
174
// ==== ===
175
// ^ ^
176
// other.m_value m_value
177
return
-(
static_cast<
SIGNED_TYPE
>
(maxValue -
m_value
+ 1 + other.
m_value
));
178
}
179
}
180
else
181
{
182
NUMERIC_TYPE diff = other.
m_value
-
m_value
;
183
if
(diff < halfMaxValue)
184
{
185
// |------------|------------|
186
// ========
187
// ^ ^
188
// m_value other.m_value
189
return
-(
static_cast<
SIGNED_TYPE
>
(diff));
190
}
191
else
192
{
193
// |------------|------------|
194
// ==== ===
195
// ^ ^
196
// m_value other.m_value
197
return
static_cast<
SIGNED_TYPE
>
(maxValue - other.
m_value
+ 1 +
m_value
);
198
}
199
}
200
}
201
202
203
// Here is the critical part, how the comparison is made taking into
204
// account wrap-around. From RFC 3626:
205
//
206
// The sequence number S1 is said to be "greater than" the sequence
207
// number S2 if:
208
//
209
// S1 > S2 AND S1 - S2 <= MAXVALUE/2 OR
210
//
211
// S2 > S1 AND S2 - S1 > MAXVALUE/2
212
bool
operator >
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
213
{
214
static
const
NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
215
216
return
(((
m_value
> other.
m_value
) && (
m_value
- other.
m_value
) <= halfMaxValue)
217
|| ((other.
m_value
>
m_value
) && (other.
m_value
-
m_value
) > halfMaxValue));
218
}
219
220
bool
operator ==
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
221
{
222
return
(
m_value
== other.
m_value
);
223
}
224
225
bool
operator !=
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
226
{
227
return
(
m_value
!= other.
m_value
);
228
}
229
230
bool
operator <= (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other)
const
231
{
232
return
(!this->
operator
> (other));
233
}
234
235
bool
operator >=
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&other)
const
236
{
237
return
(this->
operator
> (other) || this->
operator
== (other));
238
}
239
240
bool
operator < (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &other)
const
241
{
242
return
!this->
operator>
(other) &&
m_value
!= other.m_value;
243
}
244
245
246
template
<
typename
NUMERIC_TYPE2,
typename
SIGNED_TYPE2>
247
friend
std::ostream & operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
248
249
template
<
typename
NUMERIC_TYPE2,
typename
SIGNED_TYPE2>
250
friend
std::istream &
operator >>
(std::istream &is,
const
SequenceNumber<NUMERIC_TYPE2, SIGNED_TYPE2>
&val);
251
252
private
:
// unimplemented operators
253
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator+=
(
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
const
&value);
254
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&
operator-=
(
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
const
&value);
255
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator*
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
256
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator/
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
257
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator%
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
258
bool
operator !
()
const
;
259
bool
operator &&
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
260
bool
operator ||
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
261
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator~
()
const
;
262
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator&
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
263
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator|
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
264
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator^
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
265
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator<< (const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>& b)
const
;
266
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
operator>>
(
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
& b)
const
;
267
int
operator*
();
268
//SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>* operator& ();
269
270
private
:
271
NUMERIC_TYPE
m_value
;
272
};
273
274
275
template
<
typename
NUMERIC_TYPE,
typename
SIGNED_TYPE>
276
std::ostream &
277
operator<< (std::ostream& os, const SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE> &val)
278
{
279
os << val.m_value;
280
return
os;
281
}
282
283
template
<
typename
NUMERIC_TYPE,
typename
SIGNED_TYPE>
284
std::istream &
operator >>
(std::istream &is,
const
SequenceNumber<NUMERIC_TYPE, SIGNED_TYPE>
&val)
285
{
286
is >> val.
m_value
;
287
return
is;
288
}
289
290
291
typedef
SequenceNumber<uint32_t, int32_t>
SequenceNumber32
;
292
typedef
SequenceNumber<uint16_t, int16_t>
SequenceNumber16
;
293
294
}
// namespace ns3
295
296
#endif
/* NS3_SEQ_NUM_H */
297
298
src
network
utils
sequence-number.h
Generated on Tue Nov 13 2012 10:32:21 for ns-3 by
1.8.1.2