1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_Deque.h
4 
5   Copyright 2009 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2010-05-22#$
14   $Rev: 16612 $
15   $Author: hiratsu_daisuke $
16  *-------------------------------------------------------------------------*/
17 
18 #include "stdafx.h"
19 
20 #ifndef NN_RDT_DEQUE_H_
21 #define NN_RDT_DEQUE_H_
22 
23 #include "rdt_Utility.h"
24 
25 namespace nn { namespace rdt { namespace CTR {
26 
27 /*!
28     @brief これは双頭キューのクラスです。
29            本当ならSTLを使って済ませたかったのですが、CTR-SDKライブラリ内部では
30            STLを使ってはいけないので、自作することにしました。
31 
32 */
33 template <class T, size_t N>
34 class Deque{
35 public:
36 /*!
37     @brief 初期化します。
38 */
39     Deque(void);
40 
41 /*!
42     @brief 解放します。
43 */
44    ~Deque(void);
45 
46 /*!
47     @brief キューがカラッポかどうかを判定します。
48 */
49     bool IsEmpty(void) const;
50 
51 /*!
52     @brief キューが満杯かどうかを判定します。
53 */
54     bool IsFull(void) const;
55 
56 /*!
57     @brief キューの要素数を得ます。
58 */
59     size_t Size(void) const;
60 
61 /*!
62     @brief キューの後方に詰めます。
63 */
64     void PushBack(const T &value);
65 
66 /*!
67     @brief キューの先頭の要素を削除します。
68 */
69     void PopFront(void);
70 
71 /*!
72     @brief キューの先端の要素を得ます。
73 */
74     const T& Front(void) const;
75 
76 /*!
77     @brief キューの先端の要素を得ます(非const)。
78 */
79           T& Front(void);
80 
81 /*!
82     @brief キューの末端の要素を得ます。
83 */
84     const T& Back(void) const;
85 
86 /*!
87     @brief キューの末端の要素を得ます(非const)。
88 */
89           T& Back(void);
90 
91 /*!
92     @brief キューのn番目の要素を得ます。
93 */
94     const T& At(size_t n) const;
95 
96 /*!
97     @brief キューを空っぽにし、まっさらな状態に戻します。
98 */
99     void Clear(void);
100 
101 private:
102 /*!
103     @brief コピーコンストラクタは封印します。
104 */
105     Deque           (const Deque&);
106 
107 /*!
108     @brief 代入演算子は封印します。
109 */
110     Deque& operator=(const Deque&);
111 
112     // 数字の若い方が、先頭側。
113     T m_array[N];
114     size_t m_front;  // 先頭の要素を指すインデックス
115     size_t m_back;   // 後方に詰める時の位置を指すインデックス
116 
117     // m_frontとm_backが等しいとき、キューは「カラ」であるとする。
118 
119 };
120 
121 
122 template <class T, size_t N>
Deque(void)123 Deque<T, N>::Deque(void)
124 {
125     Clear();
126 }
127 
128 
129 // デストラクタ
130 template <class T, size_t N>
~Deque(void)131 Deque<T, N>::~Deque(void)
132 {
133 }
134 
135 
136 template <class T, size_t N>
IsEmpty(void)137 bool Deque<T, N>::IsEmpty(void) const
138 {
139     return m_front==m_back;
140 }
141 
142 
143 template <class T, size_t N>
IsFull(void)144 bool Deque<T, N>::IsFull(void) const
145 {
146     return (m_back + 1) % N == m_front;
147 }
148 
149 
150 template <class T, size_t N>
Size(void)151 size_t Deque<T, N>::Size(void) const
152 {
153     return (m_back - m_front + N) % N;
154 }
155 
156 
157 template <class T, size_t N>
PushBack(const T & value)158 void Deque<T, N>::PushBack(const T &value)
159 {
160     ASSERTMSG(!IsFull(), "You cannot PushBack() anymore because deque is full.");
161 
162     m_array[m_back] = value;
163     m_back = (m_back + 1) % N;
164 }
165 
166 
167 template <class T, size_t N>
PopFront(void)168 void Deque<T, N>::PopFront(void)
169 {
170     ASSERTMSG(!IsEmpty(), "You attempt to call PopFront(), but deque is empty.");
171 
172     m_front = (m_front + 1) % N;
173 }
174 
175 
176 template <class T, size_t N>
Front(void)177 const T& Deque<T, N>::Front(void) const
178 {
179     ASSERTMSG(!IsEmpty(), "You attempt to call const T& Front(), but deque is empty.");
180 
181     return m_array[m_front];
182 }
183 
184 
185 template <class T, size_t N>
Front(void)186 T& Deque<T, N>::Front(void)
187 {
188     ASSERTMSG(!IsEmpty(), "You attempt to call T& Front(), but deque is empty.");
189 
190     return m_array[m_front];
191 }
192 
193 
194 template <class T, size_t N>
Back(void)195 const T& Deque<T, N>::Back(void) const
196 {
197     ASSERTMSG(!IsEmpty(), "You attempt to call const T& Back(), but deque is empty.");
198 
199     return m_array[(m_back - 1 + N) % N];
200 }
201 
202 
203 template <class T, size_t N>
Back(void)204 T& Deque<T, N>::Back(void)
205 {
206     ASSERTMSG(!IsEmpty(), "You attempt to call T& Back(), but deque is empty.");
207 
208     return m_array[(m_back - 1 + N) % N];
209 }
210 
211 
212 template <class T, size_t N>
At(size_t n)213 const T& Deque<T, N>::At(size_t n) const
214 {
215     ASSERT(n < Size());
216 
217     return m_array[(m_front + n) % N];
218 }
219 
220 
221 template <class T, size_t N>
Clear(void)222 void Deque<T, N>::Clear(void)
223 {
224     m_front = 0;
225     m_back  = 0;
226 }
227 
228 }}} // namespace nn::rdt::CTR
229 
230 #endif  // end of NN_RDT_DEQUE_H_
231