vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_EndpointContainer.h
Go to the documentation of this file.
1
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
24#include "vrpn_Assert.h"
25
26// Library/third-party includes
27// - none
28
29// Standard includes
30#include <vector>
31#include <stddef.h> // for NULL
32
35
36namespace vrpn {
37
38 class EndpointIterator;
39
56 public:
58 typedef T &reference;
59 typedef T *pointer;
61
62 private:
63 typedef std::vector<pointer> container_type;
64
65 public:
66 typedef container_type::size_type size_type;
69
72
75
78 void clear();
79
81 pointer front() const { return get_by_index(0); }
82
86 template <typename T> T *acquire(T *endpoint)
87 {
88 acquire_(endpoint);
89 return endpoint;
90 }
91
93 void compact();
94
96 bool full() const;
97
100 bool is_valid(size_type i) const;
101
104 bool destroy(base_pointer endpoint);
105
107
111
114 iterator begin() const;
115
118 iterator end() const;
119
120 private:
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 // @}
133 void acquire_(pointer endpoint);
135 void compact_();
136
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
165 public:
166 // typedef EndpointIteratorBase<ContainerType> type;
169 typedef container_type::pointer pointer;
170 typedef container_type::reference reference;
171 typedef container_type::size_type size_type;
172
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
189 : index_(0)
190 , container_(&container)
191 {
192 // Advance index as required to maintain the class invariant.
193 skip_nulls_();
195 }
196
199 : index_(index)
200 , container_(&container)
201 {
202 // Advance index as required to maintain the class invariant.
203 skip_nulls_();
205 }
206
211 bool valid() const
212 {
213 return container_ && container_->is_valid(index_);
214 }
215
218 {
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
226 operator pointer() const
227 {
229 return get_pointer();
230 }
231
234 {
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_();
248 return *this;
249 }
250
254 {
256 return get_pointer();
257 }
258
260 {
262 return *get_raw_();
263 }
265
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 }
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 }
293 void enforce_invariant_()
294 {
295 if (!valid()) {
298 *this = type();
299 }
300 }
301
306 pointer get_raw_() const { return container_->get_by_index(index_); }
307
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
324 {
325 return (i < get_full_container_size()) && (NULL != container_[i]);
326 }
327
330 {
331 if (!is_valid(i)) {
332 return NULL;
333 }
334 return container_[i];
335 }
336
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.
size_type get_full_container_size() const
Get size of container including NULL elements that haven't been compacted yet.
pointer front() const
Shorthand for get_by_index(0)
bool full() const
Can we no longer accommodate a new endpoint?
iterator end() const
Get an iterator suitable only for testing to see if we're "done".
bool is_valid(size_type i) const
Checks to see if an index is both in-range and pointing to a still-extant object.
pointer get_by_index(size_type i) const
T * acquire(T *endpoint)
Given the result of an endpoint allocator, if it's non-NULL, takes ownership of it.
void compact()
Goes through and gets rid of the NULL entries.
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.
~EndpointContainer()
Destructor - includes a call to clear()
EndpointContainer()
Constructor of empty container.
container_type::size_type size_type
iterator begin() const
Get an iterator to the beginning that skips nulls. Invalidated by compacting.
An iterator that goes forward in an EndpointContainer skipping the NULLs, that also acts a bit like a...
bool valid() const
Does this iterator refer to a valid element?
container_type::reference reference
bool operator==(type const &other) const
EndpointIterator(container_type &container, size_type index)
Constructor with container and raw index into container.
type & operator++()
prefix ++ operator, increments (and skips any nulls)
container_type::pointer pointer
EndpointIterator(container_type &container)
Constructor with container, points to beginning of container.
bool operator!=(type const &other) const
EndpointContainer const container_type
EndpointIterator()
Default constructor, equal to all other default-constructed instances and all end()
pointer get_pointer() const
Extract the pointer (NULL if iterator is invalid)
container_type::size_type size_type
Encapsulation of the data and methods for a single IP-based connection to take care of one part of ma...
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
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...
#define VRPN_API
#define VRPN_ECITERATOR_ASSERT_INVARIANT()