//---------------------------------------------------------------------------------------------------------------------- // // Declaration of the template class 'TC_FIFO'. // // COPY OF ITS INSTANCES IS FORBIDDEN BY REDEFINITION OF COPY CONSTRUCTOR AND ASSIGNMENT OPERATOR. * // // This file is part of libpm library // // Copyright (C) 2001, ..., 2019 Pierre Molinaro. // e-mail : pierre@pcmolinaro.name // This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General // Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope it will be useful, but WITHOUT ANY WARRANTY; without even the implied // warranty of MERCHANDIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // //---------------------------------------------------------------------------------------------------------------------- #pragma once //---------------------------------------------------------------------------------------------------------------------- #include //---------------------------------------------------------------------------------------------------------------------- #include "utilities/M_SourceLocation.h" #include "utilities/TF_Swap.h" #include "utilities/MF_Assert.h" //---------------------------------------------------------------------------------------------------------------------- // // FIFO template class declaration // //---------------------------------------------------------------------------------------------------------------------- template class TC_FIFO { //--- Constructor and destructor public: TC_FIFO (void) ; public: virtual ~TC_FIFO (void) ; //--- No copy private: TC_FIFO (TC_FIFO &) ; private: void operator = (TC_FIFO &) ; //--- Length public: inline int32_t length (void) const { return mListLength ; } //--- Empty ? public: inline bool isEmpty (void) const { return mListLength == 0 ; } //--- Insert a new element at head public: void insertByCopy (const TYPE & inInfo) ; public: void insertByExchange (TYPE & ioInfo) ; //--- Delete last element public: void deleteLastItem (void) ; //--- Get and suppress last element public: void getByCopyAndSuppressLastItem (TYPE & outInfo) ; public: void getByExchangeAndSuppressLastItem (TYPE & outInfo) ; //--- Direct access public: TYPE & operator () (const int32_t inIndex COMMA_LOCATION_ARGS) ; public: TYPE & operator () (const int32_t inIndex COMMA_LOCATION_ARGS) const ; //------- Element class --------------------- private: class TC_FIFO_element { //--- Constructors public: TC_FIFO_element (const TYPE & inSource) ; public: TC_FIFO_element (void) ; //--- Data members private: TYPE mInfo ; private: TC_FIFO_element * mNextItem ; //--- No copy private: TC_FIFO_element (TC_FIFO_element &) ; private: void operator = (TC_FIFO_element &) ; //--- Friend friend class TC_FIFO ; } ; //--- Data members private: TC_FIFO_element * mFirstItem ; private: TC_FIFO_element * mLastItem ; private: int32_t mListLength ; private: mutable TC_FIFO_element * * mItemsArray ; } ; //---------------------------------------------------------------------------------------------------------------------- // // FIFO template class implementation // //---------------------------------------------------------------------------------------------------------------------- template TC_FIFO ::TC_FIFO_element::TC_FIFO_element (void) : mInfo (), mNextItem (NULL) { } //---------------------------------------------------------------------------------------------------------------------- template TC_FIFO ::TC_FIFO_element::TC_FIFO_element (const TYPE & inSource) : mInfo (inSource), mNextItem (NULL) { } //---------------------------------------------------------------------------------------------------------------------- template TC_FIFO ::TC_FIFO (void) : mFirstItem (NULL), mLastItem (NULL), mListLength (0), mItemsArray (NULL) { } //---------------------------------------------------------------------------------------------------------------------- template TC_FIFO::~TC_FIFO (void) { macroMyDeleteArray (mItemsArray) ; while (mFirstItem != (TC_FIFO_element *) NULL) { mLastItem = mFirstItem->mNextItem ; macroMyDelete (mFirstItem) ; mFirstItem = mLastItem ; } mListLength = 0 ; } //---------------------------------------------------------------------------------------------------------------------- template void TC_FIFO::insertByCopy (const TYPE & inInfo) { TC_FIFO_element * p = NULL ; macroMyNew (p, TC_FIFO_element (inInfo)) ; // Copy if (mLastItem == NULL) { mFirstItem = p ; }else{ mLastItem->mNextItem = p ; } mLastItem = p ; mListLength ++ ; macroMyDeleteArray (mItemsArray) ; } //---------------------------------------------------------------------------------------------------------------------- template void TC_FIFO::insertByExchange (TYPE & ioInfo) { TC_FIFO_element * p = NULL ; macroMyNew (p, TC_FIFO_element ()) ; swap (p->mInfo, ioInfo) ; // Exchange if (mLastItem == NULL) { mFirstItem = p ; }else{ mLastItem->mNextItem = p ; } mLastItem = p ; mListLength ++ ; macroMyDeleteArray (mItemsArray) ; } //---------------------------------------------------------------------------------------------------------------------- template void TC_FIFO::deleteLastItem (void) { if (mFirstItem != NULL) { TC_FIFO_element * p = mFirstItem->mNextItem ; macroMyDelete (mFirstItem) ; mFirstItem = p ; mListLength -- ; if (mFirstItem == NULL) { mLastItem = NULL ; } } macroMyDeleteArray (mItemsArray) ; } //---------------------------------------------------------------------------------------------------------------------- template void TC_FIFO ::getByCopyAndSuppressLastItem (TYPE & outInfo) { if (mFirstItem != NULL) { outInfo = mFirstItem->mInfo ; TC_FIFO_element * p = mFirstItem->mNextItem ; macroMyDelete (mFirstItem) ; mListLength -- ; if (mFirstItem == NULL) { mLastItem = NULL ; } } macroMyDeleteArray (mItemsArray) ; } //---------------------------------------------------------------------------------------------------------------------- template void TC_FIFO::getByExchangeAndSuppressLastItem (TYPE & outInfo) { if (mFirstItem != NULL) { swap (outInfo, mFirstItem->mInfo) ; TC_FIFO_element * p = mFirstItem->mNextItem ; macroMyDelete (mFirstItem) ; mFirstItem = p ; mListLength -- ; if (mFirstItem == NULL) { mLastItem = NULL ; } } macroMyDeleteArray (mItemsArray) ; } //---------------------------------------------------------------------------------------------------------------------- template TYPE & TC_FIFO::operator () (const int32_t inIndex COMMA_LOCATION_ARGS) { MF_AssertThere (inIndex >= 0, "inIndex (%ld) < 0", inIndex, 0) ; MF_AssertThere (inIndex < mListLength, "inIndex (%ld) >= mListLength (%ld)", inIndex, mListLength) ; TC_FIFO_element * p = (TC_FIFO_element *) NULL ; if (inIndex == 0) { p = mFirstItem ; }else if (inIndex == (mListLength - 1)) { p = mLastItem ; }else{ if (mItemsArray == NULL) { macroMyNewArray (mItemsArray, TC_FIFO_element *, uint32_t (mListLength)) ; p = mFirstItem ; for (int32_t i=0 ; imNextItem ; } } p = mItemsArray [inIndex] ; } return p->mInfo ; } //---------------------------------------------------------------------------------------------------------------------- template TYPE & TC_FIFO ::operator () (const int32_t inIndex COMMA_LOCATION_ARGS) const { MF_AssertThere (inIndex >= 0, "inIndex (%ld) < 0", inIndex, 0) ; MF_AssertThere (inIndex < mListLength, "inIndex (%ld) >= mListLength (%ld)", inIndex, mListLength) ; TC_FIFO_element * p = (TC_FIFO_element *) NULL ; if (inIndex == 0) { p = mFirstItem ; }else if (inIndex == (mListLength - 1)) { p = mLastItem ; }else{ if (mItemsArray == NULL) { macroMyNewArray (mItemsArray, TC_FIFO_element *, uint32_t (mListLength)) ; p = mFirstItem ; for (int32_t i=0 ; imNextItem ; } } p = mItemsArray [inIndex] ; } return p->mInfo ; } //----------------------------------------------------------------------------------------------------------------------