25 #ifndef INCLUDED_HistoryContainer_h_GUID_7CD22B1E_6EAC_49BF_F9FB_030C4BE3FA54 26 #define INCLUDED_HistoryContainer_h_GUID_7CD22B1E_6EAC_49BF_F9FB_030C4BE3FA54 46 template <
typename ValueType>
47 using full_value_type = std::pair<timestamp, ValueType>;
49 template <
typename ValueType>
50 using inner_container_type = std::deque<full_value_type<ValueType>>;
52 template <
typename ValueType>
53 using container_size_type =
54 typename inner_container_type<ValueType>::size_type;
56 template <
typename ValueType>
58 typename inner_container_type<ValueType>::const_iterator;
60 template <
typename ValueType>
61 using nonconst_iterator =
62 typename inner_container_type<ValueType>::iterator;
69 full_value_type<ValueType>
const &rhs) {
70 return lhs < rhs.first;
73 bool operator()(full_value_type<ValueType>
const &lhs,
75 return lhs.first < rhs;
83 using iterator = detail::iterator<ValueType>;
84 using const_iterator = detail::iterator<ValueType>;
86 : m_begin(begin_), m_end(end_) {
90 iterator begin()
const {
return m_begin; }
91 const_iterator cbegin()
const {
return m_begin; }
92 iterator end()
const {
return m_end; }
93 const_iterator cend()
const {
return m_end; }
103 template <
typename ValueType,
bool AllowDuplicateTimes_ = true>
106 using value_type = ValueType;
109 using full_value_type = detail::full_value_type<value_type>;
110 using container_type = detail::inner_container_type<value_type>;
111 using size_type = detail::container_size_type<value_type>;
113 using iterator = detail::iterator<value_type>;
114 using const_iterator = iterator;
122 static const bool AllowDuplicateTimes = AllowDuplicateTimes_;
125 size_type
size()
const {
return m_history.size(); }
131 bool empty()
const {
return m_history.empty(); }
135 throw std::logic_error(
136 "Can't get time of oldest entry in an " 137 "empty history container!");
139 return m_history.front().first;
144 throw std::logic_error(
"Can't get oldest entry in an " 145 "empty history container!");
147 return m_history.front().first;
158 throw std::logic_error(
159 "Can't get time of newest entry in an " 160 "empty history container!");
163 return m_history.back().first;
168 throw std::logic_error(
"Can't get newest entry in an " 169 "empty history container!");
172 return m_history.back().second;
179 void pop_oldest() { m_history.pop_front(); }
180 void pop_newest() { m_history.pop_back(); }
182 const_iterator begin()
const {
return m_history.cbegin(); }
183 const_iterator cbegin()
const {
return m_history.cbegin(); }
184 const_iterator end()
const {
return m_history.cend(); }
185 const_iterator cend()
const {
return m_history.cend(); }
187 void clear() { m_history.clear(); }
192 using nonconst_iterator = detail::nonconst_iterator<value_type>;
194 nonconst_iterator ncbegin() {
return m_history.begin(); }
195 nonconst_iterator ncend() {
return m_history.end(); }
202 return empty() || newest_timestamp() < tv;
209 return empty() || !(tv < newest_timestamp());
216 return empty() || tv > newest_timestamp() ||
217 (AllowDuplicateTimes && newest_timestamp() == tv);
223 return std::upper_bound(begin(), end(), tv, comparator());
229 return std::lower_bound(begin(), end(), tv, comparator());
239 return std::upper_bound(ncbegin(), ncend(), tv, comparator());
248 return std::lower_bound(ncbegin(), ncend(), tv, comparator());
261 auto it = upper_bound(tv);
284 auto count = size_type{0};
285 while (!empty() && oldest_timestamp() < tv) {
299 auto lastIt = nc_lower_bound(tv);
300 if (ncend() == lastIt) {
304 if (is_strictly_newest(tv)) {
309 auto count = std::distance(ncbegin(), lastIt);
310 m_history.erase(ncbegin(), lastIt);
321 auto count = size_type{0};
322 while (!empty() && tv < newest_timestamp()) {
336 auto firstIt = nc_upper_bound(tv);
337 if (ncend() == firstIt) {
341 auto count = std::distance(firstIt, ncend());
342 m_history.erase(firstIt, ncend());
352 if (is_valid_to_push_newest(tv)) {
353 m_history.emplace_back(tv, value);
354 updateSizeHighWaterMark();
356 throw std::logic_error(
357 "Can't push_newest a value that's older " 358 "than the most recent value!");
363 void updateSizeHighWaterMark() {
364 m_sizeHighWaterMark =
365 (std::max)(m_history.size(), m_sizeHighWaterMark);
367 container_type m_history;
368 size_type m_sizeHighWaterMark = 0;
376 #endif // INCLUDED_HistoryContainer_h_GUID_7CD22B1E_6EAC_49BF_F9FB_030C4BE3FA54 bool is_valid_to_push_newest(timestamp_type const &tv)
Returns true if the given timestamp meets the criteria of push_newest: strictly newest if AllowDuplic...
Definition: HistoryContainer.h:215
Comparison functor for std algorithms usage with HistoryContainer and related containers.
Definition: HistoryContainer.h:66
timestamp_type const & newest_timestamp() const
Returns the newest timestamp in the container.
Definition: HistoryContainer.h:156
Convenience class to refer to a subset of the range of history, primarily for use in range-for loops...
Definition: HistoryContainer.h:81
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
const_iterator lower_bound(timestamp_type const &tv) const
Wrapper around std::lower_bound: returns iterator to first element with timestamp equal or newer than...
Definition: HistoryContainer.h:228
Stores values over time, in chronological order, in a deque for two-ended access. ...
Definition: HistoryContainer.h:104
::OSVR_TimeValue TimeValue
C++-friendly typedef for the OSVR_TimeValue structure.
Definition: TimeValue.h:48
size_type size() const
Get number of entries in history.
Definition: HistoryContainer.h:125
A safe way to store and transport an orientation measurement or an angular velocity measurement witho...
Definition: CannedIMUMeasurement.h:44
Definition: newuoa.h:1888
void push_newest(osvr::util::time::TimeValue const &tv, value_type const &value)
Adds a new value to history.
Definition: HistoryContainer.h:350
Header providing a C++ wrapper around TimeValueC.h.
bool is_strictly_newest(timestamp_type const &tv) const
Returns true if the given timestamp is strictly newer than the newest timestamp in the container...
Definition: HistoryContainer.h:201
bool empty() const
Gets whether history is empty or not.
Definition: HistoryContainer.h:131
const_iterator upper_bound(timestamp_type const &tv) const
Wrapper around std::upper_bound: returns iterator to first element newer than timestamp given or end(...
Definition: HistoryContainer.h:222
bool is_as_new_as_newest(timestamp_type const &tv) const
Returns true if the given timestamp is no older than the newest timestamp in the container, or if the container is empty (thus making the timestamp trivially newest)
Definition: HistoryContainer.h:208
subset_range_type get_range_newer_than(timestamp_type const &tv) const
Returns a proxy object that can be treated as a range in a range-for loop to iterate over all element...
Definition: HistoryContainer.h:275
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
size_type highWaterMark() const
Get the maximum number of entries ever recorded.
Definition: HistoryContainer.h:128
static comparator_type comparator()
Returns a comparison functor (comparing timestamps) for use with standard algorithms like lower_bound...
Definition: HistoryContainer.h:177
const_iterator closest_not_newer(timestamp_type const &tv) const
Return an iterator to the newest, last pair of timestamp and value that is not newer than the given t...
Definition: HistoryContainer.h:255
HistorySubsetRange(iterator begin_, iterator end_)
Definition: HistoryContainer.h:85