|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.8 ! root 7: //
! 8: // 固定長キュー
! 9: //
! 10:
1.1.1.3 root 11: #pragma once
12:
1.1 root 13: #include "header.h"
14: #include <vector>
15:
16: // 固定長キュー
17: // std::queue では出来ないことがいくつかあるので仕方なく車輪の再開発。
1.1.1.6 root 18: // std::vector を親に使っているが empty() と Empty() の動作が異なるなど
19: // しているため public にせず private 継承している。
1.1 root 20: //
21: // T 型で上限 capacity 個のキュー。
22: // スレッドセーフではない。
23: template <typename T, int capacity>
1.1.1.7 root 24: class FixedQueue : private std::vector<T>
1.1 root 25: {
1.1.1.6 root 26: using inherited = std::vector<T>;
1.1 root 27: public:
28: // コンストラクタ
29: FixedQueue()
1.1.1.6 root 30: : inherited(capacity)
1.1 root 31: {
32: }
33:
34: // デストラクタ
35: virtual ~FixedQueue() {
36: }
37:
38: // 空にする
39: void Clear() {
40: start = 0;
41: length = 0;
42: }
43:
1.1.1.6 root 44: // 空きがあれば追加して true を返す。
45: // 空きがなければ何もせず false を返す。
1.1.1.8 ! root 46: bool Enqueue(const T& val) {
1.1.1.6 root 47: if (IsFull()) {
48: return false;
49: } else {
50: (*this)[(start + length) % capacity] = val;
1.1 root 51: length++;
52: return true;
53: }
54: }
55:
1.1.1.6 root 56: // 空きがなければ古いのを捨てて追加する。
1.1.1.8 ! root 57: void EnqueueForce(const T& val) {
1.1.1.6 root 58: if (IsFull()) {
59: Dequeue();
60: }
61: Enqueue(val);
62: }
63:
1.1 root 64: // 取り出し
65: // 要素が1つ以上あれば *outp に取り出して true を返す。
66: // キューが空なら false を返す。
67: bool Dequeue(T *outp) {
68: if (length > 0) {
69: // 1つ以上あれば取り出し
1.1.1.6 root 70: *outp = (*this)[start];
1.1 root 71: start = (start + 1) % capacity;
72: length--;
73: return true;
74: } else {
75: return false;
76: }
77: }
78:
79: // 取り出し
80: // 先頭の要素を取り出して返す。
1.1.1.6 root 81: // キューが空の時に呼ぶと T() が返る。
1.1 root 82: T Dequeue() {
83: if (length > 0) {
1.1.1.6 root 84: T val = (*this)[start];
1.1 root 85: start = (start + 1) % capacity;
86: length--;
1.1.1.6 root 87: return val;
88: } else {
89: return T();
1.1 root 90: }
91: }
92:
93: // 現在の要素数を取得
94: uint Length() const {
95: return length;
96: }
97:
1.1.1.6 root 98: // 要素が空なら true を返す
99: bool Empty() const {
100: return (length == 0);
101: }
102:
1.1.1.2 root 103: // 要素が一杯なら true を返す
104: bool IsFull() const {
1.1.1.6 root 105: return (Length() >= capacity);
1.1.1.2 root 106: }
107:
1.1 root 108: // 要素を覗き見る。
109: // idx は 0 .. length-1 までで、0 がキューの先頭。
1.1.1.3 root 110: T Peek(int idx) const {
1.1 root 111: // XXX 範囲チェックすべきだがとりあえず
1.1.1.6 root 112: return (*this)[(start + idx) % capacity];
113: }
114:
115: // 要素数を返す
116: constexpr int Capacity() const {
117: return capacity;
1.1 root 118: }
119:
120: private:
1.1.1.5 root 121: uint start {}; // 開始位置
122: uint length {}; // 現在有効な長さ
1.1 root 123: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.