1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/utils/common.h"
10 #include "td/utils/Span.h"
11 
12 #include <utility>
13 
14 namespace td {
15 
16 template <class T>
17 class VectorQueue {
18  public:
19   template <class S>
push(S && s)20   void push(S &&s) {
21     vector_.emplace_back(std::forward<S>(s));
22   }
23 
24   template <class... Args>
emplace(Args &&...args)25   void emplace(Args &&... args) {
26     vector_.emplace_back(std::forward<Args>(args)...);
27   }
28 
pop()29   T pop() {
30     try_shrink();
31     return std::move(vector_[read_pos_++]);
32   }
33 
pop_n(size_t n)34   void pop_n(size_t n) {
35     read_pos_ += n;
36     try_shrink();
37   }
38 
front()39   const T &front() const {
40     return vector_[read_pos_];
41   }
front()42   T &front() {
43     return vector_[read_pos_];
44   }
45 
back()46   const T &back() const {
47     return vector_.back();
48   }
back()49   T &back() {
50     return vector_.back();
51   }
52 
empty()53   bool empty() const {
54     return size() == 0;
55   }
56 
size()57   size_t size() const {
58     return vector_.size() - read_pos_;
59   }
60 
data()61   const T *data() const {
62     return vector_.data() + read_pos_;
63   }
data()64   T *data() {
65     return vector_.data() + read_pos_;
66   }
67 
as_span()68   Span<T> as_span() const {
69     return {data(), size()};
70   }
as_mutable_span()71   MutableSpan<T> as_mutable_span() {
72     return {vector_.data() + read_pos_, size()};
73   }
74 
75  private:
76   vector<T> vector_;
77   size_t read_pos_{0};
78 
try_shrink()79   void try_shrink() {
80     if (read_pos_ * 2 > vector_.size() && read_pos_ > 4) {
81       vector_.erase(vector_.begin(), vector_.begin() + read_pos_);
82       read_pos_ = 0;
83     }
84   }
85 };
86 
87 }  // namespace td
88