/*-------------------------------------------------------------------------- Project: HorizonSDK File: rdt_Deque.h Copyright 2009 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2010-05-22#$ $Rev: 16612 $ $Author: hiratsu_daisuke $ *-------------------------------------------------------------------------*/ #include "stdafx.h" #ifndef NN_RDT_DEQUE_H_ #define NN_RDT_DEQUE_H_ #include "rdt_Utility.h" namespace nn { namespace rdt { namespace CTR { /*! @brief これは双頭キューのクラスです。 本当ならSTLを使って済ませたかったのですが、CTR-SDKライブラリ内部では STLを使ってはいけないので、自作することにしました。 */ template class Deque{ public: /*! @brief 初期化します。 */ Deque(void); /*! @brief 解放します。 */ ~Deque(void); /*! @brief キューがカラッポかどうかを判定します。 */ bool IsEmpty(void) const; /*! @brief キューが満杯かどうかを判定します。 */ bool IsFull(void) const; /*! @brief キューの要素数を得ます。 */ size_t Size(void) const; /*! @brief キューの後方に詰めます。 */ void PushBack(const T &value); /*! @brief キューの先頭の要素を削除します。 */ void PopFront(void); /*! @brief キューの先端の要素を得ます。 */ const T& Front(void) const; /*! @brief キューの先端の要素を得ます(非const)。 */ T& Front(void); /*! @brief キューの末端の要素を得ます。 */ const T& Back(void) const; /*! @brief キューの末端の要素を得ます(非const)。 */ T& Back(void); /*! @brief キューのn番目の要素を得ます。 */ const T& At(size_t n) const; /*! @brief キューを空っぽにし、まっさらな状態に戻します。 */ void Clear(void); private: /*! @brief コピーコンストラクタは封印します。 */ Deque (const Deque&); /*! @brief 代入演算子は封印します。 */ Deque& operator=(const Deque&); // 数字の若い方が、先頭側。 T m_array[N]; size_t m_front; // 先頭の要素を指すインデックス size_t m_back; // 後方に詰める時の位置を指すインデックス // m_frontとm_backが等しいとき、キューは「カラ」であるとする。 }; template Deque::Deque(void) { Clear(); } // デストラクタ template Deque::~Deque(void) { } template bool Deque::IsEmpty(void) const { return m_front==m_back; } template bool Deque::IsFull(void) const { return (m_back + 1) % N == m_front; } template size_t Deque::Size(void) const { return (m_back - m_front + N) % N; } template void Deque::PushBack(const T &value) { ASSERTMSG(!IsFull(), "You cannot PushBack() anymore because deque is full."); m_array[m_back] = value; m_back = (m_back + 1) % N; } template void Deque::PopFront(void) { ASSERTMSG(!IsEmpty(), "You attempt to call PopFront(), but deque is empty."); m_front = (m_front + 1) % N; } template const T& Deque::Front(void) const { ASSERTMSG(!IsEmpty(), "You attempt to call const T& Front(), but deque is empty."); return m_array[m_front]; } template T& Deque::Front(void) { ASSERTMSG(!IsEmpty(), "You attempt to call T& Front(), but deque is empty."); return m_array[m_front]; } template const T& Deque::Back(void) const { ASSERTMSG(!IsEmpty(), "You attempt to call const T& Back(), but deque is empty."); return m_array[(m_back - 1 + N) % N]; } template T& Deque::Back(void) { ASSERTMSG(!IsEmpty(), "You attempt to call T& Back(), but deque is empty."); return m_array[(m_back - 1 + N) % N]; } template const T& Deque::At(size_t n) const { ASSERT(n < Size()); return m_array[(m_front + n) % N]; } template void Deque::Clear(void) { m_front = 0; m_back = 0; } }}} // namespace nn::rdt::CTR #endif // end of NN_RDT_DEQUE_H_