RflySimSDK v3.08
RflySimSDK说明文档
载入中...
搜索中...
未找到
vrpn_EndpointContainer.h
浏览该文件的文档.
1/** @file
2 @brief Header
3
4 @date 2015
5
6 @author
7 Ryan Pavlik
8 Sensics, Inc.
9 <http://sensics.com/osvr>
10*/
11
12// Copyright 2015 Sensics, Inc.
13// Distributed under the Boost Software License, Version 1.0.
14// (See accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16
17#ifndef INCLUDED_vrpn_EndpointContainer_h_GUID_DB073DE8_5BBC_46BF_255B_71264D47A639
18#define INCLUDED_vrpn_EndpointContainer_h_GUID_DB073DE8_5BBC_46BF_255B_71264D47A639
19
20// Internal Includes
21#include "vrpn_Types.h"
22#include "vrpn_Configure.h"
23#include "vrpn_Shared.h"
24
25#include "vrpn_Assert.h"
26
27// Library/third-party includes
28// - none
29
30// Standard includes
31#include <stddef.h> // for NULL
32
33class VRPN_API vrpn_Endpoint;
34class VRPN_API vrpn_Endpoint_IP;
35
36namespace vrpn {
37
38 class EndpointIterator;
39
40 /** @brief Container for endpoints, held by pointer.
41
42 To check if we have room, use this: `if (d_endpoints.full()) {}` instead of
43 the old code looking like this: `if (which_end >= vrpn_MAX_ENDPOINTS)`
44
45 Usage example for iteration:
46
47 ~~~
48 for (vrpn::EndpointIterator it = d_endpoints.begin(), e = d_endpoints.end();
49 it != e; ++it) {
50 it->pack_type_description(which)
51 }
52 ~~~
53
54 */
56 public:
57 typedef vrpn_Endpoint_IP T;
58 typedef T &reference;
59 typedef T *pointer;
61
62 private:
64
65 public:
66 typedef container_type::size_type size_type;
69
70 /// @brief Constructor of empty container.
72
73 /// @brief Destructor - includes a call to clear()
75
76 /// @brief Tells each held endpoint in turn to drop the connection then
77 /// deletes it
78 void clear();
79
80 /// @brief Shorthand for get_by_index(0)
81 pointer front() const { return get_by_index(0); }
82
83 /// @brief Given the result of an endpoint allocator, if it's non-NULL,
84 /// takes ownership of it.
85 /// @return the input pointer
86 template <typename T> T *acquire(T *endpoint)
87 {
88 acquire_(endpoint);
89 return endpoint;
90 }
91
92 /// @brief Goes through and gets rid of the NULL entries.
93 void compact();
94
95 /// @brief Can we no longer accommodate a new endpoint?
96 bool full() const;
97
98 /// @brief Checks to see if an index is both in-range and pointing to a
99 /// still-extant object
100 bool is_valid(size_type i) const;
101
102 /// @brief Destroys the contained endpoint by address.
103 /// @return true if there was something for us to delete
104 bool destroy(base_pointer endpoint);
105
106 pointer get_by_index(size_type i) const;
107
108 /// @brief Get size of container including NULL elements that haven't
109 /// been compacted yet.
110 size_type get_full_container_size() const;
111
112 /// @brief Get an iterator to the beginning that skips nulls.
113 /// Invalidated by compacting.
114 iterator begin() const;
115
116 /// @brief Get an iterator suitable only for testing to see if we're
117 /// "done"
118 iterator end() const;
119
120 private:
121 /// @name Internal raw iterators and methods
122 /// @{
123 typedef container_type::iterator raw_iterator;
124 typedef container_type::const_iterator raw_const_iterator;
125 raw_iterator begin_() { return container_.begin(); }
126 raw_const_iterator begin_() const { return container_.begin(); }
127 raw_iterator end_() { return container_.end(); }
128 raw_const_iterator end_() const { return container_.end(); }
129 // @}
130 /// @name Internal helper methods
131 /// @{
132 /// @brief Implementation of acquire for the stored pointer type.
133 void acquire_(pointer endpoint);
134 /// @brief Do actual compact once we've determined it's necessary.
135 void compact_();
136
137 /// @}
138 container_type container_;
139 bool needsCompact_;
140 };
141
142#define VRPN_ECITERATOR_ASSERT_INVARIANT() \
143 VRPN_ASSERT_MSG(valid() != equal_to_default_(), \
144 "Class invariant for EndpointIterator")
145
146 /// @brief An iterator that goes forward in an EndpointContainer skipping
147 /// the NULLs, that also acts a bit like a pointer/smart pointer (can treat
148 /// it as a vrpn_Endpoint *)
149 ///
150 /// Because we know at design time that it iterates through pointers,
151 /// we have pointer-related operator overloads that mean there's no need to
152 /// double-dereference.
153 ///
154 /// Fulfills the InputIterator concept:
155 /// http://en.cppreference.com/w/cpp/concept/InputIterator
156 ///
157 /// All end() iterators compare equal to each other and to the
158 /// default-constructed iterator. They are the only invalid iterators:
159 /// incrementing an iterator past the end makes it the same as the
160 /// default-constructed iterator.
161 ///
162 /// That is, for all EndpointIterators it, we enforce the class invariant
163 /// `it.valid() || (it == EndpointIterator())` (and that's actually an XOR)
165 public:
166 // typedef EndpointIteratorBase<ContainerType> type;
167 typedef EndpointIterator type;
168 typedef EndpointContainer const container_type;
169 typedef container_type::pointer pointer;
170 typedef container_type::reference reference;
171 typedef container_type::size_type size_type;
172
173 /// @brief Default constructor, equal to all other default-constructed
174 /// instances and all end()
176 : index_(0)
177 , container_(NULL)
178 {
179 VRPN_ASSERT_MSG(equal_to_default_(),
180 "Default constructed value should be equal to "
181 "default: verifies that 'equal_to_default_()' is "
182 "equivalent to '*this == EndpointIterator()'");
184 "Default constructed value should not be valid");
185 }
186
187 /// @brief Constructor with container, points to beginning of container.
188 EndpointIterator(container_type &container)
189 : index_(0)
190 , container_(&container)
191 {
192 // Advance index as required to maintain the class invariant.
193 skip_nulls_();
194 VRPN_ECITERATOR_ASSERT_INVARIANT();
195 }
196
197 /// @brief Constructor with container and raw index into container.
198 EndpointIterator(container_type &container, size_type index)
199 : index_(index)
200 , container_(&container)
201 {
202 // Advance index as required to maintain the class invariant.
203 skip_nulls_();
204 VRPN_ECITERATOR_ASSERT_INVARIANT();
205 }
206
207 /// @brief Does this iterator refer to a valid element?
208 ///
209 /// Class invariant: valid() || (*this == type())
210 /// That is, there is only one invalid value.
211 bool valid() const
212 {
213 return container_ && container_->is_valid(index_);
214 }
215
216 /// @brief Extract the pointer (NULL if iterator is invalid)
217 pointer get_pointer() const
218 {
219 // We can be a nullptr, so don't check VRPN_ECITERATOR_ASSERT_INVARIANT();
220 // Only need to condition on container validity: invalid indexes
221 // safely return null from get_raw_()
222 return container_ ? (get_raw_()) : NULL;
223 }
224
225 /// @brief Implicit conversion operator to pointer.
226 operator pointer() const
227 {
228 // We can be a nullptr, so don't check VRPN_ECITERATOR_ASSERT_INVARIANT();
229 return get_pointer();
230 }
231
232 /// @brief prefix ++ operator, increments (and skips any nulls)
234 {
235 /// Invariant might be invalid here, since the user might have just
236 /// deleted something.
237 if (equal_to_default_()) {
238 // Early out if we're already the end sentinel (default
239 // constructor value)
240 return *this;
241 }
242
243 // Increment until we either go out of bounds or get a non-null
244 // entry
245 index_++;
246 skip_nulls_();
247 VRPN_ECITERATOR_ASSERT_INVARIANT();
248 return *this;
249 }
250
251 /// @name Smart pointer idiom operators
252 /// @{
253 pointer operator->() const
254 {
255 VRPN_ECITERATOR_ASSERT_INVARIANT();
256 return get_pointer();
257 }
258
259 reference operator*() const
260 {
261 VRPN_ECITERATOR_ASSERT_INVARIANT();
262 return *get_raw_();
263 }
264 /// @}
265
266 /// @name Comparison operators, primarily for loop use
267 /// @{
268 bool operator==(type const &other) const
269 {
270 return (container_ == other.container_) && (index_ == other.index_);
271 }
272 bool operator!=(type const &other) const
273 {
274 return (container_ != other.container_) || (index_ != other.index_);
275 }
276 /// @}
277
278 private:
279 bool equal_to_default_() const
280 {
281 return (NULL == container_) && (index_ == 0);
282 }
283 void skip_nulls_()
284 {
285 while (index_in_bounds_() && (get_raw_() == NULL)) {
286 index_++;
287 }
288 // We may have run out of elements, so check the invariant
289 enforce_invariant_();
290 }
291 /// @brief Function to verify an iterator to enforce the class
292 /// invariant.
293 void enforce_invariant_()
294 {
295 if (!valid()) {
296 /// Assign from default-constructed iterator, to be the same as
297 /// end()
298 *this = type();
299 }
300 }
301
302 /// @brief get, without checking validity of container_ first!
303 ///
304 /// Note that the container handles cases where the index is out of
305 /// range by returning NULL, so that's safe.
306 pointer get_raw_() const { return container_->get_by_index(index_); }
307
308 /// @brief Helper to check index vs container bounds, without checking
309 /// validity of container_ first!
310 bool index_in_bounds_() const
311 {
312 return index_ < container_->get_full_container_size();
313 }
314
315 size_type index_;
316 container_type *container_;
317 };
318#undef VRPN_ECITERATOR_ASSERT_INVARIANT
319
320 // Inline Implementations //
321
322 inline bool
323 EndpointContainer::is_valid(EndpointContainer::size_type i) const
324 {
325 return (i < get_full_container_size()) && (NULL != container_[i]);
326 }
327
329 EndpointContainer::get_by_index(size_type i) const
330 {
331 if (!is_valid(i)) {
332 return NULL;
333 }
334 return container_[i];
335 }
336
337 inline EndpointContainer::size_type
339 {
340 return container_.size();
341 }
342
343 // making this condition inline so that it has minimal overhead if
344 // we don't actually need to perform a compaction.
346 {
347 if (needsCompact_) {
348 compact_();
349 }
350 }
351
353 {
354 return EndpointIterator(*this);
355 }
356
358 {
359 return EndpointIterator();
360 }
361
362} // namespace vrpn
363
364#endif // INCLUDED_vrpn_EndpointContainer_h_GUID_DB073DE8_5BBC_46BF_255B_71264D47A639
Container for endpoints, held by pointer.
定义 vrpn_EndpointContainer.h:55
void compact()
Goes through and gets rid of the NULL entries.
定义 vrpn_EndpointContainer.h:345
iterator end() const
Get an iterator suitable only for testing to see if we're "done"
定义 vrpn_EndpointContainer.h:357
EndpointContainer()
Constructor of empty container.
pointer front() const
Shorthand for get_by_index(0)
定义 vrpn_EndpointContainer.h:81
T * acquire(T *endpoint)
Given the result of an endpoint allocator, if it's non-NULL, takes ownership of it.
定义 vrpn_EndpointContainer.h:86
bool is_valid(size_type i) const
Checks to see if an index is both in-range and pointing to a still-extant object
定义 vrpn_EndpointContainer.h:323
size_type get_full_container_size() const
Get size of container including NULL elements that haven't been compacted yet.
定义 vrpn_EndpointContainer.h:338
bool full() const
Can we no longer accommodate a new endpoint?
bool destroy(base_pointer endpoint)
Destroys the contained endpoint by address.
void clear()
Tells each held endpoint in turn to drop the connection then deletes it
iterator begin() const
Get an iterator to the beginning that skips nulls. Invalidated by compacting.
定义 vrpn_EndpointContainer.h:352
~EndpointContainer()
Destructor - includes a call to clear()
An iterator that goes forward in an EndpointContainer skipping the NULLs, that also acts a bit like a...
定义 vrpn_EndpointContainer.h:164
bool valid() const
Does this iterator refer to a valid element?
定义 vrpn_EndpointContainer.h:211
EndpointIterator(container_type &container)
Constructor with container, points to beginning of container.
定义 vrpn_EndpointContainer.h:188
EndpointIterator(container_type &container, size_type index)
Constructor with container and raw index into container.
定义 vrpn_EndpointContainer.h:198
EndpointIterator()
Default constructor, equal to all other default-constructed instances and all end()
定义 vrpn_EndpointContainer.h:175
pointer get_pointer() const
Extract the pointer (NULL if iterator is invalid)
定义 vrpn_EndpointContainer.h:217
type & operator++()
prefix ++ operator, increments (and skips any nulls)
定义 vrpn_EndpointContainer.h:233
Encapsulation of the data and methods for a single IP-based connection to take care of one part of ma...
定义 vrpn_Connection.h:423
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
定义 vrpn_Connection.h:254
定义 vrpn_Shared.h:552
Header for assert macros.
#define VRPN_ASSERT_MSG(expr, msg)
Like VRPN_ASSERT(expr) but allows specification of a message to be included in the case of a failed a...
定义 vrpn_Assert.h:153