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/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/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/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: diff --git a/ideque.h b/ideque.h index eea7ab83..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" @@ -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..2dd03075 100644 --- a/iflat_map.h +++ b/iflat_map.h @@ -37,14 +37,11 @@ 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" - -#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..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" @@ -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..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" @@ -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..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" @@ -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/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/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/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 48108708..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" @@ -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); diff --git a/deque_base.h b/private/deque_base.h similarity index 100% rename from deque_base.h rename to private/deque_base.h diff --git a/flat_map_base.h b/private/flat_map_base.h similarity index 100% rename from flat_map_base.h rename to private/flat_map_base.h diff --git a/flat_multimap_base.h b/private/flat_multimap_base.h similarity index 100% rename from flat_multimap_base.h rename to private/flat_multimap_base.h diff --git a/flat_multiset_base.h b/private/flat_multiset_base.h similarity index 100% rename from flat_multiset_base.h rename to private/flat_multiset_base.h diff --git a/flat_set_base.h b/private/flat_set_base.h similarity index 100% rename from flat_set_base.h rename to private/flat_set_base.h diff --git a/forward_list_base.h b/private/forward_list_base.h similarity index 100% rename from forward_list_base.h rename to private/forward_list_base.h diff --git a/list_base.h b/private/list_base.h similarity index 100% rename from list_base.h rename to private/list_base.h diff --git a/map_base.h b/private/map_base.h similarity index 100% rename from map_base.h rename to private/map_base.h diff --git a/multimap_base.h b/private/multimap_base.h similarity index 100% rename from multimap_base.h rename to private/multimap_base.h diff --git a/multiset_base.h b/private/multiset_base.h similarity index 100% rename from multiset_base.h rename to private/multiset_base.h diff --git a/pool_base.h b/private/pool_base.h similarity index 100% rename from pool_base.h rename to private/pool_base.h diff --git a/priority_queue_base.h b/private/priority_queue_base.h similarity index 100% rename from priority_queue_base.h rename to private/priority_queue_base.h diff --git a/queue_base.h b/private/queue_base.h similarity index 100% rename from queue_base.h rename to private/queue_base.h diff --git a/set_base.h b/private/set_base.h similarity index 100% rename from set_base.h rename to private/set_base.h diff --git a/stack_base.h b/private/stack_base.h similarity index 100% rename from stack_base.h rename to private/stack_base.h 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/vector_base.h b/private/vector_base.h similarity index 100% rename from vector_base.h rename to private/vector_base.h 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); } 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