//Circular Queue in C++ #include #include #include #include /* requires -std=c++20 */ #include #include /* requires -std=c++23 for monadic map/bind */ using namespace std; #define None std::nullopt template requires std::copyable && std::destructible && (CAP > 2) struct CircularQueue { private: vector> Q; size_t front{0}; // size_t equiv to usize in rust size_t size{0}; size_t index(size_t i) { //converts logical index to actual index return (front + i) % Q.size(); }//index public: CircularQueue() { //Q = vector(CAP,None); // doesn't compile but should Q.reserve(CAP); for(int i=0;i> Q2(newcap,None); for(int i=0;i>(Q[index(i)], Q2[i]); Q = move(Q2); front = 0; } void push_back(T x) { if (size>=Q.size()) resize(); Q[index(size)] = move(x); // don't need to place it in optional object size+=1; }//push_back void push_front(T x) { if (size>=Q.size()) resize(); front = (front + Q.size() - 1) % Q.size(); // wrap around to the left Q[front] = move(x); size += 1; } optional pop_back() { if (size==0) return None; // std::None // optional answer = move( Q[index(size-1)] ); // not possible in rust optional answer = None; std::swap>(answer, Q[index(size-1)]); size--; return answer; }//pop_back optional pop_front() { if (size==0) return None; // std::None optional answer = None; std::swap>(answer, Q[index(0)]); front = (front + 1) % Q.size(); // wraps front to right size--; return answer; }//pop_back T& operator [] (size_t i) { // zero-overhead access return Q[index(i)].value(); // could crash } optional operator () (size_t i) { // checked access for dweebs if (i f) { for(int i=0;i in C++ - references not allowed for optional }; int main() { CircularQueue cq; for(int i=0;i<100;i++) { cq.push_back(i*2); cq.push_front(i*2 + 1); } for(int i=0;i<50;i++) { cq.pop_front(); cq.pop_back(); } cq.mapfun([](int& x){cout << x << " "; }); cout << "\nsize: " << cq.len() << endl; cout << "capacity: " << cq.current_capacity() << endl; cout << cq(5).value() << endl; cq[5] = 99999; cout << cq(5).value() << endl; return 0; }