/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once template class AbstractSparseIds { public: using Id = typename IdsContainer::value_type; AbstractSparseIds() = default; AbstractSparseIds( const IdsContainer &ids, std::optional fullCount, std::optional skippedBefore, std::optional skippedAfter) : _ids(ids) , _fullCount(fullCount) , _skippedBefore(skippedBefore) , _skippedAfter(skippedAfter) { } std::optional fullCount() const { return _fullCount; } std::optional skippedBefore() const { return _skippedBefore; } std::optional skippedAfter() const { return _skippedAfter; } std::optional indexOf(Id id) const { const auto it = ranges::find(_ids, id); if (it != _ids.end()) { return (it - _ids.begin()); } return std::nullopt; } int size() const { return _ids.size(); } Id operator[](int index) const { Expects(index >= 0 && index < size()); return *(_ids.begin() + index); } std::optional distance(Id a, Id b) const { if (const auto i = indexOf(a)) { if (const auto j = indexOf(b)) { return *j - *i; } } return std::nullopt; } std::optional nearest(Id id) const { if (const auto it = ranges::lower_bound(_ids, id); it != _ids.end()) { return *it; } else if (_ids.empty()) { return std::nullopt; } return _ids.back(); } void reverse() { ranges::reverse(_ids); std::swap(_skippedBefore, _skippedAfter); } private: IdsContainer _ids; std::optional _fullCount; std::optional _skippedBefore; std::optional _skippedAfter; };