#pragma once #include "platform/location.hpp" #include "std/chrono.hpp" #include "std/deque.hpp" #include "std/limits.hpp" #include "std/utility.hpp" #include "std/vector.hpp" class GpsTrackCollection final { public: static size_t const kInvalidId; // = numeric_limits::max(); using TItem = location::GpsTrackInfo; /// Constructor /// @param maxSize - max number of items in collection /// @param duration - duration in hours GpsTrackCollection(size_t maxSize, hours duration); /// Adds new point in the collection. /// @param item - item to be added. /// @param evictedIds - output, which contains range of identifiers evicted items or /// pair(kInvalidId,kInvalidId) if nothing was removed /// @returns the item unique identifier or kInvalidId if point has incorrect time. size_t Add(TItem const & item, pair & evictedIds); /// Adds set of new points in the collection. /// @param items - set of items to be added. /// @param evictedIds - output, which contains range of identifiers evicted items or /// pair(kInvalidId,kInvalidId) if nothing was removed /// @returns range of identifiers of added items or pair(kInvalidId,kInvalidId) if nothing was added /// @note items which does not conform to timestamp sequence, is not added. pair Add(vector const & items, pair & evictedIds); /// Get current duration in hours /// @returns current duration in hours hours GetDuration() const; /// Sets duration in hours. /// @param duration - new duration value /// @return range of item identifiers, which were removed or /// pair(kInvalidId,kInvalidId) if nothing was removed pair SetDuration(hours duration); /// Removes all points from the collection. /// @param resetIds - if it is set to true, then new identifiers will start from 0, /// otherwise new identifiers will continue from returned value res.second + 1 /// @return range of item identifiers, which were removed or /// pair(kInvalidId,kInvalidId) if nothing was removed pair Clear(bool resetIds = true); /// Returns true if collection is empty, otherwise returns false. bool IsEmpty() const; /// Returns number of items in the collection size_t GetSize() const; /// Returns range of timestamps of collection, where res.first is lower bound and /// res.second is upper bound. If collection is empty, then returns pair(0, 0). pair GetTimestampRange() const; /// Returns max size of collection size_t GetMaxSize() const; /// Enumerates items in the collection. /// @param f - callable object, which is called with params - item and item id, /// if f returns false, then enumeration is stopped. /// @param pos - position index to start enumeration template void ForEach(F && f, size_t pos = 0) const { if (pos >= m_items.size()) return; auto i = m_items.cbegin() + pos, iend = m_items.cend(); size_t id = m_lastId - m_items.size() + pos; for (; i != iend; ++i, ++id) { TItem const & item = *i; size_t const itemId = id; if (!f(item, itemId)) break; } } private: // Removes items in range [m_items.begin(), i) and returnd // range of identifiers of removed items pair RemoveUntil(deque::iterator i); // Removes items extra by timestamp and max size pair RemoveExtraItems(); size_t const m_maxSize; hours m_duration; deque m_items; // asc. sorted by timestamp size_t m_lastId; };