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;
125 size_type
size()
const {
return m_history.size(); }
131 bool empty()
const {
return m_history.empty(); }
133 timestamp_type
const &oldest_timestamp()
const {
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;
142 value_type
const &oldest()
const {
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;
166 value_type
const &newest()
const {
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(); }
223 return std::upper_bound(begin(), end(), tv,
comparator());
229 return std::lower_bound(begin(), end(), tv,
comparator());
238 nonconst_iterator nc_upper_bound(timestamp_type
const &tv) {
239 return std::upper_bound(ncbegin(), ncend(), tv,
comparator());
247 nonconst_iterator nc_lower_bound(timestamp_type
const &tv) {
248 return std::lower_bound(ncbegin(), ncend(), tv,
comparator());
280 size_type
pop_before(timestamp_type
const &tv) {
284 auto count = size_type{0};
285 while (!
empty() && oldest_timestamp() < tv) {
292 size_type
pop_before(timestamp_type
const &tv) {
299 auto lastIt = nc_lower_bound(tv);
300 if (ncend() == lastIt) {
309 auto count = std::distance(ncbegin(), lastIt);
310 m_history.erase(ncbegin(), lastIt);
320 size_type
pop_after(timestamp_type
const &tv) {
321 auto count = size_type{0};
329 size_type
pop_after(timestamp_type
const &tv) {
336 auto firstIt = nc_upper_bound(tv);
337 if (ncend() == firstIt) {
341 auto count = std::distance(firstIt, ncend());
342 m_history.erase(firstIt, ncend());
351 value_type
const &value) {
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;
372 using history::HistoryContainer;
376 #endif // INCLUDED_HistoryContainer_h_GUID_7CD22B1E_6EAC_49BF_F9FB_030C4BE3FA54
bool is_valid_to_push_newest(timestamp_type const &tv)
bool is_strictly_newest(timestamp_type const &tv) const
bool empty() const
Gets whether history is empty or not.
size_type size() const
Get number of entries in history.
size_type pop_after(timestamp_type const &tv)
const_iterator closest_not_newer(timestamp_type const &tv) const
::OSVR_TimeValue TimeValue
C++-friendly typedef for the OSVR_TimeValue structure.
const_iterator lower_bound(timestamp_type const &tv) const
const_iterator upper_bound(timestamp_type const &tv) const
size_type pop_before(timestamp_type const &tv)
void push_newest(osvr::util::time::TimeValue const &tv, value_type const &value)
Header providing a C++ wrapper around TimeValueC.h.
static const bool AllowDuplicateTimes
size_type highWaterMark() const
Get the maximum number of entries ever recorded.
bool is_as_new_as_newest(timestamp_type const &tv) const
timestamp_type const & newest_timestamp() const
subset_range_type get_range_newer_than(timestamp_type const &tv) const
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
static comparator_type comparator()
HistorySubsetRange(iterator begin_, iterator end_)