From 6f7e26523e32a32737135a3405b379d90e53b780 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 13:38:08 +0000 Subject: [PATCH 1/7] Moved more code to base class. --- bitset.h | 173 +++++++++------------------------------------------ ibitset.h | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 143 deletions(-) diff --git a/bitset.h b/bitset.h index 8b0ed1aa..2f51d8f5 100644 --- a/bitset.h +++ b/bitset.h @@ -36,10 +36,14 @@ SOFTWARE. #include #include "integral_limits.h" +#include "algorithm.h" #include "nullptr.h" #include "log.h" #include "ibitset.h" +#define ETL_NO_CHECKS +#include "error_handler.h" + #if defined(COMPILER_KEIL) #pragma diag_suppress 1300 #endif @@ -70,9 +74,7 @@ namespace etl static const size_t ALLOCATED_BITS = ARRAY_SIZE * BITS_PER_ELEMENT; public: - - - + //************************************************************************* /// Default constructor. //************************************************************************* @@ -88,7 +90,7 @@ namespace etl bitset(const bitset& other) : ibitset(N, ARRAY_SIZE, data) { - std::copy(other.data, other.data + ARRAY_SIZE, data); + etl::copy_n(other.data, ARRAY_SIZE, data); } //************************************************************************* @@ -97,27 +99,7 @@ namespace etl bitset(unsigned long long value) : ibitset(N, ARRAY_SIZE, data) { - reset(); - - const size_t SHIFT = (integral_limits::bits <= BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT; - - // Can we do it in one hit? - if (SHIFT == 0) - { - data[0] = element_t(value); - } - else - { - size_t i = 0; - - while ((value != 0) && (i < ARRAY_SIZE)) - { - data[i++] = value & ALL_SET; - value = value >> SHIFT; - } - } - - data[ARRAY_SIZE - 1] &= TOP_MASK; + initialise(value); } //************************************************************************* @@ -147,12 +129,19 @@ namespace etl return *this; } +//#define NDEBUG + + //************************************************************************* /// Set from a string. //************************************************************************* - bitset& set(const char* text) + bitset& set(const char* text) { - ibitset::set(text); + if (ETL_ASSERT(text != 0, etl::bitset_nullptr())) + { + ibitset::set(text); + } + return *this; } @@ -197,11 +186,7 @@ namespace etl //************************************************************************* bitset& operator =(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] = other.data[i]; - } - + etl::copy_n(other.data, ARRAY_SIZE, data); return *this; } @@ -210,11 +195,7 @@ namespace etl //************************************************************************* bitset& operator &=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] &= other.data[i]; - } - + ibitset::operator &=(other); return *this; } @@ -223,11 +204,7 @@ namespace etl //************************************************************************* bitset& operator |=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] |= other.data[i]; - } - + ibitset::operator |=(other); return *this; } @@ -236,11 +213,7 @@ namespace etl //************************************************************************* bitset& operator ^=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] ^= other.data[i]; - } - + ibitset::operator ^=(other); return *this; } @@ -249,13 +222,10 @@ namespace etl //************************************************************************* bitset operator ~() const { - bitset temp; - - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - temp[i] = ~data[i]; - } + bitset temp(*this); + temp.invert(); + return temp; } @@ -264,22 +234,9 @@ namespace etl //************************************************************************* bitset operator<<(size_t shift) const { - bitset temp; + bitset temp(*this); - if (ARRAY_SIZE == 1) - { - temp.data[0] = data[0] << shift; - } - else - { - size_t source = N - shift - 1; - size_t destination = N - 1; - - for (size_t i = 0; i < (N - shift); ++i) - { - temp.set(destination--, test(source--)); - } - } + temp <<= shift; return temp; } @@ -289,26 +246,7 @@ namespace etl //************************************************************************* bitset& operator<<=(size_t shift) { - if (ARRAY_SIZE == 1) - { - data[0] <<= shift; - } - else - { - size_t source = N - shift - 1; - size_t destination = N - 1; - - for (size_t i = 0; i < (N - shift); ++i) - { - set(destination--, test(source--)); - } - - for (size_t i = 0; i < shift; ++i) - { - reset(destination--); - } - } - + ibitset::operator <<=(shift); return *this; } @@ -317,22 +255,9 @@ namespace etl //************************************************************************* bitset operator>>(size_t shift) const { - bitset temp; + bitset temp(*this); - if (ARRAY_SIZE == 1) - { - temp.data[0] = data[0] >> shift; - } - else - { - size_t source = shift; - size_t destination = 0; - - while (source != N) - { - temp.set(destination++, test(source++)); - } - } + temp >>= shift; return temp; } @@ -342,54 +267,16 @@ namespace etl //************************************************************************* bitset& operator>>=(size_t shift) { - if (ARRAY_SIZE == 1) - { - data[0] >>= shift; - } - else - { - size_t source = shift; - size_t destination = 0; - - for (size_t i = 0; i < (N - shift); ++i) - { - set(destination++, test(source++)); - } - - for (size_t i = 0; i < shift; ++i) - { - reset(destination++); - } - } - + ibitset::operator >>=(shift); return *this; } - //************************************************************************* - /// swap - //************************************************************************* - void swap(bitset& other) - { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - std::swap(data, other.data); - } - } - //************************************************************************* /// operator == //************************************************************************* friend bool operator == (const bitset& lhs, const bitset& rhs) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - if (lhs.data[i] != rhs.data[i]) - { - return false; - } - } - - return true; + return ibitset::is_equal(lhs, rhs); } private: diff --git a/ibitset.h b/ibitset.h index a649e521..ff1825b4 100644 --- a/ibitset.h +++ b/ibitset.h @@ -33,6 +33,7 @@ SOFTWARE. #include #include +#include "exception.h" #include "integral_limits.h" #include "binary.h" @@ -42,6 +43,34 @@ SOFTWARE. namespace etl { + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Bitset nullptr exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_nullptr : public bitset_exception + { + public: + + bitset_nullptr() + : bitset_exception("bitset: nullptr") + { + } + }; + //************************************************************************* /// The base class for etl::bitset ///\ingroup bitset @@ -466,8 +495,152 @@ namespace etl return bit_reference(*this, position); } + //************************************************************************* + /// operator &= + //************************************************************************* + ibitset& operator &=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] &= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ibitset& operator |=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] |= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ibitset& operator ^=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] ^= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ibitset& operator<<=(size_t shift) + { + if (SIZE == 1) + { + pdata[0] <<= shift; + } + else + { + size_t source = NBITS - shift - 1; + size_t destination = NBITS - 1; + + for (size_t i = 0; i < (NBITS - shift); ++i) + { + set(destination--, test(source--)); + } + + for (size_t i = 0; i < shift; ++i) + { + reset(destination--); + } + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ibitset& operator>>=(size_t shift) + { + if (SIZE == 1) + { + pdata[0] >>= shift; + } + else + { + size_t source = shift; + size_t destination = 0; + + for (size_t i = 0; i < (NBITS - shift); ++i) + { + set(destination++, test(source++)); + } + + for (size_t i = 0; i < shift; ++i) + { + reset(destination++); + } + } + + return *this; + } + + //************************************************************************* + /// swap + //************************************************************************* + void swap(ibitset& other) + { + std::swap_ranges(pdata, pdata + SIZE, other.pdata); + } + protected: + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ibitset& initialise(unsigned long long value) + { + reset(); + + const size_t SHIFT = (integral_limits::bits <= BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT; + + // Can we do it in one hit? + if (SHIFT == 0) + { + pdata[0] = element_t(value); + } + else + { + size_t i = 0; + + while ((value != 0) && (i < SIZE)) + { + pdata[i++] = value & ALL_SET; + value = value >> SHIFT; + } + } + + pdata[SIZE - 1] &= TOP_MASK; + + return *this; + } + + //************************************************************************* + /// Invert + //************************************************************************* + void invert() + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] = ~pdata[i]; + } + } + //************************************************************************* /// Gets a reference to the specified bit. //************************************************************************* @@ -489,6 +662,14 @@ namespace etl TOP_MASK = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); } + //************************************************************************* + /// Compare bitsets. + //************************************************************************* + static bool is_equal(const ibitset& lhs, const ibitset&rhs) + { + return std::equal(lhs.pdata, lhs.pdata + lhs.SIZE, rhs.pdata); + } + element_t TOP_MASK; private: From a7d9b44f332b0d12a6141690822b7c2a54907933 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 13:38:51 +0000 Subject: [PATCH 2/7] Modified some tests to check return values of operators --- test/test_bitset.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_bitset.cpp b/test/test_bitset.cpp index 2ad08c82..c6e4d333 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset.cpp @@ -575,7 +575,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 & 0x23456789); - data2 &= data1; + etl::bitset<60>& rdata = data2 &= data1; CHECK(data2 == data3); } @@ -598,7 +598,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 | 0x23456789); - data2 |= data1; + etl::bitset<60>& rdata = data2 |= data1; CHECK(data2 == data3); } @@ -621,7 +621,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 ^ 0x23456789); - data2 ^= data1; + etl::bitset<60>& rdata = data2 ^= data1; CHECK(data2 == data3); } From 632bc59f9c0cfa7214033f3940ae4f8dbe3c81cb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 13:45:29 +0000 Subject: [PATCH 3/7] Modified the error system. Remove ETL_ERROR and replaced with ETL_ASSERT. ETL_ASSERT will eveluate to 'true' in all cases except for error logging. This will allow 'if' statements that contain the macro to be optimised away for all cases except logging. Added ETL_NO_CHECKS and ETL_LOG_ERRORS macro checks. The options are now:- ETL_NO_CHECKS ETL_ASSERT does nothing. Evaluates to 'true'. ETL_THROW_EXCEPTIONS) ETL_ASSERT throws an exception if the condition fails. Evaluates to 'true'. ETL_LOG_ERRORS ETL_ASSERT logs the error if the condition fails. Evaluates to the result of the condition. If none of the above are defined:- NDEBUG ETL_ASSERT does nothing. Evaluates to 'true'. Otherwise:- ETL_ASSERT asserts if the condition fails. Evaluates to 'true'. --- array.h | 19 +----- error_handler.h | 26 ++++++-- ideque.h | 93 +++++++-------------------- iflat_map.h | 38 ++--------- iflat_multimap.h | 40 +++++------- iflat_multiset.h | 40 +++++------- iflat_set.h | 43 ++++++------- intrusive_forward_list.h | 6 +- intrusive_forward_list_node.h | 10 +-- ivector.h | 116 +++++++++++----------------------- jenkins.h | 12 +--- murmur3.h | 12 +--- 12 files changed, 145 insertions(+), 310 deletions(-) diff --git a/array.h b/array.h index adbedd04..006e92ef 100644 --- a/array.h +++ b/array.h @@ -111,37 +111,22 @@ namespace etl //************************************************************************* /// Returns a reference to the value at index 'i'. - /// If ETL_THROW_EXCEPTIONS is defined then am array_out_of_range is - /// thown if the index is out of range. ///\param i The index of the element to access. //************************************************************************* reference at(size_t i) { - - if (i >= SIZE) - { -#ifdef ETL_THROW_EXCEPTIONS - throw array_out_of_range(); -#else - error_handler::error(array_out_of_range()); -#endif - } + ETL_ASSERT(i < SIZE, array_out_of_range()); return _buffer[i]; } //************************************************************************* /// Returns a const reference to the value at index 'i'. - /// If ETL_THROW_EXCEPTIONS is defined then am array_out_of_range is - /// thown if the index is out of range. ///\param i The index of the element to access. //************************************************************************* const_reference at(size_t i) const { - if (i >= SIZE) - { - ETL_ERROR(array_out_of_range()); - } + ETL_ASSERT(i < SIZE, array_out_of_range()); return _buffer[i]; } diff --git a/error_handler.h b/error_handler.h index f2ade040..3def7a0f 100644 --- a/error_handler.h +++ b/error_handler.h @@ -35,6 +35,8 @@ SOFTWARE. /// Error handler for when throwing exceptions is not required. ///\ingroup utilities +#include + #include "exception.h" #include "function.h" @@ -80,15 +82,27 @@ namespace etl }; //*************************************************************************** - /// Raise an error. - /// If ETL_THROW_EXCEPTIONS is defined then the error is thrown, otherwise - /// the error handler is called. + /// Asserts a coondition. + /// Versions of the macro that return a constant value of 'true' will allow the compiler to optimise away + /// any 'if' statements that it is contained within. + /// If ETL_NO_CHECKS is defined then no runtime checks are executed at all. + /// If ETL_THROW_EXCEPTIONS is defined then the error is thrown if the assert fails. The return value is always 'true'. + /// If ETL_LOG_ERRORS is defined then the error is logged if the assert fails. The return value is the value of the boolean test. + /// Otherwise 'assert' is called. The return value is always 'true'. ///\ingroup error_handler //*************************************************************************** -#ifdef ETL_THROW_EXCEPTIONS - #define ETL_ERROR(e) throw e +#if defined(ETL_NO_CHECKS) + #define ETL_ASSERT(b, e) (true) // Does nothing. Evaluates to 'true'. +#elif defined(ETL_THROW_EXCEPTIONS) + #define ETL_ASSERT(b, e) (((b) ? true : throw((e))), true) // Throws an exception if the condition fails. Evaluates to 'true'. +#elif defined (ETL_LOG_ERRORS) + #define ETL_ASSERT(b, e) (((b) ? true : etl::error_handler::error((e))), (b)) // Logs the error if the condition fails. Evaluates to the result of the condition. #else - #define ETL_ERROR(e) etl::error_handler::error(e); + #if defined(NDEBUG) + #define ETL_ASSERT(b, e) (true) // Does nothing. Evaluates to 'true'. + #elif + #define ETL_ASSERT(b, e) ((assert((b))), true) // Asserts if the condition fails. Evaluates to 'true'. + #endif #endif } diff --git a/ideque.h b/ideque.h index eea7ab83..ff2a408e 100644 --- a/ideque.h +++ b/ideque.h @@ -491,20 +491,18 @@ namespace etl //************************************************************************* void assign(size_type n, const value_type& value) { - if (n > MAX_SIZE) + if (ETL_ASSERT(n <= MAX_SIZE, deque_full())) { - ETL_ERROR(deque_full()); - } + initialise(); - initialise(); + _begin.index = 0; + _end.index = 0; - _begin.index = 0; - _end.index = 0; - - while (n > 0) - { - create_element_back(value); - --n; + while (n > 0) + { + create_element_back(value); + --n; + } } } @@ -515,14 +513,11 @@ namespace etl //************************************************************************* reference at(size_t index) { - if (index >= current_size) - { - ETL_ERROR(deque_out_of_bounds()); - } + ETL_ASSERT(index < current_size, deque_out_of_bounds()); iterator result(_begin); result += index; - + return *result; } @@ -533,10 +528,7 @@ namespace etl //************************************************************************* const_reference at(size_t index) const { - if (index >= current_size) - { - ETL_ERROR(deque_out_of_bounds()); - } + ETL_ASSERT(index < current_size, deque_out_of_bounds()); iterator result(_begin); result += index; @@ -718,7 +710,7 @@ namespace etl { iterator position(insert_position.index, *this, p_buffer); - if (!full()) + if (ETL_ASSERT(!full(), deque_full())) { if (insert_position == begin()) { @@ -757,10 +749,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_full()); - } return position; } @@ -776,7 +764,7 @@ namespace etl { iterator position; - if ((current_size + n) <= MAX_SIZE) + if (ETL_ASSERT((current_size + n) <= MAX_SIZE, deque_full())) { if (insert_position == begin()) { @@ -871,10 +859,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_full()); - } return position; } @@ -894,7 +878,7 @@ namespace etl difference_type n = std::distance(range_begin, range_end); - if ((current_size + n) <= MAX_SIZE) + if (ETL_ASSERT((current_size + n) <= MAX_SIZE, deque_full())) { if (insert_position == begin()) { @@ -983,10 +967,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_full()); - } return position; } @@ -1000,7 +980,7 @@ namespace etl { iterator position(erase_position.index, *this, p_buffer); - if (distance(position) <= difference_type(current_size)) + if (ETL_ASSERT(distance(position) <= difference_type(current_size), deque_out_of_bounds())) { if (position == _begin) { @@ -1028,10 +1008,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_out_of_bounds()); - } return position; } @@ -1046,8 +1022,7 @@ namespace etl { iterator position(range_begin.index, *this, p_buffer); - if ((distance(range_begin) <= difference_type(current_size)) && - (distance(range_end) <= difference_type(current_size))) + if (ETL_ASSERT((distance(range_begin) <= difference_type(current_size)) && (distance(range_end) <= difference_type(current_size)), deque_out_of_bounds())) { // How many to erase? size_t length = std::distance(range_begin, range_end); @@ -1101,10 +1076,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_out_of_bounds()); - } return position; } @@ -1116,14 +1087,10 @@ namespace etl //************************************************************************* void push_back(parameter_t item) { - if (!full()) + if (ETL_ASSERT(!full(), deque_full())) { create_element_back(item); } - else - { - ETL_ERROR(deque_full()); - } } //************************************************************************* @@ -1135,14 +1102,10 @@ namespace etl { reference r = *_end; - if (!full()) + if (ETL_ASSERT(!full(), deque_full())) { create_element_back(); } - else - { - ETL_ERROR(deque_full()); - } return r; } @@ -1165,14 +1128,10 @@ namespace etl //************************************************************************* void push_front(parameter_t item) { - if (!full()) + if (ETL_ASSERT(!full(), deque_full())) { create_element_front(item); } - else - { - ETL_ERROR(deque_full()); - } } //************************************************************************* @@ -1182,14 +1141,10 @@ namespace etl //************************************************************************* reference push_front() { - if (!full()) + if (ETL_ASSERT(!full(), deque_full())) { create_element_front(); } - else - { - ETL_ERROR(deque_full()); - } return *_begin; } @@ -1213,7 +1168,7 @@ namespace etl //************************************************************************* void resize(size_t new_size, const value_type& value = value_type()) { - if (new_size <= MAX_SIZE) + if (ETL_ASSERT(new_size <= MAX_SIZE, deque_out_of_bounds())) { // Make it smaller? if (new_size < current_size) @@ -1234,10 +1189,6 @@ namespace etl } } } - else - { - ETL_ERROR(deque_out_of_bounds()); - } } //************************************************************************* diff --git a/iflat_map.h b/iflat_map.h index 2d3e15dc..d3a6e20c 100644 --- a/iflat_map.h +++ b/iflat_map.h @@ -41,10 +41,7 @@ SOFTWARE. #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" - -#ifndef ETL_THROW_EXCEPTIONS #include "error_handler.h" -#endif namespace etl { @@ -243,11 +240,7 @@ namespace etl { iterator i_element = lower_bound(key); - if (i_element == end()) - { - // Doesn't exist. - ETL_ERROR(flat_map_out_of_bounds()); - } + ETL_ASSERT(i_element != end(), flat_map_out_of_bounds()); return i_element->second; } @@ -262,11 +255,7 @@ namespace etl { typename buffer_t::const_iterator i_element = lower_bound(key); - if (i_element == end()) - { - // Doesn't exist. - ETL_ERROR(flat_map_out_of_bounds()); - } + ETL_ASSERT(i_element != end(), flat_map_out_of_bounds()); return i_element->second; } @@ -284,15 +273,8 @@ namespace etl #ifdef _DEBUG difference_type count = std::distance(first, last); - if (count < 0) - { - ETL_ERROR(flat_map_iterator()); - } - - if (count > difference_type(capacity())) - { - ETL_ERROR(flat_map_full()); - } + ETL_ASSERT(count >= 0, flat_map_iterator()); + ETL_ASSERT(count <= difference_type(capacity()), flat_map_full()); #endif clear(); @@ -317,11 +299,7 @@ namespace etl if (i_element == end()) { // At the end. - if (buffer.full()) - { - ETL_ERROR(flat_map_full()); - } - else + if (ETL_ASSERT(!buffer.full(), flat_map_full())) { buffer.push_back(value); result.first = end() - 1; @@ -342,11 +320,7 @@ namespace etl else { // A new one. - if (buffer.full()) - { - ETL_ERROR(flat_map_full()); - } - else + if (ETL_ASSERT(!buffer.full(), flat_map_full())) { buffer.insert(i_element, value); result.first = i_element; diff --git a/iflat_multimap.h b/iflat_multimap.h index 1bb53583..807b8fd6 100644 --- a/iflat_multimap.h +++ b/iflat_multimap.h @@ -223,12 +223,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - if (count < 0) - { - ETL_ERROR(flat_multimap_iterator()); - return; - } + ETL_ASSERT(count >= 0, flat_multimap_iterator()); #endif clear(); @@ -250,25 +245,22 @@ namespace etl iterator i_element = lower_bound(value.first); - if (buffer.full()) - { - ETL_ERROR(flat_multimap_full()); - return result; - } - - if (i_element == end()) + if (ETL_ASSERT(!buffer.full(), flat_multimap_full())) { - // At the end. - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; + if (i_element == end()) + { + // At the end. + buffer.push_back(value); + result.first = end() - 1; + result.second = true; + } + else + { + // Not at the end. + buffer.insert(i_element, value); + result.first = i_element; + result.second = true; + } } return result; diff --git a/iflat_multiset.h b/iflat_multiset.h index d68b7ec6..14198ac3 100644 --- a/iflat_multiset.h +++ b/iflat_multiset.h @@ -200,10 +200,7 @@ namespace etl #ifdef _DEBUG difference_type count = std::distance(first, last); - if (count < 0) - { - ETL_ERROR(flat_multiset_iterator()); - } + ETL_ASSERT(count >= 0, flat_multiset_iterator()); #endif clear(); @@ -223,27 +220,24 @@ namespace etl { std::pair result(end(), false); - if (buffer.full()) + if (ETL_ASSERT(!buffer.full(), flat_multiset_full())) { - ETL_ERROR(flat_multiset_full()); - return result; - } - - iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); + iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); - if (i_element == end()) - { - // At the end. - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; + if (i_element == end()) + { + // At the end. + buffer.push_back(value); + result.first = end() - 1; + result.second = true; + } + else + { + // Not at the end. + buffer.insert(i_element, value); + result.first = i_element; + result.second = true; + } } return result; diff --git a/iflat_set.h b/iflat_set.h index bf7b0a35..45dce87a 100644 --- a/iflat_set.h +++ b/iflat_set.h @@ -199,11 +199,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - if (count < 0) - { - ETL_ERROR(flat_set_iterator()); - } + ETL_ASSERT(count >= 0, flat_set_iterator()); #endif clear(); @@ -223,27 +219,24 @@ namespace etl { std::pair result(end(), false); - if (buffer.full()) - { - ETL_ERROR(flat_set_full()); - return result; - } - - iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); + if (ETL_ASSERT(!buffer.full(), flat_set_full())) + { + iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); - if (i_element == end()) - { - // At the end. - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; + if (i_element == end()) + { + // At the end. + buffer.push_back(value); + result.first = end() - 1; + result.second = true; + } + else + { + // Not at the end. + buffer.insert(i_element, value); + result.first = i_element; + result.second = true; + } } return result; diff --git a/intrusive_forward_list.h b/intrusive_forward_list.h index f6875116..ca601040 100644 --- a/intrusive_forward_list.h +++ b/intrusive_forward_list.h @@ -408,11 +408,7 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - if (count < 0) - { - ETL_ERROR(intrusive_forward_list_iterator_exception()); - } + ETL_ASSERT(count >= 0, intrusive_forward_list_iterator_exception()); #endif initialise(); diff --git a/intrusive_forward_list_node.h b/intrusive_forward_list_node.h index 052f83a2..b71cd830 100644 --- a/intrusive_forward_list_node.h +++ b/intrusive_forward_list_node.h @@ -71,10 +71,7 @@ namespace etl __private_intrusive_forward_list__::intrusive_forward_list_node_base* get_next(size_t index) const { #ifdef _DEBUG - if (index >= SIZE) - { - ETL_ERROR(intrusive_forward_list_index_exception()); - } + ETL_ASSERT(index < SIZE, intrusive_forward_list_index_exception()); #endif return next[index]; } @@ -82,10 +79,7 @@ namespace etl void set_next(size_t index, __private_intrusive_forward_list__::intrusive_forward_list_node_base* pnext) { #ifdef _DEBUG - if (index >= SIZE) - { - ETL_ERROR(intrusive_forward_list_index_exception()); - } + ETL_ASSERT(index < SIZE, intrusive_forward_list_index_exception()); #endif next[index] = pnext; } diff --git a/ivector.h b/ivector.h index 48108708..704b0cf1 100644 --- a/ivector.h +++ b/ivector.h @@ -188,27 +188,25 @@ namespace etl //********************************************************************* void resize(size_t new_size) { - if (new_size > MAX_SIZE) + if (ETL_ASSERT(new_size <= MAX_SIZE, vector_full())) { - ETL_ERROR(vector_full()); - } - - // Size up or size down? - if (new_size > current_size) - { - for (size_t i = current_size; i < new_size; ++i) + // Size up or size down? + if (new_size > current_size) { - while (current_size < new_size) + for (size_t i = current_size; i < new_size; ++i) { - create_element(); + while (current_size < new_size) + { + create_element(); + } } } - } - else if (new_size < current_size) - { - while (current_size > new_size) + else if (new_size < current_size) { - destroy_element(); + while (current_size > new_size) + { + destroy_element(); + } } } } @@ -222,25 +220,23 @@ namespace etl //********************************************************************* void resize(size_t new_size, T value) { - if (new_size > MAX_SIZE) + if (ETL_ASSERT(new_size <= MAX_SIZE, vector_full())) { - ETL_ERROR(vector_full()); - } - - // Size up? - if (new_size > current_size) - { - while (current_size < new_size) + // Size up? + if (new_size > current_size) { - create_element(value); + while (current_size < new_size) + { + create_element(value); + } } - } - // Size down? - else if (new_size < current_size) - { - while (current_size > new_size) + // Size down? + else if (new_size < current_size) { - destroy_element(); + while (current_size > new_size) + { + destroy_element(); + } } } } @@ -273,11 +269,7 @@ namespace etl //********************************************************************* reference at(size_t i) { - if (i >= current_size) - { - ETL_ERROR(vector_out_of_bounds()); - } - + ETL_ASSERT(i < current_size, vector_out_of_bounds()); return p_buffer[i]; } @@ -289,11 +281,7 @@ namespace etl //********************************************************************* const_reference at(size_t i) const { - if (i >= current_size) - { - ETL_ERROR(vector_out_of_bounds()); - } - + ETL_ASSERT(i < current_size, vector_out_of_bounds()); return p_buffer[i]; } @@ -363,16 +351,8 @@ namespace etl { #ifdef _DEBUG difference_type count = std::distance(first, last); - - if (count < 0) - { - ETL_ERROR(vector_iterator()); - } - - if (static_cast(count) > MAX_SIZE) - { - ETL_ERROR( vector_full()); - } + ETL_ASSERT(count >= 0, vector_iterator()); + ETL_ASSERT(static_cast(count) <= MAX_SIZE, vector_full()); #endif initialise(); @@ -395,11 +375,7 @@ namespace etl { initialise(); - if (n > MAX_SIZE) - { - ETL_ERROR(vector_full()); - } - else + if (ETL_ASSERT(n <= MAX_SIZE, vector_full())) { while (n > 0) { @@ -423,12 +399,10 @@ namespace etl //************************************************************************* void push_back() { - if (current_size == MAX_SIZE) + if (ETL_ASSERT(current_size != MAX_SIZE, vector_full())) { - ETL_ERROR(vector_full()); + create_element(); } - - create_element(); } //********************************************************************* @@ -438,11 +412,7 @@ namespace etl //********************************************************************* void push_back(parameter_t value) { - if (current_size == MAX_SIZE) - { - ETL_ERROR(vector_full()); - } - else + if (ETL_ASSERT(current_size != MAX_SIZE, vector_full())) { create_element(value); } @@ -468,11 +438,7 @@ namespace etl //********************************************************************* iterator insert(iterator position, parameter_t value) { - if ((current_size + 1) > MAX_SIZE) - { - ETL_ERROR(vector_full()); - } - else + if (ETL_ASSERT((current_size) + 1 <= MAX_SIZE, vector_full())) { create_element(value); @@ -495,11 +461,7 @@ namespace etl //********************************************************************* void insert(iterator position, size_t n, parameter_t value) { - if ((current_size + n) > MAX_SIZE) - { - ETL_ERROR(vector_full()); - } - else + if (ETL_ASSERT((current_size) + 1 <= MAX_SIZE, vector_full())) { if (position == end()) { @@ -562,11 +524,7 @@ namespace etl { size_t count = std::distance(first, last); - if ((current_size + count) > MAX_SIZE) - { - ETL_ERROR(vector_full()); - } - else + if (ETL_ASSERT((current_size) + count <= MAX_SIZE, vector_full())) { if (position == end()) { diff --git a/jenkins.h b/jenkins.h index bcccd878..b778df5c 100644 --- a/jenkins.h +++ b/jenkins.h @@ -107,11 +107,7 @@ namespace etl { STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Incompatible type"); - if (is_finalised) - { - ETL_ERROR(hash_finalised()); - } - else + if (ETL_ASSERT(!is_finalised, hash_finalised())) { while (begin != end) { @@ -127,11 +123,7 @@ namespace etl //************************************************************************* void add(uint8_t value) { - if (is_finalised) - { - ETL_ERROR(hash_finalised()); - } - else + if (ETL_ASSERT(!is_finalised, hash_finalised())) { hash += value; hash += (hash << 10); diff --git a/murmur3.h b/murmur3.h index e6e4e109..223e9c1f 100644 --- a/murmur3.h +++ b/murmur3.h @@ -120,11 +120,7 @@ namespace etl { STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Incompatible type"); - if (is_finalised) - { - ETL_ERROR(hash_finalised()); - } - else + if (ETL_ASSERT(!is_finalised, hash_finalised())) { while (begin != end) { @@ -150,11 +146,7 @@ namespace etl void add(uint8_t value) { // We can't add to a finalised hash! - if (is_finalised) - { - ETL_ERROR(hash_finalised()); - } - else + if (ETL_ASSERT(!is_finalised, hash_finalised())) { block |= value << (block_fill_count * 8); From 34e4351e851712efb48ce145d6c2d1487a229784 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 14:08:47 +0000 Subject: [PATCH 4/7] Moved non-user headers to private sub-directory. --- private/flat_multimap_base.h | 182 +++++++++++ private/flat_multiset_base.h | 179 +++++++++++ private/flat_set_base.h | 182 +++++++++++ private/forward_list_base.h | 243 ++++++++++++++ private/list_base.h | 264 +++++++++++++++ private/map_base.h | 417 ++++++++++++++++++++++++ private/multimap_base.h | 581 ++++++++++++++++++++++++++++++++++ private/multiset_base.h | 580 +++++++++++++++++++++++++++++++++ private/pool_base.h | 129 ++++++++ private/priority_queue_base.h | 154 +++++++++ private/queue_base.h | 144 +++++++++ private/set_base.h | 418 ++++++++++++++++++++++++ private/stack_base.h | 143 +++++++++ private/unordered_map_base.h | 164 ++++++++++ private/vector_base.h | 183 +++++++++++ 15 files changed, 3963 insertions(+) create mode 100644 private/flat_multimap_base.h create mode 100644 private/flat_multiset_base.h create mode 100644 private/flat_set_base.h create mode 100644 private/forward_list_base.h create mode 100644 private/list_base.h create mode 100644 private/map_base.h create mode 100644 private/multimap_base.h create mode 100644 private/multiset_base.h create mode 100644 private/pool_base.h create mode 100644 private/priority_queue_base.h create mode 100644 private/queue_base.h create mode 100644 private/set_base.h create mode 100644 private/stack_base.h create mode 100644 private/unordered_map_base.h create mode 100644 private/vector_base.h diff --git a/private/flat_multimap_base.h b/private/flat_multimap_base.h new file mode 100644 index 00000000..9a054b97 --- /dev/null +++ b/private/flat_multimap_base.h @@ -0,0 +1,182 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 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_IN_IFLAT_MULTIMAP_H__ +#error This header is a private element of etl::flat_multimap & etl::iflat_multimap +#endif + +#ifndef __ETL_FLAT_MULTIMAP_BASE__ +#define __ETL_FLAT_MULTIMAP_BASE__ + +#include + +#include "exception.h" +#include "ivector.h" + +#ifndef ETL_THROW_EXCEPTIONS +#include "error_handler.h" +#endif + +namespace etl +{ + //*************************************************************************** + ///\ingroup flat_multimap + /// Exception base for flat_multimaps + //*************************************************************************** + class flat_multimap_exception : public exception + { + public: + + flat_multimap_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// Vector full exception. + //*************************************************************************** + class flat_multimap_full : public flat_multimap_exception + { + public: + + flat_multimap_full() + : flat_multimap_exception("flat_multimap: full") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// Vector out of bounds exception. + //*************************************************************************** + class flat_multimap_out_of_bounds : public flat_multimap_exception + { + public: + + flat_multimap_out_of_bounds() + : flat_multimap_exception("flat_multimap: out of bounds") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// Vector iterator exception. + //*************************************************************************** + class flat_multimap_iterator : public flat_multimap_exception + { + public: + + flat_multimap_iterator() + : flat_multimap_exception("flat_multimap: iterator error") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// The base class for all templated flat_multimap types. + //*************************************************************************** + class flat_multimap_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the flat_multimap. + ///\return The current size of the flat_multimap. + //************************************************************************* + size_type size() const + { + return vbase.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multimap. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return vbase.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multimap. + ///\return true if full. + //************************************************************************* + bool full() const + { + return vbase.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multimap. + ///\return The capacity of the flat_multimap. + //************************************************************************* + size_type capacity() const + { + return vbase.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multimap. + ///\return The maximum size of the flat_multimap. + //************************************************************************* + size_type max_size() const + { + return vbase.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return vbase.available(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + flat_multimap_base(vector_base& vbase) + : vbase(vbase) + { + } + + vector_base& vbase; + }; +} + +#endif diff --git a/private/flat_multiset_base.h b/private/flat_multiset_base.h new file mode 100644 index 00000000..b67e7fb1 --- /dev/null +++ b/private/flat_multiset_base.h @@ -0,0 +1,179 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 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_IN_IFLAT_MULTISET_H__ +#error This header is a private element of etl::flat_multiset & etl::iflat_multiset +#endif + +#ifndef __ETL_FLAT_MULTISET_BASE__ +#define __ETL_FLAT_MULTISET_BASE__ + +#include + +#include "exception.h" +#include "ivector.h" +#include "error_handler.h" + +namespace etl +{ + //*************************************************************************** + ///\ingroup flat_multiset + /// Exception base for flat_multisets + //*************************************************************************** + class flat_multiset_exception : public exception + { + public: + + flat_multiset_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// Flat multiset full exception. + //*************************************************************************** + class flat_multiset_full : public flat_multiset_exception + { + public: + + flat_multiset_full() + : flat_multiset_exception("flat_multiset: full") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// Flat multiset out of bounds exception. + //*************************************************************************** + class flat_multiset_out_of_bounds : public flat_multiset_exception + { + public: + + flat_multiset_out_of_bounds() + : flat_multiset_exception("flat_multiset: out of bounds") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// Vector iterator exception. + //*************************************************************************** + class flat_multiset_iterator : public flat_multiset_exception + { + public: + + flat_multiset_iterator() + : flat_multiset_exception("flat_multiset: iterator error") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// The base class for all templated flat_multiset types. + //*************************************************************************** + class flat_multiset_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the flat_multiset. + ///\return The current size of the flat_multiset. + //************************************************************************* + size_type size() const + { + return vbase.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multiset. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return vbase.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multiset. + ///\return true if full. + //************************************************************************* + bool full() const + { + return vbase.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multiset. + ///\return The capacity of the flat_multiset. + //************************************************************************* + size_type capacity() const + { + return vbase.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multiset. + ///\return The maximum size of the flat_multiset. + //************************************************************************* + size_type max_size() const + { + return vbase.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return vbase.available(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + flat_multiset_base(vector_base& vbase) + : vbase(vbase) + { + } + + vector_base& vbase; + }; +} + +#endif diff --git a/private/flat_set_base.h b/private/flat_set_base.h new file mode 100644 index 00000000..b87a40ac --- /dev/null +++ b/private/flat_set_base.h @@ -0,0 +1,182 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 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_IN_IFLAT_SET_H__ +#error This header is a private element of etl::flat_set & etl::iflat_set +#endif + +#ifndef __ETL_FLAT_SET_BASE__ +#define __ETL_FLAT_SET_BASE__ + +#include + +#include "exception.h" +#include "ivector.h" + +#ifndef ETL_THROW_EXCEPTIONS +#include "error_handler.h" +#endif + +namespace etl +{ + //*************************************************************************** + ///\ingroup flat_set + /// Exception base for flat_sets + //*************************************************************************** + class flat_set_exception : public exception + { + public: + + flat_set_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_set + /// Vector full exception. + //*************************************************************************** + class flat_set_full : public flat_set_exception + { + public: + + flat_set_full() + : flat_set_exception("flat_set: full") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_set + /// Vector out of bounds exception. + //*************************************************************************** + class flat_set_out_of_bounds : public flat_set_exception + { + public: + + flat_set_out_of_bounds() + : flat_set_exception("flat_set: out of bounds") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_set + /// Vector iterator exception. + //*************************************************************************** + class flat_set_iterator : public flat_set_exception + { + public: + + flat_set_iterator() + : flat_set_exception("flat_set: iterator error") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_set + /// The base class for all templated flat_set types. + //*************************************************************************** + class flat_set_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the flat_set. + ///\return The current size of the flat_set. + //************************************************************************* + size_type size() const + { + return vbase.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_set. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return vbase.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_set. + ///\return true if full. + //************************************************************************* + bool full() const + { + return vbase.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_set. + ///\return The capacity of the flat_set. + //************************************************************************* + size_type capacity() const + { + return vbase.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_set. + ///\return The maximum size of the flat_set. + //************************************************************************* + size_type max_size() const + { + return vbase.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return vbase.available(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + flat_set_base(vector_base& vbase) + : vbase(vbase) + { + } + + vector_base& vbase; + }; +} + +#endif diff --git a/private/forward_list_base.h b/private/forward_list_base.h new file mode 100644 index 00000000..cb764730 --- /dev/null +++ b/private/forward_list_base.h @@ -0,0 +1,243 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IFORWARD_LIST_H__ +#error This header is a private element of etl::forward_list & etl::iforward_list +#endif + +#ifndef __ETL_LIST_BASE__ +#define __ETL_LIST_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the forward_list. + ///\ingroup forward_list + //*************************************************************************** + class forward_list_exception : public exception + { + public: + + forward_list_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the forward_list. + ///\ingroup forward_list + //*************************************************************************** + class forward_list_full : public forward_list_exception + { + public: + + forward_list_full() + : forward_list_exception("forward list: full") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the forward_list. + ///\ingroup forward_list + //*************************************************************************** + class forward_list_iterator : public forward_list_exception + { + public: + + forward_list_iterator() + : forward_list_exception("forward_list: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all forward_lists. + ///\ingroup forward_list + //*************************************************************************** + class forward_list_base + { + protected: + + //************************************************************************* + /// The node element in the forward_list. + //************************************************************************* + struct Node + { + Node() + : next(nullptr) + { + } + + Node* next; + }; + + public: + + typedef size_t size_type; ///< The type used for determining the size of forward_list. + + //************************************************************************* + /// Gets the size of the forward_list. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the forward_list. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the forward_list is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the forward_list is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + //************************************************************************* + /// Reverses the forward_list. + //************************************************************************* + void reverse() + { + if (is_trivial_list()) + { + return; + } + + Node* p_last = &start_node; + Node* p_current = p_last->next; + Node* p_next = p_current->next; + + p_current->next = nullptr; + + while (p_next != nullptr) + { + p_last = p_current; + p_current = p_next; + p_next = p_current->next; + + p_current->next = p_last; + } + + join(&start_node, p_current); + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + forward_list_base(size_type max_size) + : next_free(0), + current_size(0), + MAX_SIZE(max_size) + { + } + + //************************************************************************* + /// Get the head node. + //************************************************************************* + Node& get_head() + { + return *start_node.next; + } + + //************************************************************************* + /// Get the head node. + //************************************************************************* + const Node& get_head() const + { + return *start_node.next; + } + + //************************************************************************* + /// Insert a node. + //************************************************************************* + void insert_node_after(Node& position, Node& node) + { + // Connect to the forward_list. + node.next = position.next; + + join(&position, &node); + + // One more. + ++current_size; + } + + //************************************************************************* + /// Is the forward_list a trivial length? + //************************************************************************* + bool is_trivial_list() const + { + return (size() < 2); + } + + //************************************************************************* + /// Join two nodes. + //************************************************************************* + void join(Node* left, Node* right) + { + left->next = right; + } + + Node start_node; ///< The node that acts as the forward_list start. + size_type next_free; ///< The index of the next free node. + size_type current_size; ///< The number of items in the list. + const size_type MAX_SIZE; ///< The maximum size of the forward_list. + }; +} + +#endif diff --git a/private/list_base.h b/private/list_base.h new file mode 100644 index 00000000..5ff44959 --- /dev/null +++ b/private/list_base.h @@ -0,0 +1,264 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_ILIST_H__ +#error This header is a private element of etl::list & etl::ilist +#endif + +#ifndef __ETL_LIST_BASE__ +#define __ETL_LIST_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the list. + ///\ingroup list + //*************************************************************************** + class list_exception : public exception + { + public: + + list_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the list. + ///\ingroup list + //*************************************************************************** + class list_full : public list_exception + { + public: + + list_full() + : list_exception("list: full") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the list. + ///\ingroup list + //*************************************************************************** + class list_iterator : public list_exception + { + public: + + list_iterator() + : list_exception("list: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all lists. + ///\ingroup list + //*************************************************************************** + class list_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of list. + + //************************************************************************* + /// The node element in the list. + //************************************************************************* + struct Node + { + //*********************************************************************** + /// Constructor + //*********************************************************************** + Node() + : previous(nullptr), + next(nullptr) + { + } + + //*********************************************************************** + /// Reverses the previous & next pointers. + //*********************************************************************** + void reverse() + { + std::swap(previous, next); + } + + Node* previous; + Node* next; + }; + + //************************************************************************* + /// Reverses the list. + //************************************************************************* + void reverse() + { + if (is_trivial_list()) + { + return; + } + + Node* p_node = terminal_node.next; + + while (p_node != &terminal_node) + { + p_node->reverse(); + p_node = p_node->previous; // Now we've reversed it, we must go to the previous node. + } + + // Terminal node. + p_node->reverse(); + } + + //************************************************************************* + /// Gets the size of the list. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the list. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the list is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the list is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// Get the head node. + //************************************************************************* + Node& get_head() + { + return *terminal_node.next; + } + + //************************************************************************* + /// Get the head node. + //************************************************************************* + const Node& get_head() const + { + return *terminal_node.next; + } + + //************************************************************************* + /// Get the tail node. + //************************************************************************* + Node& get_tail() + { + return *terminal_node.previous; + } + + //************************************************************************* + /// Get the tail node. + //************************************************************************* + const Node& get_tail() const + { + return *terminal_node.previous; + } + + //************************************************************************* + /// Insert a node before 'position'. + //************************************************************************* + void insert_node(Node& position, Node& node) + { + // Connect to the list. + join(*position.previous, node); + join(node, position); + + // One more. + ++current_size; + } + + //************************************************************************* + /// Is the list a trivial length? + //************************************************************************* + bool is_trivial_list() const + { + return (size() < 2); + } + + //************************************************************************* + /// Join two nodes. + //************************************************************************* + void join(Node& left, Node& right) + { + left.next = &right; + right.previous = &left; + } + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + list_base(size_type max_size) + : current_size(0), + MAX_SIZE(max_size) + + { + } + + + Node terminal_node; ///< The node that acts as the list start and end. + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the list. + }; +} + +#endif diff --git a/private/map_base.h b/private/map_base.h new file mode 100644 index 00000000..12264f9d --- /dev/null +++ b/private/map_base.h @@ -0,0 +1,417 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2014 jwellbelove, rlindeman + +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. +******************************************************************************/ + +#if !defined(__ETL_IN_IMAP_H__) +#error This header is a private element of etl::map & etl::imap +#endif + +#ifndef __ETL_MAP_BASE__ +#define __ETL_MAP_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the map. + ///\ingroup map + //*************************************************************************** + class map_exception : public exception + { + public: + + map_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the map. + ///\ingroup map + //*************************************************************************** + class map_full : public map_exception + { + public: + + map_full() + : map_exception("map: full") + { + } + }; + + //*************************************************************************** + /// Map out of bounds exception. + ///\ingroup map + //*************************************************************************** + class map_out_of_bounds : public map_exception + { + public: + + map_out_of_bounds() + : map_exception("map: out of bounds") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the map. + ///\ingroup map + //*************************************************************************** + class map_iterator : public map_exception + { + public: + + map_iterator() + : map_exception("map: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all maps. + ///\ingroup map + //*************************************************************************** + class map_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of map. + + //************************************************************************* + /// Gets the size of the map. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the map. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the map is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the map is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the capacity of the vector. + ///\return The capacity of the vector. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + static const uint8_t kLeft = 0; + static const uint8_t kRight = 1; + static const uint8_t kNeither = 2; + + //************************************************************************* + /// The node element in the map. + //************************************************************************* + struct Node + { + //*********************************************************************** + /// Constructor + //*********************************************************************** + Node() : + weight(kNeither), + dir(kNeither) + { + } + + //*********************************************************************** + /// Marks the node as a leaf. + //*********************************************************************** + void mark_as_leaf() + { + weight = kNeither; + dir = kNeither; + children[0] = nullptr; + children[1] = nullptr; + } + + Node* children[2]; + uint8_t weight; + uint8_t dir; + }; + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + map_base(size_type max_size) + : current_size(0) + , MAX_SIZE(max_size) + , root_node(nullptr) + + { + } + + //************************************************************************* + /// Balance the critical node at the position provided as needed + //************************************************************************* + void balance_node(Node*& critical_node) + { + // Step 1: Update weights for all children of the critical node up to the + // newly inserted node. This step is costly (in terms of traversing nodes + // multiple times during insertion) but doesn't require as much recursion + Node* weight_node = critical_node->children[critical_node->dir]; + while (weight_node) + { + // Keep going until we reach a terminal node (dir == kNeither) + if (kNeither != weight_node->dir) + { + // Does this insert balance the previous weight factor value? + if (weight_node->weight == 1 - weight_node->dir) + { + weight_node->weight = kNeither; + } + else + { + weight_node->weight = weight_node->dir; + } + + // Update weight factor node to point to next node + weight_node = weight_node->children[weight_node->dir]; + } + else + { + // Stop loop, terminal node found + break; + } + } // while(weight_node) + + // Step 2: Update weight for critical_node or rotate tree to balance node + if (kNeither == critical_node->weight) + { + critical_node->weight = critical_node->dir; + } + // If direction is different than weight, then it will now be balanced + else if (critical_node->dir != critical_node->weight) + { + critical_node->weight = kNeither; + } + // Rotate is required to balance the tree at the critical node + else + { + // If critical node matches child node direction then perform a two + // node rotate in the direction of the critical node + if (critical_node->weight == critical_node->children[critical_node->dir]->dir) + { + rotate_2node(critical_node, critical_node->dir); + } + // Otherwise perform a three node rotation in the direction of the + // critical node + else + { + rotate_3node(critical_node, critical_node->dir, + critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); + } + } + } + + //************************************************************************* + /// Rotate two nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_2node(Node*& position, uint8_t dir) + { + // A C A B + // B C -> A E OR B C -> D A + // D E B D D E E C + // C (new position) becomes the root + // A (position) takes ownership of D as its children[kRight] child + // C (new position) takes ownership of A as its left child + // OR + // B (new position) becomes the root + // A (position) takes ownership of E as its left child + // B (new position) takes ownership of A as its right child + + // Capture new root + Node* new_root = position->children[dir]; + // Replace position's previous child with new root's other child + position->children[dir] = new_root->children[1 - dir]; + // New root now becomes parent of current position + new_root->children[1 - dir] = position; + // Clear weight factor from current position + position->weight = kNeither; + // Newly detached right now becomes current position + position = new_root; + // Clear weight factor from new root + position->weight = kNeither; + } + + //************************************************************************* + /// Rotate three nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + { + // __A__ __E__ __A__ __D__ + // _B_ C -> B A OR B _C_ -> A C + // D E D F G C D E B F G E + // F G F G + // E (new position) becomes the root + // B (position) takes ownership of F as its left child + // A takes ownership of G as its right child + // OR + // D (new position) becomes the root + // A (position) takes ownership of F as its right child + // C takes ownership of G as its left child + + // Capture new root (either E or D depending on dir) + Node* new_root = position->children[dir]->children[1 - dir]; + // Set weight factor for B or C based on F or G existing and being a different than dir + position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; + + // Detach new root from its tree (replace with new roots child) + position->children[dir]->children[1 - dir] = + new_root->children[dir]; + // Attach current left tree to new root + new_root->children[dir] = position->children[dir]; + // Set weight factor for A based on F or G + position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; + + // Move new root's right tree to current roots left tree + position->children[dir] = new_root->children[1 - dir]; + // Attach current root to new roots right tree + new_root->children[1 - dir] = position; + // Replace current position with new root + position = new_root; + // Clear weight factor for new current position + position->weight = kNeither; + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + Node* find_limit_node(Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + const Node* find_limit_node(const Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + const Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Attach the provided node to the position provided + //************************************************************************* + void attach_node(Node*& position, Node& node) + { + // Mark new node as leaf on attach to tree at position provided + node.mark_as_leaf(); + + // Add the node here + position = &node; + + // One more. + ++current_size; + } + + //************************************************************************* + /// Detach the node at the position provided + //************************************************************************* + void detach_node(Node*& position, Node*& replacement) + { + // Make temporary copy of actual nodes involved because we might lose + // their references in the process (e.g. position is the same as + // replacement or replacement is a child of position) + Node* detached = position; + Node* swap = replacement; + + // Update current position to point to swap (replacement) node first + position = swap; + + // Update replacement node to point to child in opposite direction + // otherwise we might lose the other child of the swap node + replacement = swap->children[1 - swap->dir]; + + // Point swap node to detached node's children and weight + swap->children[kLeft] = detached->children[kLeft]; + swap->children[kRight] = detached->children[kRight]; + swap->weight = detached->weight; + } + + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the map. + Node* root_node; ///< The node that acts as the map root. + }; +} + +#endif diff --git a/private/multimap_base.h b/private/multimap_base.h new file mode 100644 index 00000000..b9201f32 --- /dev/null +++ b/private/multimap_base.h @@ -0,0 +1,581 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2014 jwellbelove, rlindeman + +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. +******************************************************************************/ + +#if !defined(__ETL_IN_IMULTIMAP_H__) +#error This header is a private element of etl::multimap & etl::imultimap +#endif + +#ifndef __ETL_MULTIMAP_BASE__ +#define __ETL_MULTIMAP_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the map. + ///\ingroup map + //*************************************************************************** + class multimap_exception : public exception + { + public: + + multimap_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the map. + ///\ingroup map + //*************************************************************************** + class multimap_full : public multimap_exception + { + public: + + multimap_full() + : multimap_exception("multimap: full") + { + } + }; + + //*************************************************************************** + /// Map out of bounds exception. + ///\ingroup map + //*************************************************************************** + class multimap_out_of_bounds : public multimap_exception + { + public: + + multimap_out_of_bounds() + : multimap_exception("multimap: out of bounds") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the map. + ///\ingroup map + //*************************************************************************** + class multimap_iterator : public multimap_exception + { + public: + + multimap_iterator() + : multimap_exception("multimap: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all maps. + ///\ingroup map + //*************************************************************************** + class multimap_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of map. + + //************************************************************************* + /// Gets the size of the map. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the map. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the map is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the map is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the capacity of the vector. + ///\return The capacity of the vector. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + static const uint8_t kLeft = 0; + static const uint8_t kRight = 1; + static const uint8_t kNeither = 2; + + //************************************************************************* + /// The node element in the multimap. + //************************************************************************* + struct Node + { + //*********************************************************************** + /// Constructor + //*********************************************************************** + Node() : + weight(kNeither), + dir(kNeither) + { + } + + //*********************************************************************** + /// Marks the node as a leaf. + //*********************************************************************** + void mark_as_leaf() + { + weight = kNeither; + dir = kNeither; + parent = nullptr; + children[0] = nullptr; + children[1] = nullptr; + } + + Node* parent; + Node* children[2]; + uint8_t weight; + uint8_t dir; + }; + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + multimap_base(size_type max_size) + : current_size(0) + , MAX_SIZE(max_size) + , root_node(nullptr) + + { + } + + //************************************************************************* + /// Balance the critical node at the position provided as needed + //************************************************************************* + void balance_node(Node*& critical_node) + { + // Step 1: Update weights for all children of the critical node up to the + // newly inserted node. This step is costly (in terms of traversing nodes + // multiple times during insertion) but doesn't require as much recursion + Node* weight_node = critical_node->children[critical_node->dir]; + while (weight_node) + { + // Keep going until we reach a terminal node (dir == kNeither) + if (kNeither != weight_node->dir) + { + // Does this insert balance the previous weight factor value? + if (weight_node->weight == 1 - weight_node->dir) + { + weight_node->weight = kNeither; + } + else + { + weight_node->weight = weight_node->dir; + } + + // Update weight factor node to point to next node + weight_node = weight_node->children[weight_node->dir]; + } + else + { + // Stop loop, terminal node found + break; + } + } // while(weight_node) + + // Step 2: Update weight for critical_node or rotate tree to balance node + if (kNeither == critical_node->weight) + { + critical_node->weight = critical_node->dir; + } + // If direction is different than weight, then it will now be balanced + else if (critical_node->dir != critical_node->weight) + { + critical_node->weight = kNeither; + } + // Rotate is required to balance the tree at the critical node + else + { + // If critical node matches child node direction then perform a two + // node rotate in the direction of the critical node + if (critical_node->weight == critical_node->children[critical_node->dir]->dir) + { + rotate_2node(critical_node, critical_node->dir); + } + // Otherwise perform a three node rotation in the direction of the + // critical node + else + { + rotate_3node(critical_node, critical_node->dir, + critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); + } + } + } + + //************************************************************************* + /// Rotate two nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_2node(Node*& position, uint8_t dir) + { + // A C A B + // B C -> A E OR B C -> D A + // D E B D D E E C + // C (new position) becomes the root + // A (position) takes ownership of D as its children[kRight] child + // C (new position) takes ownership of A as its left child + // OR + // B (new position) becomes the root + // A (position) takes ownership of E as its left child + // B (new position) takes ownership of A as its right child + + // Capture new root (either B or C depending on dir) and its parent + Node* new_root = position->children[dir]; + + // Replace position's previous child with new root's other child + position->children[dir] = new_root->children[1 - dir]; + // Update new root's other child parent pointer + if (position->children[dir]) + { + position->children[dir]->parent = position; + } + + // New root's parent becomes current position's parent + new_root->parent = position->parent; + new_root->children[1 - dir] = position; + new_root->dir = 1 - dir; + + // Clear weight factor from current position + position->weight = kNeither; + // Position's parent becomes new_root + position->parent = new_root; + position = new_root; + // Clear weight factor from new root + position->weight = kNeither; + } + + //************************************************************************* + /// Rotate three nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + { + // __A__ __E__ __A__ __D__ + // _B_ C -> B A OR B _C_ -> A C + // D E D F G C D E B F G E + // F G F G + // E (new position) becomes the root + // B (position) takes ownership of F as its left child + // A takes ownership of G as its right child + // OR + // D (new position) becomes the root + // A (position) takes ownership of F as its right child + // C takes ownership of G as its left child + + // Capture new root (either E or D depending on dir) + Node* new_root = position->children[dir]->children[1 - dir]; + // Set weight factor for B or C based on F or G existing and being a different than dir + position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; + + // Detach new root from its tree (replace with new roots child) + position->children[dir]->children[1 - dir] = new_root->children[dir]; + // Update new roots child parent pointer + if (new_root->children[dir]) + { + new_root->children[dir]->parent = position->children[dir]; + } + + // Attach current left tree to new root and update its parent + new_root->children[dir] = position->children[dir]; + position->children[dir]->parent = new_root; + + // Set weight factor for A based on F or G + position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; + + // Move new root's right tree to current roots left tree + position->children[dir] = new_root->children[1 - dir]; + if (new_root->children[1 - dir]) + { + new_root->children[1 - dir]->parent = position; + } + + // Attach current root to new roots right tree and assume its parent + new_root->parent = position->parent; + new_root->children[1 - dir] = position; + new_root->dir = 1 - dir; + + // Update current position's parent and replace with new root + position->parent = new_root; + position = new_root; + // Clear weight factor for new current position + position->weight = kNeither; + } + + //************************************************************************* + /// Find the next node in sequence from the node provided + //************************************************************************* + void next_node(Node*& position) const + { + if (position) + { + // Is there a tree on the right? then find the minimum of that tree + if (position->children[kRight]) + { + // Return minimum node found + position = find_limit_node(position->children[kRight], kLeft); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; // find_parent_node(root_node, position); + // Repeat while previous position was on right side of parent tree + } while (parent && parent->children[kRight] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the next node in sequence from the node provided + //************************************************************************* + void next_node(const Node*& position) const + { + if (position) + { + // Is there a tree on the right? then find the minimum of that tree + if (position->children[kRight]) + { + // Return minimum node found + position = find_limit_node(position->children[kRight], kLeft); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + const Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on right side of parent tree + } while (parent && parent->children[kRight] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the previous node in sequence from the node provided + //************************************************************************* + void prev_node(Node*& position) const + { + // If starting at the terminal end, the previous node is the maximum node + // from the root + if (!position) + { + position = find_limit_node(root_node, kRight); + } + else + { + // Is there a tree on the left? then find the maximum of that tree + if (position->children[kLeft]) + { + // Return maximum node found + position = find_limit_node(position->children[kLeft], kRight); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on left side of parent tree + } while (parent && parent->children[kLeft] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the previous node in sequence from the node provided + //************************************************************************* + void prev_node(const Node*& position) const + { + // If starting at the terminal end, the previous node is the maximum node + // from the root + if (!position) + { + position = find_limit_node(root_node, kRight); + } + else + { + // Is there a tree on the left? then find the maximum of that tree + if (position->children[kLeft]) + { + // Return maximum node found + position = find_limit_node(position->children[kLeft], kRight); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + const Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on left side of parent tree + } while (parent && parent->children[kLeft] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + Node* find_limit_node(Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Attach the provided node to the position provided + //************************************************************************* + void attach_node(Node* parent, Node*& position, Node& node) + { + // Mark new node as leaf on attach to tree at position provided + node.mark_as_leaf(); + + // Keep track of this node's parent + node.parent = parent; + + // Add the node here + position = &node; + + // One more. + ++current_size; + } + + //************************************************************************* + /// Detach the node at the position provided + //************************************************************************* + void detach_node(Node*& position, Node*& replacement) + { + // Make temporary copy of actual nodes involved because we might lose + // their references in the process (e.g. position is the same as + // replacement or replacement is a child of position) + Node* detached = position; + Node* swap = replacement; + + // Update current position to point to swap (replacement) node first + position = swap; + + // Update replacement node to point to child in opposite direction + // otherwise we might lose the other child of the swap node + replacement = swap->children[1 - swap->dir]; + + // Point swap node to detached node's parent, children and weight + swap->parent = detached->parent; + swap->children[kLeft] = detached->children[kLeft]; + swap->children[kRight] = detached->children[kRight]; + if (swap->children[kLeft]) + { + swap->children[kLeft]->parent = swap; + } + if (swap->children[kRight]) + { + swap->children[kRight]->parent = swap; + } + swap->weight = detached->weight; + } + + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the map. + Node* root_node; ///< The node that acts as the multimap root. + }; +} + +#endif diff --git a/private/multiset_base.h b/private/multiset_base.h new file mode 100644 index 00000000..6e0827d8 --- /dev/null +++ b/private/multiset_base.h @@ -0,0 +1,580 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 jwellbelove, rlindeman + +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. +******************************************************************************/ + +#if !defined(__ETL_IN_IMULTISET_H__) +#error This header is a private element of etl::multiset & etl::imultiset +#endif + +#ifndef __ETL_MULTISET_BASE__ +#define __ETL_MULTISET_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the set. + ///\ingroup set + //*************************************************************************** + class multiset_exception : public exception + { + public: + + multiset_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the set. + ///\ingroup set + //*************************************************************************** + class multiset_full : public multiset_exception + { + public: + + multiset_full() + : multiset_exception("multiset: full") + { + } + }; + + //*************************************************************************** + /// Map out of bounds exception. + ///\ingroup set + //*************************************************************************** + class multiset_out_of_bounds : public multiset_exception + { + public: + + multiset_out_of_bounds() + : multiset_exception("multiset: out of bounds") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the set. + ///\ingroup set + //*************************************************************************** + class multiset_iterator : public multiset_exception + { + public: + + multiset_iterator() + : multiset_exception("multiset: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all sets. + ///\ingroup set + //*************************************************************************** + class multiset_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of set. + + //************************************************************************* + /// Gets the size of the set. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the set. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the set is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the set is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the capacity of the vector. + ///\return The capacity of the vector. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + static const uint8_t kLeft = 0; + static const uint8_t kRight = 1; + static const uint8_t kNeither = 2; + + //************************************************************************* + /// The node element in the multiset. + //************************************************************************* + struct Node + { + //*********************************************************************** + /// Constructor + //*********************************************************************** + Node() : + weight(kNeither), + dir(kNeither) + { + } + + //*********************************************************************** + /// Marks the node as a leaf. + //*********************************************************************** + void mark_as_leaf() + { + weight = kNeither; + dir = kNeither; + parent = nullptr; + children[0] = nullptr; + children[1] = nullptr; + } + + Node* parent; + Node* children[2]; + uint8_t weight; + uint8_t dir; + }; + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + multiset_base(size_type max_size) + : current_size(0) + , MAX_SIZE(max_size) + , root_node(nullptr) + { + } + + //************************************************************************* + /// Attach the provided node to the position provided + //************************************************************************* + void attach_node(Node* parent, Node*& position, Node& node) + { + // Mark new node as leaf on attach to tree at position provided + node.mark_as_leaf(); + + // Keep track of this node's parent + node.parent = parent; + + // Add the node here + position = &node; + + // One more. + ++current_size; + } + + //************************************************************************* + /// Detach the node at the position provided + //************************************************************************* + void detach_node(Node*& position, Node*& replacement) + { + // Make temporary copy of actual nodes involved because we might lose + // their references in the process (e.g. position is the same as + // replacement or replacement is a child of position) + Node* detached = position; + Node* swap = replacement; + + // Update current position to point to swap (replacement) node first + position = swap; + + // Update replacement node to point to child in opposite direction + // otherwise we might lose the other child of the swap node + replacement = swap->children[1 - swap->dir]; + + // Point swap node to detached node's parent, children and weight + swap->parent = detached->parent; + swap->children[kLeft] = detached->children[kLeft]; + swap->children[kRight] = detached->children[kRight]; + if (swap->children[kLeft]) + { + swap->children[kLeft]->parent = swap; + } + if (swap->children[kRight]) + { + swap->children[kRight]->parent = swap; + } + swap->weight = detached->weight; + } + + //************************************************************************* + /// Balance the critical node at the position provided as needed + //************************************************************************* + void balance_node(Node*& critical_node) + { + // Step 1: Update weights for all children of the critical node up to the + // newly inserted node. This step is costly (in terms of traversing nodes + // multiple times during insertion) but doesn't require as much recursion + Node* weight_node = critical_node->children[critical_node->dir]; + while (weight_node) + { + // Keep going until we reach a terminal node (dir == kNeither) + if (kNeither != weight_node->dir) + { + // Does this insert balance the previous weight factor value? + if (weight_node->weight == 1 - weight_node->dir) + { + weight_node->weight = kNeither; + } + else + { + weight_node->weight = weight_node->dir; + } + + // Update weight factor node to point to next node + weight_node = weight_node->children[weight_node->dir]; + } + else + { + // Stop loop, terminal node found + break; + } + } // while(weight_node) + + // Step 2: Update weight for critical_node or rotate tree to balance node + if (kNeither == critical_node->weight) + { + critical_node->weight = critical_node->dir; + } + // If direction is different than weight, then it will now be balanced + else if (critical_node->dir != critical_node->weight) + { + critical_node->weight = kNeither; + } + // Rotate is required to balance the tree at the critical node + else + { + // If critical node matches child node direction then perform a two + // node rotate in the direction of the critical node + if (critical_node->weight == critical_node->children[critical_node->dir]->dir) + { + rotate_2node(critical_node, critical_node->dir); + } + // Otherwise perform a three node rotation in the direction of the + // critical node + else + { + rotate_3node(critical_node, critical_node->dir, + critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); + } + } + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + Node* find_limit_node(Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Find the next node in sequence from the node provided + //************************************************************************* + void next_node(Node*& position) const + { + if (position) + { + // Is there a tree on the right? then find the minimum of that tree + if (position->children[kRight]) + { + // Return minimum node found + position = find_limit_node(position->children[kRight], kLeft); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; // find_parent_node(root_node, position); + // Repeat while previous position was on right side of parent tree + } while (parent && parent->children[kRight] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the next node in sequence from the node provided + //************************************************************************* + void next_node(const Node*& position) const + { + if (position) + { + // Is there a tree on the right? then find the minimum of that tree + if (position->children[kRight]) + { + // Return minimum node found + position = find_limit_node(position->children[kRight], kLeft); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + const Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on right side of parent tree + } while (parent && parent->children[kRight] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the previous node in sequence from the node provided + //************************************************************************* + void prev_node(Node*& position) const + { + // If starting at the terminal end, the previous node is the maximum node + // from the root + if (!position) + { + position = find_limit_node(root_node, kRight); + } + else + { + // Is there a tree on the left? then find the maximum of that tree + if (position->children[kLeft]) + { + // Return maximum node found + position = find_limit_node(position->children[kLeft], kRight); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on left side of parent tree + } while (parent && parent->children[kLeft] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Find the previous node in sequence from the node provided + //************************************************************************* + void prev_node(const Node*& position) const + { + // If starting at the terminal end, the previous node is the maximum node + // from the root + if (!position) + { + position = find_limit_node(root_node, kRight); + } + else + { + // Is there a tree on the left? then find the maximum of that tree + if (position->children[kLeft]) + { + // Return maximum node found + position = find_limit_node(position->children[kLeft], kRight); + } + // Otherwise find the parent of this node + else + { + // Start with current position as parent + const Node* parent = position; + do { + // Update current position as previous parent + position = parent; + // Find parent of current position + parent = position->parent; + // Repeat while previous position was on left side of parent tree + } while (parent && parent->children[kLeft] == position); + + // Set parent node as the next position + position = parent; + } + } + } + + //************************************************************************* + /// Rotate two nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_2node(Node*& position, uint8_t dir) + { + // A C A B + // B C -> A E OR B C -> D A + // D E B D D E E C + // C (new position) becomes the root + // A (position) takes ownership of D as its children[kRight] child + // C (new position) takes ownership of A as its left child + // OR + // B (new position) becomes the root + // A (position) takes ownership of E as its left child + // B (new position) takes ownership of A as its right child + + // Capture new root (either B or C depending on dir) and its parent + Node* new_root = position->children[dir]; + + // Replace position's previous child with new root's other child + position->children[dir] = new_root->children[1 - dir]; + // Update new root's other child parent pointer + if (position->children[dir]) + { + position->children[dir]->parent = position; + } + + // New root's parent becomes current position's parent + new_root->parent = position->parent; + new_root->children[1 - dir] = position; + new_root->dir = 1 - dir; + + // Clear weight factor from current position + position->weight = kNeither; + // Position's parent becomes new_root + position->parent = new_root; + position = new_root; + // Clear weight factor from new root + position->weight = kNeither; + } + + //************************************************************************* + /// Rotate three nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + { + // __A__ __E__ __A__ __D__ + // _B_ C -> B A OR B _C_ -> A C + // D E D F G C D E B F G E + // F G F G + // E (new position) becomes the root + // B (position) takes ownership of F as its left child + // A takes ownership of G as its right child + // OR + // D (new position) becomes the root + // A (position) takes ownership of F as its right child + // C takes ownership of G as its left child + + // Capture new root (either E or D depending on dir) + Node* new_root = position->children[dir]->children[1 - dir]; + // Set weight factor for B or C based on F or G existing and being a different than dir + position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; + + // Detach new root from its tree (replace with new roots child) + position->children[dir]->children[1 - dir] = new_root->children[dir]; + // Update new roots child parent pointer + if (new_root->children[dir]) + { + new_root->children[dir]->parent = position->children[dir]; + } + + // Attach current left tree to new root and update its parent + new_root->children[dir] = position->children[dir]; + position->children[dir]->parent = new_root; + + // Set weight factor for A based on F or G + position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; + + // Move new root's right tree to current roots left tree + position->children[dir] = new_root->children[1 - dir]; + if (new_root->children[1 - dir]) + { + new_root->children[1 - dir]->parent = position; + } + + // Attach current root to new roots right tree and assume its parent + new_root->parent = position->parent; + new_root->children[1 - dir] = position; + new_root->dir = 1 - dir; + + // Update current position's parent and replace with new root + position->parent = new_root; + position = new_root; + // Clear weight factor for new current position + position->weight = kNeither; + } + + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the set. + Node* root_node; ///< The node that acts as the multiset root. + }; +} + +#endif diff --git a/private/pool_base.h b/private/pool_base.h new file mode 100644 index 00000000..ebb90355 --- /dev/null +++ b/private/pool_base.h @@ -0,0 +1,129 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IPOOL_H__ +#error This header is a private element of etl::pool & etl::ipool +#endif + +#ifndef __ETL_POOL_BASE__ +#define __ETL_POOL_BASE__ + +#include + +#include "exception.h" + +#ifndef ETL_THROW_EXCEPTIONS +#include "error_handler.h" +#endif + +namespace etl +{ + //*************************************************************************** + /// The base class for pool exceptions. + ///\ingroup pool + //*************************************************************************** + class pool_exception : public exception + { + public: + + pool_exception(const char* what) + : exception(what) + {} + }; + + //*************************************************************************** + /// The exception thrown when the pool has no more free items. + ///\ingroup pool + //*************************************************************************** + class pool_no_allocation : public pool_exception + { + public: + + pool_no_allocation() + : pool_exception("pool: no allocation") + {} + }; + + //*************************************************************************** + /// The exception thrown when an object is released which does not belong to the pool. + ///\ingroup pool + //*************************************************************************** + class pool_object_not_in_pool : public pool_exception + { + public: + + pool_object_not_in_pool() + : pool_exception("pool: not in pool") + {} + }; + + //************************************************************************* + /// The base class for all templated pool types. + ///\ingroup pool + //************************************************************************* + class pool_base + { + public: + + //************************************************************************* + /// Returns the number of free items in the pool. + //************************************************************************* + size_t available() const + { + return MAX_SIZE - items_allocated; + } + + //************************************************************************* + /// Checks to see if there are no free items in the pool. + /// \return true if there are none free (or 'empty') + //************************************************************************* + bool none_free() const + { + return items_allocated == MAX_SIZE; + } + + protected: + + //************************************************************************* + /// Constructor + //************************************************************************* + pool_base(size_t max_size) + : next_free(0), + items_allocated(0), + MAX_SIZE(max_size) + { + } + + size_t next_free; ///< The next free slot in the block. + size_t items_allocated; ///< The number of items allocated. + const size_t MAX_SIZE; ///< The maximum number of objects that can be allocated. + }; +} +#endif + diff --git a/private/priority_queue_base.h b/private/priority_queue_base.h new file mode 100644 index 00000000..ac441c5a --- /dev/null +++ b/private/priority_queue_base.h @@ -0,0 +1,154 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 jwellbelove, rlindeman + +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_IN_IPRIORITY_QUEUE_H__ +#error This header is a private element of etl::priority_queue & etl::ipriority_queue +#endif + +#ifndef __ETL_PRIORITY_QUEUE_BASE__ +#define __ETL_PRIORITY_QUEUE_BASE__ + +#include + +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// The base class for priority_queue exceptions. + ///\ingroup queue + //*************************************************************************** + class priority_queue_exception : public exception + { + public: + + priority_queue_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// The exception thrown when the queue is full. + ///\ingroup queue + //*************************************************************************** + class priority_queue_full : public priority_queue_exception + { + public: + + priority_queue_full() + : priority_queue_exception("priority_queue: full") + { + } + }; + + //*************************************************************************** + /// The priority queue iterator exception on reversed iterators + ///\ingroup queue + //*************************************************************************** + class priority_queue_iterator : public priority_queue_exception + { + public: + + priority_queue_iterator() + : priority_queue_exception("priority_queue: iterator error") + { + } + }; + + //*************************************************************************** + /// The base class for all priority queues. + ///\ingroup queue + //*************************************************************************** + class priority_queue_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of queue. + + //************************************************************************* + /// Returns the current number of items in the priority queue. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Returns the maximum number of items that can be queued. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the priority queue is empty. + /// \return true if the queue is empty, otherwise false + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the priority queue is full. + /// \return true if the priority queue is full, otherwise false + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + priority_queue_base(size_type max_size) + : current_size(0), + MAX_SIZE(max_size) + { + } + + size_type current_size; ///< The number of items in the priority queue. + const size_type MAX_SIZE; ///< The maximum number of items in the priority queue. + }; +} + +#endif diff --git a/private/queue_base.h b/private/queue_base.h new file mode 100644 index 00000000..39d3724b --- /dev/null +++ b/private/queue_base.h @@ -0,0 +1,144 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IQUEUE_H__ +#error This header is a private element of etl::queue & etl::iqueue +#endif + +#ifndef __ETL_QUEUE_BASE__ +#define __ETL_QUEUE_BASE__ + +#include + +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// The base class for queue exceptions. + ///\ingroup queue + //*************************************************************************** + class queue_exception : public exception + { + public: + + queue_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// The exception thrown when the queue is full. + ///\ingroup queue + //*************************************************************************** + class queue_full : public queue_exception + { + public: + + queue_full() + : queue_exception("queue: full") + { + } + }; + + //*************************************************************************** + /// The base class for all queues. + ///\ingroup queue + //*************************************************************************** + class queue_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of queue. + + //************************************************************************* + /// Returns the current number of items in the queue. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Returns the maximum number of items that can be queued. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the queue is empty. + /// \return true if the queue is empty, otherwise false + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the queue is full. + /// \return true if the queue is full, otherwise false + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + queue_base(size_type max_size) + : in(0), + out(0), + current_size(0), + MAX_SIZE(max_size) + { + } + + size_type in; ///< Where to input new data. + size_type out; ///< Where to get the oldest data. + size_type current_size; ///< The number of items in the queue. + const size_type MAX_SIZE; ///< The maximum number of items in the queue. + }; +} + +#endif diff --git a/private/set_base.h b/private/set_base.h new file mode 100644 index 00000000..1148bfac --- /dev/null +++ b/private/set_base.h @@ -0,0 +1,418 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 jwellbelove, rlindeman + +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. +******************************************************************************/ + +#if !defined(__ETL_IN_ISET_H__) +#error This header is a private element of etl::set & etl::iset +#endif + +#ifndef __ETL_SET_BASE__ +#define __ETL_SET_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the set. + ///\ingroup set + //*************************************************************************** + class set_exception : public exception + { + public: + + set_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the set. + ///\ingroup set + //*************************************************************************** + class set_full : public set_exception + { + public: + + set_full() + : set_exception("set: full") + { + } + }; + + //*************************************************************************** + /// Map out of bounds exception. + ///\ingroup set + //*************************************************************************** + class set_out_of_bounds : public set_exception + { + public: + + set_out_of_bounds() + : set_exception("set: out of bounds") + { + } + }; + + //*************************************************************************** + /// Iterator exception for the set. + ///\ingroup set + //*************************************************************************** + class set_iterator : public set_exception + { + public: + + set_iterator() + : set_exception("set: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all sets. + ///\ingroup set + //*************************************************************************** + class set_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of set. + + //************************************************************************* + /// Gets the size of the set. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the set. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the set is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the set is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the capacity of the vector. + ///\return The capacity of the vector. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + static const uint8_t kLeft = 0; + static const uint8_t kRight = 1; + static const uint8_t kNeither = 2; + + //************************************************************************* + /// The node element in the set. + //************************************************************************* + struct Node + { + //*********************************************************************** + /// Constructor + //*********************************************************************** + Node() : + weight(kNeither), + dir(kNeither) + { + } + + //*********************************************************************** + /// Marks the node as a leaf. + //*********************************************************************** + void mark_as_leaf() + { + weight = kNeither; + dir = kNeither; + children[0] = nullptr; + children[1] = nullptr; + } + + Node* children[2]; + uint8_t weight; + uint8_t dir; + }; + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + set_base(size_type max_size) + : current_size(0) + , MAX_SIZE(max_size) + , root_node(nullptr) + + { + } + + //************************************************************************* + /// Attach the provided node to the position provided + //************************************************************************* + void attach_node(Node*& position, Node& node) + { + // Mark new node as leaf on attach to tree at position provided + node.mark_as_leaf(); + + // Add the node here + position = &node; + + // One more. + ++current_size; + } + + //************************************************************************* + /// Detach the node at the position provided + //************************************************************************* + void detach_node(Node*& position, Node*& replacement) + { + // Make temporary copy of actual nodes involved because we might lose + // their references in the process (e.g. position is the same as + // replacement or replacement is a child of position) + Node* detached = position; + Node* swap = replacement; + + // Update current position to point to swap (replacement) node first + position = swap; + + // Update replacement node to point to child in opposite direction + // otherwise we might lose the other child of the swap node + replacement = swap->children[1 - swap->dir]; + + // Point swap node to detached node's children and weight + swap->children[kLeft] = detached->children[kLeft]; + swap->children[kRight] = detached->children[kRight]; + swap->weight = detached->weight; + } + + //************************************************************************* + /// Balance the critical node at the position provided as needed + //************************************************************************* + void balance_node(Node*& critical_node) + { + // Step 1: Update weights for all children of the critical node up to the + // newly inserted node. This step is costly (in terms of traversing nodes + // multiple times during insertion) but doesn't require as much recursion + Node* weight_node = critical_node->children[critical_node->dir]; + while (weight_node) + { + // Keep going until we reach a terminal node (dir == kNeither) + if (kNeither != weight_node->dir) + { + // Does this insert balance the previous weight factor value? + if (weight_node->weight == 1 - weight_node->dir) + { + weight_node->weight = kNeither; + } + else + { + weight_node->weight = weight_node->dir; + } + + // Update weight factor node to point to next node + weight_node = weight_node->children[weight_node->dir]; + } + else + { + // Stop loop, terminal node found + break; + } + } // while(weight_node) + + // Step 2: Update weight for critical_node or rotate tree to balance node + if (kNeither == critical_node->weight) + { + critical_node->weight = critical_node->dir; + } + // If direction is different than weight, then it will now be balanced + else if (critical_node->dir != critical_node->weight) + { + critical_node->weight = kNeither; + } + // Rotate is required to balance the tree at the critical node + else + { + // If critical node matches child node direction then perform a two + // node rotate in the direction of the critical node + if (critical_node->weight == critical_node->children[critical_node->dir]->dir) + { + rotate_2node(critical_node, critical_node->dir); + } + // Otherwise perform a three node rotation in the direction of the + // critical node + else + { + rotate_3node(critical_node, critical_node->dir, + critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); + } + } + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + Node* find_limit_node(Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Find the node whose key would go before all the other keys from the + /// position provided + //************************************************************************* + const Node* find_limit_node(const Node* position, const int8_t dir) const + { + // Something at this position and in the direction specified? keep going + const Node* limit_node = position; + while (limit_node && limit_node->children[dir]) + { + limit_node = limit_node->children[dir]; + } + + // Return the limit node position found + return limit_node; + } + + //************************************************************************* + /// Rotate two nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_2node(Node*& position, uint8_t dir) + { + // A C A B + // B C -> A E OR B C -> D A + // D E B D D E E C + // C (new position) becomes the root + // A (position) takes ownership of D as its children[kRight] child + // C (new position) takes ownership of A as its left child + // OR + // B (new position) becomes the root + // A (position) takes ownership of E as its left child + // B (new position) takes ownership of A as its right child + + // Capture new root + Node* new_root = position->children[dir]; + // Replace position's previous child with new root's other child + position->children[dir] = new_root->children[1 - dir]; + // New root now becomes parent of current position + new_root->children[1 - dir] = position; + // Clear weight factor from current position + position->weight = kNeither; + // Newly detached right now becomes current position + position = new_root; + // Clear weight factor from new root + position->weight = kNeither; + } + + //************************************************************************* + /// Rotate three nodes at the position provided the to balance the tree + //************************************************************************* + void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + { + // __A__ __E__ __A__ __D__ + // _B_ C -> B A OR B _C_ -> A C + // D E D F G C D E B F G E + // F G F G + // E (new position) becomes the root + // B (position) takes ownership of F as its left child + // A takes ownership of G as its right child + // OR + // D (new position) becomes the root + // A (position) takes ownership of F as its right child + // C takes ownership of G as its left child + + // Capture new root (either E or D depending on dir) + Node* new_root = position->children[dir]->children[1 - dir]; + // Set weight factor for B or C based on F or G existing and being a different than dir + position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; + + // Detach new root from its tree (replace with new roots child) + position->children[dir]->children[1 - dir] = + new_root->children[dir]; + // Attach current left tree to new root + new_root->children[dir] = position->children[dir]; + // Set weight factor for A based on F or G + position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; + + // Move new root's right tree to current roots left tree + position->children[dir] = new_root->children[1 - dir]; + // Attach current root to new roots right tree + new_root->children[1 - dir] = position; + // Replace current position with new root + position = new_root; + // Clear weight factor for new current position + position->weight = kNeither; + } + + + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the set. + Node* root_node; ///< The node that acts as the set root. + }; +} + +#endif diff --git a/private/stack_base.h b/private/stack_base.h new file mode 100644 index 00000000..8e60c6f7 --- /dev/null +++ b/private/stack_base.h @@ -0,0 +1,143 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2014 jwellbelove + +Permission is hereby granted, free of charge, to any person obtatoptopg a copy +of this software and associated documentation files(the "Software"), to deal +top the Software withtop restriction, topcludtopg withtop 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 followtopg conditions : + +The above copyright notice and this permission notice shall be included top 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_IN_ISTACK_H__ +#error This header is a private element of etl::stack & etl::istack +#endif + +#ifndef __ETL_STACK_BASE__ +#define __ETL_STACK_BASE__ + +#include + +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + ///\ingroup stack + /// The base class for stack exceptions. + //*************************************************************************** + class stack_exception : public exception + { + public: + + stack_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup stack + /// The exception thrown when the stack is full. + //*************************************************************************** + class stack_full : public stack_exception + { + public: + + stack_full() + : stack_exception("stack: full") + { + } + }; + + //*************************************************************************** + ///\ingroup stack + /// A fixed capacity stack written in the STL style. + /// \warntopg This stack cannot be used for concurrent access from multiple threads. + //*************************************************************************** + class stack_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of stack. + + //************************************************************************* + /// Checks to see if the stack is empty. + /// \return true if the stack is empty, otherwise false + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the stack is full. + /// \return true if the stack is full, otherwise false + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the current number of items top the stack. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Returns the maximum number of items that can be stacked. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + stack_base(size_type max_size) + : top_index(0), + current_size(0), + MAX_SIZE(max_size) + { + } + + size_type top_index; ///< The index of the top of the stack. + size_type current_size; ///< The number of items in the stack. + const size_type MAX_SIZE; ///< The maximum number of items in the stack. + }; +} + +#endif diff --git a/private/unordered_map_base.h b/private/unordered_map_base.h new file mode 100644 index 00000000..4c7d25a8 --- /dev/null +++ b/private/unordered_map_base.h @@ -0,0 +1,164 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IUNORDERED_MAP_H__ +#error This header is a private element of etl::unordered_map & etl::iunordered_map +#endif + +#ifndef __ETL_UNORDERED_MAP_BASE__ +#define __ETL_UNORDERED_MAP_BASE__ + +#include +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception for the unordered_map. + ///\ingroup unordered_map + //*************************************************************************** + class unordered_map_exception : public exception + { + public: + + unordered_map_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Full exception for the unordered_map. + ///\ingroup unordered_map + //*************************************************************************** + class unordered_map_full : public unordered_map_exception + { + public: + + unordered_map_full() + : unordered_map_exception("unordered_map: full") + { + } + }; + + //*************************************************************************** + /// Out of range exception for the unordered_map. + ///\ingroup unordered_map + //*************************************************************************** + class unordered_map_out_of_range : public unordered_map_exception + { + public: + + unordered_map_out_of_range() + : unordered_map_exception("unordered_map: out of range") + {} + }; + + //*************************************************************************** + /// Iterator exception for the unordered_map. + ///\ingroup unordered_map + //*************************************************************************** + class unordered_map_iterator : public unordered_map_exception + { + public: + + unordered_map_iterator() + : unordered_map_exception("unordered_map: iterator problem") + { + } + }; + + //*************************************************************************** + /// The base class for all unordered_maps. + ///\ingroup unordered_map + //*************************************************************************** + class unordered_map_base + { + public: + + typedef size_t size_type; ///< The type used for determining the size of unordered_map. + + //************************************************************************* + /// Gets the size of the unordered_map. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Gets the maximum possible size of the unordered_map. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Checks to see if the unordered_map is empty. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Checks to see if the unordered_map is full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// The constructor that is called from derived classes. + //************************************************************************* + unordered_map_base(size_type max_size) + : current_size(0), + MAX_SIZE(max_size) + { + } + + size_type current_size; ///< The number of the used nodes. + const size_type MAX_SIZE; ///< The maximum size of the unordered_map. + }; +} + +#endif diff --git a/private/vector_base.h b/private/vector_base.h new file mode 100644 index 00000000..74a94ed9 --- /dev/null +++ b/private/vector_base.h @@ -0,0 +1,183 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IVECTOR_H__ +#error This header is a private element of etl::vector & etl::ivector +#endif + +#ifndef __ETL_VECTOR_BASE__ +#define __ETL_VECTOR_BASE__ + +#include + +#include "exception.h" + +#ifndef ETL_THROW_EXCEPTIONS +#include "error_handler.h" +#endif + +namespace etl +{ + //*************************************************************************** + ///\ingroup vector + /// Exception base for vectors + //*************************************************************************** + class vector_exception : public exception + { + public: + + vector_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup vector + /// Vector full exception. + //*************************************************************************** + class vector_full : public vector_exception + { + public: + + vector_full() + : vector_exception("vector: full") + { + } + }; + + //*************************************************************************** + ///\ingroup vector + /// Vector out of bounds exception. + //*************************************************************************** + class vector_out_of_bounds : public vector_exception + { + public: + + vector_out_of_bounds() + : vector_exception("vector: out of bounds") + { + } + }; + + //*************************************************************************** + ///\ingroup vector + /// Vector iterator exception. + //*************************************************************************** + class vector_iterator : public vector_exception + { + public: + + vector_iterator() + : vector_exception("vector: iterator error") + { + } + }; + + //*************************************************************************** + ///\ingroup vector + /// The base class for all templated vector types. + //*************************************************************************** + class vector_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the vector. + ///\return The current size of the vector. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Checks the 'empty' state of the vector. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return (current_size == 0); + } + + //************************************************************************* + /// Checks the 'full' state of the vector. + ///\return true if full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the capacity of the vector. + ///\return The capacity of the vector. + //************************************************************************* + size_type capacity() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the maximum possible size of the vector. + ///\return The maximum size of the vector. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + vector_base(size_t max_size) + : current_size(0), + MAX_SIZE(max_size) + { + } + + size_type current_size; /// Date: Thu, 10 Dec 2015 14:08:59 +0000 Subject: [PATCH 5/7] Moved non-user headers to private sub-directory. --- private/deque_base.h | 172 +++++++++++++++++++++++++++++++++++++ private/flat_map_base.h | 182 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 private/deque_base.h create mode 100644 private/flat_map_base.h diff --git a/private/deque_base.h b/private/deque_base.h new file mode 100644 index 00000000..3553eef5 --- /dev/null +++ b/private/deque_base.h @@ -0,0 +1,172 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +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_IN_IDEQUE_H__ +#error This header is a private element of etl::deque & etl::ideque +#endif + +#ifndef __ETL_DEQUE_BASE__ +#define __ETL_DEQUE_BASE__ + +#include + +#include "exception.h" + +namespace etl +{ + //*************************************************************************** + /// Exception base for deques + ///\ingroup deque + //*************************************************************************** + class deque_exception : public exception + { + public: + + deque_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Deque full exception. + ///\ingroup deque + //*************************************************************************** + class deque_full : public deque_exception + { + public: + + deque_full() + : deque_exception("deque: full") + { + } + }; + + //*************************************************************************** + /// Deque empty exception. + ///\ingroup deque + //*************************************************************************** + class deque_empty : public deque_exception + { + public: + + deque_empty() + : deque_exception("deque: empty") + { + } + }; + + //*************************************************************************** + /// Deque out of bounds exception. + ///\ingroup deque + //*************************************************************************** + class deque_out_of_bounds : public deque_exception + { + public: + + deque_out_of_bounds() + : deque_exception("deque: out of bounds") + { + } + }; + + //*************************************************************************** + /// The base class for all templated deque types. + ///\ingroup deque + //*************************************************************************** + class deque_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the deque. + ///\return The current size of the deque. + //************************************************************************* + size_type size() const + { + return current_size; + } + + //************************************************************************* + /// Checks the 'empty' state of the deque. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return (current_size == 0); + } + + //************************************************************************* + /// Checks the 'full' state of the deque. + ///\return true if full. + //************************************************************************* + bool full() const + { + return current_size == MAX_SIZE; + } + + //************************************************************************* + /// Returns the maximum possible size of the deque. + ///\return The maximum size of the deque. + //************************************************************************* + size_type max_size() const + { + return MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + deque_base(size_t max_size, size_t buffer_size) + : current_size(0), + MAX_SIZE(max_size), + BUFFER_SIZE(buffer_size) + { + } + + size_type current_size; ///< The current number of elements in the deque. + const size_type MAX_SIZE; ///< The maximum number of elements in the deque. + const size_type BUFFER_SIZE; ///< The number of elements in the buffer. + }; +} + +#endif diff --git a/private/flat_map_base.h b/private/flat_map_base.h new file mode 100644 index 00000000..b95797d1 --- /dev/null +++ b/private/flat_map_base.h @@ -0,0 +1,182 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl + +Copyright(c) 2015 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_IN_IFLAT_MAP_H__ +#error This header is a private element of etl::flat_map & etl::iflat_map +#endif + +#ifndef __ETL_FLAT_MAP_BASE__ +#define __ETL_FLAT_MAP_BASE__ + +#include + +#include "exception.h" +#include "ivector.h" + +#ifndef ETL_THROW_EXCEPTIONS +#include "error_handler.h" +#endif + +namespace etl +{ + //*************************************************************************** + ///\ingroup flat_map + /// Exception base for flat_maps + //*************************************************************************** + class flat_map_exception : public exception + { + public: + + flat_map_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_map + /// Vector full exception. + //*************************************************************************** + class flat_map_full : public flat_map_exception + { + public: + + flat_map_full() + : flat_map_exception("flat_map: full") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_map + /// Vector out of bounds exception. + //*************************************************************************** + class flat_map_out_of_bounds : public flat_map_exception + { + public: + + flat_map_out_of_bounds() + : flat_map_exception("flat_map: out of bounds") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_map + /// Vector iterator exception. + //*************************************************************************** + class flat_map_iterator : public flat_map_exception + { + public: + + flat_map_iterator() + : flat_map_exception("flat_map: iterator error") + { + } + }; + + //*************************************************************************** + ///\ingroup flat_map + /// The base class for all templated flat_map types. + //*************************************************************************** + class flat_map_base + { + public: + + typedef size_t size_type; + + //************************************************************************* + /// Gets the current size of the flat_map. + ///\return The current size of the flat_map. + //************************************************************************* + size_type size() const + { + return vbase.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_map. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return vbase.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_map. + ///\return true if full. + //************************************************************************* + bool full() const + { + return vbase.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_map. + ///\return The capacity of the flat_map. + //************************************************************************* + size_type capacity() const + { + return vbase.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_map. + ///\return The maximum size of the flat_map. + //************************************************************************* + size_type max_size() const + { + return vbase.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return vbase.available(); + } + + protected: + + //************************************************************************* + /// Constructor. + //************************************************************************* + flat_map_base(vector_base& vbase) + : vbase(vbase) + { + } + + vector_base& vbase; + }; +} + +#endif From 72fc0e451d2ab91b35c6008531ffd0e136fb4b6c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 14:09:22 +0000 Subject: [PATCH 6/7] Moved non-user headers to private sub-directory. --- deque_base.h | 172 ------------- flat_map_base.h | 182 ------------- flat_multimap_base.h | 182 ------------- flat_multiset_base.h | 179 ------------- flat_set_base.h | 182 ------------- forward_list_base.h | 243 ------------------ list_base.h | 264 ------------------- map_base.h | 417 ------------------------------ multimap_base.h | 581 ------------------------------------------ multiset_base.h | 580 ----------------------------------------- pool_base.h | 129 ---------- priority_queue_base.h | 154 ----------- queue_base.h | 144 ----------- set_base.h | 418 ------------------------------ stack_base.h | 143 ----------- vector_base.h | 183 ------------- 16 files changed, 4153 deletions(-) delete mode 100644 deque_base.h delete mode 100644 flat_map_base.h delete mode 100644 flat_multimap_base.h delete mode 100644 flat_multiset_base.h delete mode 100644 flat_set_base.h delete mode 100644 forward_list_base.h delete mode 100644 list_base.h delete mode 100644 map_base.h delete mode 100644 multimap_base.h delete mode 100644 multiset_base.h delete mode 100644 pool_base.h delete mode 100644 priority_queue_base.h delete mode 100644 queue_base.h delete mode 100644 set_base.h delete mode 100644 stack_base.h delete mode 100644 vector_base.h diff --git a/deque_base.h b/deque_base.h deleted file mode 100644 index 3553eef5..00000000 --- a/deque_base.h +++ /dev/null @@ -1,172 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_IDEQUE_H__ -#error This header is a private element of etl::deque & etl::ideque -#endif - -#ifndef __ETL_DEQUE_BASE__ -#define __ETL_DEQUE_BASE__ - -#include - -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception base for deques - ///\ingroup deque - //*************************************************************************** - class deque_exception : public exception - { - public: - - deque_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Deque full exception. - ///\ingroup deque - //*************************************************************************** - class deque_full : public deque_exception - { - public: - - deque_full() - : deque_exception("deque: full") - { - } - }; - - //*************************************************************************** - /// Deque empty exception. - ///\ingroup deque - //*************************************************************************** - class deque_empty : public deque_exception - { - public: - - deque_empty() - : deque_exception("deque: empty") - { - } - }; - - //*************************************************************************** - /// Deque out of bounds exception. - ///\ingroup deque - //*************************************************************************** - class deque_out_of_bounds : public deque_exception - { - public: - - deque_out_of_bounds() - : deque_exception("deque: out of bounds") - { - } - }; - - //*************************************************************************** - /// The base class for all templated deque types. - ///\ingroup deque - //*************************************************************************** - class deque_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the deque. - ///\return The current size of the deque. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Checks the 'empty' state of the deque. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return (current_size == 0); - } - - //************************************************************************* - /// Checks the 'full' state of the deque. - ///\return true if full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the maximum possible size of the deque. - ///\return The maximum size of the deque. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - deque_base(size_t max_size, size_t buffer_size) - : current_size(0), - MAX_SIZE(max_size), - BUFFER_SIZE(buffer_size) - { - } - - size_type current_size; ///< The current number of elements in the deque. - const size_type MAX_SIZE; ///< The maximum number of elements in the deque. - const size_type BUFFER_SIZE; ///< The number of elements in the buffer. - }; -} - -#endif diff --git a/flat_map_base.h b/flat_map_base.h deleted file mode 100644 index b95797d1..00000000 --- a/flat_map_base.h +++ /dev/null @@ -1,182 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 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_IN_IFLAT_MAP_H__ -#error This header is a private element of etl::flat_map & etl::iflat_map -#endif - -#ifndef __ETL_FLAT_MAP_BASE__ -#define __ETL_FLAT_MAP_BASE__ - -#include - -#include "exception.h" -#include "ivector.h" - -#ifndef ETL_THROW_EXCEPTIONS -#include "error_handler.h" -#endif - -namespace etl -{ - //*************************************************************************** - ///\ingroup flat_map - /// Exception base for flat_maps - //*************************************************************************** - class flat_map_exception : public exception - { - public: - - flat_map_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_map - /// Vector full exception. - //*************************************************************************** - class flat_map_full : public flat_map_exception - { - public: - - flat_map_full() - : flat_map_exception("flat_map: full") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_map - /// Vector out of bounds exception. - //*************************************************************************** - class flat_map_out_of_bounds : public flat_map_exception - { - public: - - flat_map_out_of_bounds() - : flat_map_exception("flat_map: out of bounds") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_map - /// Vector iterator exception. - //*************************************************************************** - class flat_map_iterator : public flat_map_exception - { - public: - - flat_map_iterator() - : flat_map_exception("flat_map: iterator error") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_map - /// The base class for all templated flat_map types. - //*************************************************************************** - class flat_map_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the flat_map. - ///\return The current size of the flat_map. - //************************************************************************* - size_type size() const - { - return vbase.size(); - } - - //************************************************************************* - /// Checks the 'empty' state of the flat_map. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return vbase.empty(); - } - - //************************************************************************* - /// Checks the 'full' state of the flat_map. - ///\return true if full. - //************************************************************************* - bool full() const - { - return vbase.full(); - } - - //************************************************************************* - /// Returns the capacity of the flat_map. - ///\return The capacity of the flat_map. - //************************************************************************* - size_type capacity() const - { - return vbase.capacity(); - } - - //************************************************************************* - /// Returns the maximum possible size of the flat_map. - ///\return The maximum size of the flat_map. - //************************************************************************* - size_type max_size() const - { - return vbase.max_size(); - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return vbase.available(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - flat_map_base(vector_base& vbase) - : vbase(vbase) - { - } - - vector_base& vbase; - }; -} - -#endif diff --git a/flat_multimap_base.h b/flat_multimap_base.h deleted file mode 100644 index 9a054b97..00000000 --- a/flat_multimap_base.h +++ /dev/null @@ -1,182 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 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_IN_IFLAT_MULTIMAP_H__ -#error This header is a private element of etl::flat_multimap & etl::iflat_multimap -#endif - -#ifndef __ETL_FLAT_MULTIMAP_BASE__ -#define __ETL_FLAT_MULTIMAP_BASE__ - -#include - -#include "exception.h" -#include "ivector.h" - -#ifndef ETL_THROW_EXCEPTIONS -#include "error_handler.h" -#endif - -namespace etl -{ - //*************************************************************************** - ///\ingroup flat_multimap - /// Exception base for flat_multimaps - //*************************************************************************** - class flat_multimap_exception : public exception - { - public: - - flat_multimap_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multimap - /// Vector full exception. - //*************************************************************************** - class flat_multimap_full : public flat_multimap_exception - { - public: - - flat_multimap_full() - : flat_multimap_exception("flat_multimap: full") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multimap - /// Vector out of bounds exception. - //*************************************************************************** - class flat_multimap_out_of_bounds : public flat_multimap_exception - { - public: - - flat_multimap_out_of_bounds() - : flat_multimap_exception("flat_multimap: out of bounds") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multimap - /// Vector iterator exception. - //*************************************************************************** - class flat_multimap_iterator : public flat_multimap_exception - { - public: - - flat_multimap_iterator() - : flat_multimap_exception("flat_multimap: iterator error") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multimap - /// The base class for all templated flat_multimap types. - //*************************************************************************** - class flat_multimap_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the flat_multimap. - ///\return The current size of the flat_multimap. - //************************************************************************* - size_type size() const - { - return vbase.size(); - } - - //************************************************************************* - /// Checks the 'empty' state of the flat_multimap. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return vbase.empty(); - } - - //************************************************************************* - /// Checks the 'full' state of the flat_multimap. - ///\return true if full. - //************************************************************************* - bool full() const - { - return vbase.full(); - } - - //************************************************************************* - /// Returns the capacity of the flat_multimap. - ///\return The capacity of the flat_multimap. - //************************************************************************* - size_type capacity() const - { - return vbase.capacity(); - } - - //************************************************************************* - /// Returns the maximum possible size of the flat_multimap. - ///\return The maximum size of the flat_multimap. - //************************************************************************* - size_type max_size() const - { - return vbase.max_size(); - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return vbase.available(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - flat_multimap_base(vector_base& vbase) - : vbase(vbase) - { - } - - vector_base& vbase; - }; -} - -#endif diff --git a/flat_multiset_base.h b/flat_multiset_base.h deleted file mode 100644 index b67e7fb1..00000000 --- a/flat_multiset_base.h +++ /dev/null @@ -1,179 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 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_IN_IFLAT_MULTISET_H__ -#error This header is a private element of etl::flat_multiset & etl::iflat_multiset -#endif - -#ifndef __ETL_FLAT_MULTISET_BASE__ -#define __ETL_FLAT_MULTISET_BASE__ - -#include - -#include "exception.h" -#include "ivector.h" -#include "error_handler.h" - -namespace etl -{ - //*************************************************************************** - ///\ingroup flat_multiset - /// Exception base for flat_multisets - //*************************************************************************** - class flat_multiset_exception : public exception - { - public: - - flat_multiset_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multiset - /// Flat multiset full exception. - //*************************************************************************** - class flat_multiset_full : public flat_multiset_exception - { - public: - - flat_multiset_full() - : flat_multiset_exception("flat_multiset: full") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multiset - /// Flat multiset out of bounds exception. - //*************************************************************************** - class flat_multiset_out_of_bounds : public flat_multiset_exception - { - public: - - flat_multiset_out_of_bounds() - : flat_multiset_exception("flat_multiset: out of bounds") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multiset - /// Vector iterator exception. - //*************************************************************************** - class flat_multiset_iterator : public flat_multiset_exception - { - public: - - flat_multiset_iterator() - : flat_multiset_exception("flat_multiset: iterator error") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_multiset - /// The base class for all templated flat_multiset types. - //*************************************************************************** - class flat_multiset_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the flat_multiset. - ///\return The current size of the flat_multiset. - //************************************************************************* - size_type size() const - { - return vbase.size(); - } - - //************************************************************************* - /// Checks the 'empty' state of the flat_multiset. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return vbase.empty(); - } - - //************************************************************************* - /// Checks the 'full' state of the flat_multiset. - ///\return true if full. - //************************************************************************* - bool full() const - { - return vbase.full(); - } - - //************************************************************************* - /// Returns the capacity of the flat_multiset. - ///\return The capacity of the flat_multiset. - //************************************************************************* - size_type capacity() const - { - return vbase.capacity(); - } - - //************************************************************************* - /// Returns the maximum possible size of the flat_multiset. - ///\return The maximum size of the flat_multiset. - //************************************************************************* - size_type max_size() const - { - return vbase.max_size(); - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return vbase.available(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - flat_multiset_base(vector_base& vbase) - : vbase(vbase) - { - } - - vector_base& vbase; - }; -} - -#endif diff --git a/flat_set_base.h b/flat_set_base.h deleted file mode 100644 index b87a40ac..00000000 --- a/flat_set_base.h +++ /dev/null @@ -1,182 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 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_IN_IFLAT_SET_H__ -#error This header is a private element of etl::flat_set & etl::iflat_set -#endif - -#ifndef __ETL_FLAT_SET_BASE__ -#define __ETL_FLAT_SET_BASE__ - -#include - -#include "exception.h" -#include "ivector.h" - -#ifndef ETL_THROW_EXCEPTIONS -#include "error_handler.h" -#endif - -namespace etl -{ - //*************************************************************************** - ///\ingroup flat_set - /// Exception base for flat_sets - //*************************************************************************** - class flat_set_exception : public exception - { - public: - - flat_set_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup flat_set - /// Vector full exception. - //*************************************************************************** - class flat_set_full : public flat_set_exception - { - public: - - flat_set_full() - : flat_set_exception("flat_set: full") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_set - /// Vector out of bounds exception. - //*************************************************************************** - class flat_set_out_of_bounds : public flat_set_exception - { - public: - - flat_set_out_of_bounds() - : flat_set_exception("flat_set: out of bounds") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_set - /// Vector iterator exception. - //*************************************************************************** - class flat_set_iterator : public flat_set_exception - { - public: - - flat_set_iterator() - : flat_set_exception("flat_set: iterator error") - { - } - }; - - //*************************************************************************** - ///\ingroup flat_set - /// The base class for all templated flat_set types. - //*************************************************************************** - class flat_set_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the flat_set. - ///\return The current size of the flat_set. - //************************************************************************* - size_type size() const - { - return vbase.size(); - } - - //************************************************************************* - /// Checks the 'empty' state of the flat_set. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return vbase.empty(); - } - - //************************************************************************* - /// Checks the 'full' state of the flat_set. - ///\return true if full. - //************************************************************************* - bool full() const - { - return vbase.full(); - } - - //************************************************************************* - /// Returns the capacity of the flat_set. - ///\return The capacity of the flat_set. - //************************************************************************* - size_type capacity() const - { - return vbase.capacity(); - } - - //************************************************************************* - /// Returns the maximum possible size of the flat_set. - ///\return The maximum size of the flat_set. - //************************************************************************* - size_type max_size() const - { - return vbase.max_size(); - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return vbase.available(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - flat_set_base(vector_base& vbase) - : vbase(vbase) - { - } - - vector_base& vbase; - }; -} - -#endif diff --git a/forward_list_base.h b/forward_list_base.h deleted file mode 100644 index cb764730..00000000 --- a/forward_list_base.h +++ /dev/null @@ -1,243 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_IFORWARD_LIST_H__ -#error This header is a private element of etl::forward_list & etl::iforward_list -#endif - -#ifndef __ETL_LIST_BASE__ -#define __ETL_LIST_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the forward_list. - ///\ingroup forward_list - //*************************************************************************** - class forward_list_exception : public exception - { - public: - - forward_list_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the forward_list. - ///\ingroup forward_list - //*************************************************************************** - class forward_list_full : public forward_list_exception - { - public: - - forward_list_full() - : forward_list_exception("forward list: full") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the forward_list. - ///\ingroup forward_list - //*************************************************************************** - class forward_list_iterator : public forward_list_exception - { - public: - - forward_list_iterator() - : forward_list_exception("forward_list: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all forward_lists. - ///\ingroup forward_list - //*************************************************************************** - class forward_list_base - { - protected: - - //************************************************************************* - /// The node element in the forward_list. - //************************************************************************* - struct Node - { - Node() - : next(nullptr) - { - } - - Node* next; - }; - - public: - - typedef size_t size_type; ///< The type used for determining the size of forward_list. - - //************************************************************************* - /// Gets the size of the forward_list. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the forward_list. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the forward_list is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the forward_list is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - //************************************************************************* - /// Reverses the forward_list. - //************************************************************************* - void reverse() - { - if (is_trivial_list()) - { - return; - } - - Node* p_last = &start_node; - Node* p_current = p_last->next; - Node* p_next = p_current->next; - - p_current->next = nullptr; - - while (p_next != nullptr) - { - p_last = p_current; - p_current = p_next; - p_next = p_current->next; - - p_current->next = p_last; - } - - join(&start_node, p_current); - } - - protected: - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - forward_list_base(size_type max_size) - : next_free(0), - current_size(0), - MAX_SIZE(max_size) - { - } - - //************************************************************************* - /// Get the head node. - //************************************************************************* - Node& get_head() - { - return *start_node.next; - } - - //************************************************************************* - /// Get the head node. - //************************************************************************* - const Node& get_head() const - { - return *start_node.next; - } - - //************************************************************************* - /// Insert a node. - //************************************************************************* - void insert_node_after(Node& position, Node& node) - { - // Connect to the forward_list. - node.next = position.next; - - join(&position, &node); - - // One more. - ++current_size; - } - - //************************************************************************* - /// Is the forward_list a trivial length? - //************************************************************************* - bool is_trivial_list() const - { - return (size() < 2); - } - - //************************************************************************* - /// Join two nodes. - //************************************************************************* - void join(Node* left, Node* right) - { - left->next = right; - } - - Node start_node; ///< The node that acts as the forward_list start. - size_type next_free; ///< The index of the next free node. - size_type current_size; ///< The number of items in the list. - const size_type MAX_SIZE; ///< The maximum size of the forward_list. - }; -} - -#endif diff --git a/list_base.h b/list_base.h deleted file mode 100644 index 5ff44959..00000000 --- a/list_base.h +++ /dev/null @@ -1,264 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_ILIST_H__ -#error This header is a private element of etl::list & etl::ilist -#endif - -#ifndef __ETL_LIST_BASE__ -#define __ETL_LIST_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the list. - ///\ingroup list - //*************************************************************************** - class list_exception : public exception - { - public: - - list_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the list. - ///\ingroup list - //*************************************************************************** - class list_full : public list_exception - { - public: - - list_full() - : list_exception("list: full") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the list. - ///\ingroup list - //*************************************************************************** - class list_iterator : public list_exception - { - public: - - list_iterator() - : list_exception("list: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all lists. - ///\ingroup list - //*************************************************************************** - class list_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of list. - - //************************************************************************* - /// The node element in the list. - //************************************************************************* - struct Node - { - //*********************************************************************** - /// Constructor - //*********************************************************************** - Node() - : previous(nullptr), - next(nullptr) - { - } - - //*********************************************************************** - /// Reverses the previous & next pointers. - //*********************************************************************** - void reverse() - { - std::swap(previous, next); - } - - Node* previous; - Node* next; - }; - - //************************************************************************* - /// Reverses the list. - //************************************************************************* - void reverse() - { - if (is_trivial_list()) - { - return; - } - - Node* p_node = terminal_node.next; - - while (p_node != &terminal_node) - { - p_node->reverse(); - p_node = p_node->previous; // Now we've reversed it, we must go to the previous node. - } - - // Terminal node. - p_node->reverse(); - } - - //************************************************************************* - /// Gets the size of the list. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the list. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the list is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the list is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// Get the head node. - //************************************************************************* - Node& get_head() - { - return *terminal_node.next; - } - - //************************************************************************* - /// Get the head node. - //************************************************************************* - const Node& get_head() const - { - return *terminal_node.next; - } - - //************************************************************************* - /// Get the tail node. - //************************************************************************* - Node& get_tail() - { - return *terminal_node.previous; - } - - //************************************************************************* - /// Get the tail node. - //************************************************************************* - const Node& get_tail() const - { - return *terminal_node.previous; - } - - //************************************************************************* - /// Insert a node before 'position'. - //************************************************************************* - void insert_node(Node& position, Node& node) - { - // Connect to the list. - join(*position.previous, node); - join(node, position); - - // One more. - ++current_size; - } - - //************************************************************************* - /// Is the list a trivial length? - //************************************************************************* - bool is_trivial_list() const - { - return (size() < 2); - } - - //************************************************************************* - /// Join two nodes. - //************************************************************************* - void join(Node& left, Node& right) - { - left.next = &right; - right.previous = &left; - } - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - list_base(size_type max_size) - : current_size(0), - MAX_SIZE(max_size) - - { - } - - - Node terminal_node; ///< The node that acts as the list start and end. - size_type current_size; ///< The number of the used nodes. - const size_type MAX_SIZE; ///< The maximum size of the list. - }; -} - -#endif diff --git a/map_base.h b/map_base.h deleted file mode 100644 index 12264f9d..00000000 --- a/map_base.h +++ /dev/null @@ -1,417 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2014 jwellbelove, rlindeman - -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. -******************************************************************************/ - -#if !defined(__ETL_IN_IMAP_H__) -#error This header is a private element of etl::map & etl::imap -#endif - -#ifndef __ETL_MAP_BASE__ -#define __ETL_MAP_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the map. - ///\ingroup map - //*************************************************************************** - class map_exception : public exception - { - public: - - map_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the map. - ///\ingroup map - //*************************************************************************** - class map_full : public map_exception - { - public: - - map_full() - : map_exception("map: full") - { - } - }; - - //*************************************************************************** - /// Map out of bounds exception. - ///\ingroup map - //*************************************************************************** - class map_out_of_bounds : public map_exception - { - public: - - map_out_of_bounds() - : map_exception("map: out of bounds") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the map. - ///\ingroup map - //*************************************************************************** - class map_iterator : public map_exception - { - public: - - map_iterator() - : map_exception("map: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all maps. - ///\ingroup map - //*************************************************************************** - class map_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of map. - - //************************************************************************* - /// Gets the size of the map. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the map. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the map is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the map is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the capacity of the vector. - ///\return The capacity of the vector. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; - - //************************************************************************* - /// The node element in the map. - //************************************************************************* - struct Node - { - //*********************************************************************** - /// Constructor - //*********************************************************************** - Node() : - weight(kNeither), - dir(kNeither) - { - } - - //*********************************************************************** - /// Marks the node as a leaf. - //*********************************************************************** - void mark_as_leaf() - { - weight = kNeither; - dir = kNeither; - children[0] = nullptr; - children[1] = nullptr; - } - - Node* children[2]; - uint8_t weight; - uint8_t dir; - }; - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - map_base(size_type max_size) - : current_size(0) - , MAX_SIZE(max_size) - , root_node(nullptr) - - { - } - - //************************************************************************* - /// Balance the critical node at the position provided as needed - //************************************************************************* - void balance_node(Node*& critical_node) - { - // Step 1: Update weights for all children of the critical node up to the - // newly inserted node. This step is costly (in terms of traversing nodes - // multiple times during insertion) but doesn't require as much recursion - Node* weight_node = critical_node->children[critical_node->dir]; - while (weight_node) - { - // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) - { - // Does this insert balance the previous weight factor value? - if (weight_node->weight == 1 - weight_node->dir) - { - weight_node->weight = kNeither; - } - else - { - weight_node->weight = weight_node->dir; - } - - // Update weight factor node to point to next node - weight_node = weight_node->children[weight_node->dir]; - } - else - { - // Stop loop, terminal node found - break; - } - } // while(weight_node) - - // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) - { - critical_node->weight = critical_node->dir; - } - // If direction is different than weight, then it will now be balanced - else if (critical_node->dir != critical_node->weight) - { - critical_node->weight = kNeither; - } - // Rotate is required to balance the tree at the critical node - else - { - // If critical node matches child node direction then perform a two - // node rotate in the direction of the critical node - if (critical_node->weight == critical_node->children[critical_node->dir]->dir) - { - rotate_2node(critical_node, critical_node->dir); - } - // Otherwise perform a three node rotation in the direction of the - // critical node - else - { - rotate_3node(critical_node, critical_node->dir, - critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); - } - } - } - - //************************************************************************* - /// Rotate two nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) - { - // A C A B - // B C -> A E OR B C -> D A - // D E B D D E E C - // C (new position) becomes the root - // A (position) takes ownership of D as its children[kRight] child - // C (new position) takes ownership of A as its left child - // OR - // B (new position) becomes the root - // A (position) takes ownership of E as its left child - // B (new position) takes ownership of A as its right child - - // Capture new root - Node* new_root = position->children[dir]; - // Replace position's previous child with new root's other child - position->children[dir] = new_root->children[1 - dir]; - // New root now becomes parent of current position - new_root->children[1 - dir] = position; - // Clear weight factor from current position - position->weight = kNeither; - // Newly detached right now becomes current position - position = new_root; - // Clear weight factor from new root - position->weight = kNeither; - } - - //************************************************************************* - /// Rotate three nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) - { - // __A__ __E__ __A__ __D__ - // _B_ C -> B A OR B _C_ -> A C - // D E D F G C D E B F G E - // F G F G - // E (new position) becomes the root - // B (position) takes ownership of F as its left child - // A takes ownership of G as its right child - // OR - // D (new position) becomes the root - // A (position) takes ownership of F as its right child - // C takes ownership of G as its left child - - // Capture new root (either E or D depending on dir) - Node* new_root = position->children[dir]->children[1 - dir]; - // Set weight factor for B or C based on F or G existing and being a different than dir - position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; - - // Detach new root from its tree (replace with new roots child) - position->children[dir]->children[1 - dir] = - new_root->children[dir]; - // Attach current left tree to new root - new_root->children[dir] = position->children[dir]; - // Set weight factor for A based on F or G - position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; - - // Move new root's right tree to current roots left tree - position->children[dir] = new_root->children[1 - dir]; - // Attach current root to new roots right tree - new_root->children[1 - dir] = position; - // Replace current position with new root - position = new_root; - // Clear weight factor for new current position - position->weight = kNeither; - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - Node* find_limit_node(Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - const Node* find_limit_node(const Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - const Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Attach the provided node to the position provided - //************************************************************************* - void attach_node(Node*& position, Node& node) - { - // Mark new node as leaf on attach to tree at position provided - node.mark_as_leaf(); - - // Add the node here - position = &node; - - // One more. - ++current_size; - } - - //************************************************************************* - /// Detach the node at the position provided - //************************************************************************* - void detach_node(Node*& position, Node*& replacement) - { - // Make temporary copy of actual nodes involved because we might lose - // their references in the process (e.g. position is the same as - // replacement or replacement is a child of position) - Node* detached = position; - Node* swap = replacement; - - // Update current position to point to swap (replacement) node first - position = swap; - - // Update replacement node to point to child in opposite direction - // otherwise we might lose the other child of the swap node - replacement = swap->children[1 - swap->dir]; - - // Point swap node to detached node's children and weight - swap->children[kLeft] = detached->children[kLeft]; - swap->children[kRight] = detached->children[kRight]; - swap->weight = detached->weight; - } - - size_type current_size; ///< The number of the used nodes. - const size_type MAX_SIZE; ///< The maximum size of the map. - Node* root_node; ///< The node that acts as the map root. - }; -} - -#endif diff --git a/multimap_base.h b/multimap_base.h deleted file mode 100644 index b9201f32..00000000 --- a/multimap_base.h +++ /dev/null @@ -1,581 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2014 jwellbelove, rlindeman - -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. -******************************************************************************/ - -#if !defined(__ETL_IN_IMULTIMAP_H__) -#error This header is a private element of etl::multimap & etl::imultimap -#endif - -#ifndef __ETL_MULTIMAP_BASE__ -#define __ETL_MULTIMAP_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the map. - ///\ingroup map - //*************************************************************************** - class multimap_exception : public exception - { - public: - - multimap_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the map. - ///\ingroup map - //*************************************************************************** - class multimap_full : public multimap_exception - { - public: - - multimap_full() - : multimap_exception("multimap: full") - { - } - }; - - //*************************************************************************** - /// Map out of bounds exception. - ///\ingroup map - //*************************************************************************** - class multimap_out_of_bounds : public multimap_exception - { - public: - - multimap_out_of_bounds() - : multimap_exception("multimap: out of bounds") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the map. - ///\ingroup map - //*************************************************************************** - class multimap_iterator : public multimap_exception - { - public: - - multimap_iterator() - : multimap_exception("multimap: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all maps. - ///\ingroup map - //*************************************************************************** - class multimap_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of map. - - //************************************************************************* - /// Gets the size of the map. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the map. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the map is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the map is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the capacity of the vector. - ///\return The capacity of the vector. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; - - //************************************************************************* - /// The node element in the multimap. - //************************************************************************* - struct Node - { - //*********************************************************************** - /// Constructor - //*********************************************************************** - Node() : - weight(kNeither), - dir(kNeither) - { - } - - //*********************************************************************** - /// Marks the node as a leaf. - //*********************************************************************** - void mark_as_leaf() - { - weight = kNeither; - dir = kNeither; - parent = nullptr; - children[0] = nullptr; - children[1] = nullptr; - } - - Node* parent; - Node* children[2]; - uint8_t weight; - uint8_t dir; - }; - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - multimap_base(size_type max_size) - : current_size(0) - , MAX_SIZE(max_size) - , root_node(nullptr) - - { - } - - //************************************************************************* - /// Balance the critical node at the position provided as needed - //************************************************************************* - void balance_node(Node*& critical_node) - { - // Step 1: Update weights for all children of the critical node up to the - // newly inserted node. This step is costly (in terms of traversing nodes - // multiple times during insertion) but doesn't require as much recursion - Node* weight_node = critical_node->children[critical_node->dir]; - while (weight_node) - { - // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) - { - // Does this insert balance the previous weight factor value? - if (weight_node->weight == 1 - weight_node->dir) - { - weight_node->weight = kNeither; - } - else - { - weight_node->weight = weight_node->dir; - } - - // Update weight factor node to point to next node - weight_node = weight_node->children[weight_node->dir]; - } - else - { - // Stop loop, terminal node found - break; - } - } // while(weight_node) - - // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) - { - critical_node->weight = critical_node->dir; - } - // If direction is different than weight, then it will now be balanced - else if (critical_node->dir != critical_node->weight) - { - critical_node->weight = kNeither; - } - // Rotate is required to balance the tree at the critical node - else - { - // If critical node matches child node direction then perform a two - // node rotate in the direction of the critical node - if (critical_node->weight == critical_node->children[critical_node->dir]->dir) - { - rotate_2node(critical_node, critical_node->dir); - } - // Otherwise perform a three node rotation in the direction of the - // critical node - else - { - rotate_3node(critical_node, critical_node->dir, - critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); - } - } - } - - //************************************************************************* - /// Rotate two nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) - { - // A C A B - // B C -> A E OR B C -> D A - // D E B D D E E C - // C (new position) becomes the root - // A (position) takes ownership of D as its children[kRight] child - // C (new position) takes ownership of A as its left child - // OR - // B (new position) becomes the root - // A (position) takes ownership of E as its left child - // B (new position) takes ownership of A as its right child - - // Capture new root (either B or C depending on dir) and its parent - Node* new_root = position->children[dir]; - - // Replace position's previous child with new root's other child - position->children[dir] = new_root->children[1 - dir]; - // Update new root's other child parent pointer - if (position->children[dir]) - { - position->children[dir]->parent = position; - } - - // New root's parent becomes current position's parent - new_root->parent = position->parent; - new_root->children[1 - dir] = position; - new_root->dir = 1 - dir; - - // Clear weight factor from current position - position->weight = kNeither; - // Position's parent becomes new_root - position->parent = new_root; - position = new_root; - // Clear weight factor from new root - position->weight = kNeither; - } - - //************************************************************************* - /// Rotate three nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) - { - // __A__ __E__ __A__ __D__ - // _B_ C -> B A OR B _C_ -> A C - // D E D F G C D E B F G E - // F G F G - // E (new position) becomes the root - // B (position) takes ownership of F as its left child - // A takes ownership of G as its right child - // OR - // D (new position) becomes the root - // A (position) takes ownership of F as its right child - // C takes ownership of G as its left child - - // Capture new root (either E or D depending on dir) - Node* new_root = position->children[dir]->children[1 - dir]; - // Set weight factor for B or C based on F or G existing and being a different than dir - position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; - - // Detach new root from its tree (replace with new roots child) - position->children[dir]->children[1 - dir] = new_root->children[dir]; - // Update new roots child parent pointer - if (new_root->children[dir]) - { - new_root->children[dir]->parent = position->children[dir]; - } - - // Attach current left tree to new root and update its parent - new_root->children[dir] = position->children[dir]; - position->children[dir]->parent = new_root; - - // Set weight factor for A based on F or G - position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; - - // Move new root's right tree to current roots left tree - position->children[dir] = new_root->children[1 - dir]; - if (new_root->children[1 - dir]) - { - new_root->children[1 - dir]->parent = position; - } - - // Attach current root to new roots right tree and assume its parent - new_root->parent = position->parent; - new_root->children[1 - dir] = position; - new_root->dir = 1 - dir; - - // Update current position's parent and replace with new root - position->parent = new_root; - position = new_root; - // Clear weight factor for new current position - position->weight = kNeither; - } - - //************************************************************************* - /// Find the next node in sequence from the node provided - //************************************************************************* - void next_node(Node*& position) const - { - if (position) - { - // Is there a tree on the right? then find the minimum of that tree - if (position->children[kRight]) - { - // Return minimum node found - position = find_limit_node(position->children[kRight], kLeft); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; // find_parent_node(root_node, position); - // Repeat while previous position was on right side of parent tree - } while (parent && parent->children[kRight] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the next node in sequence from the node provided - //************************************************************************* - void next_node(const Node*& position) const - { - if (position) - { - // Is there a tree on the right? then find the minimum of that tree - if (position->children[kRight]) - { - // Return minimum node found - position = find_limit_node(position->children[kRight], kLeft); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - const Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on right side of parent tree - } while (parent && parent->children[kRight] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the previous node in sequence from the node provided - //************************************************************************* - void prev_node(Node*& position) const - { - // If starting at the terminal end, the previous node is the maximum node - // from the root - if (!position) - { - position = find_limit_node(root_node, kRight); - } - else - { - // Is there a tree on the left? then find the maximum of that tree - if (position->children[kLeft]) - { - // Return maximum node found - position = find_limit_node(position->children[kLeft], kRight); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on left side of parent tree - } while (parent && parent->children[kLeft] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the previous node in sequence from the node provided - //************************************************************************* - void prev_node(const Node*& position) const - { - // If starting at the terminal end, the previous node is the maximum node - // from the root - if (!position) - { - position = find_limit_node(root_node, kRight); - } - else - { - // Is there a tree on the left? then find the maximum of that tree - if (position->children[kLeft]) - { - // Return maximum node found - position = find_limit_node(position->children[kLeft], kRight); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - const Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on left side of parent tree - } while (parent && parent->children[kLeft] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - Node* find_limit_node(Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Attach the provided node to the position provided - //************************************************************************* - void attach_node(Node* parent, Node*& position, Node& node) - { - // Mark new node as leaf on attach to tree at position provided - node.mark_as_leaf(); - - // Keep track of this node's parent - node.parent = parent; - - // Add the node here - position = &node; - - // One more. - ++current_size; - } - - //************************************************************************* - /// Detach the node at the position provided - //************************************************************************* - void detach_node(Node*& position, Node*& replacement) - { - // Make temporary copy of actual nodes involved because we might lose - // their references in the process (e.g. position is the same as - // replacement or replacement is a child of position) - Node* detached = position; - Node* swap = replacement; - - // Update current position to point to swap (replacement) node first - position = swap; - - // Update replacement node to point to child in opposite direction - // otherwise we might lose the other child of the swap node - replacement = swap->children[1 - swap->dir]; - - // Point swap node to detached node's parent, children and weight - swap->parent = detached->parent; - swap->children[kLeft] = detached->children[kLeft]; - swap->children[kRight] = detached->children[kRight]; - if (swap->children[kLeft]) - { - swap->children[kLeft]->parent = swap; - } - if (swap->children[kRight]) - { - swap->children[kRight]->parent = swap; - } - swap->weight = detached->weight; - } - - size_type current_size; ///< The number of the used nodes. - const size_type MAX_SIZE; ///< The maximum size of the map. - Node* root_node; ///< The node that acts as the multimap root. - }; -} - -#endif diff --git a/multiset_base.h b/multiset_base.h deleted file mode 100644 index 6e0827d8..00000000 --- a/multiset_base.h +++ /dev/null @@ -1,580 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 jwellbelove, rlindeman - -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. -******************************************************************************/ - -#if !defined(__ETL_IN_IMULTISET_H__) -#error This header is a private element of etl::multiset & etl::imultiset -#endif - -#ifndef __ETL_MULTISET_BASE__ -#define __ETL_MULTISET_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the set. - ///\ingroup set - //*************************************************************************** - class multiset_exception : public exception - { - public: - - multiset_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the set. - ///\ingroup set - //*************************************************************************** - class multiset_full : public multiset_exception - { - public: - - multiset_full() - : multiset_exception("multiset: full") - { - } - }; - - //*************************************************************************** - /// Map out of bounds exception. - ///\ingroup set - //*************************************************************************** - class multiset_out_of_bounds : public multiset_exception - { - public: - - multiset_out_of_bounds() - : multiset_exception("multiset: out of bounds") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the set. - ///\ingroup set - //*************************************************************************** - class multiset_iterator : public multiset_exception - { - public: - - multiset_iterator() - : multiset_exception("multiset: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all sets. - ///\ingroup set - //*************************************************************************** - class multiset_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of set. - - //************************************************************************* - /// Gets the size of the set. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the set. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the set is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the set is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the capacity of the vector. - ///\return The capacity of the vector. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; - - //************************************************************************* - /// The node element in the multiset. - //************************************************************************* - struct Node - { - //*********************************************************************** - /// Constructor - //*********************************************************************** - Node() : - weight(kNeither), - dir(kNeither) - { - } - - //*********************************************************************** - /// Marks the node as a leaf. - //*********************************************************************** - void mark_as_leaf() - { - weight = kNeither; - dir = kNeither; - parent = nullptr; - children[0] = nullptr; - children[1] = nullptr; - } - - Node* parent; - Node* children[2]; - uint8_t weight; - uint8_t dir; - }; - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - multiset_base(size_type max_size) - : current_size(0) - , MAX_SIZE(max_size) - , root_node(nullptr) - { - } - - //************************************************************************* - /// Attach the provided node to the position provided - //************************************************************************* - void attach_node(Node* parent, Node*& position, Node& node) - { - // Mark new node as leaf on attach to tree at position provided - node.mark_as_leaf(); - - // Keep track of this node's parent - node.parent = parent; - - // Add the node here - position = &node; - - // One more. - ++current_size; - } - - //************************************************************************* - /// Detach the node at the position provided - //************************************************************************* - void detach_node(Node*& position, Node*& replacement) - { - // Make temporary copy of actual nodes involved because we might lose - // their references in the process (e.g. position is the same as - // replacement or replacement is a child of position) - Node* detached = position; - Node* swap = replacement; - - // Update current position to point to swap (replacement) node first - position = swap; - - // Update replacement node to point to child in opposite direction - // otherwise we might lose the other child of the swap node - replacement = swap->children[1 - swap->dir]; - - // Point swap node to detached node's parent, children and weight - swap->parent = detached->parent; - swap->children[kLeft] = detached->children[kLeft]; - swap->children[kRight] = detached->children[kRight]; - if (swap->children[kLeft]) - { - swap->children[kLeft]->parent = swap; - } - if (swap->children[kRight]) - { - swap->children[kRight]->parent = swap; - } - swap->weight = detached->weight; - } - - //************************************************************************* - /// Balance the critical node at the position provided as needed - //************************************************************************* - void balance_node(Node*& critical_node) - { - // Step 1: Update weights for all children of the critical node up to the - // newly inserted node. This step is costly (in terms of traversing nodes - // multiple times during insertion) but doesn't require as much recursion - Node* weight_node = critical_node->children[critical_node->dir]; - while (weight_node) - { - // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) - { - // Does this insert balance the previous weight factor value? - if (weight_node->weight == 1 - weight_node->dir) - { - weight_node->weight = kNeither; - } - else - { - weight_node->weight = weight_node->dir; - } - - // Update weight factor node to point to next node - weight_node = weight_node->children[weight_node->dir]; - } - else - { - // Stop loop, terminal node found - break; - } - } // while(weight_node) - - // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) - { - critical_node->weight = critical_node->dir; - } - // If direction is different than weight, then it will now be balanced - else if (critical_node->dir != critical_node->weight) - { - critical_node->weight = kNeither; - } - // Rotate is required to balance the tree at the critical node - else - { - // If critical node matches child node direction then perform a two - // node rotate in the direction of the critical node - if (critical_node->weight == critical_node->children[critical_node->dir]->dir) - { - rotate_2node(critical_node, critical_node->dir); - } - // Otherwise perform a three node rotation in the direction of the - // critical node - else - { - rotate_3node(critical_node, critical_node->dir, - critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); - } - } - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - Node* find_limit_node(Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Find the next node in sequence from the node provided - //************************************************************************* - void next_node(Node*& position) const - { - if (position) - { - // Is there a tree on the right? then find the minimum of that tree - if (position->children[kRight]) - { - // Return minimum node found - position = find_limit_node(position->children[kRight], kLeft); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; // find_parent_node(root_node, position); - // Repeat while previous position was on right side of parent tree - } while (parent && parent->children[kRight] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the next node in sequence from the node provided - //************************************************************************* - void next_node(const Node*& position) const - { - if (position) - { - // Is there a tree on the right? then find the minimum of that tree - if (position->children[kRight]) - { - // Return minimum node found - position = find_limit_node(position->children[kRight], kLeft); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - const Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on right side of parent tree - } while (parent && parent->children[kRight] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the previous node in sequence from the node provided - //************************************************************************* - void prev_node(Node*& position) const - { - // If starting at the terminal end, the previous node is the maximum node - // from the root - if (!position) - { - position = find_limit_node(root_node, kRight); - } - else - { - // Is there a tree on the left? then find the maximum of that tree - if (position->children[kLeft]) - { - // Return maximum node found - position = find_limit_node(position->children[kLeft], kRight); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on left side of parent tree - } while (parent && parent->children[kLeft] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Find the previous node in sequence from the node provided - //************************************************************************* - void prev_node(const Node*& position) const - { - // If starting at the terminal end, the previous node is the maximum node - // from the root - if (!position) - { - position = find_limit_node(root_node, kRight); - } - else - { - // Is there a tree on the left? then find the maximum of that tree - if (position->children[kLeft]) - { - // Return maximum node found - position = find_limit_node(position->children[kLeft], kRight); - } - // Otherwise find the parent of this node - else - { - // Start with current position as parent - const Node* parent = position; - do { - // Update current position as previous parent - position = parent; - // Find parent of current position - parent = position->parent; - // Repeat while previous position was on left side of parent tree - } while (parent && parent->children[kLeft] == position); - - // Set parent node as the next position - position = parent; - } - } - } - - //************************************************************************* - /// Rotate two nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) - { - // A C A B - // B C -> A E OR B C -> D A - // D E B D D E E C - // C (new position) becomes the root - // A (position) takes ownership of D as its children[kRight] child - // C (new position) takes ownership of A as its left child - // OR - // B (new position) becomes the root - // A (position) takes ownership of E as its left child - // B (new position) takes ownership of A as its right child - - // Capture new root (either B or C depending on dir) and its parent - Node* new_root = position->children[dir]; - - // Replace position's previous child with new root's other child - position->children[dir] = new_root->children[1 - dir]; - // Update new root's other child parent pointer - if (position->children[dir]) - { - position->children[dir]->parent = position; - } - - // New root's parent becomes current position's parent - new_root->parent = position->parent; - new_root->children[1 - dir] = position; - new_root->dir = 1 - dir; - - // Clear weight factor from current position - position->weight = kNeither; - // Position's parent becomes new_root - position->parent = new_root; - position = new_root; - // Clear weight factor from new root - position->weight = kNeither; - } - - //************************************************************************* - /// Rotate three nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) - { - // __A__ __E__ __A__ __D__ - // _B_ C -> B A OR B _C_ -> A C - // D E D F G C D E B F G E - // F G F G - // E (new position) becomes the root - // B (position) takes ownership of F as its left child - // A takes ownership of G as its right child - // OR - // D (new position) becomes the root - // A (position) takes ownership of F as its right child - // C takes ownership of G as its left child - - // Capture new root (either E or D depending on dir) - Node* new_root = position->children[dir]->children[1 - dir]; - // Set weight factor for B or C based on F or G existing and being a different than dir - position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; - - // Detach new root from its tree (replace with new roots child) - position->children[dir]->children[1 - dir] = new_root->children[dir]; - // Update new roots child parent pointer - if (new_root->children[dir]) - { - new_root->children[dir]->parent = position->children[dir]; - } - - // Attach current left tree to new root and update its parent - new_root->children[dir] = position->children[dir]; - position->children[dir]->parent = new_root; - - // Set weight factor for A based on F or G - position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; - - // Move new root's right tree to current roots left tree - position->children[dir] = new_root->children[1 - dir]; - if (new_root->children[1 - dir]) - { - new_root->children[1 - dir]->parent = position; - } - - // Attach current root to new roots right tree and assume its parent - new_root->parent = position->parent; - new_root->children[1 - dir] = position; - new_root->dir = 1 - dir; - - // Update current position's parent and replace with new root - position->parent = new_root; - position = new_root; - // Clear weight factor for new current position - position->weight = kNeither; - } - - size_type current_size; ///< The number of the used nodes. - const size_type MAX_SIZE; ///< The maximum size of the set. - Node* root_node; ///< The node that acts as the multiset root. - }; -} - -#endif diff --git a/pool_base.h b/pool_base.h deleted file mode 100644 index ebb90355..00000000 --- a/pool_base.h +++ /dev/null @@ -1,129 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_IPOOL_H__ -#error This header is a private element of etl::pool & etl::ipool -#endif - -#ifndef __ETL_POOL_BASE__ -#define __ETL_POOL_BASE__ - -#include - -#include "exception.h" - -#ifndef ETL_THROW_EXCEPTIONS -#include "error_handler.h" -#endif - -namespace etl -{ - //*************************************************************************** - /// The base class for pool exceptions. - ///\ingroup pool - //*************************************************************************** - class pool_exception : public exception - { - public: - - pool_exception(const char* what) - : exception(what) - {} - }; - - //*************************************************************************** - /// The exception thrown when the pool has no more free items. - ///\ingroup pool - //*************************************************************************** - class pool_no_allocation : public pool_exception - { - public: - - pool_no_allocation() - : pool_exception("pool: no allocation") - {} - }; - - //*************************************************************************** - /// The exception thrown when an object is released which does not belong to the pool. - ///\ingroup pool - //*************************************************************************** - class pool_object_not_in_pool : public pool_exception - { - public: - - pool_object_not_in_pool() - : pool_exception("pool: not in pool") - {} - }; - - //************************************************************************* - /// The base class for all templated pool types. - ///\ingroup pool - //************************************************************************* - class pool_base - { - public: - - //************************************************************************* - /// Returns the number of free items in the pool. - //************************************************************************* - size_t available() const - { - return MAX_SIZE - items_allocated; - } - - //************************************************************************* - /// Checks to see if there are no free items in the pool. - /// \return true if there are none free (or 'empty') - //************************************************************************* - bool none_free() const - { - return items_allocated == MAX_SIZE; - } - - protected: - - //************************************************************************* - /// Constructor - //************************************************************************* - pool_base(size_t max_size) - : next_free(0), - items_allocated(0), - MAX_SIZE(max_size) - { - } - - size_t next_free; ///< The next free slot in the block. - size_t items_allocated; ///< The number of items allocated. - const size_t MAX_SIZE; ///< The maximum number of objects that can be allocated. - }; -} -#endif - diff --git a/priority_queue_base.h b/priority_queue_base.h deleted file mode 100644 index ac441c5a..00000000 --- a/priority_queue_base.h +++ /dev/null @@ -1,154 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 jwellbelove, rlindeman - -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_IN_IPRIORITY_QUEUE_H__ -#error This header is a private element of etl::priority_queue & etl::ipriority_queue -#endif - -#ifndef __ETL_PRIORITY_QUEUE_BASE__ -#define __ETL_PRIORITY_QUEUE_BASE__ - -#include - -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// The base class for priority_queue exceptions. - ///\ingroup queue - //*************************************************************************** - class priority_queue_exception : public exception - { - public: - - priority_queue_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// The exception thrown when the queue is full. - ///\ingroup queue - //*************************************************************************** - class priority_queue_full : public priority_queue_exception - { - public: - - priority_queue_full() - : priority_queue_exception("priority_queue: full") - { - } - }; - - //*************************************************************************** - /// The priority queue iterator exception on reversed iterators - ///\ingroup queue - //*************************************************************************** - class priority_queue_iterator : public priority_queue_exception - { - public: - - priority_queue_iterator() - : priority_queue_exception("priority_queue: iterator error") - { - } - }; - - //*************************************************************************** - /// The base class for all priority queues. - ///\ingroup queue - //*************************************************************************** - class priority_queue_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of queue. - - //************************************************************************* - /// Returns the current number of items in the priority queue. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Returns the maximum number of items that can be queued. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the priority queue is empty. - /// \return true if the queue is empty, otherwise false - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the priority queue is full. - /// \return true if the priority queue is full, otherwise false - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - priority_queue_base(size_type max_size) - : current_size(0), - MAX_SIZE(max_size) - { - } - - size_type current_size; ///< The number of items in the priority queue. - const size_type MAX_SIZE; ///< The maximum number of items in the priority queue. - }; -} - -#endif diff --git a/queue_base.h b/queue_base.h deleted file mode 100644 index 39d3724b..00000000 --- a/queue_base.h +++ /dev/null @@ -1,144 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_IQUEUE_H__ -#error This header is a private element of etl::queue & etl::iqueue -#endif - -#ifndef __ETL_QUEUE_BASE__ -#define __ETL_QUEUE_BASE__ - -#include - -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// The base class for queue exceptions. - ///\ingroup queue - //*************************************************************************** - class queue_exception : public exception - { - public: - - queue_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// The exception thrown when the queue is full. - ///\ingroup queue - //*************************************************************************** - class queue_full : public queue_exception - { - public: - - queue_full() - : queue_exception("queue: full") - { - } - }; - - //*************************************************************************** - /// The base class for all queues. - ///\ingroup queue - //*************************************************************************** - class queue_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of queue. - - //************************************************************************* - /// Returns the current number of items in the queue. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Returns the maximum number of items that can be queued. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the queue is empty. - /// \return true if the queue is empty, otherwise false - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the queue is full. - /// \return true if the queue is full, otherwise false - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - queue_base(size_type max_size) - : in(0), - out(0), - current_size(0), - MAX_SIZE(max_size) - { - } - - size_type in; ///< Where to input new data. - size_type out; ///< Where to get the oldest data. - size_type current_size; ///< The number of items in the queue. - const size_type MAX_SIZE; ///< The maximum number of items in the queue. - }; -} - -#endif diff --git a/set_base.h b/set_base.h deleted file mode 100644 index 1148bfac..00000000 --- a/set_base.h +++ /dev/null @@ -1,418 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2015 jwellbelove, rlindeman - -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. -******************************************************************************/ - -#if !defined(__ETL_IN_ISET_H__) -#error This header is a private element of etl::set & etl::iset -#endif - -#ifndef __ETL_SET_BASE__ -#define __ETL_SET_BASE__ - -#include -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - /// Exception for the set. - ///\ingroup set - //*************************************************************************** - class set_exception : public exception - { - public: - - set_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - /// Full exception for the set. - ///\ingroup set - //*************************************************************************** - class set_full : public set_exception - { - public: - - set_full() - : set_exception("set: full") - { - } - }; - - //*************************************************************************** - /// Map out of bounds exception. - ///\ingroup set - //*************************************************************************** - class set_out_of_bounds : public set_exception - { - public: - - set_out_of_bounds() - : set_exception("set: out of bounds") - { - } - }; - - //*************************************************************************** - /// Iterator exception for the set. - ///\ingroup set - //*************************************************************************** - class set_iterator : public set_exception - { - public: - - set_iterator() - : set_exception("set: iterator problem") - { - } - }; - - //*************************************************************************** - /// The base class for all sets. - ///\ingroup set - //*************************************************************************** - class set_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of set. - - //************************************************************************* - /// Gets the size of the set. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Gets the maximum possible size of the set. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Checks to see if the set is empty. - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the set is full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the capacity of the vector. - ///\return The capacity of the vector. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; - - //************************************************************************* - /// The node element in the set. - //************************************************************************* - struct Node - { - //*********************************************************************** - /// Constructor - //*********************************************************************** - Node() : - weight(kNeither), - dir(kNeither) - { - } - - //*********************************************************************** - /// Marks the node as a leaf. - //*********************************************************************** - void mark_as_leaf() - { - weight = kNeither; - dir = kNeither; - children[0] = nullptr; - children[1] = nullptr; - } - - Node* children[2]; - uint8_t weight; - uint8_t dir; - }; - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - set_base(size_type max_size) - : current_size(0) - , MAX_SIZE(max_size) - , root_node(nullptr) - - { - } - - //************************************************************************* - /// Attach the provided node to the position provided - //************************************************************************* - void attach_node(Node*& position, Node& node) - { - // Mark new node as leaf on attach to tree at position provided - node.mark_as_leaf(); - - // Add the node here - position = &node; - - // One more. - ++current_size; - } - - //************************************************************************* - /// Detach the node at the position provided - //************************************************************************* - void detach_node(Node*& position, Node*& replacement) - { - // Make temporary copy of actual nodes involved because we might lose - // their references in the process (e.g. position is the same as - // replacement or replacement is a child of position) - Node* detached = position; - Node* swap = replacement; - - // Update current position to point to swap (replacement) node first - position = swap; - - // Update replacement node to point to child in opposite direction - // otherwise we might lose the other child of the swap node - replacement = swap->children[1 - swap->dir]; - - // Point swap node to detached node's children and weight - swap->children[kLeft] = detached->children[kLeft]; - swap->children[kRight] = detached->children[kRight]; - swap->weight = detached->weight; - } - - //************************************************************************* - /// Balance the critical node at the position provided as needed - //************************************************************************* - void balance_node(Node*& critical_node) - { - // Step 1: Update weights for all children of the critical node up to the - // newly inserted node. This step is costly (in terms of traversing nodes - // multiple times during insertion) but doesn't require as much recursion - Node* weight_node = critical_node->children[critical_node->dir]; - while (weight_node) - { - // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) - { - // Does this insert balance the previous weight factor value? - if (weight_node->weight == 1 - weight_node->dir) - { - weight_node->weight = kNeither; - } - else - { - weight_node->weight = weight_node->dir; - } - - // Update weight factor node to point to next node - weight_node = weight_node->children[weight_node->dir]; - } - else - { - // Stop loop, terminal node found - break; - } - } // while(weight_node) - - // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) - { - critical_node->weight = critical_node->dir; - } - // If direction is different than weight, then it will now be balanced - else if (critical_node->dir != critical_node->weight) - { - critical_node->weight = kNeither; - } - // Rotate is required to balance the tree at the critical node - else - { - // If critical node matches child node direction then perform a two - // node rotate in the direction of the critical node - if (critical_node->weight == critical_node->children[critical_node->dir]->dir) - { - rotate_2node(critical_node, critical_node->dir); - } - // Otherwise perform a three node rotation in the direction of the - // critical node - else - { - rotate_3node(critical_node, critical_node->dir, - critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir); - } - } - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - Node* find_limit_node(Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Find the node whose key would go before all the other keys from the - /// position provided - //************************************************************************* - const Node* find_limit_node(const Node* position, const int8_t dir) const - { - // Something at this position and in the direction specified? keep going - const Node* limit_node = position; - while (limit_node && limit_node->children[dir]) - { - limit_node = limit_node->children[dir]; - } - - // Return the limit node position found - return limit_node; - } - - //************************************************************************* - /// Rotate two nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) - { - // A C A B - // B C -> A E OR B C -> D A - // D E B D D E E C - // C (new position) becomes the root - // A (position) takes ownership of D as its children[kRight] child - // C (new position) takes ownership of A as its left child - // OR - // B (new position) becomes the root - // A (position) takes ownership of E as its left child - // B (new position) takes ownership of A as its right child - - // Capture new root - Node* new_root = position->children[dir]; - // Replace position's previous child with new root's other child - position->children[dir] = new_root->children[1 - dir]; - // New root now becomes parent of current position - new_root->children[1 - dir] = position; - // Clear weight factor from current position - position->weight = kNeither; - // Newly detached right now becomes current position - position = new_root; - // Clear weight factor from new root - position->weight = kNeither; - } - - //************************************************************************* - /// Rotate three nodes at the position provided the to balance the tree - //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) - { - // __A__ __E__ __A__ __D__ - // _B_ C -> B A OR B _C_ -> A C - // D E D F G C D E B F G E - // F G F G - // E (new position) becomes the root - // B (position) takes ownership of F as its left child - // A takes ownership of G as its right child - // OR - // D (new position) becomes the root - // A (position) takes ownership of F as its right child - // C takes ownership of G as its left child - - // Capture new root (either E or D depending on dir) - Node* new_root = position->children[dir]->children[1 - dir]; - // Set weight factor for B or C based on F or G existing and being a different than dir - position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither; - - // Detach new root from its tree (replace with new roots child) - position->children[dir]->children[1 - dir] = - new_root->children[dir]; - // Attach current left tree to new root - new_root->children[dir] = position->children[dir]; - // Set weight factor for A based on F or G - position->weight = third != kNeither && third == dir ? 1 - dir : kNeither; - - // Move new root's right tree to current roots left tree - position->children[dir] = new_root->children[1 - dir]; - // Attach current root to new roots right tree - new_root->children[1 - dir] = position; - // Replace current position with new root - position = new_root; - // Clear weight factor for new current position - position->weight = kNeither; - } - - - size_type current_size; ///< The number of the used nodes. - const size_type MAX_SIZE; ///< The maximum size of the set. - Node* root_node; ///< The node that acts as the set root. - }; -} - -#endif diff --git a/stack_base.h b/stack_base.h deleted file mode 100644 index 8e60c6f7..00000000 --- a/stack_base.h +++ /dev/null @@ -1,143 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -Copyright(c) 2014 jwellbelove - -Permission is hereby granted, free of charge, to any person obtatoptopg a copy -of this software and associated documentation files(the "Software"), to deal -top the Software withtop restriction, topcludtopg withtop 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 followtopg conditions : - -The above copyright notice and this permission notice shall be included top 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_IN_ISTACK_H__ -#error This header is a private element of etl::stack & etl::istack -#endif - -#ifndef __ETL_STACK_BASE__ -#define __ETL_STACK_BASE__ - -#include - -#include "exception.h" - -namespace etl -{ - //*************************************************************************** - ///\ingroup stack - /// The base class for stack exceptions. - //*************************************************************************** - class stack_exception : public exception - { - public: - - stack_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup stack - /// The exception thrown when the stack is full. - //*************************************************************************** - class stack_full : public stack_exception - { - public: - - stack_full() - : stack_exception("stack: full") - { - } - }; - - //*************************************************************************** - ///\ingroup stack - /// A fixed capacity stack written in the STL style. - /// \warntopg This stack cannot be used for concurrent access from multiple threads. - //*************************************************************************** - class stack_base - { - public: - - typedef size_t size_type; ///< The type used for determining the size of stack. - - //************************************************************************* - /// Checks to see if the stack is empty. - /// \return true if the stack is empty, otherwise false - //************************************************************************* - bool empty() const - { - return current_size == 0; - } - - //************************************************************************* - /// Checks to see if the stack is full. - /// \return true if the stack is full, otherwise false - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the current number of items top the stack. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Returns the maximum number of items that can be stacked. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// The constructor that is called from derived classes. - //************************************************************************* - stack_base(size_type max_size) - : top_index(0), - current_size(0), - MAX_SIZE(max_size) - { - } - - size_type top_index; ///< The index of the top of the stack. - size_type current_size; ///< The number of items in the stack. - const size_type MAX_SIZE; ///< The maximum number of items in the stack. - }; -} - -#endif diff --git a/vector_base.h b/vector_base.h deleted file mode 100644 index 74a94ed9..00000000 --- a/vector_base.h +++ /dev/null @@ -1,183 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl - -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_IN_IVECTOR_H__ -#error This header is a private element of etl::vector & etl::ivector -#endif - -#ifndef __ETL_VECTOR_BASE__ -#define __ETL_VECTOR_BASE__ - -#include - -#include "exception.h" - -#ifndef ETL_THROW_EXCEPTIONS -#include "error_handler.h" -#endif - -namespace etl -{ - //*************************************************************************** - ///\ingroup vector - /// Exception base for vectors - //*************************************************************************** - class vector_exception : public exception - { - public: - - vector_exception(const char* what) - : exception(what) - { - } - }; - - //*************************************************************************** - ///\ingroup vector - /// Vector full exception. - //*************************************************************************** - class vector_full : public vector_exception - { - public: - - vector_full() - : vector_exception("vector: full") - { - } - }; - - //*************************************************************************** - ///\ingroup vector - /// Vector out of bounds exception. - //*************************************************************************** - class vector_out_of_bounds : public vector_exception - { - public: - - vector_out_of_bounds() - : vector_exception("vector: out of bounds") - { - } - }; - - //*************************************************************************** - ///\ingroup vector - /// Vector iterator exception. - //*************************************************************************** - class vector_iterator : public vector_exception - { - public: - - vector_iterator() - : vector_exception("vector: iterator error") - { - } - }; - - //*************************************************************************** - ///\ingroup vector - /// The base class for all templated vector types. - //*************************************************************************** - class vector_base - { - public: - - typedef size_t size_type; - - //************************************************************************* - /// Gets the current size of the vector. - ///\return The current size of the vector. - //************************************************************************* - size_type size() const - { - return current_size; - } - - //************************************************************************* - /// Checks the 'empty' state of the vector. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return (current_size == 0); - } - - //************************************************************************* - /// Checks the 'full' state of the vector. - ///\return true if full. - //************************************************************************* - bool full() const - { - return current_size == MAX_SIZE; - } - - //************************************************************************* - /// Returns the capacity of the vector. - ///\return The capacity of the vector. - //************************************************************************* - size_type capacity() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the maximum possible size of the vector. - ///\return The maximum size of the vector. - //************************************************************************* - size_type max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } - - protected: - - //************************************************************************* - /// Constructor. - //************************************************************************* - vector_base(size_t max_size) - : current_size(0), - MAX_SIZE(max_size) - { - } - - size_type current_size; /// Date: Thu, 10 Dec 2015 14:09:57 +0000 Subject: [PATCH 7/7] Moved non-user headers to private sub-directory. --- ideque.h | 2 +- iflat_map.h | 2 +- iflat_multimap.h | 2 +- iflat_multiset.h | 2 +- iflat_set.h | 2 +- iforward_list.h | 2 +- ilist.h | 2 +- imap.h | 2 +- imultimap.h | 2 +- imultiset.h | 2 +- ipool.h | 2 +- ipriority_queue.h | 2 +- iqueue.h | 2 +- iset.h | 2 +- istack.h | 2 +- ivector.h | 2 +- test/vs2015/etl.vcxproj.filters | 97 +++++++++++++++++---------------- 17 files changed, 66 insertions(+), 63 deletions(-) diff --git a/ideque.h b/ideque.h index ff2a408e..95e92a94 100644 --- a/ideque.h +++ b/ideque.h @@ -36,7 +36,7 @@ SOFTWARE. #include "algorithm.h" #include "type_traits.h" -#include "deque_base.h" +#include "private/deque_base.h" #include "parameter_type.h" #include "error_handler.h" diff --git a/iflat_map.h b/iflat_map.h index d3a6e20c..2dd03075 100644 --- a/iflat_map.h +++ b/iflat_map.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include -#include "flat_map_base.h" +#include "private/flat_map_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" diff --git a/iflat_multimap.h b/iflat_multimap.h index 807b8fd6..e347e0c1 100644 --- a/iflat_multimap.h +++ b/iflat_multimap.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include -#include "flat_multimap_base.h" +#include "private/flat_multimap_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" diff --git a/iflat_multiset.h b/iflat_multiset.h index 14198ac3..f8e23727 100644 --- a/iflat_multiset.h +++ b/iflat_multiset.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include -#include "flat_multiset_base.h" +#include "private/flat_multiset_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" diff --git a/iflat_set.h b/iflat_set.h index 45dce87a..abc8869a 100644 --- a/iflat_set.h +++ b/iflat_set.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include -#include "flat_set_base.h" +#include "private/flat_set_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" diff --git a/iforward_list.h b/iforward_list.h index 976bd342..2b5cb91b 100644 --- a/iforward_list.h +++ b/iforward_list.h @@ -42,7 +42,7 @@ SOFTWARE. #include "pool.h" #include "nullptr.h" -#include "forward_list_base.h" +#include "private/forward_list_base.h" #include "type_traits.h" #include "parameter_type.h" diff --git a/ilist.h b/ilist.h index a5e5ceec..b68a80b6 100644 --- a/ilist.h +++ b/ilist.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "nullptr.h" -#include "list_base.h" +#include "private/list_base.h" #include "type_traits.h" #include "parameter_type.h" #include "pool.h" diff --git a/imap.h b/imap.h index 5698985d..60900950 100644 --- a/imap.h +++ b/imap.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "nullptr.h" -#include "map_base.h" +#include "private/map_base.h" #include "type_traits.h" #include "parameter_type.h" #include "pool.h" diff --git a/imultimap.h b/imultimap.h index 63ba491f..cdf18270 100644 --- a/imultimap.h +++ b/imultimap.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "nullptr.h" -#include "multimap_base.h" +#include "private/multimap_base.h" #include "type_traits.h" #include "parameter_type.h" #include "pool.h" diff --git a/imultiset.h b/imultiset.h index d35b62dd..ef1e6f7f 100644 --- a/imultiset.h +++ b/imultiset.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "nullptr.h" -#include "multiset_base.h" +#include "private/multiset_base.h" #include "type_traits.h" #include "parameter_type.h" #include "pool.h" diff --git a/ipool.h b/ipool.h index da333f8f..bb3da80b 100644 --- a/ipool.h +++ b/ipool.h @@ -33,7 +33,7 @@ SOFTWARE. #include -#include "pool_base.h" +#include "private/pool_base.h" #include "nullptr.h" #include "ibitset.h" diff --git a/ipriority_queue.h b/ipriority_queue.h index fc7ef7fb..1806353a 100644 --- a/ipriority_queue.h +++ b/ipriority_queue.h @@ -34,7 +34,7 @@ SOFTWARE. #include #include -#include "priority_queue_base.h" +#include "private/priority_queue_base.h" #include "type_traits.h" #include "parameter_type.h" diff --git a/iqueue.h b/iqueue.h index d38aabb6..fff02d92 100644 --- a/iqueue.h +++ b/iqueue.h @@ -33,7 +33,7 @@ SOFTWARE. #include -#include "queue_base.h" +#include "private/queue_base.h" #include "type_traits.h" #include "parameter_type.h" diff --git a/iset.h b/iset.h index 03ab618f..2bfa670c 100644 --- a/iset.h +++ b/iset.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "nullptr.h" -#include "set_base.h" +#include "private/set_base.h" #include "type_traits.h" #include "parameter_type.h" #include "pool.h" diff --git a/istack.h b/istack.h index bcef71cb..2ff3eaa7 100644 --- a/istack.h +++ b/istack.h @@ -33,7 +33,7 @@ SOFTWARE. #include -#include "stack_base.h" +#include "private/stack_base.h" #include "type_traits.h" #include "parameter_type.h" diff --git a/ivector.h b/ivector.h index 704b0cf1..ef497dcd 100644 --- a/ivector.h +++ b/ivector.h @@ -37,7 +37,7 @@ SOFTWARE. #include #include "algorithm.h" -#include "vector_base.h" +#include "private/vector_base.h" #include "type_traits.h" #include "parameter_type.h" #include "error_handler.h" diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index 848a444d..66a57edb 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -34,6 +34,9 @@ {1c55dd7d-c04b-428c-810b-dd3a08fc4c65} + + {7028012c-30c4-4993-b2d9-3b1521a610ae} + @@ -153,21 +156,12 @@ ETL\Containers - - ETL\Containers - ETL\Containers - - ETL\Containers - ETL\Containers - - ETL\Containers - ETL\Utilities @@ -201,18 +195,12 @@ ETL\Containers - - ETL\Containers - ETL\Containers ETL\Containers - - ETL\Containers - ETL\Maths @@ -234,9 +222,6 @@ ETL\Containers - - ETL\Containers - ETL\Containers @@ -246,9 +231,6 @@ ETL\Containers - - ETL\Containers - ETL\Containers @@ -309,9 +291,6 @@ ETL\Containers - - ETL\Containers - ETL\Maths @@ -336,18 +315,12 @@ ETL\Containers - - ETL\Containers - ETL\Maths ETL\Containers - - ETL\Containers - ETL\Containers @@ -357,9 +330,6 @@ ETL\Containers - - ETL\Containers - ETL\Utilities @@ -372,9 +342,6 @@ ETL\Containers - - ETL\Containers - ETL\Containers @@ -393,9 +360,6 @@ ETL\Containers - - ETL\Containers - ETL\Maths @@ -432,15 +396,9 @@ ETL\Containers - - ETL\Containers - ETL\Containers - - ETL\Containers - ETL\Containers @@ -459,11 +417,56 @@ ETL\Containers + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + - ETL\Containers + ETL\Containers\Private + + + ETL\Containers\Private - ETL\Containers + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private + + + ETL\Containers\Private