diff --git a/iqueue.h b/iqueue.h index fb973185..8fa8383a 100644 --- a/iqueue.h +++ b/iqueue.h @@ -31,123 +31,30 @@ SOFTWARE. #include -#include "exception.h" +#include "queue_base.h" namespace etl { -#ifdef USE_ETL_EXCEPTIONS - //*************************************************************************** - /// The base class for queue exceptions. - //*************************************************************************** - class queue_exception : public exception - { - public: - - queue_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// The exception thrown when the queue is full. - //*************************************************************************** - class queue_full_exception : public queue_exception - { - public: - - queue_full_exception() - : queue_exception("queue full exception") - { - } - }; - - //*************************************************************************** - /// The exception thrown when the queue is empty. - //*************************************************************************** - class queue_empty_exception : public queue_exception - { - public: - - queue_empty_exception() - : queue_exception("queue empty exception") - { - } - }; -#endif - //*************************************************************************** /// A fixed capacity queue written in the STL style. /// This queue cannot be used for concurrent access from multiple threads. /// \tparam T The type of item that the queue holds. //*************************************************************************** template - class iqueue + class iqueue : public queue_base { public: - typedef size_t size_type; - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - - //************************************************************************* - /// Returns the current number of items in the queue. - //************************************************************************* - size_type size() const - { - return size; - } - - //************************************************************************* - /// Returns the maximum number of items that can be queued. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the maximum number of items that can be queued. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Clears the queue to the empty state. - //************************************************************************* - void clear() - { - in = 0; - out = 0; - size = 0; - } - - //************************************************************************* - /// Checks to see if the queue is empty. - /// \return true if the queue is empty, otherwise false - //************************************************************************* - bool empty() const - { - return size == 0; - } - - //************************************************************************* - /// Checks to see if the queue is full. - /// \return true if the queue is full, otherwise false - //************************************************************************* - bool full() const - { - return size == MAX_SIZE; - } + typedef queue_base::size_type size_type; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; //************************************************************************* /// Adds an item to the queue. - /// If USE_ETL_EXCEPTIONS is defined, throws a queue_full_exception is the queue is already full, + /// If ETL_USE_EXCEPTIONS is defined, throws a queue_full_exception is the queue is already full, /// otherwise does nothing if full. ///\param item The item to push to the queue. //************************************************************************* @@ -156,10 +63,10 @@ namespace etl if (!full()) { buffer[in++] = item; - in %= MAX_SIZE; + in = (in == (MAX_SIZE - 1)) ? 0 : ++in; ++size; } -#ifdef USE_ETL_EXCEPTIONS +#ifdef ETL_USE_EXCEPTIONS else { throw queue_full_exception(); @@ -171,21 +78,20 @@ namespace etl /// Allows a possibly more efficient 'push' by moving to the next input item /// and returning a reference to it. /// This may eliminate a copy by allowing direct construction in-place. - /// If USE_ETL_EXCEPTIONS is defined, throws a queue_full_exception is the queue is already full, + /// If ETL_USE_EXCEPTIONS is defined, throws a queue_full_exception is the queue is already full, /// otherwise does nothing if full. /// \return A reference to the position to 'push' to. //************************************************************************* reference push() { - size_type next = in; + const size_type next = in; if (!full()) { - ++in; - in %= MAX_SIZE; + in = (in == (MAX_SIZE - 1)) ? 0 : ++in; ++size; } -#ifdef USE_ETL_EXCEPTIONS +#ifdef ETL_USE_EXCEPTIONS else { throw queue_full_exception(); @@ -195,28 +101,15 @@ namespace etl return buffer[next]; } - //************************************************************************* - /// Removes the oldest item from the back of the queue. - /// Does nothing if the queue is already empty. - //************************************************************************* - void pop() - { - if (!empty()) - { - out = (out + 1) % MAX_SIZE; - --size; - } - } - //************************************************************************* /// Gets a reference to the item at the front of the queue. - /// If USE_ETL_EXCEPTIONS is defined, throws a queue_empty_exception if the queue is empty. - /// If USE_ETL_EXCEPTIONS is not defined and the queue is empty, the return value is undefined. + /// If ETL_USE_EXCEPTIONS is defined, throws a queue_empty_exception if the queue is empty. + /// If ETL_USE_EXCEPTIONS is not defined and the queue is empty, the return value is undefined. /// \return A reference to the item at the front of the queue. //************************************************************************* reference front() { -#ifdef USE_ETL_EXCEPTIONS +#ifdef ETL_USE_EXCEPTIONS if (empty()) { throw queue_empty_exception(); @@ -228,13 +121,13 @@ namespace etl //************************************************************************* /// Gets a const reference to the item at the front of the queue. - /// If USE_ETL_EXCEPTIONS is defined, throws a queue_empty_exception if the queue is empty. - /// If USE_ETL_EXCEPTIONS is not defined and the queue is empty, the return value is undefined. + /// If ETL_USE_EXCEPTIONS is defined, throws a queue_empty_exception if the queue is empty. + /// If ETL_USE_EXCEPTIONS is not defined and the queue is empty, the return value is undefined. /// \return A const reference to the item at the front of the queue. //************************************************************************* const_reference front() const { -#ifdef USE_ETL_EXCEPTIONS +#ifdef ETL_USE_EXCEPTIONS if (empty()) { throw queue_empty_exception(); @@ -250,19 +143,14 @@ namespace etl /// The constructor that is called from derived classes. //************************************************************************* queue(T* buffer, size_type max_size) - : buffer(buffer), - MAX_SIZE(max_size) + : queue_base(max_size), + buffer(buffer) { - clear(); } private: - size_type in; ///< Where to input new data. - size_type out; ///< Where to get the oldest data. - size_type size; ///< The number of items in the queue. - const size_type MAX_SIZE; ///< The maximum number of items in the queue. - T* buffer; ///< The internal buffer. + T* buffer; ///< The internal buffer. }; } diff --git a/queue_base.h b/queue_base.h new file mode 100644 index 00000000..59b1ead0 --- /dev/null +++ b/queue_base.h @@ -0,0 +1,171 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. + +Copyright(c) 2014 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef __etl_queue_base__ +#define __etl_queue_base__ + +#include + +#include "exception.h" + +namespace etl +{ +#ifdef ETL_USE_EXCEPTIONS + //*************************************************************************** + /// The base class for queue exceptions. + //*************************************************************************** + class queue_exception : public exception + { + public: + + queue_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// The exception thrown when the queue is full. + //*************************************************************************** + class queue_full_exception : public queue_exception + { + public: + + queue_full_exception() + : queue_exception("queue full exception") + { + } + }; + + //*************************************************************************** + /// The exception thrown when the queue is empty. + //*************************************************************************** + class queue_empty_exception : public queue_exception + { + public: + + queue_empty_exception() + : queue_exception("queue empty exception") + { + } + }; +#endif + + //*************************************************************************** + /// A fixed capacity queue written in the STL style. + /// This queue cannot be used for concurrent access from multiple threads. + //*************************************************************************** + class queue_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Returns the current number of items in the queue. + //************************************************************************* + size_type size() const + { + return size; + } + + //************************************************************************* + /// Returns the maximum number of items that can be queued. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the maximum number of items that can be queued. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Clears the queue to the empty state. + //************************************************************************* + void clear() + { + in = 0; + out = 0; + size = 0; + } + + //************************************************************************* + /// Checks to see if the queue is empty. + /// \return true if the queue is empty, otherwise false + //************************************************************************* + bool empty() const + { + return size == 0; + } + + //************************************************************************* + /// Checks to see if the queue is full. + /// \return true if the queue is full, otherwise false + //************************************************************************* + bool full() const + { + return size == MAX_SIZE; + } + + //************************************************************************* + /// Removes the oldest item from the back of the queue. + /// Does nothing if the queue is already empty. + //************************************************************************* + void pop() + { + if (!empty()) + { + out = (out == (MAX_SIZE - 1)) ? 0 : ++out; + --size; + } + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + queue_base(size_type max_size) + : MAX_SIZE(max_size) + { + clear(); + } + + size_type in; ///< Where to input new data. + size_type out; ///< Where to get the oldest data. + size_type size; ///< The number of items in the queue. + const size_type MAX_SIZE; ///< The maximum number of items in the queue. + }; +} +