diff --git a/library.properties b/library.properties index a29ea47a..cfc24522 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=Embedded Template Library -version=8.2.0 +version=9.1.0 author= John Wellbelove maintainer=John Wellbelove sentence=A C++ template library tailored for embedded systems. paragraph=Requires some support from STL. See http://andybrown.me.uk/2011/01/15/the-standard-template-library-stl-for-avr-with-c-streams/ category=Other url=http://www.etlcpp.com/ -architectures=* +architectures=* diff --git a/src/algorithm.h b/src/algorithm.h index f3afa52b..eeaa88a5 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -33,14 +33,17 @@ SOFTWARE. ///\defgroup algorithm algorithm /// Reverse engineered algorithms from C++ 0x11 +/// Additional new variants of certain algorithms. ///\ingroup utilities #include #include #include #include +#include #include +#include "iterator.h" #include "type_traits.h" namespace etl @@ -50,8 +53,11 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template - std::pair minmax_element(TIterator begin, TIterator end, TCompare compare) + template + std::pair minmax_element(TIterator begin, + TIterator end, + TCompare compare) { TIterator minimum = begin; TIterator maximum = begin; @@ -67,7 +73,7 @@ namespace etl { maximum = begin; } - + ++begin; } @@ -80,7 +86,8 @@ namespace etl /// //*************************************************************************** template - std::pair minmax_element(TIterator begin, TIterator end) + std::pair minmax_element(TIterator begin, + TIterator end) { typedef typename std::iterator_traits::value_type value_t; @@ -93,9 +100,10 @@ namespace etl /// //*************************************************************************** template - std::pair minmax(const T& a, const T& b) + std::pair minmax(const T& a, + const T& b) { - return (b < a) ? std::pair(b, a) : std::pair(a, b); + return (b < a) ? std::pair(b, a) : std::pair(a, b); } //*************************************************************************** @@ -103,8 +111,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - std::pair minmax(const T& a, const T& b, TCompare compare) + template + std::pair minmax(const T& a, + const T& b, + TCompare compare) { return compare(b, a) ? std::pair(b, a) : std::pair(a, b); } @@ -115,7 +126,8 @@ namespace etl /// //*************************************************************************** template - TIterator is_sorted_until(TIterator begin, TIterator end) + TIterator is_sorted_until(TIterator begin, + TIterator end) { if (begin != end) { @@ -140,8 +152,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare) + template + TIterator is_sorted_until(TIterator begin, + TIterator end, + TCompare compare) { if (begin != end) { @@ -167,7 +182,8 @@ namespace etl /// //*************************************************************************** template - bool is_sorted(TIterator begin, TIterator end) + bool is_sorted(TIterator begin, + TIterator end) { return etl::is_sorted_until(begin, end) == end; } @@ -177,29 +193,99 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_sorted(TIterator begin, TIterator end, TCompare compare) + template + bool is_sorted(TIterator begin, + TIterator end, + TCompare compare) { return etl::is_sorted_until(begin, end, compare) == end; } + //*************************************************************************** + /// copy + /// A form of copy where the smallest of the two ranges is used. + /// There is currently no STL equivalent. + /// Specialisation for random access iterators. + ///\param i_begin Beginning of the input range. + ///\param i_end End of the input range. + ///\param o_begin Beginning of the output range. + ///\param o_end End of the output range. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value && + etl::is_random_iterator::value, TOutputIterator>::type + copy(TInputIterator i_begin, + TInputIterator i_end, + TOutputIterator o_begin, + TOutputIterator o_end) + { + size_t s_size = std::distance(i_begin, i_end); + size_t d_size = std::distance(o_begin, o_end); + size_t size = (s_size < d_size) ? s_size : d_size; + + return std::copy(i_begin, i_begin + size, o_begin); + } + + //*************************************************************************** + /// copy + /// A form of copy where the smallest of the two ranges is used. + /// There is currently no STL equivalent. + /// Specialisation for non random access iterators. + ///\param i_begin Beginning of the input range. + ///\param i_end End of the input range. + ///\param o_begin Beginning of the output range. + ///\param o_end End of the output range. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value || + !etl::is_random_iterator::value, TOutputIterator>::type + copy(TInputIterator i_begin, + TInputIterator i_end, + TOutputIterator o_begin, + TOutputIterator o_end) + { + while ((i_begin != i_end) && (o_begin != o_end)) + { + *o_begin++ = *i_begin++; + } + + return o_begin; + } + //*************************************************************************** /// copy_n ///\ingroup algorithm /// //*************************************************************************** - template - TOutputIterator copy_n(TInputIterator begin, Size count, TOutputIterator result) + template + TOutputIterator copy_n(TInputIterator begin, + TSize count, + TOutputIterator result) { - if (count > 0) - { - for (Size i = 0; i < count; ++i) - { - *result++ = *begin++; - } - } + return std::copy(begin, begin + count, result); + } - return result; + //*************************************************************************** + /// copy_n + /// A form of copy_n where the smallest of the two ranges is used. + ///\ingroup algorithm + //*************************************************************************** + template + TOutputIterator copy_n(TInputIterator i_begin, + TSize count, + TOutputIterator o_begin, + TOutputIterator o_end) + { + return etl::copy(i_begin, i_begin + count, o_begin, o_end);; } //*************************************************************************** @@ -207,8 +293,13 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate) + template + TOutputIterator copy_if(TIterator begin, + TIterator end, + TOutputIterator out, + TUnaryPredicate predicate) { while (begin != end) { @@ -223,13 +314,44 @@ namespace etl return out; } + //*************************************************************************** + /// copy_if + /// A form of copy_if where it terminates when the first end iterator is reached. + /// There is currently no STL equivelent. + ///\ingroup algorithm + //*************************************************************************** + template + TOutputIterator copy_if(TInputIterator i_begin, + TInputIterator i_end, + TOutputIterator o_begin, + TOutputIterator o_end, + TUnaryPredicate predicate) + { + while ((i_begin != i_end) && (o_begin != o_end)) + { + if (predicate(*i_begin)) + { + *o_begin++ = *i_begin; + } + + ++i_begin; + } + + return o_begin; + } + //*************************************************************************** /// find_if_not ///\ingroup algorithm /// //*************************************************************************** - template - TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + TIterator find_if_not(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -249,8 +371,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + bool all_of(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { return etl::find_if_not(begin, end, predicate) == end; } @@ -260,8 +385,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + bool any_of(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { return std::find_if(begin, end, predicate) != end; } @@ -271,8 +399,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + bool none_of(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { return std::find_if(begin, end, predicate) == end; } @@ -282,8 +413,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2) { if (begin1 != end1) { @@ -313,8 +447,12 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TIterator2 end2) { if (begin1 != end1) { @@ -340,8 +478,13 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TBinaryPredicate predicate) { if (begin1 != end1) { @@ -371,8 +514,14 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TIterator2 end2, + TBinaryPredicate predicate) { if (begin1 != end1) { @@ -398,8 +547,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + bool is_partitioned(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -425,8 +577,11 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template - TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + TIterator partition_point(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -447,12 +602,15 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template + template std::pair partition_copy(TSource begin, - TSource end, - TDestinationTrue destination_true, - TDestinationFalse destination_false, - TUnaryPredicate predicate) + TSource end, + TDestinationTrue destination_true, + TDestinationFalse destination_false, + TUnaryPredicate predicate) { while (begin != end) { @@ -468,6 +626,266 @@ namespace etl return std::pair(destination_true, destination_false); } + + //*************************************************************************** + /// Like std::for_each but applies a predicate before calling the function. + ///\ingroup algorithm + //*************************************************************************** + template + TUnaryFunction for_each_if(TIterator begin, + const TIterator end, + TUnaryFunction function, + TUnaryPredicate predicate) + { + while (begin != end) + { + if (predicate(*begin)) + { + function(*begin); + } + + ++begin; + } + + return function; + } + + //*************************************************************************** + /// A form of std::transform where the transform returns when the first range + /// end is reached. + /// There is currently no STL equivalent. + ///\ingroup algorithm + //*************************************************************************** + template + void transform(TInputIterator i_begin, + TInputIterator i_end, + TOutputIterator o_begin, + TOutputIterator o_end, + TUnaryFunction function) + { + while ((i_begin != i_end) && (o_begin != o_end)) + { + *o_begin++ = function(*i_begin++); + } + } + + //*************************************************************************** + /// Transform 'n' items. + /// Random iterators. + /// There is currently no STL equivalent. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value, void>::type + transform_n(TInputIterator i_begin, + TSize n, + TOutputIterator o_begin, + TUnaryFunction function) + { + std::transform(i_begin, i_begin + n, o_begin, function); + } + + //*************************************************************************** + /// Transform 'n' items from two ranges. + /// Random iterators. + /// There is currently no STL equivalent. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value && + etl::is_random_iterator::value, void>::type + transform_n(TInputIterator1 i_begin1, + TInputIterator2 i_begin2, + TSize n, + TOutputIterator o_begin, + TBinaryFunction function) + { + std::transform(i_begin, i_begin + n, i_begin2, o_begin, function); + } + + //*************************************************************************** + /// Transform 'n' items. + /// Non-random iterators. + /// There is currently no STL equivalent. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value, void>::type + transform_n(TInputIterator i_begin, + TSize n, + TOutputIterator o_begin, + TUnaryFunction function) + { + while (n > 0) + { + *o_begin++ = function(*i_begin++); + --n; + } + } + + //*************************************************************************** + /// Transform 'n' items from two ranges. + /// Non-random iterators. + /// There is currently no STL equivalent. + ///\ingroup algorithm + //*************************************************************************** + template + typename etl::enable_if::value || + !etl::is_random_iterator::value, void>::type + transform_n(TInputIterator1 i_begin1, + TInputIterator2 i_begin2, + TSize n, + TOutputIterator o_begin, + TBinaryFunction function) + { + while (n > 0) + { + *o_begin++ = function(*i_begin1++, *i_begin2++); + --n; + } + } + + //*************************************************************************** + /// Like std::transform but applies a predicate before calling the function. + ///\ingroup algorithm + //*************************************************************************** + template + TOutputIterator transform_if(TInputIterator i_begin, + const TInputIterator i_end, + TOutputIterator o_begin, + TUnaryFunction function, + TUnaryPredicate predicate) + { + while (i_begin != i_end) + { + if (predicate(*i_begin)) + { + *o_begin++ = function(*i_begin); + } + + ++i_begin; + } + + return o_begin; + } + + //*************************************************************************** + /// Like etl::transform_if but inputs from two ranges. + ///\ingroup algorithm + //*************************************************************************** + template + TOutputIterator transform_if(TInputIterator1 i_begin1, + const TInputIterator1 i_end1, + TInputIterator2 i_begin2, + TOutputIterator o_begin, + TBinaryFunction function, + TBinaryPredicate predicate) + { + while (i_begin1 != i_end1) + { + if (predicate(*i_begin1, *i_begin2)) + { + *o_begin++ = function(*i_begin1, *i_begin2); + } + + ++i_begin1; + ++i_begin2; + } + + return o_begin; + } + + //*************************************************************************** + /// Transforms the elements from the range (begin, end) to two different ranges + /// depending on the value returned by the predicate.
+ ///\ingroup algorithm + //*************************************************************************** + template + std::pair partition_transform(TSource begin, + TSource end, + TDestinationTrue destination_true, + TDestinationFalse destination_false, + TUnaryFunctionTrue function_true, + TUnaryFunctionFalse function_false, + TUnaryPredicate predicate) + { + while (begin != end) + { + if (predicate(*begin)) + { + *destination_true++ = function_true(*begin++); + } + else + { + *destination_false++ = function_false(*begin++); + } + } + + return std::pair(destination_true, destination_false); + } + + //*************************************************************************** + /// Transforms the elements from the ranges (begin1, end1) & (begin2) + /// to two different ranges depending on the value returned by the predicate. + ///\ingroup algorithm + //*************************************************************************** + template + std::pair partition_transform(TSource1 begin1, + TSource1 end1, + TSource2 begin2, + TDestinationTrue destination_true, + TDestinationFalse destination_false, + TBinaryFunctionTrue function_true, + TBinaryFunctionFalse function_false, + TBinaryPredicate predicate) + { + while (begin1 != end1) + { + if (predicate(*begin1, *begin2)) + { + *destination_true++ = function_true(*begin1++, *begin2++); + } + else + { + *destination_false++ = function_false(*begin1++, *begin2++); + } + } + + return std::pair(destination_true, destination_false); + } } #endif diff --git a/src/alignment.h b/src/alignment.h index 69ebbf54..668208f8 100644 --- a/src/alignment.h +++ b/src/alignment.h @@ -174,7 +174,7 @@ namespace etl union { - uint8_t data[LENGTH]; + uint_least8_t data[LENGTH]; typename etl::type_with_alignment::type __etl_alignment_type__; // A POD type that has the same alignment as ALIGNMENT. }; }; diff --git a/src/array.h b/src/array.h index f6c64a80..1e514c98 100644 --- a/src/array.h +++ b/src/array.h @@ -41,6 +41,7 @@ SOFTWARE. #include "parameter_type.h" #include "static_assert.h" #include "error_handler.h" +#include "algorithm.h" ///\defgroup array array /// A replacement for std::array if you haven't got C++0x11. @@ -76,18 +77,18 @@ namespace etl } }; - //*************************************************************************** + //*************************************************************************** ///\ingroup array /// A replacement for std::array if you haven't got C++0x11. - //*************************************************************************** + //*************************************************************************** template class array - { + { private: typedef typename parameter_type::type parameter_t; - public: + public: enum { @@ -102,9 +103,9 @@ namespace etl typedef T* pointer; typedef const T* const_pointer; typedef T* iterator; - typedef const T* const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef const T* const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; //************************************************************************* // Element access @@ -204,29 +205,29 @@ namespace etl // Iterators //************************************************************************* - //************************************************************************* - /// Returns an iterator to the beginning of the array. - //************************************************************************* - iterator begin() - { - return &_buffer[0]; - } - - //************************************************************************* - /// Returns a const iterator to the beginning of the array. - //************************************************************************* - const_iterator begin() const - { - return &_buffer[0]; - } + //************************************************************************* + /// Returns an iterator to the beginning of the array. + //************************************************************************* + iterator begin() + { + return &_buffer[0]; + } - //************************************************************************* - /// Returns a const iterator to the beginning of the array. - //************************************************************************* - const_iterator cbegin() const - { - return begin(); - } + //************************************************************************* + /// Returns a const iterator to the beginning of the array. + //************************************************************************* + const_iterator begin() const + { + return &_buffer[0]; + } + + //************************************************************************* + /// Returns a const iterator to the beginning of the array. + //************************************************************************* + const_iterator cbegin() const + { + return begin(); + } //************************************************************************* /// Returns an iterator to the end of the array. @@ -252,53 +253,53 @@ namespace etl return &_buffer[SIZE]; } - //************************************************************************* - // Returns an reverse iterator to the reverse beginning of the array. - //************************************************************************* - reverse_iterator rbegin() - { - return reverse_iterator(end()); - } - - //************************************************************************* - /// Returns a const reverse iterator to the reverse beginning of the array. - //************************************************************************* - const_reverse_iterator rbegin() const - { - return const_reverse_iterator(end()); - } + //************************************************************************* + // Returns an reverse iterator to the reverse beginning of the array. + //************************************************************************* + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } - //************************************************************************* - /// Returns a const reverse iterator to the reverse beginning of the array. - //************************************************************************* - const_reverse_iterator crbegin() const - { - return const_reverse_iterator(end()); - } + //************************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the array. + //************************************************************************* + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } - //************************************************************************* - /// Returns a reverse iterator to the end of the array. - //************************************************************************* - reverse_iterator rend() - { - return reverse_iterator(begin()); - } - - //************************************************************************* - /// Returns a const reverse iterator to the end of the array. - //************************************************************************* - const_reverse_iterator rend() const - { - return const_reverse_iterator(begin()); - } + //************************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the array. + //************************************************************************* + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(end()); + } - //************************************************************************* - /// Returns a const reverse iterator to the end of the array. - //************************************************************************* - const_reverse_iterator crend() const - { - return const_reverse_iterator(begin()); - } + //************************************************************************* + /// Returns a reverse iterator to the end of the array. + //************************************************************************* + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + + //************************************************************************* + /// Returns a const reverse iterator to the end of the array. + //************************************************************************* + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + + //************************************************************************* + /// Returns a const reverse iterator to the end of the array. + //************************************************************************* + const_reverse_iterator crend() const + { + return const_reverse_iterator(begin()); + } //************************************************************************* // Capacity @@ -312,21 +313,21 @@ namespace etl return (SIZE == 0); } - //************************************************************************* - /// Returns the size of the array. - //************************************************************************* - size_t size() const - { - return SIZE; - } + //************************************************************************* + /// Returns the size of the array. + //************************************************************************* + size_t size() const + { + return SIZE; + } - //************************************************************************* - /// Returns the maximum possible size of the array. - //************************************************************************* - size_t max_size() const - { - return SIZE; - } + //************************************************************************* + /// Returns the maximum possible size of the array. + //************************************************************************* + size_t max_size() const + { + return SIZE; + } //************************************************************************* // Operations @@ -353,20 +354,215 @@ namespace etl } } + //************************************************************************* + /// Fills the array from the range. + /// If the range is larger than the array then the extra data is ignored. + /// If the range is smaller than the array then the unused array elements are left unmodified. + ///\param first The iterator to the first item in the ramge. + ///\param last The iterator to one past the final item in the range. + //************************************************************************* + template + void assign(TIterator first, const TIterator last) + { + iterator itr = begin(); + + etl::copy(first, last, begin(), end()); + } + + //************************************************************************* + /// Fills the array from the range. + /// If the range is larger than the array then the extra data is ignored. + /// If the range is smaller than the array then the unused array elements are initialised with the supplied value. + ///\param first The iterator to the first item in the ramge. + ///\param last The iterator to one past the final item in the range. + //************************************************************************* + template + void assign(TIterator first, const TIterator last, parameter_t value) + { + // Copy from the range. + iterator p = etl::copy(first, last, begin(), end()); + + // Default initialise any that are left. + std::fill(p, end(), value); + } + + //************************************************************************* + /// Inserts a value into the array. + ///\param position The index of the position to insert at. + ///\param value The value to insert. + //************************************************************************* + inline iterator insert_at(size_t position, parameter_t value) + { + return insert(begin() + position, value); + } + + //************************************************************************* + /// Inserts a value into the array. + ///\param position The iterator to the position to insert at. + ///\param value The value to insert. + //************************************************************************* + iterator insert(const_iterator position, parameter_t value) + { + iterator p = const_cast(position); + + std::copy_backward(p, end() - 1, end()); + *p = value; + + return p; + } + + //************************************************************************* + /// Insert into the array from the range. + ///\param position The position to insert at. + ///\param first The iterator to the first item in the range. + ///\param last The iterator to one past the final item in the range. + //************************************************************************* + template + inline iterator insert_at(size_t position, TIterator first, const TIterator last) + { + return insert(begin() + position, first, last); + } + + //************************************************************************* + /// Insert into the array from the range. + ///\param position The position to insert at. + ///\param first The iterator to the first item in the range. + ///\param last The iterator to one past the final item in the range. + //************************************************************************* + template + iterator insert(const_iterator position, TIterator first, const TIterator last) + { + iterator p = const_cast(position); + iterator result(p); + + size_t source_size = std::distance(first, last); + size_t destination_space = std::distance(position, cend()); + + // Do we need to move anything? + if (source_size < destination_space) + { + size_t length = SIZE - (std::distance(begin(), p) + source_size); + std::copy_backward(p, p + length, end()); + } + + // Copy from the range. + etl::copy(first, last, p, end()); + + return result; + } + + //************************************************************************* + /// Erases a value from the array. + /// The after erase, the last value in the array will be unmodified. + ///\param position The index of the position to erase at. + //************************************************************************* + inline iterator erase_at(size_t position) + { + return erase(begin() + position); + } + + //************************************************************************* + /// Inserts a value into the array. + /// The after erase, the last value in the array will be unmodified. + ///\param position The iterator to the position to erase at. + //************************************************************************* + iterator erase(const_iterator position) + { + iterator p = const_cast(position); + std::copy(p + 1, end(), p); + + return p; + } + + //************************************************************************* + /// Erases a range of values from the array. + /// The after erase, the last values in the array will be unmodified. + ///\param first The first item to erase. + ///\param last The one past the last item to erase. + //************************************************************************* + iterator erase_range(size_t first, size_t last) + { + return erase(begin() + first, begin() + last); + } + + //************************************************************************* + /// Erases a range of values from the array. + /// The after erase, the last values in the array will be unmodified. + ///\param first The first item to erase. + ///\param last The one past the last item to erase. + //************************************************************************* + iterator erase(const_iterator first, const_iterator last) + { + iterator p = const_cast(first); + std::copy(last, cend(), p); + return p; + } + + //************************************************************************* + /// Erases a value from the array. + ///\param position The index of the position to erase at. + ///\param value The value to use to overwrite the last element in the array. + //************************************************************************* + inline iterator erase_at(size_t position, parameter_t value) + { + return erase(begin() + position, value); + } + + //************************************************************************* + /// Inserts a value into the array. + ///\param position The iterator to the position to erase at. + ///\param value The value to use to overwrite the last element in the array. + //************************************************************************* + iterator erase(const_iterator position, parameter_t value) + { + iterator p = const_cast(position); + + std::copy(p + 1, end(), p); + back() = value; + + return p; + } + + //************************************************************************* + /// Erases a range of values from the array. + ///\param first The first item to erase. + ///\param last The one past the last item to erase. + ///\param value The value to use to overwrite the last elements in the array. + //************************************************************************* + iterator erase_range(size_t first, size_t last, parameter_t value) + { + return erase(begin() + first, begin() + last, value); + } + + //************************************************************************* + /// Erases a range of values from the array. + ///\param position The iterator to the position to erase at. + ///\param value The value to use to overwrite the last elements in the array. + //************************************************************************* + iterator erase(const_iterator first, const_iterator last, parameter_t value) + { + iterator p = const_cast(first); + + p = std::copy(last, cend(), p); + std::fill(p, end(), value); + + return const_cast(first); + } + /// The array data. T _buffer[SIZE]; }; //************************************************************************* - /// Overloaded swap for etl::array - ///\param lhs The first array. - ///\param rhs The second array. - //************************************************************************* + /// Overloaded swap for etl::array + ///\param lhs The first array. + ///\param rhs The second array. + //************************************************************************* template void swap(etl::array &lhs, etl::array &rhs) - { - lhs.swap(rhs); - } + { + lhs.swap(rhs); + } //************************************************************************* /// Equal operator. @@ -391,7 +587,7 @@ namespace etl { return !(lhs == rhs); } - + //************************************************************************* /// Less than operator. ///\param lhs The first array. @@ -402,8 +598,8 @@ namespace etl bool operator <(const etl::array& lhs, const etl::array& rhs) { return std::lexicographical_compare(lhs.cbegin(), - lhs.cend(), - rhs.cbegin(), + lhs.cend(), + rhs.cbegin(), rhs.cend()); } diff --git a/src/binary.h b/src/binary.h index 3a1be615..f6558c1c 100644 --- a/src/binary.h +++ b/src/binary.h @@ -44,6 +44,7 @@ SOFTWARE. #include "log.h" #include "power.h" #include "smallest.h" +#include "platform.h" namespace etl { @@ -170,6 +171,7 @@ namespace etl return result; } +#if ETL_8BIT_SUPPORT //*************************************************************************** /// Reverse 8 bits. //*************************************************************************** @@ -183,6 +185,7 @@ namespace etl return value; } +#endif //*************************************************************************** /// Reverse 16 bits. @@ -282,6 +285,7 @@ namespace etl return (value >> 1) ^ value; } +#if ETL_8BIT_SUPPORT //*************************************************************************** /// Converts Gray code to binary. //*************************************************************************** @@ -295,6 +299,7 @@ namespace etl return value; } +#endif //*************************************************************************** /// Converts Gray code to binary. @@ -344,6 +349,7 @@ namespace etl return value; } +#if ETL_8BIT_SUPPORT //*************************************************************************** /// Count set bits. 8 bits. //*************************************************************************** @@ -361,6 +367,7 @@ namespace etl return count; } +#endif //*************************************************************************** /// Count set bits. 16 bits. @@ -389,14 +396,10 @@ namespace etl count_bits(T value) { uint32_t count; - static const int S[] = { 1, 2, 4, 8, 16 }; - static const uint32_t B[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF }; - count = value - ((value >> 1) & B[0]); - count = ((count >> S[1]) & B[1]) + (count & B[1]); - count = ((count >> S[2]) + count) & B[2]; - count = ((count >> S[3]) + count) & B[3]; - count = ((count >> S[4]) + count) & B[4]; + value = value - ((value >> 1) & 0x55555555); + value = (value & 0x33333333) + ((value >> 2) & 0x33333333); + count = ((value + (value >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; return count; } @@ -422,6 +425,7 @@ namespace etl return size_t(count); } +#if ETL_8BIT_SUPPORT //*************************************************************************** /// Parity. 8bits. 0 = even, 1 = odd //*************************************************************************** @@ -433,6 +437,7 @@ namespace etl value &= 0x0F; return (0x6996 >> value) & 1; } +#endif //*************************************************************************** /// Parity. 16bits. 0 = even, 1 = odd @@ -555,6 +560,224 @@ namespace etl return signed_value; } +#if ETL_8BIT_SUPPORT + //*************************************************************************** + /// Count trailing zeros. bit. + /// Uses a binary search. + //*************************************************************************** + template + typename etl::enable_if::type, uint8_t>::value, uint_least8_t>::type + count_trailing_zeros(T value) + { + uint_least8_t count; + + if (value & 0x1) + { + count = 0; + } + else + { + count = 1; + + if ((value & 0xF) == 0) + { + value >>= 4; + count += 4; + } + + if ((value & 0x3) == 0) + { + value >>= 2; + count += 2; + } + + count -= value & 0x1; + } + + return count; + } +#endif + + //*************************************************************************** + /// Count trailing zeros. 16bit. + /// Uses a binary search. + //*************************************************************************** + template + typename etl::enable_if::type, uint16_t>::value, uint_least8_t>::type + count_trailing_zeros(T value) + { + uint_least8_t count; + + if (value & 0x1) + { + count = 0; + } + else + { + count = 1; + + if ((value & 0xFF) == 0) + { + value >>= 8; + count += 8; + } + + if ((value & 0xF) == 0) + { + value >>= 4; + count += 4; + } + + if ((value & 0x3) == 0) + { + value >>= 2; + count += 2; + } + + count -= value & 0x1; + } + + return count; + } + + //*************************************************************************** + /// Count trailing zeros. 32bit. + /// Uses a binary search. + //*************************************************************************** + template + typename etl::enable_if::type, uint32_t>::value, uint_least8_t>::type + count_trailing_zeros(T value) + { + uint_least8_t count; + + if (value & 0x1) + { + count = 0; + } + else + { + count = 1; + + if ((value & 0xFFFF) == 0) + { + value >>= 16; + count += 16; + } + + if ((value & 0xFF) == 0) + { + value >>= 8; + count += 8; + } + + if ((value & 0xF) == 0) + { + value >>= 4; + count += 4; + } + + if ((value & 0x3) == 0) + { + value >>= 2; + count += 2; + } + + count -= value & 0x1; + } + + return count; + } + + //*************************************************************************** + /// Count trailing zeros. 64bit. + /// Uses a binary search. + //*************************************************************************** + template + typename etl::enable_if::type, uint64_t>::value, uint_least8_t>::type + count_trailing_zeros(T value) + { + uint_least8_t count; + + if (value & 0x1) + { + count = 0; + } + else + { + count = 1; + + if ((value & 0xFFFFFFFF) == 0) + { + value >>= 32; + count += 32; + } + + if ((value & 0xFFFF) == 0) + { + value >>= 16; + count += 16; + } + + if ((value & 0xFF) == 0) + { + value >>= 8; + count += 8; + } + + if ((value & 0xF) == 0) + { + value >>= 4; + count += 4; + } + + if ((value & 0x3) == 0) + { + value >>= 2; + count += 2; + } + + count -= value & 0x1; + } + + return count; + } + + //*************************************************************************** + /// Find the position of the first set bit. + /// Starts from LSB. + //*************************************************************************** + template + uint_least8_t first_set_bit_position(T value) + { + return count_trailing_zeros(value); + } + + //*************************************************************************** + /// Find the position of the first clear bit. + /// Starts from LSB. + //*************************************************************************** + template + uint_least8_t first_clear_bit_position(T value) + { + value = ~value; + return count_trailing_zeros(value); + } + + //*************************************************************************** + /// Find the position of the first bit that is clear or set. + /// Starts from LSB. + //*************************************************************************** + template + uint_least8_t first_bit_position(bool state, T value) + { + if (!state) + { + value = ~value; + } + + return count_trailing_zeros(value); + } + //*************************************************************************** /// 8 bit binary constants. //*************************************************************************** diff --git a/src/callback.h b/src/callback.h new file mode 100644 index 00000000..805e3bec --- /dev/null +++ b/src/callback.h @@ -0,0 +1,81 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +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_CALLBACK__ +#define __ETL_CALLBACK__ + +namespace etl +{ + //*************************************************************************** + /// A callback class designed to be multiply inherited by other client classes. + /// The class is parametrised with a callback parameter type and a unique id. + /// The unique id allows multiple callbacks with the same parameter type. + ///\tparam TParameter The callback parameter type. + ///\tparam ID The unique id for this callback. + //*************************************************************************** + template + class callback + { + private: + + // Creates a parameter type unique to this ID. + template + struct parameter + { + parameter(T value) + : value(value) + { + } + + typedef T value_type; + + T value; + + private: + + parameter(); + }; + + // Specialisation for void. + template + struct parameter + { + typedef void value_type; + }; + + public: + + typedef parameter type; + + virtual void etl_callback(type p = type()) = 0; + }; +} + +#endif \ No newline at end of file diff --git a/src/char_traits.h b/src/char_traits.h index 6caab98a..21afb8cb 100644 --- a/src/char_traits.h +++ b/src/char_traits.h @@ -44,7 +44,7 @@ SOFTWARE. //***************************************************************************** // Define the large character types if necessary. -#ifdef NO_LARGE_CHAR_SUPPORT +#ifdef ETL_NO_LARGE_CHAR_SUPPORT typedef int16_t char16_t; typedef int32_t char32_t; #endif diff --git a/src/container.h b/src/container.h index d03cddc4..1cf87391 100644 --- a/src/container.h +++ b/src/container.h @@ -277,7 +277,7 @@ namespace etl ///\ingroup container ///************************************************************************** template - size_t size(TValue(&data)[ARRAY_SIZE]) + size_t size(TValue(&)[ARRAY_SIZE]) { return ARRAY_SIZE; } diff --git a/src/crc8_ccitt.cpp b/src/crc8_ccitt.cpp index 1919d21d..3ab90ceb 100644 --- a/src/crc8_ccitt.cpp +++ b/src/crc8_ccitt.cpp @@ -30,6 +30,11 @@ SOFTWARE. #include +#include "platform.h" +#include "static_assert.h" + +STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); + namespace etl { //*************************************************************************** diff --git a/src/string.h b/src/cstring.h similarity index 89% rename from src/string.h rename to src/cstring.h index 3f5bfb80..61f08f64 100644 --- a/src/string.h +++ b/src/cstring.h @@ -33,6 +33,8 @@ SOFTWARE. #include "platform.h" #include "basic_string.h" +#include "ibasic_string.h" +#include "hash.h" #if defined(ETL_COMPILER_MICROSOFT) #undef min @@ -40,7 +42,7 @@ SOFTWARE. namespace etl { - typedef ibasic_string istring; + typedef etl::ibasic_string istring; //*************************************************************************** /// A string implementation that uses a fixed size buffer. @@ -151,11 +153,11 @@ namespace etl { etl::string new_string; - if (position != size()) + if (position != this->size()) { - ETL_ASSERT(position < size(), ETL_ERROR(string_out_of_bounds)); + ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds)); - length = std::min(length, size() - position); + length = std::min(length, this->size() - position); new_string.assign(buffer + position, buffer + position + length); } @@ -180,6 +182,19 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; + + //************************************************************************* + /// Hash function. + //************************************************************************* + template <> + struct hash + { + size_t operator()(const etl::istring& text) const + { + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); + } + }; } #if defined(ETL_COMPILER_MICROSOFT) diff --git a/src/debounce.h b/src/debounce.h index 531b584d..729451f2 100644 --- a/src/debounce.h +++ b/src/debounce.h @@ -116,7 +116,7 @@ namespace etl REPEATING = 16 }; - uint8_t state; + uint_least8_t state; /// The state count. uint16_t count; diff --git a/src/debug_count.h b/src/debug_count.h new file mode 100644 index 00000000..45c55414 --- /dev/null +++ b/src/debug_count.h @@ -0,0 +1,137 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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_DEBUG_COUNT__ +#define __ETL_DEBUG_COUNT__ + +#include +#include + +#include "platform.h" + +///\defgroup debug_count debug count +///\ingroup utilities + +namespace etl +{ + //*************************************************************************** + /// Used to count instances. + /// Asserts if the count is decremented below zero. + /// Asserts if the count is not zero when destructed. + /// Does nothing in a non-debug build. + ///\ingroup reference + //*************************************************************************** + class debug_count + { + public: + +#if defined(ETL_DEBUG) + inline debug_count() + : count(0) + { + } + + inline ~debug_count() + { + assert(count == 0); + } + + inline debug_count& operator ++() + { + ++count; + return *this; + } + + inline debug_count& operator --() + { + --count; + assert(count >= 0); + return *this; + } + + inline debug_count& operator +=(int32_t n) + { + count += n; + return *this; + } + + inline debug_count& operator -=(int32_t n) + { + count -= n; + return *this; + } + + inline operator int32_t() + { + return count; + } + + private: + + int32_t count; +#else + inline debug_count() + { + } + + inline ~debug_count() + { + } + + inline debug_count& operator ++() + { + return *this; + } + + inline debug_count& operator --() + { + return *this; + } + + inline debug_count& operator +=(int32_t /*n*/) + { + return *this; + } + + inline debug_count& operator -=(int32_t /*n*/) + { + return *this; + } + + inline operator int32_t() + { + return 0; + } +#endif + }; +} + +#endif + diff --git a/src/deque.h b/src/deque.h index 08db51d5..540de43c 100644 --- a/src/deque.h +++ b/src/deque.h @@ -86,6 +86,14 @@ namespace etl ideque::initialise(); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~deque() + { + ideque::initialise(); + } + //************************************************************************* /// Copy constructor. //************************************************************************* diff --git a/src/endian.h b/src/endian.h index d905d8e1..c5600534 100644 --- a/src/endian.h +++ b/src/endian.h @@ -54,11 +54,11 @@ namespace etl native }; - DECLARE_ENUM_TYPE(endian, int) - ENUM_TYPE(little, "little") - ENUM_TYPE(big, "big") - ENUM_TYPE(native, "native") - END_ENUM_TYPE + ETL_DECLARE_ENUM_TYPE(endian, int) + ETL_ENUM_TYPE(little, "little") + ETL_ENUM_TYPE(big, "big") + ETL_ENUM_TYPE(native, "native") + ETL_END_ENUM_TYPE }; //*************************************************************************** @@ -68,7 +68,7 @@ namespace etl struct endianness { endianness() - : ETL_ENDIAN_TEST(0x0011) + : ETL_ENDIAN_TEST(0x0011223344556677) { } @@ -79,12 +79,12 @@ namespace etl operator endian() const { - return (*reinterpret_cast(&ETL_ENDIAN_TEST) == 0x11) ? endian::little : endian::big; + return (*reinterpret_cast(&ETL_ENDIAN_TEST) == 0x44556677) ? endian::little : endian::big; } private: - const uint16_t ETL_ENDIAN_TEST; + const uint64_t ETL_ENDIAN_TEST; }; } diff --git a/src/enum_type.h b/src/enum_type.h index 971e8044..82415064 100644 --- a/src/enum_type.h +++ b/src/enum_type.h @@ -48,12 +48,12 @@ SOFTWARE. /// West = 270 /// }; /// -/// DECLARE_ENUM_TYPE(CompassDirection, int) -/// ENUM_TYPE(North, "North") -/// ENUM_TYPE(South, "South") -/// ENUM_TYPE(East, "East") -/// ENUM_TYPE(West, "West") -/// END_ENUM_TYPE +/// ETL_DECLARE_ENUM_TYPE(CompassDirection, int) +/// ETL_ENUM_TYPE(North, "North") +/// ETL_ENUM_TYPE(South, "South") +/// ETL_ENUM_TYPE(East, "East") +/// ETL_ENUM_TYPE(West, "West") +/// ETL_END_ENUM_TYPE /// }; ///\endcode /// Using the enumeration. @@ -72,15 +72,15 @@ SOFTWARE. /// /// std::cout << "Direction = " << direction.c_str(); // Prints "Direction = North" ///\endcode -/// If a conversion to a string is not required then the 'ENUM_TYPE' declaration may be omitted. +/// If a conversion to a string is not required then the 'ETL_ENUM_TYPE' declaration may be omitted. /// In that case the c_str() function will return a "?". This will also be the case for any -/// enumeration value that does not have an ENUM_TYPE entry. +/// enumeration value that does not have an ETL_ENUM_TYPE entry. ///\ingroup utilities //***************************************************************************** // The declaration of the member functions and the first section of the 'c_str' function. //***************************************************************************** -#define DECLARE_ENUM_TYPE(TypeName, ValueType) \ +#define ETL_DECLARE_ENUM_TYPE(TypeName, ValueType) \ typedef ValueType value_type; \ TypeName() {} \ TypeName(const TypeName &other) : value(other.value) {} \ @@ -98,14 +98,14 @@ SOFTWARE. //***************************************************************************** // A case in the 'c_str' function's switch statement. //***************************************************************************** -#define ENUM_TYPE(value, name) \ +#define ETL_ENUM_TYPE(value, name) \ case value: \ return name; \ //***************************************************************************** // The final section of the 'c_str' function and the value declaration. //***************************************************************************** -#define END_ENUM_TYPE \ +#define ETL_END_ENUM_TYPE \ default: \ return "?"; \ } \ diff --git a/src/exception.h b/src/exception.h index 52369caa..3b39f1e9 100644 --- a/src/exception.h +++ b/src/exception.h @@ -35,7 +35,7 @@ SOFTWARE. /// The base class for all ETL exceptions. ///\ingroup utilities -namespace etl +namespace etl { //*************************************************************************** ///\ingroup exception @@ -66,6 +66,7 @@ namespace etl : reason(reason), line(line) { + (void)file; } #endif diff --git a/src/file_error_numbers.txt b/src/file_error_numbers.txt index db9728cc..fc8953bc 100644 --- a/src/file_error_numbers.txt +++ b/src/file_error_numbers.txt @@ -8,7 +8,7 @@ 8 map_base 9 multimap_base 10 multiset_base -11 pool_base +11 ipool 12 ipriority_queue 13 queue_base 14 set_base @@ -23,4 +23,7 @@ 23 iunordered_set, iunordered_multiset 24 variant 25 iunordered_multimap -26 iunordered_multiset \ No newline at end of file +26 iunordered_multiset +27 string_base +28 intrusive_stack +29 intrusive_queue \ No newline at end of file diff --git a/src/fixed_iterator.h b/src/fixed_iterator.h index 1b9d1370..8357f30a 100644 --- a/src/fixed_iterator.h +++ b/src/fixed_iterator.h @@ -137,7 +137,7 @@ namespace etl //*************************************************************************** /// += operator. //*************************************************************************** - fixed_iterator& operator +=(typename std::iterator_traits::difference_type offset) + fixed_iterator& operator +=(typename std::iterator_traits::difference_type /*offset*/) { return *this; } @@ -145,7 +145,7 @@ namespace etl //*************************************************************************** /// -= operator. //*************************************************************************** - fixed_iterator& operator -=(typename std::iterator_traits::difference_type offset) + fixed_iterator& operator -=(typename std::iterator_traits::difference_type /*offset*/) { return *this; } @@ -179,7 +179,7 @@ namespace etl //***************************************************************************** template etl::fixed_iterator& operator +(etl::fixed_iterator& lhs, - typename std::iterator_traits::difference_type rhs) + typename std::iterator_traits::difference_type /*rhs*/) { return lhs; } @@ -189,7 +189,7 @@ etl::fixed_iterator& operator +(etl::fixed_iterator& lhs, //***************************************************************************** template etl::fixed_iterator& operator -(etl::fixed_iterator& lhs, - typename std::iterator_traits::difference_type rhs) + typename std::iterator_traits::difference_type /*rhs*/) { return lhs; } diff --git a/src/flat_map.h b/src/flat_map.h index f323a367..12cca227 100644 --- a/src/flat_map.h +++ b/src/flat_map.h @@ -37,18 +37,18 @@ SOFTWARE. #include "iflat_map.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_map flat_map /// A flat_map with the capacity defined at compile time. /// Has insertion of O(N) and flat_map of O(logN) -/// Duplicate entries and not allowed. +/// Duplicate entries are not allowed. ///\ingroup containers //***************************************************************************** namespace etl { - template > //*************************************************************************** /// A flat_map implementation that uses a fixed size buffer. ///\tparam TKey The key type. @@ -57,6 +57,7 @@ namespace etl ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. ///\ingroup flat_map //*************************************************************************** + template > class flat_map : public iflat_map { public: @@ -67,7 +68,7 @@ namespace etl /// Constructor. //************************************************************************* flat_map() - : iflat_map(buffer) + : iflat_map(lookup, storage) { } @@ -75,7 +76,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_map(const flat_map& other) - : iflat_map(buffer) + : iflat_map(lookup, storage) { iflat_map::assign(other.cbegin(), other.cend()); } @@ -88,11 +89,19 @@ namespace etl //************************************************************************* template flat_map(TIterator first, TIterator last) - : iflat_map(buffer) + : iflat_map(lookup, storage) { iflat_map::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_map() + { + iflat_map::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -108,7 +117,13 @@ namespace etl private: - etl::vector::value_type, MAX_SIZE> buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_multimap.h b/src/flat_multimap.h index b0d3722b..603ff4b5 100644 --- a/src/flat_multimap.h +++ b/src/flat_multimap.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_multimap.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_multimap flat_multimap @@ -67,7 +68,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multimap() - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { } @@ -75,7 +76,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_multimap(const flat_multimap& other) - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { iflat_multimap::assign(other.cbegin(), other.cend()); } @@ -88,11 +89,19 @@ namespace etl //************************************************************************* template flat_multimap(TIterator first, TIterator last) - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { iflat_multimap::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_multimap() + { + iflat_multimap::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -108,7 +117,13 @@ namespace etl private: - etl::vector::value_type, MAX_SIZE> buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_multiset.h b/src/flat_multiset.h index 3f5c47f9..be7a9273 100644 --- a/src/flat_multiset.h +++ b/src/flat_multiset.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_multiset.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_multiset flat_multiset @@ -66,7 +67,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multiset() - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { } @@ -74,7 +75,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_multiset(const flat_multiset& other) - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { iflat_multiset::assign(other.cbegin(), other.cend()); } @@ -87,11 +88,19 @@ namespace etl //************************************************************************* template flat_multiset(TIterator first, TIterator last) - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { iflat_multiset::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_multiset() + { + iflat_multiset::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -107,7 +116,13 @@ namespace etl private: - etl::vector buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_set.h b/src/flat_set.h index 07ce888a..4a01b066 100644 --- a/src/flat_set.h +++ b/src/flat_set.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_set.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_set flat_set @@ -66,7 +67,7 @@ namespace etl /// Constructor. //************************************************************************* flat_set() - : iflat_set(buffer) + : iflat_set(lookup, storage) { } @@ -74,7 +75,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_set(const flat_set& other) - : iflat_set(buffer) + : iflat_set(lookup, storage) { iflat_set::assign(other.cbegin(), other.cend()); } @@ -87,11 +88,19 @@ namespace etl //************************************************************************* template flat_set(TIterator first, TIterator last) - : iflat_set(buffer) + : iflat_set(lookup, storage) { iflat_set::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_set() + { + iflat_set::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -107,7 +116,13 @@ namespace etl private: - etl::vector buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/fnv_1.h b/src/fnv_1.h index 5ae00dac..c9799196 100644 --- a/src/fnv_1.h +++ b/src/fnv_1.h @@ -37,6 +37,8 @@ SOFTWARE. #include "static_assert.h" #include "type_traits.h" #include "ihash.h" +#include "frame_check_sequence.h" + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 1300 @@ -47,22 +49,49 @@ SOFTWARE. namespace etl { + //*************************************************************************** + /// fnv_1 policy. + /// Calculates FNV1. + //*************************************************************************** + struct fnv_1_policy_64 + { + typedef uint64_t value_type; + + inline uint64_t initial() const + { + return OFFSET_BASIS; + } + + inline uint64_t add(uint64_t hash, uint8_t value) const + { + hash *= PRIME; + hash ^= value; + return hash; + } + + inline uint64_t final(uint64_t hash) const + { + return hash; + } + + static const uint64_t OFFSET_BASIS = 0xCBF29CE484222325; + static const uint64_t PRIME = 0x00000100000001b3; + }; + //*************************************************************************** /// Calculates the fnv_1_64 hash. ///\ingroup fnv_1_64 //*************************************************************************** - class fnv_1_64 + class fnv_1_64 : public etl::frame_check_sequence { public: - typedef uint64_t value_type; - //************************************************************************* /// Default constructor. //************************************************************************* fnv_1_64() { - reset(); + this->reset(); } //************************************************************************* @@ -73,70 +102,36 @@ namespace etl template fnv_1_64(TIterator begin, const TIterator end) { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + this->reset(); + this->add(begin, end); + } + }; - reset(); - while (begin != end) + //*************************************************************************** + /// fnv_1a policy. + /// Calculates FNV1A. + //*************************************************************************** + struct fnv_1a_policy_64 + { + typedef uint64_t value_type; + + inline uint64_t initial() const { - hash *= PRIME; - hash ^= *begin++; - } + return OFFSET_BASIS; } - //************************************************************************* - /// Resets the CRC to the initial state. - //************************************************************************* - void reset() + inline uint64_t add(uint64_t hash, uint8_t value) const { - hash = OFFSET_BASIS; - } - - //************************************************************************* - /// Adds a range. - /// \param begin - /// \param end - //************************************************************************* - template - void add(TIterator begin, const TIterator end) - { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - - while (begin != end) - { - hash *= PRIME; - hash ^= *begin++; - } - } - - //************************************************************************* - /// \param value The char to add to the fnv_1_64. - //************************************************************************* - void add(uint8_t value) - { - hash *= PRIME; hash ^= value; - } - - //************************************************************************* - /// Gets the fnv_1_64 value. - //************************************************************************* - value_type value() const - { + hash *= PRIME; return hash; } - //************************************************************************* - /// Conversion operator to value_type. - //************************************************************************* - operator value_type () const + inline uint64_t final(uint64_t hash) const { return hash; } - private: - - value_type hash; - static const uint64_t OFFSET_BASIS = 0xCBF29CE484222325; static const uint64_t PRIME = 0x00000100000001b3; }; @@ -145,18 +140,16 @@ namespace etl /// Calculates the fnv_1a_64 hash. ///\ingroup fnv_1a_64 //*************************************************************************** - class fnv_1a_64 + class fnv_1a_64 : public etl::frame_check_sequence { public: - typedef uint64_t value_type; - //************************************************************************* /// Default constructor. //************************************************************************* fnv_1a_64() { - reset(); + this->reset(); } //************************************************************************* @@ -167,90 +160,54 @@ namespace etl template fnv_1a_64(TIterator begin, const TIterator end) { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - - reset(); - while (begin != end) - { - hash ^= *begin++; - hash *= PRIME; - } + this->reset(); + this->add(begin, end); } + }; - //************************************************************************* - /// Resets the CRC to the initial state. - //************************************************************************* - void reset() + //*************************************************************************** + /// fnv_1 policy. + /// Calculates FNV1. + //*************************************************************************** + struct fnv_1_policy_32 { - hash = OFFSET_BASIS; - } - - //************************************************************************* - /// Adds a range. - /// \param begin - /// \param end - //************************************************************************* - template - void add(TIterator begin, const TIterator end) - { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + typedef uint32_t value_type; - while (begin != end) + inline uint32_t initial() const { - hash ^= *begin++; - hash *= PRIME; - } + return OFFSET_BASIS; } - //************************************************************************* - /// \param value The char to add to the fnv_1a_64. - //************************************************************************* - void add(uint8_t value) + inline uint32_t add(uint32_t hash, uint8_t value) const { - hash ^= value; hash *= PRIME; + hash ^= value; + return hash; } - //************************************************************************* - /// Gets the fnv_1a_64 value. - //************************************************************************* - value_type value() const + inline uint32_t final(uint32_t hash) const { return hash; } - //************************************************************************* - /// Conversion operator to value_type. - //************************************************************************* - operator value_type () const - { - return hash; - } - - private: - - value_type hash; - - static const uint64_t OFFSET_BASIS = 0xCBF29CE484222325; - static const uint64_t PRIME = 0x00000100000001b3; + static const uint32_t OFFSET_BASIS = 0x811C9DC5; + static const uint32_t PRIME = 0x01000193; }; //*************************************************************************** /// Calculates the fnv_1_32 hash. ///\ingroup fnv_1_32 //*************************************************************************** - class fnv_1_32 + class fnv_1_32 : public etl::frame_check_sequence { public: - typedef uint32_t value_type; - //************************************************************************* /// Default constructor. //************************************************************************* fnv_1_32() { - reset(); + this->reset(); } //************************************************************************* @@ -261,70 +218,36 @@ namespace etl template fnv_1_32(TIterator begin, const TIterator end) { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); + this->reset(); + this->add(begin, end); + } + }; - reset(); - while (begin != end) + //*************************************************************************** + /// fnv_1a policy. + /// Calculates FNV1A. + //*************************************************************************** + struct fnv_1a_policy_32 + { + typedef uint32_t value_type; + + inline uint32_t initial() const { - hash *= PRIME; - hash ^= *begin++; - } + return OFFSET_BASIS; } - //************************************************************************* - /// Resets the CRC to the initial state. - //************************************************************************* - void reset() + inline uint32_t add(uint32_t hash, uint8_t value) const { - hash = OFFSET_BASIS; - } - - //************************************************************************* - /// Adds a range. - /// \param begin - /// \param end - //************************************************************************* - template - void add(TIterator begin, const TIterator end) - { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - - while (begin != end) - { - hash *= PRIME; - hash ^= *begin++; - } - } - - //************************************************************************* - /// \param value The char to add to the fnv_1_32. - //************************************************************************* - void add(uint8_t value) - { - hash *= PRIME; hash ^= value; - } - - //************************************************************************* - /// Gets the fnv_1_32 value. - //************************************************************************* - value_type value() const - { + hash *= PRIME; return hash; } - //************************************************************************* - /// Conversion operator to value_type. - //************************************************************************* - operator value_type () const + inline uint32_t final(uint32_t hash) const { return hash; } - private: - - value_type hash; - static const uint32_t OFFSET_BASIS = 0x811C9DC5; static const uint32_t PRIME = 0x01000193; }; @@ -333,18 +256,16 @@ namespace etl /// Calculates the fnv_1a_32 hash. ///\ingroup fnv_1a_32 //*************************************************************************** - class fnv_1a_32 + class fnv_1a_32 : public etl::frame_check_sequence { public: - typedef uint32_t value_type; - //************************************************************************* /// Default constructor. //************************************************************************* fnv_1a_32() { - reset(); + this->reset(); } //************************************************************************* @@ -355,72 +276,9 @@ namespace etl template fnv_1a_32(TIterator begin, const TIterator end) { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - - reset(); - while (begin != end) - { - hash ^= *begin++; - hash *= PRIME; - } + this->reset(); + this->add(begin, end); } - - //************************************************************************* - /// Resets the CRC to the initial state. - //************************************************************************* - void reset() - { - hash = OFFSET_BASIS; - } - - //************************************************************************* - /// Adds a range. - /// \param begin - /// \param end - //************************************************************************* - template - void add(TIterator begin, const TIterator end) - { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Type not supported"); - - while (begin != end) - { - hash ^= *begin++; - hash *= PRIME; - } - } - - //************************************************************************* - /// \param value The char to add to the fnv_1a_32. - //************************************************************************* - void add(uint8_t value) - { - hash ^= value; - hash *= PRIME; - } - - //************************************************************************* - /// Gets the fnv_1a_32 value. - //************************************************************************* - value_type value() const - { - return hash; - } - - //************************************************************************* - /// Conversion operator to value_type. - //************************************************************************* - operator value_type () const - { - return hash; - } - - private: - - value_type hash; - - static const uint32_t OFFSET_BASIS = 0x811C9DC5; - static const uint32_t PRIME = 0x01000193; }; } diff --git a/src/forward_list.h b/src/forward_list.h index 8ca61191..054a1982 100644 --- a/src/forward_list.h +++ b/src/forward_list.h @@ -89,7 +89,7 @@ namespace etl forward_list(const forward_list& other) : iforward_list(node_pool, MAX_SIZE) { - iforward_list::assign(other.cbegin(), other.cend()); + iforward_list::assign(other.cbegin(), other.cend()); } //************************************************************************* @@ -102,6 +102,14 @@ namespace etl iforward_list::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~forward_list() + { + iforward_list::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -118,7 +126,7 @@ namespace etl private: /// The pool of nodes used in the list. - etl::pool::Data_Node, MAX_SIZE> node_pool; + etl::pool::data_node_t, MAX_SIZE> node_pool; }; } diff --git a/src/frame_check_sequence.h b/src/frame_check_sequence.h index 74dc7744..0a1aabc7 100644 --- a/src/frame_check_sequence.h +++ b/src/frame_check_sequence.h @@ -29,10 +29,13 @@ SOFTWARE. #include +#include "platform.h" #include "static_assert.h" #include "type_traits.h" #include "binary.h" +STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); + ///\defgroup frame_check_sequence Frame check sequence calculation ///\ingroup maths @@ -50,9 +53,9 @@ namespace etl typedef TPolicy policy_type; typedef typename policy_type::value_type value_type; - + STATIC_ASSERT(etl::is_unsigned::value, "Signed frame check type not supported"); - + //************************************************************************* /// Default constructor. //************************************************************************* @@ -110,7 +113,7 @@ namespace etl //************************************************************************* /// Gets the FCS value. //************************************************************************* - value_type value() const + value_type value() { return policy.final(frame_check); } @@ -118,7 +121,7 @@ namespace etl //************************************************************************* /// Conversion operator to value_type. //************************************************************************* - operator value_type () const + operator value_type () { return policy.final(frame_check); } diff --git a/src/function.h b/src/function.h index caf7b4c9..6e1053da 100644 --- a/src/function.h +++ b/src/function.h @@ -200,8 +200,8 @@ namespace etl /// Constructor. ///\param p_function Pointer to the function. //************************************************************************* - function(void(*p_function)(void)) - : p_function(p_function) + function(void(*p_function_)(void)) + : p_function(p_function_) { } diff --git a/src/hash.h b/src/hash.h index 3d02ab9b..39408f3a 100644 --- a/src/hash.h +++ b/src/hash.h @@ -32,6 +32,7 @@ SOFTWARE. #define __ETL_HASH__ #include +#include // The default hash calculation. #include "fnv_1.h" @@ -49,9 +50,9 @@ namespace etl /// Hash to use when size_t is 16 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { uint32_t h = fnv_1a_32(begin, end); @@ -62,9 +63,9 @@ namespace etl /// Hash to use when size_t is 32 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { return fnv_1a_32(begin, end); } @@ -73,9 +74,9 @@ namespace etl /// Hash to use when size_t is 64 bits. /// T is always expected to be size_t. //************************************************************************* - template + template typename enable_if::type - generic_hash(uint8_t* begin, uint8_t* end) + generic_hash(const uint8_t* begin, const uint8_t* end) { return fnv_1a_64(begin, end); } @@ -229,9 +230,9 @@ namespace etl template<> struct hash { - // If it fits into a size_t. size_t operator ()(long v) const { + // If it's the same size as a size_t. if (sizeof(size_t) >= sizeof(v)) { return static_cast(v); @@ -251,9 +252,9 @@ namespace etl template<> struct hash { - // If it fits into a size_t. size_t operator ()(long long v) const { + // If it's the same size as a size_t. if (sizeof(size_t) >= sizeof(v)) { return static_cast(v); @@ -273,9 +274,9 @@ namespace etl template<> struct hash { - // If it fits into a size_t. size_t operator ()(unsigned long v) const { + // If it's the same size as a size_t. if (sizeof(size_t) >= sizeof(v)) { return static_cast(v); @@ -295,9 +296,9 @@ namespace etl template<> struct hash { - // If it fits into a size_t. size_t operator ()(unsigned long long v) const { + // If it's the same size as a size_t. if (sizeof(size_t) >= sizeof(v)) { return static_cast(v); @@ -317,12 +318,20 @@ namespace etl template<> struct hash { - // If it's the same size as a size_t. size_t operator ()(float v) const { + // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - return *reinterpret_cast(&v); + union + { + size_t s; + float v; + } u; + + u.v = v; + + return u.s; } else { @@ -339,12 +348,20 @@ namespace etl template<> struct hash { - // If it's the same size as a size_t. size_t operator ()(double v) const { + // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - return *reinterpret_cast(&v); + union + { + size_t s; + double v; + } u; + + u.v = v; + + return u.s; } else { @@ -361,12 +378,20 @@ namespace etl template<> struct hash { - // If it's the same size as a size_t. size_t operator ()(long double v) const { + // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(v)) { - return *reinterpret_cast(&v); + union + { + size_t s; + long double v; + } u; + + u.v = v; + + return u.s; } else { @@ -385,9 +410,18 @@ namespace etl { size_t operator ()(const T* v) const { + // If it's the same size as a size_t. if (sizeof(size_t) == sizeof(T*)) { - return reinterpret_cast(v); + union + { + size_t s; + const T* v; + } u; + + u.v = v; + + return u.s; } else { diff --git a/src/ibasic_string.h b/src/ibasic_string.h index 275f0328..88fbf484 100644 --- a/src/ibasic_string.h +++ b/src/ibasic_string.h @@ -36,7 +36,7 @@ SOFTWARE. #include #include #include -#include +#include #include "private/string_base.h" #include "platform.h" @@ -148,7 +148,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return reverse_iterator(end()); + return reverse_iterator(end()); } //********************************************************************* @@ -157,7 +157,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); + return const_reverse_iterator(end()); } //********************************************************************* @@ -184,7 +184,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return const_reverse_iterator(cend()); + return const_reverse_iterator(cend()); } //********************************************************************* @@ -193,7 +193,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return const_reverse_iterator(cbegin()); + return const_reverse_iterator(cbegin()); } //********************************************************************* @@ -400,7 +400,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(string_iterator)); #endif @@ -464,10 +464,11 @@ namespace etl //************************************************************************* void pop_back() { - if (current_size > 0) - { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!empty(), ETL_ERROR(string_empty)); +#endif + p_buffer[--current_size] = 0; - } } //********************************************************************* @@ -892,7 +893,7 @@ namespace etl //********************************************************************* size_t find(const_pointer s, size_t pos = 0) const { -#ifdef _DEBUG +#if defined(ETL_DEBUG) if ((pos + etl::strlen(s)) > size()) { return npos; @@ -919,7 +920,7 @@ namespace etl //********************************************************************* size_t find(const_pointer s, size_t pos, size_t n) const { -#ifdef _DEBUG +#if defined(ETL_DEBUG) if ((pos + etl::strlen(s) - n) > size()) { return npos; diff --git a/src/ibitset.h b/src/ibitset.h index ee2747f8..b207c7a8 100644 --- a/src/ibitset.h +++ b/src/ibitset.h @@ -85,7 +85,7 @@ namespace etl // The type used for each element in the array. #if !defined(ETL_BITSET_ELEMENT_TYPE) - typedef uint8_t element_t; + typedef uint_least8_t element_t; #else typedef ETL_BITSET_ELEMENT_TYPE element_t; #endif diff --git a/src/ideque.h b/src/ideque.h index 6c235183..d5d47141 100644 --- a/src/ideque.h +++ b/src/ideque.h @@ -295,7 +295,7 @@ namespace etl //*************************************************** const_iterator& operator ++() { - index = (index == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1; + index = (static_cast(index) == p_deque->BUFFER_SIZE - 1) ? 0 : index + 1; return *this; } @@ -331,7 +331,7 @@ namespace etl if (offset > 0) { index -= offset; - index = (index < 0) ? index + p_deque->BUFFER_SIZE : index; + index = (index < 0) ? static_cast(index) + p_deque->BUFFER_SIZE : index; } else if (offset < 0) { @@ -1251,13 +1251,10 @@ namespace etl //********************************************************************* void create_element_front() { - if (!empty()) - { - --_begin; - } - - new(&(*_begin)) T(); + --_begin; + ::new (&(*_begin)) T(); ++current_size; + ++construct_count; } //********************************************************************* @@ -1286,9 +1283,10 @@ namespace etl do { - new(&(*item++)) T(*from); + ::new (&(*item++)) T(*from); ++from; ++current_size; + ++construct_count; } while (n-- != 0); } @@ -1297,9 +1295,10 @@ namespace etl //********************************************************************* void create_element_back() { - new(&(*_end)) T(); + ::new (&(*_end)) T(); ++_end; ++current_size; + ++construct_count; } //********************************************************************* @@ -1308,8 +1307,9 @@ namespace etl void create_element_front(parameter_t value) { --_begin; - new(&(*_begin)) T(value); + ::new (&(*_begin)) T(value); ++current_size; + ++construct_count; } //********************************************************************* @@ -1317,9 +1317,10 @@ namespace etl //********************************************************************* void create_element_back(parameter_t value) { - new(&(*_end)) T(value); + ::new (&(*_end)) T(value); ++_end; ++current_size; + ++construct_count; } //********************************************************************* @@ -1329,6 +1330,7 @@ namespace etl { (*_begin).~T(); --current_size; + --construct_count; ++_begin; } @@ -1340,6 +1342,7 @@ namespace etl --_end; (*_end).~T(); --current_size; + --construct_count; } //************************************************************************* diff --git a/src/iflat_map.h b/src/iflat_map.h index 399897f2..20dbed02 100644 --- a/src/iflat_map.h +++ b/src/iflat_map.h @@ -38,10 +38,12 @@ SOFTWARE. #include #include +#include "platform.h" #include "private/flat_map_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" +#include "ipool.h" #include "error_handler.h" namespace etl @@ -60,22 +62,229 @@ namespace etl private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef TKey key_type; - typedef TMapped mapped_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKey key_type; + typedef TMapped mapped_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_map; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_map; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; protected: @@ -110,7 +319,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -119,7 +328,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -128,7 +337,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -137,7 +346,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -146,7 +355,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -155,7 +364,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -164,7 +373,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -173,7 +382,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -182,7 +391,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -191,7 +400,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -200,7 +409,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -209,7 +418,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -223,9 +432,9 @@ namespace etl if (i_element == end()) { - // Doesn't exist, so create a new one. - value_type value(key, mapped_type()); - i_element = insert(value).first; + std::pair result = insert_at(i_element, value_type(key, mapped_type())); + + i_element = result.first; } return i_element->second; @@ -254,7 +463,7 @@ namespace etl //********************************************************************* const mapped_type& at(key_value_parameter_t key) const { - typename buffer_t::const_iterator i_element = lower_bound(key); + typename const_iterator i_element = lower_bound(key); ETL_ASSERT(i_element != end(), ETL_ERROR(flat_map_out_of_bounds)); @@ -271,7 +480,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_map_full)); #endif @@ -291,33 +500,9 @@ namespace etl //********************************************************************* std::pair insert(const value_type& value) { - std::pair result(end(), false); - iterator i_element = lower_bound(value.first); - if (i_element == end()) - { - // At the end. - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_map_full)); - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - // Existing element? - if (value.first != i_element->first) - { - // A new one. - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_map_full)); - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; - } - } - - return result; + return insert_at(i_element, value); } //********************************************************************* @@ -362,7 +547,10 @@ namespace etl } else { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; return 1; } } @@ -373,7 +561,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -385,7 +576,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -393,7 +594,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -531,23 +732,120 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the flat_map. + ///\return The current size of the flat_map. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_map. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_map. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_map. + ///\return The capacity of the flat_map. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_map. + ///\return The maximum size of the flat_map. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - iflat_map(buffer_t& buffer) - : flat_map_base(buffer), - buffer(buffer) + iflat_map(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } private: + //********************************************************************* + /// Inserts a value to the flat_map. + ///\param i_element The place to insert. + ///\param value The value to insert. + //********************************************************************* + std::pair insert_at(iterator i_element, const value_type& value) + { + std::pair result(end(), false); + + if (i_element == end()) + { + // At the end. + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full)); + + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); + result.second = true; + ++construct_count; + } + else + { + // Not at the end. + result.first = i_element; + + // Existing element? + if (value.first != i_element->first) + { + // A new one. + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full)); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); + result.second = true; + ++construct_count; + } + } + + return result; + } + // Disable copy construction. iflat_map(const iflat_map&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_multimap.h b/src/iflat_multimap.h index e5fa864e..f16abda9 100644 --- a/src/iflat_multimap.h +++ b/src/iflat_multimap.h @@ -38,11 +38,13 @@ SOFTWARE. #include #include +#include "platform.h" #include "private/flat_multimap_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" #include "error_handler.h" +#include "ipool.h" namespace etl { @@ -60,22 +62,229 @@ namespace etl private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef TKey key_type; - typedef TMapped mapped_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKey key_type; + typedef TMapped mapped_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_multimap; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_multimap; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; protected: @@ -110,7 +319,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -119,7 +328,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -128,7 +337,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -137,7 +346,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -146,7 +355,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -155,7 +364,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -164,7 +373,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -173,7 +382,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -182,7 +391,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -191,7 +400,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -200,7 +409,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -209,7 +418,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -222,7 +431,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multimap_full)); #endif @@ -242,28 +451,13 @@ namespace etl //********************************************************************* std::pair insert(const value_type& value) { - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multimap_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multimap_full)); - std::pair result(end(), false); +std::pair result(end(), false); iterator i_element = lower_bound(value.first); - 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; + return insert_at(i_element, value); } //********************************************************************* @@ -300,7 +494,7 @@ namespace etl //********************************************************************* size_t erase(key_value_parameter_t key) { - std::pair range = equal_range(key); + std::pair range = equal_range(key); if (range.first == end()) { @@ -308,8 +502,8 @@ namespace etl } else { - size_t count = std::distance(range.first, range.second); - erase(range.first, range.second); + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); return count; } } @@ -320,7 +514,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -332,7 +529,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -340,7 +547,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -398,9 +605,9 @@ namespace etl //********************************************************************* size_t count(key_value_parameter_t key) const { - std::pair range = equal_range(key); + std::pair range = equal_range(key); - return std::distance(range.first, range.second); + return std::distance(range.first, range.second); } //********************************************************************* @@ -480,23 +687,111 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the flat_multiset. + ///\return The current size of the flat_multiset. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multiset. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multiset. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multiset. + ///\return The capacity of the flat_multiset. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multiset. + ///\return The maximum size of the flat_multiset. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - iflat_multimap(buffer_t& buffer) - : flat_multimap_base(buffer), - buffer(buffer) + iflat_multimap(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } private: + //********************************************************************* + /// Inserts a value to the flat_multimap. + ///\param i_element The place to insert. + ///\param value The value to insert. + //********************************************************************* + std::pair insert_at(iterator i_element, const value_type& value) + { + std::pair result(end(), false); + + if (i_element == end()) + { + // At the end. + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); + result.second = true; + } + else + { + // Not at the end. + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); + result.first = i_element; + result.second = true; + } + + ++construct_count; + + return result; + } + // Disable copy construction. iflat_multimap(const iflat_multimap&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_multiset.h b/src/iflat_multiset.h index 135511c0..541e723a 100644 --- a/src/iflat_multiset.h +++ b/src/iflat_multiset.h @@ -38,11 +38,13 @@ SOFTWARE. #include #include +#include "platform.h" #include "private/flat_multiset_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" #include "error_handler.h" +#include "ipool.h" namespace etl { @@ -54,26 +56,237 @@ namespace etl template > class iflat_multiset : public flat_multiset_base { + public: + + typedef T key_type; + typedef T value_type; + private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef T key_type; - typedef T value_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_multiset; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_multiset; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; + protected: typedef typename parameter_type::type parameter_t; @@ -86,7 +299,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -95,7 +308,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -104,7 +317,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -113,7 +326,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -122,7 +335,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -131,7 +344,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -140,7 +353,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -149,7 +362,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -158,7 +371,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -167,7 +380,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -176,7 +389,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -185,7 +398,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -198,7 +411,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multiset_full)); #endif @@ -220,25 +433,31 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multiset_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_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; + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); result.second = true; } else { // Not at the end. - buffer.insert(i_element, value); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); result.first = i_element; result.second = true; } - + + ++construct_count; + return result; } @@ -276,7 +495,7 @@ namespace etl //********************************************************************* size_t erase(parameter_t key) { - std::pair range = equal_range(key); + std::pair range = equal_range(key); if (range.first == end()) { @@ -284,9 +503,9 @@ namespace etl } else { - size_t count = std::distance(range.first, range.second); - erase(range.first, range.second); - return count; + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); + return count; } } @@ -296,7 +515,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -308,7 +530,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -316,7 +548,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -376,7 +608,7 @@ namespace etl { std::pair range = equal_range(key); - return std::distance(range.first, range.second); + return std::distance(range.first, range.second); } //********************************************************************* @@ -452,14 +684,68 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the flat_multiset. + ///\return The current size of the flat_multiset. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multiset. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multiset. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multiset. + ///\return The capacity of the flat_multiset. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multiset. + ///\return The maximum size of the flat_multiset. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - iflat_multiset(buffer_t& buffer) - : flat_multiset_base(buffer), - buffer(buffer) + iflat_multiset(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } @@ -468,7 +754,8 @@ namespace etl // Disable copy construction. iflat_multiset(const iflat_multiset&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_set.h b/src/iflat_set.h index 55ca571a..c5cbaf78 100644 --- a/src/iflat_set.h +++ b/src/iflat_set.h @@ -38,10 +38,12 @@ SOFTWARE. #include #include +#include "platform.h" #include "private/flat_set_base.h" #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" +#include "ipool.h" #include "error_handler.h" namespace etl @@ -54,25 +56,230 @@ namespace etl template > class iflat_set : public flat_set_base { + public: + + typedef T key_type; + typedef T value_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef T key_type; - typedef T value_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; - typedef typename std::iterator_traits::difference_type difference_type; + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_set; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_set; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; protected: @@ -80,13 +287,17 @@ namespace etl public: + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename std::iterator_traits::difference_type difference_type; + //********************************************************************* /// Returns an iterator to the beginning of the flat_set. ///\return An iterator to the beginning of the flat_set. //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -95,7 +306,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -104,7 +315,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -113,7 +324,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -122,7 +333,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -131,7 +342,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -140,7 +351,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -149,7 +360,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -158,7 +369,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -167,7 +378,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -176,7 +387,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -185,7 +396,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -198,7 +409,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_set_full)); #endif @@ -220,16 +431,19 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_set_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full)); iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); if (i_element == end()) { // At the end. Doesn't exist. - buffer.push_back(value); - result.first = end() - 1; + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); result.second = true; + ++construct_count; } else { @@ -237,9 +451,12 @@ namespace etl // Does not exist already? if (*i_element != value) { - buffer.insert(i_element, value); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); result.first = i_element; result.second = true; + ++construct_count; } else { @@ -293,7 +510,10 @@ namespace etl } else { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; return 1; } } @@ -304,7 +524,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -316,7 +539,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup);; } //************************************************************************* @@ -324,7 +557,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -458,14 +691,68 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the flat_set. + ///\return The current size of the flat_set. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_set. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_set. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_set. + ///\return The capacity of the flat_set. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_set. + ///\return The maximum size of the flat_set. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - iflat_set(buffer_t& buffer) - : flat_set_base(buffer), - buffer(buffer) + iflat_set(lookup_t& lookup_, storage_t& storage) + : lookup(lookup_), + storage(storage) { } @@ -474,7 +761,8 @@ namespace etl // Disable copy construction. iflat_set(const iflat_set&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iforward_list.h b/src/iforward_list.h index b663ad8e..c128ec55 100644 --- a/src/iforward_list.h +++ b/src/iforward_list.h @@ -74,9 +74,9 @@ namespace etl //************************************************************************* /// The data node element in the forward_list. //************************************************************************* - struct Data_Node : public Node + struct data_node_t : public node_t { - explicit Data_Node(parameter_t value) + explicit data_node_t(parameter_t value) : value(value) {} @@ -99,7 +99,7 @@ namespace etl { } - iterator(Node& node) + iterator(node_t& node) : p_node(&node) { } @@ -170,7 +170,7 @@ namespace etl private: - Node* p_node; + node_t* p_node; }; //************************************************************************* @@ -187,12 +187,12 @@ namespace etl { } - const_iterator(Node& node) + const_iterator(node_t& node) : p_node(&node) { } - const_iterator(const Node& node) + const_iterator(const node_t& node) : p_node(&node) { } @@ -253,10 +253,10 @@ namespace etl private: - const Node* p_node; + const node_t* p_node; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Gets the beginning of the forward_list. @@ -279,7 +279,7 @@ namespace etl //************************************************************************* iterator before_begin() { - return iterator(static_cast(start_node)); + return iterator(static_cast(start_node)); } //************************************************************************* @@ -287,7 +287,7 @@ namespace etl //************************************************************************* const_iterator before_begin() const { - return const_iterator(static_cast(start_node)); + return const_iterator(static_cast(start_node)); } //************************************************************************* @@ -348,31 +348,30 @@ namespace etl //************************************************************************* /// Assigns a range of values to the forward_list. - /// If asserts or exceptions are enabled throws etl::forward_list_full if the forward_list does not have enough free space. + /// If asserts or exceptions are enabled throws etl::forward_list_full if the forward_list does not have enough free space. /// If ETL_THROW_EXCEPTIONS & _DEBUG are defined throws forward_list_iterator if the iterators are reversed. //************************************************************************* template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(forward_list_iterator)); #endif initialise(); - Node* p_last_node = &start_node; + node_t* p_last_node = &start_node; // Add all of the elements. while (first != last) { ETL_ASSERT(!full(), ETL_ERROR(forward_list_iterator)); - Data_Node& data_node = allocate_data_node(*first++); + data_node_t& data_node = allocate_data_node(*first++); join(p_last_node, &data_node); data_node.next = nullptr; p_last_node = &data_node; - ++current_size; } } @@ -385,16 +384,15 @@ namespace etl initialise(); - Node* p_last_node = &start_node; - + node_t* p_last_node = &start_node; + // Add all of the elements. - while (current_size < n) + while (size() < n) { - Data_Node& data_node = allocate_data_node(value); + data_node_t& data_node = allocate_data_node(value); join(p_last_node, &data_node); data_node.next = nullptr; p_last_node = &data_node; - ++current_size; } } @@ -403,11 +401,7 @@ namespace etl //************************************************************************* void push_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif - Data_Node& data_node = allocate_data_node(T()); - insert_node_after(start_node, data_node); + push_front(T()); } //************************************************************************* @@ -418,7 +412,8 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); #endif - Data_Node& data_node = allocate_data_node(value); + + data_node_t& data_node = allocate_data_node(value); insert_node_after(start_node, data_node); } @@ -485,7 +480,7 @@ namespace etl { ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); - Data_Node& data_node = allocate_data_node(value); + data_node_t& data_node = allocate_data_node(value); insert_node_after(*position.p_node, data_node); return iterator(data_node); @@ -501,7 +496,7 @@ namespace etl for (size_t i = 0; !full() && (i < n); ++i) { // Set up the next free node. - Data_Node& data_node = allocate_data_node(value); + data_node_t& data_node = allocate_data_node(value); insert_node_after(*position.p_node, data_node); } } @@ -512,15 +507,15 @@ namespace etl template void insert_after(iterator position, TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); - ETL_ASSERT((count + current_size) <= MAX_SIZE, ETL_ERROR(forward_list_full)); + ETL_ASSERT((count + size()) <= MAX_SIZE, ETL_ERROR(forward_list_full)); #endif while (first != last) { // Set up the next free node. - Data_Node& data_node = allocate_data_node(*first++); + data_node_t& data_node = allocate_data_node(*first++); insert_node_after(*position.p_node, data_node); ++position; } @@ -532,10 +527,15 @@ namespace etl iterator erase_after(iterator position) { iterator next(position); - ++next; - ++next; - - remove_node_after(*position.p_node); + if (next != end()) + { + ++next; + if (next != end()) + { + ++next; + remove_node_after(*position.p_node); + } + } return next; } @@ -545,33 +545,37 @@ namespace etl //************************************************************************* iterator erase_after(iterator first, iterator last) { - Node* p_first = first.p_node; - Node* p_last = last.p_node; - Node* p_next = p_first->next; - - // Join the ends. - join(p_first, p_last); - - p_first = p_next; - - // Erase the ones in between. - while (p_first != p_last) + if (first != end() && (first != last)) { - // One less. - --current_size; + node_t* p_first = first.p_node; + node_t* p_last = last.p_node; + node_t* p_next = p_first->next; - p_next = p_first->next; // Remember the next node. - destroy_data_node(static_cast(*p_first)); // Destroy the pool object. - p_first = p_next; // Move to the next node. - } + // Join the ends. + join(p_first, p_last); - if (p_next == nullptr) - { - return end(); + p_first = p_next; + + // Erase the ones in between. + while (p_first != p_last) + { + p_next = p_first->next; // Remember the next node. + destroy_data_node(static_cast(*p_first)); // Destroy the pool object. + p_first = p_next; // Move to the next node. + } + + if (p_next == nullptr) + { + return end(); + } + else + { + return iterator(*p_last); + } } else { - return iterator(*p_last); + return end(); } } @@ -580,15 +584,15 @@ namespace etl //************************************************************************* void move_after(const_iterator from_before, const_iterator to_before) { - if (from_before == to_before) // Can't more to after yourself! + if (from_before == to_before) // Can't move to after yourself! { return; } - Node* p_from_before = const_cast(from_before.p_node); // We're not changing the value, just it's position. - Node* p_to_before = const_cast(to_before.p_node); // We're not changing the value, just it's position. + node_t* p_from_before = const_cast(from_before.p_node); // We're not changing the value, just it's position. + node_t* p_to_before = const_cast(to_before.p_node); // We're not changing the value, just it's position. - Node* p_from = p_from_before->next; + node_t* p_from = p_from_before->next; // Disconnect from the list. join(p_from_before, p_from->next); @@ -609,7 +613,7 @@ namespace etl return; // Can't more to before yourself! } -#ifdef _DEBUG +#if defined(ETL_DEBUG) // Check that we are not doing an illegal move! for (const_iterator item = first_before; item != last; ++item) { @@ -617,11 +621,11 @@ namespace etl } #endif - Node* p_first_before = const_cast(first_before.p_node); // We're not changing the value, just it's position. - Node* p_last = const_cast(last.p_node); // We're not changing the value, just it's position. - Node* p_to_before = const_cast(to_before.p_node); // We're not changing the value, just it's position. - Node* p_first = p_first_before->next; - Node* p_final = p_first_before; + node_t* p_first_before = const_cast(first_before.p_node); // We're not changing the value, just it's position. + node_t* p_last = const_cast(last.p_node); // We're not changing the value, just it's position. + node_t* p_to_before = const_cast(to_before.p_node); // We're not changing the value, just it's position. + node_t* p_first = p_first_before->next; + node_t* p_final = p_first_before; // Find the last node that will be moved. while (p_final->next != p_last) @@ -658,8 +662,8 @@ namespace etl return; } - Node* last = &get_head(); - Node* current = last->next; + node_t* last = &get_head(); + node_t* current = last->next; while (current != nullptr) { @@ -707,7 +711,7 @@ namespace etl if (is_trivial_list()) { - return; + return; } while (true) @@ -746,32 +750,32 @@ namespace etl // Decide whether the next node of merge comes from left or right. if (left_size == 0) { - // Left is empty. The node must come from right. - p_node = p_right; + // Left is empty. The node must come from right. + p_node = p_right; ++p_right; --right_size; - } + } else if (right_size == 0 || p_right == end()) { - // Right is empty. The node must come from left. - p_node = p_left; + // Right is empty. The node must come from left. + p_node = p_left; ++p_left; --left_size; - } + } else if (compare(*p_left, *p_right)) { - // First node of left is lower or same. The node must come from left. - p_node = p_left; + // First node of left is lower or same. The node must come from left. + p_node = p_left; ++p_left; --left_size; - } + } else { - // First node of right is lower. The node must come from right. - p_node = p_right; + // First node of right is lower. The node must come from right. + p_node = p_right; ++p_right; --right_size; - } + } // Add the next node to the merged head. if (p_head == before_begin()) @@ -867,9 +871,8 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - iforward_list(etl::ipool& node_pool, size_t max_size_) - : forward_list_base(max_size_), - p_node_pool(&node_pool) + iforward_list(etl::ipool& node_pool, size_t max_size_) + : forward_list_base(node_pool, max_size_) { } @@ -880,57 +883,62 @@ namespace etl { if (!empty()) { - p_node_pool->release_all(); + node_t* p_first = start_node.next; + node_t* p_next; + + // Erase the ones in between. + while (p_first != nullptr) + { + p_next = p_first->next; // Remember the next node. + destroy_data_node(static_cast(*p_first)); // Destroy the pool object. + p_first = p_next; // Move to the next node. + } } - current_size = 0; start_node.next = nullptr; } private: - /// The pool of data nodes used in the list. - etl::ipool* p_node_pool; - //************************************************************************* - /// Downcast a Node* to a Data_Node* + /// Downcast a node_t* to a data_node_t* //************************************************************************* - static Data_Node* data_cast(Node* p_node) + static data_node_t* data_cast(node_t* p_node) { - return static_cast(p_node); + return static_cast(p_node); } //************************************************************************* - /// Downcast a Node& to a Data_Node& + /// Downcast a node_t& to a data_node_t& //************************************************************************* - static Data_Node& data_cast(Node& node) + static data_node_t& data_cast(node_t& node) { - return static_cast(node); + return static_cast(node); } //************************************************************************* - /// Downcast a const Node* to a const Data_Node* + /// Downcast a const node_t* to a const data_node_t* //************************************************************************* - static const Data_Node* data_cast(const Node* p_node) + static const data_node_t* data_cast(const node_t* p_node) { - return static_cast(p_node); + return static_cast(p_node); } //************************************************************************* - /// Downcast a const Node& to a const Data_Node& + /// Downcast a const node_t& to a const data_node_t& //************************************************************************* - static const Data_Node& data_cast(const Node& node) + static const data_node_t& data_cast(const node_t& node) { - return static_cast(node); + return static_cast(node); } //************************************************************************* /// Remove a node. //************************************************************************* - void remove_node_after(Node& node) + void remove_node_after(node_t& node) { // The node to erase. - Node* p_node = node.next; + node_t* p_node = node.next; if (p_node != nullptr) { @@ -938,27 +946,30 @@ namespace etl join(&node, p_node->next); // Destroy the pool object. - destroy_data_node(static_cast(*p_node)); - - // One less. - --current_size; + destroy_data_node(static_cast(*p_node)); } } //************************************************************************* - /// Allocate a Data_Node. + /// Allocate a data_node_t. //************************************************************************* - Data_Node& allocate_data_node(parameter_t value) const + data_node_t& allocate_data_node(parameter_t value) { - return *(p_node_pool->allocate(Data_Node(value))); + data_node_t* p_node = p_node_pool->allocate(); + ::new (&(p_node->value)) T(value); + ++construct_count; + + return *p_node; } //************************************************************************* - /// Destroy a Data_Node. + /// Destroy a data_node_t. //************************************************************************* - void destroy_data_node(Data_Node& node) const + void destroy_data_node(data_node_t& node) { - p_node_pool->release(node); + node.value.~T(); + p_node_pool->release(&node); + --construct_count; } // Disable copy construction. diff --git a/src/ilist.h b/src/ilist.h index 50795bf2..9d42904a 100644 --- a/src/ilist.h +++ b/src/ilist.h @@ -37,12 +37,12 @@ SOFTWARE. #include #include +#include "platform.h" #include "nullptr.h" #include "private/list_base.h" #include "type_traits.h" #include "parameter_type.h" -#include "pool.h" -#include "platform.h" +#include "algorithm.h" #ifdef ETL_COMPILER_MICROSOFT #undef min @@ -85,15 +85,12 @@ namespace etl private: - /// The pool of data nodes used in the list. - etl::ipool* p_node_pool; - //************************************************************************* /// Downcast a node_t* to a data_node_t* //************************************************************************* static data_node_t* data_cast(node_t* p_node) { - return static_cast(p_node); + return reinterpret_cast(p_node); } //************************************************************************* @@ -101,7 +98,7 @@ namespace etl //************************************************************************* static data_node_t& data_cast(node_t& node) { - return static_cast(node); + return reinterpret_cast(node); } //************************************************************************* @@ -109,7 +106,7 @@ namespace etl //************************************************************************* static const data_node_t* data_cast(const node_t* p_node) { - return static_cast(p_node); + return reinterpret_cast(p_node); } //************************************************************************* @@ -117,7 +114,7 @@ namespace etl //************************************************************************* static const data_node_t& data_cast(const node_t& node) { - return static_cast(node); + return reinterpret_cast(node); } public: @@ -452,7 +449,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(list_iterator)); ETL_ASSERT(size_t(count) <= MAX_SIZE, ETL_ERROR(list_full)); @@ -462,11 +459,10 @@ namespace etl // Add all of the elements. while (first != last) { - data_node_t& data_node = allocate_data_node(*first); - join(get_tail(), data_node); - join(data_node, terminal_node); + data_node_t& node = allocate_data_node(*first); + join(get_tail(), node); + join(node, terminal_node); ++first; - ++current_size; } } @@ -475,19 +471,18 @@ namespace etl //************************************************************************* void assign(size_t n, parameter_t value) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(list_full)); #endif initialise(); // Add all of the elements. - while (current_size < n) + while (size() < n) { - data_node_t& data_node = allocate_data_node(value); - join(*terminal_node.previous, data_node); - join(data_node, terminal_node); - ++current_size; + data_node_t& node = allocate_data_node(value); + join(*terminal_node.previous, node); + join(node, terminal_node); } } @@ -496,11 +491,7 @@ namespace etl //************************************************************************* void push_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif - data_node_t& data_node = allocate_data_node(T()); - insert_node(get_head(), data_node); + push_front(T()); } //************************************************************************* @@ -511,8 +502,7 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); #endif - node_t& data_node = allocate_data_node(value); - insert_node(get_head(), data_node); + insert_node(get_head(), allocate_data_node(value)); } //************************************************************************* @@ -532,11 +522,7 @@ namespace etl //************************************************************************* void push_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif - data_node_t& data_node = allocate_data_node(T()); - insert_node(terminal_node, data_node); + push_back(T()); } //************************************************************************* @@ -547,8 +533,7 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); #endif - data_node_t& data_node = allocate_data_node(value); - insert_node(terminal_node, data_node); + insert_node(terminal_node, allocate_data_node(value)); } //************************************************************************* @@ -586,8 +571,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(list_full)); // Set up the next free node and insert. - data_node_t& data_node = allocate_data_node(value); - insert_node(*position.p_node, data_node); + insert_node(*position.p_node, allocate_data_node(value)); } } @@ -602,8 +586,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(list_full)); // Set up the next free node and insert. - data_node_t& data_node = allocate_data_node(*first++); - insert_node(*position.p_node, data_node); + insert_node(*position.p_node, allocate_data_node(*first++)); } } @@ -612,12 +595,9 @@ namespace etl //************************************************************************* iterator erase(iterator position) { - iterator next(position); - ++next; - - remove_node(*position.p_node); - - return next; + ++position; + remove_node(*position.p_node->previous); + return position; } //************************************************************************* @@ -635,12 +615,9 @@ namespace etl // Erase the ones in between. while (p_first != p_last) { - // One less. - --current_size; - - p_next = p_first->next; // Remember the next node. + p_next = p_first->next; // Remember the next node. destroy_data_node(static_cast(*p_first)); // Destroy the current node. - p_first = p_next; // Move to the next node. + p_first = p_next; // Move to the next node. } return last; @@ -846,6 +823,9 @@ namespace etl ++this_begin; } + bool t = this_begin != this_end; + bool o = other_begin != other_end; + // Insert. if (this_begin != this_end) { @@ -853,6 +833,8 @@ namespace etl { insert(this_begin, *other_begin); ++other_begin; + + o = other_begin != other_end; } } } @@ -1001,15 +983,14 @@ namespace etl return *this; } - + protected: //************************************************************************* /// Constructor. //************************************************************************* - ilist(etl::ipool& node_pool, size_t max_size_) - : list_base(max_size_), - p_node_pool(&node_pool) + ilist(etl::ipool& node_pool, size_t max_size_) + : list_base(node_pool, max_size_) { } @@ -1020,10 +1001,16 @@ namespace etl { if (!empty()) { - p_node_pool->release_all(); + node_t* p_first = terminal_node.next; + node_t* p_last = &terminal_node; + + while (p_first != p_last) + { + destroy_data_node(static_cast(*p_first)); // Destroy the current node. + p_first = p_first->next; // Move to the next node. + } } - current_size = 0; join(terminal_node, terminal_node); } @@ -1062,7 +1049,7 @@ namespace etl return; // Can't more to before yourself! } -#ifdef _DEBUG +#if defined(ETL_DEBUG) // Check that we are not doing an illegal move! for (const_iterator item = first; item != last; ++item) { @@ -1093,25 +1080,28 @@ namespace etl // Destroy the pool object. destroy_data_node(static_cast(node)); - - // One less. - --current_size; } //************************************************************************* /// Allocate a data_node_t. //************************************************************************* - data_node_t& allocate_data_node(parameter_t value) const + data_node_t& allocate_data_node(parameter_t value) { - return *(p_node_pool->allocate(data_node_t(value))); + data_node_t* p_data_node = p_node_pool->allocate(); + ::new (&(p_data_node->value)) T(value); + ++construct_count; + + return *p_data_node; } //************************************************************************* /// Destroy a data_node_t. //************************************************************************* - void destroy_data_node(data_node_t& node) const + void destroy_data_node(data_node_t& node) { + node.value.~T(); p_node_pool->release(&node); + --construct_count; } // Disable copy construction. diff --git a/src/imap.h b/src/imap.h index ecf4ddbb..1bc48cdd 100644 --- a/src/imap.h +++ b/src/imap.h @@ -103,6 +103,11 @@ namespace etl { } + ~Data_Node() + { + + } + value_type value; }; @@ -128,7 +133,7 @@ namespace etl private: /// The pool of data nodes used in the map. - ipool* p_node_pool; + ipool* p_node_pool; //************************************************************************* /// Downcast a Node* to a Data_Node* @@ -830,7 +835,7 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - imap(ipool& node_pool, size_t max_size_) + imap(ipool& node_pool, size_t max_size_) : map_base(max_size_) , p_node_pool(&node_pool) { @@ -841,13 +846,7 @@ namespace etl //************************************************************************* void initialise() { - if (!empty()) - { - p_node_pool->release_all(); - } - - current_size = 0; - root_node = nullptr; + erase(begin(), end()); } private: @@ -855,17 +854,22 @@ namespace etl //************************************************************************* /// Allocate a Data_Node. //************************************************************************* - Data_Node& allocate_data_node(value_type value) const + Data_Node& allocate_data_node(value_type value) { - return *(p_node_pool->allocate(Data_Node(value))); + Data_Node& node = *p_node_pool->allocate(); + ::new (&node.value) const value_type(value); + ++construct_count; + return node; } //************************************************************************* /// Destroy a Data_Node. //************************************************************************* - void destroy_data_node(Data_Node& node) const + void destroy_data_node(Data_Node& node) { + node.value.~value_type(); p_node_pool->release(&node); + --construct_count; } //************************************************************************* diff --git a/src/imultimap.h b/src/imultimap.h index f88fd25b..d9cc7084 100644 --- a/src/imultimap.h +++ b/src/imultimap.h @@ -130,7 +130,7 @@ namespace etl private: /// The pool of data nodes used in the multimap. - ipool* p_node_pool; + ipool* p_node_pool; //************************************************************************* /// Downcast a Node* to a Data_Node* @@ -675,7 +675,7 @@ namespace etl ///\param position The position that would precede the value to insert. ///\param value The value to insert. //********************************************************************* - iterator insert(iterator position, const value_type& value) + iterator insert(iterator /*position*/, const value_type& value) { // Ignore position provided and just do a normal insert return insert(value); @@ -687,7 +687,7 @@ namespace etl ///\param position The position that would precede the value to insert. ///\param value The value to insert. //********************************************************************* - iterator insert(const_iterator position, const value_type& value) + iterator insert(const_iterator /*position*/, const value_type& value) { // Ignore position provided and just do a normal insert return insert(value); @@ -772,7 +772,7 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - imultimap(ipool& node_pool, size_t max_size_) + imultimap(ipool& node_pool, size_t max_size_) : multimap_base(max_size_) , p_node_pool(&node_pool) { @@ -783,13 +783,7 @@ namespace etl //************************************************************************* void initialise() { - if (!empty()) - { - p_node_pool->release_all(); - } - - current_size = 0; - root_node = nullptr; + erase(begin(), end()); } private: @@ -797,17 +791,22 @@ namespace etl //************************************************************************* /// Allocate a Data_Node. //************************************************************************* - Data_Node& allocate_data_node(value_type value) const + Data_Node& allocate_data_node(value_type value) { - return *(p_node_pool->allocate(Data_Node(value))); + Data_Node& node = *p_node_pool->allocate(); + ::new (&node.value) const value_type(value); + ++construct_count; + return node; } //************************************************************************* /// Destroy a Data_Node. //************************************************************************* - void destroy_data_node(Data_Node& node) const + void destroy_data_node(Data_Node& node) { + node.value.~value_type(); p_node_pool->release(&node); + --construct_count; } //************************************************************************* diff --git a/src/imultiset.h b/src/imultiset.h index 9f36182c..632c7f91 100644 --- a/src/imultiset.h +++ b/src/imultiset.h @@ -126,7 +126,7 @@ namespace etl private: /// The pool of data nodes used in the multiset. - ipool* p_node_pool; + ipool* p_node_pool; //************************************************************************* /// Downcast a Node* to a Data_Node* @@ -656,7 +656,7 @@ namespace etl ///\param position The position that would precede the value to insert. ///\param value The value to insert. //********************************************************************* - iterator insert(iterator position, const value_type& value) + iterator insert(iterator /*position*/, const value_type& value) { // Ignore position provided and just do a normal insert return insert(value); @@ -668,7 +668,7 @@ namespace etl ///\param position The position that would precede the value to insert. ///\param value The value to insert. //********************************************************************* - iterator insert(const_iterator position, const value_type& value) + iterator insert(const_iterator /*position*/, const value_type& value) { // Ignore position provided and just do a normal insert return insert(value); @@ -753,7 +753,7 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - imultiset(ipool& node_pool, size_t max_size_) + imultiset(ipool& node_pool, size_t max_size_) : multiset_base(max_size_) , p_node_pool(&node_pool) { @@ -764,13 +764,7 @@ namespace etl //************************************************************************* void initialise() { - if (!empty()) - { - p_node_pool->release_all(); - } - - current_size = 0; - root_node = nullptr; + erase(begin(), end()); } private: @@ -778,17 +772,22 @@ namespace etl //************************************************************************* /// Allocate a Data_Node. //************************************************************************* - Data_Node& allocate_data_node(value_type value) const + Data_Node& allocate_data_node(value_type value) { - return *(p_node_pool->allocate(Data_Node(value))); + Data_Node& node = *p_node_pool->allocate(); + ::new ((void*)&node.value) value_type(value); + ++construct_count; + return node; } //************************************************************************* /// Destroy a Data_Node. //************************************************************************* - void destroy_data_node(Data_Node& node) const + void destroy_data_node(Data_Node& node) { + node.value.~value_type(); p_node_pool->release(&node); + --construct_count; } //************************************************************************* diff --git a/src/intrusive_forward_list.h b/src/intrusive_forward_list.h index 21ea1ed2..00019df8 100644 --- a/src/intrusive_forward_list.h +++ b/src/intrusive_forward_list.h @@ -42,6 +42,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "nullptr.h" #include "type_traits.h" #include "exception.h" @@ -145,13 +146,6 @@ namespace etl typedef const value_type& const_reference; typedef size_t size_type; - enum - { - // The count option is based on the type of link. - COUNT_OPTION = ((TLink::OPTION == etl::link_option::AUTO) || - (TLink::OPTION == etl::link_option::CHECKED)) ? etl::count_option::SLOW_COUNT : etl::count_option::FAST_COUNT - }; - typedef intrusive_forward_list list_type; //************************************************************************* @@ -324,7 +318,7 @@ namespace etl const value_type* p_value; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Constructor. @@ -334,6 +328,14 @@ namespace etl initialise(); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~intrusive_forward_list() + { + clear(); + } + //************************************************************************* /// Constructor from range //************************************************************************* @@ -438,7 +440,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(intrusive_forward_list_iterator_exception)); #endif @@ -503,33 +505,21 @@ namespace etl //************************************************************************* /// Inserts a value to the intrusive_forward_list after the specified position. - /// Checks that the value is unlinked if CHECKED. //************************************************************************* iterator insert_after(iterator position, value_type& value) { - if (TLink::OPTION == etl::link_option::CHECKED) - { - ETL_ASSERT(!value.TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception)); - } - insert_link_after(*position.p_value, value); return iterator(value); } //************************************************************************* /// Inserts a range of values to the intrusive_forward_list after the specified position. - /// Checks that the values are unlinked if CHECKED. //************************************************************************* template void insert_after(iterator position, TIterator first, TIterator last) { while (first != last) { - if (TLink::OPTION == etl::link_option::CHECKED) - { - ETL_ASSERT(!position.p_value->TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception)); - } - // Set up the next free link. insert_link_after(*position.p_value, *first++); ++position; @@ -538,19 +528,18 @@ namespace etl //************************************************************************* /// Erases the value at the specified position. - /// Clears the link after erasing if CHECKED. //************************************************************************* iterator erase_after(iterator position) { iterator next(position); - ++next; - ++next; - - remove_link_after(*position.p_value); - - if (TLink::OPTION == etl::link_option::CHECKED) + if (next != end()) { - position.p_value->TLink::clear(); + ++next; + if (next != end()) + { + ++next; + remove_link_after(*position.p_value); + } } return next; @@ -558,42 +547,32 @@ namespace etl //************************************************************************* /// Erases a range of elements. - /// Clears the links after erasing if CHECKED. //************************************************************************* iterator erase_after(iterator first, iterator last) { - link_type* p_first = first.p_value; - link_type* p_last = last.p_value; - link_type* p_next = p_first->etl_next; - - // Join the ends. - etl::link(p_first, p_last); - - p_first = p_next; - - // Erase the ones in between. - while (p_first != p_last) + if (first != end() && (first != last)) { - // One less. - --current_size; + current_size -= std::distance(first, last) - 1; - p_next = p_first->etl_next; // Remember the next link. + link_type* p_first = first.p_value; + link_type* p_last = last.p_value; + link_type* p_next = p_first->etl_next; - if (TLink::OPTION == etl::link_option::CHECKED) + // Join the ends. + etl::link(p_first, p_last); + + if (p_next == nullptr) { - p_first->TLink::clear(); // Clear the link. + return end(); + } + else + { + return last; } - - p_first = p_next; // Move to the next link. - } - - if (p_next == nullptr) - { - return end(); } else { - return iterator(*static_cast(p_last)); + return last; } } @@ -657,7 +636,7 @@ namespace etl if (is_trivial_list()) { - return; + return; } while (true) @@ -696,32 +675,32 @@ namespace etl // Decide whether the next link of merge comes from left or right. if (left_size == 0) { - // Left is empty. The link must come from right. - i_link = i_right; + // Left is empty. The link must come from right. + i_link = i_right; ++i_right; --right_size; - } + } else if (right_size == 0 || i_right == end()) { - // Right is empty. The link must come from left. - i_link = i_left; + // Right is empty. The link must come from left. + i_link = i_left; ++i_left; --left_size; - } + } else if (compare(*i_left, *i_right)) { - // First link of left is lower or same. The link must come from left. - i_link = i_left; + // First link of left is lower or same. The link must come from left. + i_link = i_left; ++i_left; --left_size; - } + } else { - // First link of right is lower. The link must come from right. - i_link = i_right; + // First link of right is lower. The link must come from right. + i_link = i_right; ++i_right; --right_size; - } + } // Add the next link to the merged head. if (i_head == before_begin()) @@ -812,34 +791,24 @@ namespace etl //************************************************************************* size_t size() const { - if (COUNT_OPTION == etl::count_option::SLOW_COUNT) - { - return std::distance(cbegin(), cend()); - } - else - { - return current_size.get_count(); - } + return current_size; } //************************************************************************* /// Splice another list into this one. //************************************************************************* - void splice_after(iterator position, etl::intrusive_forward_list& list) + void splice_after(iterator position, etl::intrusive_forward_list& other) { // No point splicing to ourself! - if (&list != this) + if (&other != this) { - if (!list.empty()) + if (!other.empty()) { - link_type& first = list.get_head(); + link_type& first = other.get_head(); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - current_size += list.size(); - } + current_size += other.size(); } link_type& before = *position.p_value; @@ -855,7 +824,7 @@ namespace etl etl::link(last, after); - list.clear(); + other.initialise(); } } } @@ -863,38 +832,32 @@ namespace etl //************************************************************************* /// Splice an element from another list into this one. //************************************************************************* - void splice(iterator position, etl::intrusive_forward_list& list, iterator isource) + void splice(iterator position, etl::intrusive_forward_list& other, iterator isource) { link_type& before = *position.p_value; etl::unlink(*isource.p_value); etl::link_splice(before, *isource.p_value); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - ++current_size; - --list.current_size; - } + ++current_size; + --other.current_size; } } //************************************************************************* /// Splice a range of elements from another list into this one. //************************************************************************* - void splice_after(iterator position, etl::intrusive_forward_list& list, iterator begin_, iterator end_) + void splice_after(iterator position, etl::intrusive_forward_list& other, iterator begin_, iterator end_) { - if (!list.empty()) + if (!other.empty()) { - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - size_t n = std::distance(begin_, end_) - 1; - current_size += n; - list.current_size -= n; - } + size_t n = std::distance(begin_, end_) - 1; + current_size += n; + other.current_size -= n; } link_type* first = begin_.p_value; @@ -919,25 +882,25 @@ namespace etl //************************************************************************* /// Merge another list into this one. Both lists should be sorted. //************************************************************************* - void merge(list_type& list) + void merge(list_type& other) { - merge(list, std::less()); + merge(other, std::less()); } //************************************************************************* /// Merge another list into this one. Both lists should be sorted. //************************************************************************* template - void merge(list_type& list, TCompare compare) + void merge(list_type& other, TCompare compare) { - if (!list.empty()) + if (!other.empty()) { #if _DEBUG - ETL_ASSERT(etl::is_sorted(list.begin(), list.end(), compare), ETL_ERROR(intrusive_forward_list_unsorted)); + ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(intrusive_forward_list_unsorted)); ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(intrusive_forward_list_unsorted)); #endif - value_type* other_begin = static_cast(&list.get_head()); + value_type* other_begin = static_cast(&other.get_head()); value_type* other_terminal = nullptr; value_type* before = static_cast(&start_link); @@ -978,12 +941,9 @@ namespace etl } } - if (COUNT_OPTION == etl::count_option::FAST_COUNT) - { - current_size += list.size(); - } + current_size += other.size(); - list.clear(); + other.initialise(); } } @@ -991,105 +951,7 @@ namespace etl link_type start_link; ///< The link that acts as the intrusive_forward_list start. - //************************************************************************* - /// Counter type based on count option. - //************************************************************************* - template - class counter_type - { - }; - - //************************************************************************* - /// Slow type. - //************************************************************************* - template - class counter_type - { - public: - - counter_type& operator ++() - { - return *this; - } - - counter_type& operator --() - { - return *this; - } - - counter_type& operator =(size_t new_count) - { - return *this; - } - - counter_type& operator +=(size_t diff) - { - return *this; - } - - counter_type& operator -=(size_t diff) - { - return *this; - } - - size_t get_count() const - { - return 0; - } - }; - - //************************************************************************* - /// Fast type. - //************************************************************************* - template - class counter_type - { - public: - - counter_type() - : count(0) - { - } - - counter_type& operator ++() - { - ++count; - return *this; - } - - counter_type& operator --() - { - --count; - return *this; - } - - counter_type& operator =(size_t new_count) - { - count = new_count; - return *this; - } - - counter_type& operator +=(size_t diff) - { - count += diff; - return *this; - } - - counter_type& operator -=(size_t diff) - { - count -= diff; - return *this; - } - - size_t get_count() const - { - return count; - } - - size_t count; - }; - - counter_type current_size; ///< Counts the number of elements in the list. + size_t current_size; ///< Counts the number of elements in the list. //************************************************************************* /// Is the intrusive_forward_list a trivial length? @@ -1114,7 +976,9 @@ namespace etl //************************************************************************* void remove_link_after(link_type& link) { - if (link.etl_next != nullptr) + link_type* p_next = link.etl_next; + + if (p_next != nullptr) { etl::unlink_after(link); --current_size; diff --git a/src/intrusive_links.h b/src/intrusive_links.h index 00ebb14f..35a8e345 100644 --- a/src/intrusive_links.h +++ b/src/intrusive_links.h @@ -55,25 +55,6 @@ SOFTWARE. namespace etl { - namespace link_option - { - enum - { - DEFAULT, - AUTO, - CHECKED - }; - } - - namespace count_option - { - enum - { - SLOW_COUNT, - FAST_COUNT - }; - } - //*************************************************************************** /// Link exception. //*************************************************************************** @@ -100,18 +81,15 @@ namespace etl } }; - namespace __private_intrusive_links__ + //*************************************************************************** + /// A forward link. + //*************************************************************************** + template + struct forward_link { - //*************************************************************************** - /// A forward link base. - //*************************************************************************** - template - struct forward_link_base - { enum { ID = ID_, - OPTION = OPTION_ }; void clear() @@ -124,55 +102,12 @@ namespace etl return etl_next != nullptr; } - TLink* etl_next; - }; - } - - //*************************************************************************** - /// A forward link. - //*************************************************************************** - template - struct forward_link - : public __private_intrusive_links__::forward_link_base, ID_, OPTION_> - { - }; - - //****************************************************************** - // There is no valid specialisation for auto link - //****************************************************************** - template - struct forward_link - : public __private_intrusive_links__::forward_link_base, ID_, etl::link_option::AUTO> - { - forward_link() - { - this->clear(); - } - }; - - //****************************************************************** - // Specialisation for checked unlink option. - // An error will be generated if the links are valid when the object - // is destroyed. - //****************************************************************** - template - struct forward_link - : public __private_intrusive_links__::forward_link_base, ID_, etl::link_option::CHECKED> - { - forward_link() - { - this->clear(); - } - - ~forward_link() - { - assert(this->etl_next != nullptr); - } + forward_link* etl_next; }; // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink& lhs, TLink& rhs) { lhs.etl_next = &rhs; @@ -180,7 +115,7 @@ namespace etl // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink& rhs) { rhs.etl_next = lhs.etl_next; @@ -189,7 +124,7 @@ namespace etl // Pointer, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink* lhs, TLink* rhs) { if (lhs != nullptr) @@ -200,7 +135,7 @@ namespace etl // Pointer, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink* rhs) { if (lhs != nullptr) @@ -216,7 +151,7 @@ namespace etl // Reference, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink& lhs, TLink* rhs) { lhs.etl_next = rhs; @@ -224,7 +159,7 @@ namespace etl // Reference, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink* rhs) { if (rhs != nullptr) @@ -237,7 +172,7 @@ namespace etl // Pointer, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink* lhs, TLink& rhs) { if (lhs != nullptr) @@ -248,7 +183,7 @@ namespace etl // Pointer, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink& rhs) { if (lhs != nullptr) @@ -260,7 +195,7 @@ namespace etl // Reference, Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink& first, TLink& last) { last.etl_next = lhs.etl_next; @@ -269,7 +204,7 @@ namespace etl // Pointer, Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink& first, TLink& last) { if (lhs != nullptr) @@ -285,48 +220,33 @@ namespace etl // Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type unlink_after(TLink& node) { if (node.etl_next != nullptr) { TLink* unlinked_node = node.etl_next; node.etl_next = unlinked_node->etl_next; - - if ((int(TLink::OPTION) == etl::link_option::AUTO) || - (int(TLink::OPTION) == etl::link_option::CHECKED)) - { - unlinked_node->clear(); - } } } // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type unlink_after(TLink& before, TLink& last) { before.etl_next = last.etl_next; - - if ((int(TLink::OPTION) == etl::link_option::AUTO) || - (int(TLink::OPTION) == etl::link_option::CHECKED)) - { - last.clear(); - } } - namespace __private_intrusive_links__ + //*************************************************************************** + /// A bidirectional link. + //*************************************************************************** + template + struct bidirectional_link { - //*************************************************************************** - /// A bidirectional link base. - //*************************************************************************** - template - struct bidirectional_link_base - { enum { - ID = ID_, - OPTION = OPTION_ + ID = ID_, }; void clear() @@ -345,13 +265,11 @@ namespace etl std::swap(etl_previous, etl_next); } - TLink* etl_previous; - TLink* etl_next; + bidirectional_link* etl_previous; + bidirectional_link* etl_next; - protected: - - void base_unlink() - { + void unlink() + { // Connect the previous link with the next. if (etl_previous != nullptr) { @@ -363,78 +281,12 @@ namespace etl { etl_next->etl_previous = etl_previous; } - } - }; - } - - //*************************************************************************** - /// A bidirectional link. - //*************************************************************************** - template - struct bidirectional_link - : public __private_intrusive_links__::bidirectional_link_base, ID_, OPTION_> - { - void unlink() - { - this->base_unlink(); - } - }; - - //****************************************************************** - // Specialisation for auto unlinked option. - // When this link is destroyed it will automatically unlink itself. - //****************************************************************** - template - struct bidirectional_link - : public __private_intrusive_links__::bidirectional_link_base, ID_, etl::link_option::AUTO> - { - bidirectional_link() - { - this->clear(); - } - - ~bidirectional_link() - { - this->base_unlink(); - } - - void unlink() - { - this->base_unlink(); - this->clear(); - } - }; - - //****************************************************************** - // Specialisation for checked unlink option. - // An error will be generated if the links are valid when the object - // is destroyed. - //****************************************************************** - template - struct bidirectional_link - : public __private_intrusive_links__::bidirectional_link_base, ID_, etl::link_option::CHECKED> - { - bidirectional_link() - { - this->clear(); - } - - ~bidirectional_link() - { - assert(this->etl_previous == nullptr); - assert(this->etl_next == nullptr); - } - - void unlink() - { - this->base_unlink(); - this->clear(); } }; // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink& lhs, TLink& rhs) { lhs.etl_next = &rhs; @@ -443,7 +295,7 @@ namespace etl // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink& rhs) { rhs.etl_next = lhs.etl_next; @@ -459,7 +311,7 @@ namespace etl // Pointer, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink* lhs, TLink* rhs) { if (lhs != nullptr) @@ -475,7 +327,7 @@ namespace etl // Pointer, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink* rhs) { if (rhs != nullptr) @@ -501,7 +353,7 @@ namespace etl // Reference, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink& lhs, TLink* rhs) { lhs.etl_next = rhs; @@ -514,7 +366,7 @@ namespace etl // Reference, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink* rhs) { if (rhs != nullptr) @@ -533,7 +385,7 @@ namespace etl // Pointer, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link(TLink* lhs, TLink& rhs) { if (lhs != nullptr) @@ -546,7 +398,7 @@ namespace etl // Pointer, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink& rhs) { if (lhs != nullptr) @@ -569,7 +421,7 @@ namespace etl // Reference, Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink& lhs, TLink& first, TLink& last) { last.etl_next = lhs.etl_next; @@ -585,7 +437,7 @@ namespace etl // Pointer, Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_splice(TLink* lhs, TLink& first, TLink& last) { if (lhs != nullptr) @@ -612,7 +464,7 @@ namespace etl // Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type unlink(TLink& node) { node.unlink(); @@ -620,7 +472,7 @@ namespace etl // Reference Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type unlink(TLink& first, TLink& last) { if (&first == &last) @@ -638,28 +490,18 @@ namespace etl { first.etl_previous->etl_next = last.etl_next; } - - if ((TLink::OPTION == etl::link_option::AUTO) || - (int(TLink::OPTION) == etl::link_option::CHECKED)) - { - first.etl_previous = nullptr; - last.etl_next = nullptr; - } } } - namespace __private_intrusive_links__ + //*************************************************************************** + /// A binary tree link. + //*************************************************************************** + template + struct tree_link { - //*************************************************************************** - /// A tree link base. - //*************************************************************************** - template - struct tree_link_base - { enum { - ID = ID_, - OPTION = OPTION_ + ID = ID_, }; void clear() @@ -674,59 +516,14 @@ namespace etl return (etl_parent != nullptr) || (etl_left != nullptr) || (etl_right != nullptr); } - TLink* etl_parent; - TLink* etl_left; - TLink* etl_right; - }; - } - - //*************************************************************************** - /// A tree link. - //*************************************************************************** - template - struct tree_link - : public __private_intrusive_links__::tree_link_base, ID_, OPTION_> - { - }; - - //****************************************************************** - // There is no valid specialisation for auto link - //****************************************************************** - template - struct tree_link - : public __private_intrusive_links__::tree_link_base, ID_, etl::link_option::AUTO> - { - tree_link() - { - this->clear(); - } - }; - - //****************************************************************** - // Specialisation for checked unlink option. - // An error will be generated if the links are valid when the object - // is destroyed. - //****************************************************************** - template - struct tree_link - : public __private_intrusive_links__::tree_link_base, ID_, etl::link_option::CHECKED> - { - tree_link() - { - this->clear(); - } - - ~tree_link() - { - assert(this->etl_parent != nullptr); - assert(this->etl_left != nullptr); - assert(this->etl_right != nullptr); - } + tree_link* etl_parent; + tree_link* etl_left; + tree_link* etl_right; }; // Reference, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_left(TLink& parent, TLink& leaf) { parent.etl_left = &leaf; @@ -734,7 +531,7 @@ namespace etl } template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_right(TLink& parent, TLink& leaf) { parent.etl_right = &leaf; @@ -743,7 +540,7 @@ namespace etl // Pointer, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_left(TLink* parent, TLink* leaf) { if (parent != nullptr) @@ -758,7 +555,7 @@ namespace etl } template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_right(TLink* parent, TLink* leaf) { if (parent != nullptr) @@ -774,7 +571,7 @@ namespace etl // Reference, Pointer template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_left(TLink& parent, TLink* leaf) { parent.etl_left = leaf; @@ -786,7 +583,7 @@ namespace etl } template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_right(TLink& parent, TLink* leaf) { parent.etl_right = leaf; @@ -799,7 +596,7 @@ namespace etl // Pointer, Reference template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_left(TLink* parent, TLink& leaf) { if (parent != nullptr) @@ -811,7 +608,7 @@ namespace etl } template - typename etl::enable_if >::value, void>::type + typename etl::enable_if >::value, void>::type link_right(TLink* parent, TLink& leaf) { if (parent != nullptr) @@ -821,6 +618,175 @@ namespace etl leaf.etl_parent = parent; } + + // Reference, Reference + template + typename etl::enable_if >::value, void>::type + link_rotate_left(TLink& parent, TLink& leaf) + { + parent.etl_right = leaf.etl_left; + + if (parent.etl_right != nullptr) + { + parent.etl_right->etl_parent = &parent; + } + + leaf.etl_parent = parent.etl_parent; + parent.etl_parent = &leaf; + leaf.etl_left = &parent; + } + + template + typename etl::enable_if >::value, void>::type + link_rotate_right(TLink& parent, TLink& leaf) + { + parent.etl_left = leaf.etl_right; + + if (parent.etl_left != nullptr) + { + parent.etl_left->etl_parent = &parent; + } + + leaf.etl_parent = parent.etl_parent; + parent.etl_parent = &leaf; + leaf.etl_right = &parent; + } + + // Pointer, Pointer + template + typename etl::enable_if >::value, void>::type + link_rotate_left(TLink* parent, TLink* leaf) + { + if ((parent != nullptr) && (leaf != nullptr)) + { + link_rotate_left(*parent, *leaf); + } + } + + template + typename etl::enable_if >::value, void>::type + link_rotate_right(TLink* parent, TLink* leaf) + { + if ((parent != nullptr) && (leaf != nullptr)) + { + link_rotate_right(*parent, *leaf); + } + } + + // Reference, Pointer + template + typename etl::enable_if >::value, void>::type + link_rotate_left(TLink& parent, TLink* leaf) + { + if (leaf != nullptr) + { + link_rotate_left(parent, *leaf); + } + } + + template + typename etl::enable_if >::value, void>::type + link_rotate_right(TLink& parent, TLink* leaf) + { + if (leaf != nullptr) + { + link_rotate_right(parent, *leaf); + } + } + + // Pointer, Reference + template + typename etl::enable_if >::value, void>::type + link_rotate_left(TLink* parent, TLink& leaf) + { + if (parent != nullptr) + { + link_rotate_left(*parent, leaf); + } + } + + template + typename etl::enable_if >::value, void>::type + link_rotate_right(TLink* parent, TLink& leaf) + { + if (parent != nullptr) + { + link_rotate_right(*parent, leaf); + } + } + + // Reference, Reference + /// Automatically detects whether a left or right rotate is expected. + template + typename etl::enable_if >::value, void>::type + link_rotate(TLink& parent, TLink& leaf) + { + if (parent.etl_left == &leaf) + { + etl::link_rotate_right(parent, leaf); + } + else + { + etl::link_rotate_left(parent, leaf); + } + } + + // Pointer, Pointer + /// Automatically detects whether a left or right rotate is expected. + template + typename etl::enable_if >::value, void>::type + link_rotate(TLink* parent, TLink* leaf) + { + if ((parent != nullptr) && (leaf != nullptr)) + { + if (parent->etl_left == leaf) + { + etl::link_rotate_right(*parent, *leaf); + } + else + { + etl::link_rotate_left(*parent, *leaf); + } + } + } + + // Reference, Pointer + /// Automatically detects whether a left or right rotate is expected. + template + typename etl::enable_if >::value, void>::type + link_rotate(TLink& parent, TLink* leaf) + { + if (leaf != nullptr) + { + if (parent.etl_left == leaf) + { + etl::link_rotate_right(parent, *leaf); + } + else + { + etl::link_rotate_left(parent, *leaf); + } + } + } + + // Pointer, Reference + /// Automatically detects whether a left or right rotate is expected. + template + typename etl::enable_if >::value, void>::type + link_rotate(TLink* parent, TLink& leaf) + { + if (parent != nullptr) + { + if (parent->etl_left == &leaf) + { + etl::link_rotate_right(*parent, leaf); + } + else + { + etl::link_rotate_left(*parent, leaf); + } + } + } } #undef ETL_FILE diff --git a/src/intrusive_list.h b/src/intrusive_list.h index c4050db9..4d72abe2 100644 --- a/src/intrusive_list.h +++ b/src/intrusive_list.h @@ -42,6 +42,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "nullptr.h" #include "type_traits.h" #include "exception.h" @@ -121,13 +122,6 @@ namespace etl { public: - enum - { - // The count option is based on the type of link. - COUNT_OPTION = ((TLink::OPTION == etl::link_option::AUTO) || - (TLink::OPTION == etl::link_option::CHECKED)) ? etl::count_option::SLOW_COUNT : etl::count_option::FAST_COUNT - }; - typedef intrusive_list list_type; // Node typedef. @@ -341,7 +335,7 @@ namespace etl const value_type* p_value; }; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::difference_type difference_type; //************************************************************************* /// Constructor. @@ -351,6 +345,14 @@ namespace etl initialise(); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~intrusive_list() + { + clear(); + } + //************************************************************************* /// Constructor from range //************************************************************************* @@ -456,7 +458,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(intrusive_list_iterator_exception)); #endif @@ -478,7 +480,7 @@ namespace etl //************************************************************************* /// Pushes a value to the front of the intrusive_list. //************************************************************************* - void push_front(value_type& value) + void push_front(link_type& value) { insert_link(terminal_link, value); } @@ -537,33 +539,21 @@ namespace etl //************************************************************************* /// Inserts a value to the intrusive_list before the specified position. - /// Checks that the value is unlinked if CHECKED //************************************************************************* iterator insert(iterator position, value_type& value) { - if (TLink::OPTION == etl::link_option::CHECKED) - { - ETL_ASSERT(!value.TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception)); - } - insert_link(position.p_value->link_type::etl_previous, value); return iterator(value); } //************************************************************************* /// Inserts a range of values to the intrusive_list after the specified position. - /// Checks that the values are unlinked if CHECKED. //************************************************************************* template void insert(iterator position, TIterator first, TIterator last) { while (first != last) { - if (TLink::OPTION == etl::link_option::CHECKED) - { - ETL_ASSERT(!position.p_value->TLink::is_linked(), ETL_ERROR(etl::not_unlinked_exception)); - } - // Set up the next free link. insert_link(*position.p_value->link_type::etl_previous, *first++); } @@ -594,27 +584,7 @@ namespace etl // Join the ends. etl::link(p_first->etl_previous, p_last); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) - { - current_size -= std::distance(first, last); - } - - if ((TLink::OPTION == etl::link_option::AUTO) || - (TLink::OPTION == etl::link_option::CHECKED)) - { - // Clear the ones in between. - link_type* p_next; - - while (p_first != p_last) - { - // One less. - --current_size; - - p_next = p_first->etl_next; // Remember the next link. - p_first->TLink::clear(); // Clear the link. - p_first = p_next; // Move to the next link. - } - } + current_size -= std::distance(first, last); if (p_last == &terminal_link) { @@ -831,35 +801,25 @@ namespace etl //************************************************************************* size_t size() const { - if (COUNT_OPTION == etl::count_option::SLOW_COUNT) - { - return std::distance(cbegin(), cend()); - } - else - { - return current_size.get_count(); - } + return current_size; } //************************************************************************* /// Splice another list into this one. //************************************************************************* - void splice(iterator position, list_type& list) + void splice(iterator position, list_type& other) { // No point splicing to ourself! - if (&list != this) + if (&other != this) { - if (!list.empty()) + if (!other.empty()) { - link_type& first = *list.get_head(); - link_type& last = *list.get_tail(); + link_type& first = *other.get_head(); + link_type& last = *other.get_tail(); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - current_size += list.size(); - } + current_size += other.size(); } link_type& after = *position.p_value; @@ -868,7 +828,7 @@ namespace etl etl::link(before, first); etl::link(last, after); - list.clear(); + other.initialise(); } } } @@ -876,38 +836,32 @@ namespace etl //************************************************************************* /// Splice an element from another list into this one. //************************************************************************* - void splice(iterator position, list_type& list, iterator isource) + void splice(iterator position, list_type& other, iterator isource) { link_type& before = *position.p_value->link_type::etl_previous; etl::unlink(*isource.p_value); etl::link_splice(before, *isource.p_value); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - ++current_size; - --list.current_size; - } + ++current_size; + --other.current_size; } } //************************************************************************* /// Splice a range of elements from another list into this one. //************************************************************************* - void splice(iterator position, list_type& list, iterator begin_, iterator end_) + void splice(iterator position, list_type& other, iterator begin_, iterator end_) { - if (!list.empty()) + if (!other.empty()) { - if (COUNT_OPTION == etl::count_option::FAST_COUNT) + if (&other != this) { - if (&list != this) - { - size_t n = std::distance(begin_, end_); - current_size += n; - list.current_size -= n; - } + size_t n = std::distance(begin_, end_); + current_size += n; + other.current_size -= n; } link_type& first = *begin_.p_value; @@ -926,26 +880,26 @@ namespace etl //************************************************************************* /// Merge another list into this one. Both lists should be sorted. //************************************************************************* - void merge(list_type& list) + void merge(list_type& other) { - merge(list, std::less()); + merge(other, std::less()); } //************************************************************************* /// Merge another list into this one. Both lists should be sorted. //************************************************************************* template - void merge(list_type& list, TCompare compare) + void merge(list_type& other, TCompare compare) { - if (!list.empty()) + if (!other.empty()) { #if _DEBUG - ETL_ASSERT(etl::is_sorted(list.begin(), list.end(), compare), ETL_ERROR(intrusive_list_unsorted)); + ETL_ASSERT(etl::is_sorted(other.begin(), other.end(), compare), ETL_ERROR(intrusive_list_unsorted)); ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(intrusive_list_unsorted)); #endif - value_type* other_begin = static_cast(list.get_head()); - value_type* other_end = static_cast(&list.terminal_link); + value_type* other_begin = static_cast(other.get_head()); + value_type* other_end = static_cast(&other.terminal_link); value_type* begin = static_cast(get_head()); value_type* end = static_cast(&terminal_link); @@ -976,13 +930,9 @@ namespace etl etl::link_splice(*get_tail(), *other_begin, *other_end->link_type::etl_previous); } + current_size += other.size(); - if (COUNT_OPTION == etl::count_option::FAST_COUNT) - { - current_size += list.size(); - } - - list.clear(); + other.initialise(); } } @@ -991,105 +941,7 @@ namespace etl /// The link that acts as the intrusive_list start & end. link_type terminal_link; - //************************************************************************* - /// Counter type based on count option. - //************************************************************************* - template - class counter_type - { - }; - - //************************************************************************* - /// Slow type. - //************************************************************************* - template - class counter_type - { - public: - - counter_type& operator ++() - { - return *this; - } - - counter_type& operator --() - { - return *this; - } - - counter_type& operator =(size_t new_count) - { - return *this; - } - - counter_type& operator +=(size_t diff) - { - return *this; - } - - counter_type& operator -=(size_t diff) - { - return *this; - } - - size_t get_count() const - { - return 0; - } - }; - - //************************************************************************* - /// Fast type. - //************************************************************************* - template - class counter_type - { - public: - - counter_type() - : count(0) - { - } - - counter_type& operator ++() - { - ++count; - return *this; - } - - counter_type& operator --() - { - --count; - return *this; - } - - counter_type& operator =(size_t new_count) - { - count = new_count; - return *this; - } - - counter_type& operator +=(size_t diff) - { - count += diff; - return *this; - } - - counter_type& operator -=(size_t diff) - { - count -= diff; - return *this; - } - - size_t get_count() const - { - return count; - } - - size_t count; - }; - - counter_type current_size; ///< Counts the number of elements in the list. + size_t current_size; ///< Counts the number of elements in the list. //************************************************************************* /// Is the intrusive_list a trivial length? diff --git a/src/intrusive_queue.h b/src/intrusive_queue.h new file mode 100644 index 00000000..e48111b9 --- /dev/null +++ b/src/intrusive_queue.h @@ -0,0 +1,233 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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_INTRUSIVE_QUEUE__ +#define __ETL_INTRUSIVE_QUEUE__ + +#include + +#include "type_traits.h" +#include "error_handler.h" +#include "intrusive_links.h" + +#define ETL_FILE "29" + +namespace etl +{ + //*************************************************************************** + /// Exception base for intrusive queue + ///\ingroup intrusive_queue + //*************************************************************************** + class intrusive_queue_exception : public etl::exception + { + public: + + intrusive_queue_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + /// intrusive_queue empty exception. + ///\ingroup intrusive_queue + //*************************************************************************** + class intrusive_queue_empty : public intrusive_queue_exception + { + public: + + intrusive_queue_empty(string_type file_name, numeric_type line_number) + : intrusive_queue_exception(ETL_ERROR_TEXT("intrusive_queue:empty", ETL_FILE"A"), file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup queue + /// An intrusive queue. Stores elements derived from etl::forward_link + /// \warning This queue cannot be used for concurrent access from multiple threads. + /// \tparam TValue The type of value that the queue holds. + /// \tparam TLink The link type that the value is derived from. + //*************************************************************************** + template + class intrusive_queue + { + public: + + // Node typedef. + typedef TLink link_type; + + // STL style typedefs. + typedef TValue value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + + //************************************************************************* + /// Constructor + //************************************************************************* + intrusive_queue() + : p_front(nullptr), + p_back(nullptr), + current_size(0) + { + } + + //************************************************************************* + /// Gets a reference to the value at the front of the queue. + /// Undefined behaviour if the queue is empty. + /// \return A reference to the value at the front of the queue. + //************************************************************************* + reference front() + { + return *static_cast(p_front); + } + + //************************************************************************* + /// Gets a reference to the value at the back of the queue. + /// Undefined behaviour if the queue is empty. + /// \return A reference to the value at the back of the queue. + //************************************************************************* + reference back() + { + return *static_cast(p_back); + } + + //************************************************************************* + /// Gets a const reference to the value at the front of the queue. + /// Undefined behaviour if the queue is empty. + /// \return A const reference to the value at the front of the queue. + //************************************************************************* + const_reference front() const + { + return *static_cast(p_front); + } + + //************************************************************************* + /// Gets a reference to the value at the back of the queue. + /// Undefined behaviour if the queue is empty. + /// \return A reference to the value at the back of the queue. + //************************************************************************* + const_reference back() const + { + return *static_cast(p_back); + } + + //************************************************************************* + /// Adds a value to the queue. + ///\param value The value to push to the queue. + //************************************************************************* + void push(link_type& value) + { + value.clear(); + + if (p_back != nullptr) + { + etl::link(p_back, value); + } + else + { + p_front = &value; + } + + p_back = &value; + + ++current_size; + } + + //************************************************************************* + /// Removes the oldest item from the queue. + /// Undefined behaviour if the queue is already empty. + //************************************************************************* + void pop() + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!empty(), ETL_ERROR(intrusive_queue_empty)); +#endif + link_type* p_next = p_front->etl_next; + + p_front = p_next; + + // Now empty? + if (p_front == nullptr) + { + p_back = nullptr; + } + + --current_size; + } + + //************************************************************************* + /// Clears the queue to the empty state. + //************************************************************************* + void clear() + { + while (!empty()) + { + pop(); + } + + current_size = 0; + } + + //************************************************************************* + /// Checks if the queue is in the empty state. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Returns the number of elements. + //************************************************************************* + size_t size() const + { + return current_size; + } + + private: + + // Disable copy construction and assignment. + intrusive_queue(const intrusive_queue&); + intrusive_queue& operator = (const intrusive_queue& rhs); + + link_type* p_front; // The current front of the queue. + link_type* p_back; // The current back of the queue. + + size_t current_size; ///< Counts the number of elements in the list. + }; +} + +#undef ETL_FILE + +#endif diff --git a/src/intrusive_stack.h b/src/intrusive_stack.h new file mode 100644 index 00000000..cb358609 --- /dev/null +++ b/src/intrusive_stack.h @@ -0,0 +1,198 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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_INTRUSIVE_STACK__ +#define __ETL_INTRUSIVE_STACK__ + +#include + +#include "type_traits.h" +#include "error_handler.h" +#include "intrusive_links.h" + +#define ETL_FILE "28" + +namespace etl +{ + //*************************************************************************** + /// Exception base for intrusive stack + ///\ingroup intrusive_stack + //*************************************************************************** + class intrusive_stack_exception : public etl::exception + { + public: + + intrusive_stack_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + /// intrusive_stack empty exception. + ///\ingroup intrusive_stack + //*************************************************************************** + class intrusive_stack_empty : public intrusive_stack_exception + { + public: + + intrusive_stack_empty(string_type file_name, numeric_type line_number) + : intrusive_stack_exception(ETL_ERROR_TEXT("intrusive_stack:empty", ETL_FILE"A"), file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup stack + /// An intrusive stack. Stores elements derived from etl::forward_link + /// \warning This stack cannot be used for concurrent access from multiple threads. + /// \tparam TValue The type of value that the stack holds. + /// \tparam TLink The link type that the value is derived from. + //*************************************************************************** + template + class intrusive_stack + { + public: + + // Node typedef. + typedef TLink link_type; + + // STL style typedefs. + typedef TValue value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + + //************************************************************************* + /// Constructor + //************************************************************************* + intrusive_stack() + : p_top(nullptr), + current_size(0) + { + } + + //************************************************************************* + /// Gets a reference to the value at the top of the stack. + /// Undefined behaviour if the stack is empty. + /// \return A reference to the value at the top of the stack. + //************************************************************************* + reference top() + { + return *static_cast(p_top); + } + + //************************************************************************* + /// Gets a const reference to the value at the top of the stack.
+ /// \return A const reference to the value at the top of the stack. + //************************************************************************* + const_reference top() const + { + return *static_cast(p_top); + } + + //************************************************************************* + /// Adds a value to the stack. + ///\param value The value to push to the stack. + //************************************************************************* + void push(link_type& value) + { + value.clear(); + + if (p_top != nullptr) + { + etl::link(value, p_top); + } + + p_top = &value; + + ++current_size; + } + + //************************************************************************* + /// Removes the oldest item from the top of the stack. + /// Undefined behaviour if the stack is already empty. + //************************************************************************* + void pop() + { +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(!empty(), ETL_ERROR(intrusive_stack_empty)); +#endif + link_type* p_next = p_top->etl_next; + p_top = p_next; + --current_size; + } + + //************************************************************************* + /// Clears the stack to the empty state. + //************************************************************************* + void clear() + { + while (!empty()) + { + pop(); + } + + current_size = 0; + } + + //************************************************************************* + /// Checks if the stack is in the empty state. + //************************************************************************* + bool empty() const + { + return current_size == 0; + } + + //************************************************************************* + /// Returns the number of elements. + //************************************************************************* + size_t size() const + { + return current_size; + } + + private: + + // Disable copy construction and assignment. + intrusive_stack(const intrusive_stack&); + intrusive_stack& operator = (const intrusive_stack& rhs); + + link_type* p_top; // The current top of the stack. + + size_t current_size; ///< Counts the number of elements in the list. + }; +} + +#undef ETL_FILE + +#endif diff --git a/src/ipool.h b/src/ipool.h index 34c4e7d2..18a196ea 100644 --- a/src/ipool.h +++ b/src/ipool.h @@ -34,340 +34,76 @@ SOFTWARE. #include -#include "private/pool_base.h" +#include "platform.h" #include "nullptr.h" -#include "ibitset.h" +#include "alignment.h" #include "error_handler.h" +#include + +#undef ETL_FILE +#define ETL_FILE "11" + namespace etl { //*************************************************************************** + /// The base class for pool exceptions. ///\ingroup pool //*************************************************************************** - template - class ipool : public pool_base - { + class pool_exception : public exception + { public: - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef size_t size_type; + pool_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + {} + }; - //************************************************************************* - /// iterator - //************************************************************************* - class iterator : public std::iterator - { - public: + //*************************************************************************** + /// The exception thrown when the pool has no more free items. + ///\ingroup pool + //*************************************************************************** + class pool_no_allocation : public pool_exception + { + public: - friend class ipool; - friend class const_iterator; + explicit pool_no_allocation(string_type file_name, numeric_type line_number) + : pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_FILE"A"), file_name, line_number) + {} + }; - //******************************* - iterator() - : index(0), - p_buffer(nullptr), - p_in_use_flags(nullptr) - { - } + //*************************************************************************** + /// 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: - //******************************* - iterator(const iterator& other) - : index(other.index), - p_buffer(other.p_buffer), - p_in_use_flags(other.p_in_use_flags) - { - } + pool_object_not_in_pool(string_type file_name, numeric_type line_number) + : pool_exception(ETL_ERROR_TEXT("pool:notinpool", ETL_FILE"B"), file_name, line_number) + {} + }; - //******************************* - iterator& operator ++() - { - index = p_in_use_flags->find_next(true, index + 1); - return *this; - } + //*************************************************************************** + ///\ingroup pool + //*************************************************************************** + class ipool + { + public: - //******************************* - iterator operator ++(int) - { - iterator temp(*this); - index = p_in_use_flags->find_next(true, index + 1); - return temp; - } - - //******************************* - iterator operator =(const iterator& other) - { - index = other.index; - p_buffer = other.p_buffer; - p_in_use_flags = other.p_in_use_flags; - return *this; - } - - //******************************* - const_reference operator *() const - { - return p_buffer[index]; - } - - //******************************* - const_pointer operator ->() const - { - return &p_buffer[index]; - } - - //******************************* - friend bool operator == (const iterator& lhs, const iterator& rhs) - { - return (lhs.p_buffer == rhs.p_buffer) && (lhs.index == rhs.index); - } - - //******************************* - friend bool operator != (const iterator& lhs, const iterator& rhs) - { - return !(lhs == rhs); - } - - private: - - //******************************* - iterator(size_t index, - pointer p_buffer, - const ibitset* p_in_use_flags) - : index(index), - p_buffer(p_buffer), - p_in_use_flags(p_in_use_flags) - { - } - - size_t index; - pointer p_buffer; - const ibitset* p_in_use_flags; - }; - - - //************************************************************************* - /// const_iterator - //************************************************************************* - class const_iterator : public std::iterator - { - public: - - friend class ipool; - - //******************************* - const_iterator() - : index(0), - p_buffer(nullptr), - p_in_use_flags(nullptr) - { - } - - //******************************* - const_iterator(const const_iterator& other) - : index(other.index), - p_buffer(other.p_buffer), - p_in_use_flags(other.p_in_use_flags) - { - } - - //******************************* - const_iterator(const typename ipool::iterator& other) - : index(other.index), - p_buffer(other.p_buffer), - p_in_use_flags(other.p_in_use_flags) - { - } - - //******************************* - const_iterator& operator ++() - { - index = p_in_use_flags->find_next(true, index + 1); - return *this; - } - - //******************************* - const_iterator operator ++(int) - { - const_iterator temp(*this); - index = p_in_use_flags->find_next(true, index + 1); - return temp; - } - - //******************************* - const_iterator operator =(const const_iterator& other) - { - index = other.index; - p_buffer = other.p_buffer; - p_in_use_flags = other.p_in_use_flags; - return *this; - } - - //******************************* - const_reference operator *() const - { - return p_buffer[index]; - } - - //******************************* - const_pointer operator ->() const - { - return &p_buffer[index]; - } - - //******************************* - friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) - { - return (lhs.p_buffer == rhs.p_buffer) && (lhs.index == rhs.index); - } - - //******************************* - friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) - { - return !(lhs == rhs); - } - - private: - - //******************************* - const_iterator(size_t index, - const_pointer p_buffer, - const ibitset* p_in_use_flags) - : index(index), - p_buffer(p_buffer), - p_in_use_flags(p_in_use_flags) - { - } - - size_t index; - const_pointer p_buffer; - const ibitset* p_in_use_flags; - }; - - //************************************************************************* - /// Get an iterator to the first allocated item in the pool. - //************************************************************************* - iterator begin() - { - size_t index = in_use_flags.find_first(true); - - if (index != ibitset::npos) - { - return iterator(index, p_buffer, &in_use_flags); - } - else - { - return end(); - } - } - - //************************************************************************* - /// Get a const iterator to the first allocated item in the pool. - //************************************************************************* - const_iterator begin() const - { - size_t index = in_use_flags.find_first(true); - - if (index != ibitset::npos) - { - return const_iterator(index, p_buffer, &in_use_flags); - } - else - { - return end(); - } - } - - //************************************************************************* - /// Get a const iterator to the first allocated item in the pool. - //************************************************************************* - const_iterator cbegin() const - { - return begin(); - } - - //************************************************************************* - /// Get an iterator to the end of the pool. - //************************************************************************* - iterator end() - { - return iterator(ibitset::npos, p_buffer, &in_use_flags); - } - - //************************************************************************* - /// Get a const iterator to the end of the pool. - //************************************************************************* - const_iterator end() const - { - return const_iterator(ibitset::npos, p_buffer, &in_use_flags); - } - - //************************************************************************* - /// Get a const iterator to the end of the pool. - //************************************************************************* - const_iterator cend() const - { - return end(); - } + typedef size_t size_type; //************************************************************************* /// Allocate an object from the pool. /// Uses the default constructor. /// If asserts or exceptions are enabled and there are no more free items an /// etl::pool_no_allocation if thrown, otherwise a nullptr is returned. - /// \note The state of the object returned is undefined. //************************************************************************* + template T* allocate() { -#if defined(_DEBUG) || defined(DEBUG) - ETL_ASSERT(items_allocated < MAX_SIZE && !in_use_flags.test(next_free), ETL_ERROR(pool_no_allocation)); -#else - ETL_ASSERT(items_allocated < MAX_SIZE, ETL_ERROR(pool_no_allocation)); -#endif - - T* result = new(&p_buffer[next_free]) T(); - - in_use_flags.set(next_free); - next_free = in_use_flags.find_first(false); - ++items_allocated; - - return result; - } - - //************************************************************************* - /// Allocate an object from the pool from an initial value. - /// If asserts or exceptions are enabled and there are no more free items an - /// etl::pool_no_allocation if thrown, otherwise a nullptr is returned. - /// \note The state of the object returned is undefined. - //************************************************************************* - T* allocate(const T& initial) - { -#if defined(_DEBUG) || defined(DEBUG) - ETL_ASSERT(items_allocated < MAX_SIZE && !in_use_flags.test(next_free), ETL_ERROR(pool_no_allocation)); -#else - ETL_ASSERT(items_allocated < MAX_SIZE, ETL_ERROR(pool_no_allocation)); -#endif - - T* result = new(&p_buffer[next_free]) T(initial); - - in_use_flags.set(next_free); - next_free = in_use_flags.find_first(false); - ++items_allocated; - - return result; - } - - //************************************************************************* - /// Release an object in the pool. - /// If asserts or exceptions are enabled and the object does not belong to this - /// pool then an etl::pool_object_not_in_pool is thrown. - /// \param p_object A pointer to the object to be released. - //************************************************************************* - void release(const T& object) - { - release(&object); + return reinterpret_cast(allocate_item()); } //************************************************************************* @@ -376,52 +112,19 @@ namespace etl /// pool then an etl::pool_object_not_in_pool is thrown. /// \param p_object A pointer to the object to be released. //************************************************************************* - void release(const T* const p_object) + void release(const void* p_object) { - // Does it belong to me? - ETL_ASSERT(is_in_pool(p_object), ETL_ERROR(pool_object_not_in_pool)); - - // Where is it in the buffer? - typename std::iterator_traits::difference_type distance = p_object - p_buffer; - size_t index = static_cast(distance); - - // Check that it hasn't already been released. - if (in_use_flags.test(index)) - { - // Destroy the object and mark as available. - p_object->~T(); - in_use_flags.reset(index); - --items_allocated; - next_free = index; - } + release_item((char*)p_object); } //************************************************************************* - /// Releases all objects in the pool. + /// Release all objects in the pool. //************************************************************************* void release_all() { - const_iterator i_object = begin(); - - while (i_object != end()) - { - i_object->~T(); - ++i_object; - } - - in_use_flags.reset(); - items_allocated = 0; - next_free = 0; - } - - //************************************************************************* - /// Check to see if the object belongs to the pool. - /// \param p_object A pointer to the object to be checked. - /// \return true<\b> if it does, otherwise false - //************************************************************************* - bool is_in_pool(const T& object) const - { - return is_in_pool(&object); + items_allocated = 0; + items_initialised = 0; + p_next = p_buffer; } //************************************************************************* @@ -429,93 +132,173 @@ namespace etl /// \param p_object A pointer to the object to be checked. /// \return true<\b> if it does, otherwise false //************************************************************************* - bool is_in_pool(const T* p_object) const + //template + bool is_in_pool(const void* p_object) const { - // Does this object belong to this pool? - typename std::iterator_traits::difference_type distance = p_object - p_buffer; - - // Within the range of the buffer? - return ((distance >= 0) && (distance < static_cast::difference_type>(MAX_SIZE))); + return is_item_in_pool((const char*)p_object); } //************************************************************************* - /// Gets the iterator to the object. - /// If the object is not in the pool then end() is returned. - /// \param object A const reference to the object to be checked. - /// \return An iterator to the object or end(). + /// Returns the maximum number of items in the pool. //************************************************************************* - iterator get_iterator(T& object) + size_t max_items() const { - if (is_in_pool(object)) - { - iterator i_object = begin(); - - while (i_object != end()) - { - // Same one? - if (&object == &*i_object) - { - return i_object; - } - - ++i_object; - } - } - - return end(); + return MAX_ITEMS; } //************************************************************************* - /// Gets the const_iterator to the object. - /// If the object is not in the pool then end() is returned. - /// \param object A const reference to the object to be checked. - /// \return An const_iterator to the object or end(). + /// Returns the number of free items in the pool. //************************************************************************* - const_iterator get_iterator(const T& object) const + size_t available() const { - if (is_in_pool(object)) - { - const_iterator i_object = begin(); - - while (i_object != end()) - { - // Same one? - if (&object == &*i_object) - { - return i_object; - } - - ++i_object; - } - } - - return end(); + return MAX_ITEMS - items_allocated; } + //************************************************************************* + /// Returns the number of allocated items in the pool. + //************************************************************************* + size_t size() const + { + return items_allocated; + } + + //************************************************************************* + /// Checks to see if there are no allocated items in the pool. + /// \return true if there are none allocated. + //************************************************************************* + bool empty() const + { + return items_allocated == 0; + } + + //************************************************************************* + /// Checks to see if there are no free items in the pool. + /// \return true if there are none free. + //************************************************************************* + bool full() const + { + return items_allocated == MAX_ITEMS; + } protected: - + //************************************************************************* /// Constructor //************************************************************************* - ipool(T* p_buffer, ibitset& in_use_flags, size_t size) - : pool_base(size), - p_buffer(p_buffer), - in_use_flags(in_use_flags) + ipool(char* p_buffer_, uint32_t item_size, uint32_t max_items) + : p_buffer(p_buffer_), + p_next(p_buffer_), + items_allocated(0), + items_initialised(0), + ITEM_SIZE(item_size), + MAX_ITEMS(max_items) { } private: + //************************************************************************* + /// Allocate an item from the pool. + //************************************************************************* + char* allocate_item() + { + char* p_value = nullptr; + + // Any free space left? + if (items_allocated < MAX_ITEMS) + { + // Initialise another one if necessary. + if (items_initialised < MAX_ITEMS) + { + uintptr_t p = reinterpret_cast(p_buffer + (items_initialised * ITEM_SIZE)); + *reinterpret_cast(p) = p + ITEM_SIZE; + ++items_initialised; + } + + // Get the address of new allocated item. + p_value = p_next; + + ++items_allocated; + if (items_allocated != MAX_ITEMS) + { + // Set up the pointer to the next free item + p_next = *reinterpret_cast(p_next); + } + else + { + // No more left! + p_next = nullptr; + } + } + else + { + ETL_ASSERT(false, ETL_ERROR(etl::pool_no_allocation)); + } + + return p_value; + } + + //************************************************************************* + /// Release an item back to the pool. + //************************************************************************* + void release_item(char* p_value) + { + // Does it belong to us? + ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool)); + + if (p_next != nullptr) + { + // Point it to the current free item. + *(uintptr_t*)p_value = reinterpret_cast(p_next); + } + else + { + // This is the only free item. + *((uintptr_t*)p_value) = 0; + } + + p_next = p_value; + + --items_allocated; + } + + //************************************************************************* + /// Check if the item belongs to this pool. + //************************************************************************* + bool is_item_in_pool(const char* p) const + { + // Within the range of the buffer? + intptr_t distance = p - p_buffer; + bool is_within_range = (distance >= 0) && (distance <= intptr_t((ITEM_SIZE * MAX_ITEMS) - ITEM_SIZE)); + + // Modulus and division can be slow on some architectures, so only do this in debug. +#if defined(ETL_DEBUG) + // Is the address on a valid object boundary? + bool is_valid_address = ((distance % ITEM_SIZE) == 0); +#else + bool is_valid_address = true; +#endif + + return is_within_range && is_valid_address; + } + // Disable copy construction and assignment. ipool(const ipool&); ipool& operator =(const ipool&); - T* p_buffer; - ibitset& in_use_flags; + char* p_buffer; + char* p_next; + + uint32_t items_allocated; ///< The number of items allocated. + uint32_t items_initialised; ///< The number of items initialised. + + const uint32_t ITEM_SIZE; ///< The size of allocated items. + const uint32_t MAX_ITEMS; ///< The maximum number of objects that can be allocated. }; } +#undef ETL_FILE + #undef __ETL_IN_IPOOL_H__ #endif diff --git a/src/ipriority_queue.h b/src/ipriority_queue.h index fd3cb832..b00bd5f7 100644 --- a/src/ipriority_queue.h +++ b/src/ipriority_queue.h @@ -34,6 +34,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "type_traits.h" #include "parameter_type.h" #include "error_handler.h" @@ -167,7 +168,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(priority_queue_iterator)); ETL_ASSERT(static_cast(count) <= max_size(), ETL_ERROR(priority_queue_full)); @@ -184,13 +185,10 @@ namespace etl //************************************************************************* void pop() { - if (!empty()) - { // Move largest element to end - std::pop_heap(container.begin(), container.end(), TCompare()); + std::pop_heap(container.begin(), container.end(), TCompare()); // Actually remove largest element at end container.pop_back(); - } } //************************************************************************* diff --git a/src/iqueue.h b/src/iqueue.h index 0f55963c..952484b4 100644 --- a/src/iqueue.h +++ b/src/iqueue.h @@ -117,9 +117,10 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - new(&p_buffer[in]) T(value); + ::new (&p_buffer[in]) T(value); in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; ++current_size; + ++construct_count; } //************************************************************************* @@ -137,9 +138,10 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - new(&p_buffer[in]) T(); + ::new (&p_buffer[in]) T(); in = (in == (MAX_SIZE - 1)) ? 0 : in + 1; ++current_size; + ++construct_count; return p_buffer[next]; } @@ -154,6 +156,7 @@ namespace etl p_buffer[out].~T(); out = (out == (MAX_SIZE - 1)) ? 0 : out + 1; --current_size; + --construct_count; } in = 0; @@ -172,6 +175,7 @@ namespace etl p_buffer[out].~T(); out = (out == (MAX_SIZE - 1)) ? 0 : out + 1; --current_size; + --construct_count; } //************************************************************************* diff --git a/src/iset.h b/src/iset.h index 83f495cb..d84b51ba 100644 --- a/src/iset.h +++ b/src/iset.h @@ -126,7 +126,7 @@ namespace etl private: /// The pool of data nodes used in the set. - ipool* p_node_pool; + etl::ipool* p_node_pool; //************************************************************************* /// Downcast a Node* to a Data_Node* @@ -761,7 +761,7 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - iset(ipool& node_pool, size_t max_size_) + iset(ipool& node_pool, size_t max_size_) : set_base(max_size_) , p_node_pool(&node_pool) { @@ -772,13 +772,7 @@ namespace etl //************************************************************************* void initialise() { - if (!empty()) - { - p_node_pool->release_all(); - } - - current_size = 0; - root_node = nullptr; + erase(begin(), end()); } private: @@ -786,17 +780,22 @@ namespace etl //************************************************************************* /// Allocate a Data_Node. //************************************************************************* - Data_Node& allocate_data_node(value_type value) const + Data_Node& allocate_data_node(value_type value) { - return *(p_node_pool->allocate(Data_Node(value))); + Data_Node& node = *p_node_pool->allocate(); + ::new ((void*)&node.value) value_type(value); + ++construct_count; + return node; } //************************************************************************* /// Destroy a Data_Node. //************************************************************************* - void destroy_data_node(Data_Node& node) const + void destroy_data_node(Data_Node& node) { + node.value.~value_type(); p_node_pool->release(&node); + --construct_count; } //************************************************************************* diff --git a/src/istack.h b/src/istack.h index 35e8107c..432fa615 100644 --- a/src/istack.h +++ b/src/istack.h @@ -90,7 +90,8 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(stack_full)); #endif top_index = current_size++; - new(&p_buffer[top_index]) T(value); + ::new (&p_buffer[top_index]) T(value); + ++construct_count; } //************************************************************************* @@ -106,7 +107,8 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(stack_full)); #endif top_index = current_size++; - new(&p_buffer[top_index]) T(); + ::new (&p_buffer[top_index]) T(); + ++construct_count; return p_buffer[top_index]; } @@ -130,6 +132,7 @@ namespace etl p_buffer[top_index].~T(); --top_index; --current_size; + --construct_count; } } @@ -145,6 +148,7 @@ namespace etl p_buffer[top_index].~T(); --top_index; --current_size; + --construct_count; } //************************************************************************* diff --git a/src/iterator.h b/src/iterator.h new file mode 100644 index 00000000..e451c62b --- /dev/null +++ b/src/iterator.h @@ -0,0 +1,115 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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_ITERATOR__ +#define __ETL_ITERATOR__ + +#include + +#include "type_traits.h" + +///\defgroup iterator iterator +///\ingroup utilities + +namespace etl +{ + template + struct is_input_iterator + { + static const bool value = etl::is_same::iterator_category, std::input_iterator_tag>::value; + }; + + template + struct is_output_iterator + { + static const bool value = etl::is_same::iterator_category, std::output_iterator_tag>::value; + }; + + template + struct is_forward_iterator + { + static const bool value = etl::is_same::iterator_category, std::forward_iterator_tag>::value; + }; + + template + struct is_bidirectional_iterator + { + static const bool value = etl::is_same::iterator_category, std::bidirectional_iterator_tag>::value; + }; + + template + struct is_random_iterator + { + static const bool value = etl::is_same::iterator_category, std::random_access_iterator_tag>::value; + }; + + template + struct is_input_iterator_concept + { + static const bool value = etl::is_input_iterator::value || + etl::is_forward_iterator::value || + etl::is_bidirectional_iterator::value || + etl::is_random_iterator::value; + }; + + template + struct is_output_iterator_concept + { + static const bool value = etl::is_output_iterator::value || + etl::is_forward_iterator::value || + etl::is_bidirectional_iterator::value || + etl::is_random_iterator::value; + }; + + template + struct is_forward_iterator_concept + { + static const bool value = etl::is_forward_iterator::value || + etl::is_bidirectional_iterator::value || + etl::is_random_iterator::value; + }; + + template + struct is_bidirectional_iterator_concept + { + static const bool value = etl::is_bidirectional_iterator::value || + etl::is_random_iterator::value; + }; + + template + struct is_random_iterator_concept + { + static const bool value = etl::is_random_iterator::value; + }; + +} + +#endif + diff --git a/src/iunordered_map.h b/src/iunordered_map.h index e8447fa6..22127922 100644 --- a/src/iunordered_map.h +++ b/src/iunordered_map.h @@ -37,6 +37,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "type_traits.h" #include "parameter_type.h" #include "hash.h" @@ -47,6 +48,7 @@ SOFTWARE. #include "intrusive_forward_list.h" #include "exception.h" #include "error_handler.h" +#include "debug_count.h" #undef ETL_FILE #define ETL_FILE "16" @@ -149,10 +151,7 @@ namespace etl private: typedef etl::intrusive_forward_list bucket_t; - typedef etl::ipool pool_t; - typedef etl::ivector bucket_list_t; - - typedef typename bucket_list_t::iterator bucket_list_iterator; + typedef etl::ipool pool_t; public: @@ -185,8 +184,8 @@ namespace etl //********************************* iterator(const iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -197,19 +196,19 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -227,8 +226,8 @@ namespace etl //********************************* iterator operator =(const iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -284,9 +283,9 @@ namespace etl private: //********************************* - iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -300,13 +299,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t* get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -315,9 +314,9 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; - local_iterator inode; + bucket_t* pbuckets_end; + bucket_t* pbucket; + local_iterator inode; }; //********************************************************************* @@ -346,16 +345,16 @@ namespace etl //********************************* const_iterator(const typename iunordered_map::iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } //********************************* const_iterator(const const_iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -366,20 +365,19 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -397,8 +395,8 @@ namespace etl //********************************* const_iterator operator =(const const_iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -436,9 +434,9 @@ namespace etl private: //********************************* - const_iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + const_iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -452,13 +450,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t* get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -467,9 +465,9 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; - local_iterator inode; + bucket_t* pbuckets_end; + bucket_t* pbucket; + local_iterator inode; }; typedef typename std::iterator_traits::difference_type difference_type; @@ -480,7 +478,7 @@ namespace etl //********************************************************************* iterator begin() { - return iterator(pbuckets->end(), first, first->begin()); + return iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -489,7 +487,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -498,7 +496,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -534,7 +532,7 @@ namespace etl //********************************************************************* iterator end() { - return iterator(pbuckets->end(), last, last->end()); + return iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -543,7 +541,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -552,7 +550,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -588,7 +586,7 @@ namespace etl //********************************************************************* size_type bucket(key_value_parameter_t key) const { - return key_hash_function(key) % pbuckets->size(); + return key_hash_function(key) % number_of_buckets; } //********************************************************************* @@ -608,7 +606,7 @@ namespace etl //********************************************************************* size_type max_bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -617,7 +615,7 @@ namespace etl //********************************************************************* size_type bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -628,13 +626,13 @@ namespace etl mapped_type& operator [](key_value_parameter_t key) { // Find the bucket. - bucket_list_iterator ibucket = pbuckets->begin() + bucket(key); + bucket_t* pbucket = pbuckets + bucket(key); // Find the first node in the bucket. - local_iterator inode = ibucket->begin(); + local_iterator inode = pbucket->begin(); // Walk the list looking for the right one. - while (inode != ibucket->end()) + while (inode != pbucket->end()) { // Equal keys? if (key_equal_function(key, inode->key_value_pair.first)) @@ -650,10 +648,13 @@ namespace etl // Doesn't exist, so add a new one. // Get a new node. - node_t& node = *pnodepool->allocate(node_t(value_type(key, T()))); - ibucket->insert_after(ibucket->before_begin(), node); + node_t& node = *pnodepool->allocate(); + ::new (&node.key_value_pair) value_type(key, T()); + ++construct_count; - return ibucket->begin()->key_value_pair.second; + pbucket->insert_after(pbucket->before_begin(), node); + + return pbucket->begin()->key_value_pair.second; } //********************************************************************* @@ -665,13 +666,13 @@ namespace etl mapped_type& at(key_value_parameter_t key) { // Find the bucket. - bucket_list_iterator ibucket = pbuckets->begin() + bucket(key); + bucket_t* pbucket = pbuckets + bucket(key); // Find the first node in the bucket. - local_iterator inode = ibucket->begin(); + local_iterator inode = pbucket->begin(); // Walk the list looking for the right one. - while (inode != ibucket->end()) + while (inode != pbucket->end()) { // Equal keys? if (key_equal_function(key, inode->key_value_pair.first)) @@ -700,13 +701,13 @@ namespace etl const mapped_type& at(key_value_parameter_t key) const { // Find the bucket. - typename bucket_list_t::const_iterator ibucket = pbuckets->begin() + bucket(key); + bucket_t* pbucket = pbuckets + bucket(key); // Find the first node in the bucket. - typename bucket_t::const_iterator inode = ibucket->begin(); + local_iterator inode = pbucket->begin(); // Walk the list looking for the right one. - while (inode != ibucket->end()) + while (inode != pbucket->end()) { // Equal keys? if (key_equal_function(key, inode->key_value_pair.first)) @@ -736,7 +737,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(unordered_map_iterator)); ETL_ASSERT(size_t(count) <= max_size() , ETL_ERROR(unordered_map_full)); @@ -768,22 +769,26 @@ namespace etl size_t index = bucket(key); // Get the bucket & bucket iterator. - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; + + size_t s = pbuckets->size(); // The first one in the bucket? if (bucket.empty()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key_value_pair)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key_value_pair) value_type(key_value_pair); + ++construct_count; // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); - result.first = iterator(pbuckets->end(), ibucket, ibucket->begin()); + result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin()); result.second = true; - adjust_first_last_markers(ibucket); + adjust_first_last_markers(pbucket); } else { @@ -807,13 +812,15 @@ namespace etl if (inode == bucket.end()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key_value_pair)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key_value_pair) value_type(key_value_pair); + ++construct_count; // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); ++inode_previous; - result.first = iterator(pbuckets->end(), ibucket, inode_previous); + result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous); result.second = true; } } @@ -856,23 +863,28 @@ namespace etl size_t erase(key_value_parameter_t key) { size_t count = 0; - size_t bucket_id = bucket(key); + size_t index = bucket(key); - bucket_t& bucket = (*pbuckets)[bucket_id]; + bucket_t& bucket = pbuckets[index]; local_iterator iprevious = bucket.before_begin(); local_iterator icurrent = bucket.begin(); + // Search for the key, if we have it. while ((icurrent != bucket.end()) && (icurrent->key_value_pair.first != key)) { ++iprevious; ++icurrent; } + // Did we find it? if (icurrent != bucket.end()) { - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. count = 1; + --construct_count; } return count; @@ -885,20 +897,23 @@ namespace etl iterator erase(const_iterator ielement) { // Make a note of the next one. - iterator inext(pbuckets->end(), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); + iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); ++inext; bucket_t& bucket = ielement.get_bucket(); - local_iterator icurrent = ielement.get_local_iterator(); local_iterator iprevious = bucket.before_begin(); + local_iterator icurrent = ielement.get_local_iterator(); - // Find the node we're interested in. + // Find the node previous to the one we're interested in. while (iprevious->etl_next != &*icurrent) { ++iprevious; } - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; return inext; } @@ -913,48 +928,45 @@ namespace etl iterator erase(const_iterator first, const_iterator last) { // Make a note of the last. - iterator result(pbuckets->end(), last.get_bucket_list_iterator(), last.get_local_iterator()); + iterator result((pbuckets + number_of_buckets), last.get_bucket_list_iterator(), last.get_local_iterator()); // Get the starting point. - bucket_list_iterator ibucket = first.get_bucket_list_iterator(); - local_iterator ifirst = first.get_local_iterator(); - local_iterator iprevious = ibucket->before_begin(); - local_iterator iend; + bucket_t* pbucket = first.get_bucket_list_iterator(); + local_iterator iprevious = pbucket->before_begin(); + local_iterator icurrent = first.get_local_iterator(); + local_iterator iend = last.get_local_iterator(); // Note: May not be in the same bucket as icurrent. - // Find the first node we're interested in. - while (iprevious->etl_next != &*ifirst) + // Find the node previous to the first one. + while (iprevious->etl_next != &*icurrent) { - ++iprevious; + ++iprevious; } - - iend = iprevious; - iend++; - - while (first != last) + + while (icurrent != iend) { - // Find how far we can go in this bucket. - while ((first != last) && (iend != ibucket->end())) - { - ++first; - ++iend; - } - // Erase the range. - ibucket->erase_after(iprevious, iend); + local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; - // At the end of this bucket? - if (iend == ibucket->end()) + icurrent = inext; + + // Are we there yet? + if (icurrent != iend) { - // Move on to the next bucket. - ++ibucket; - iprevious = ibucket->before_begin(); - iend = iprevious; - ++iend; - } - else - { - // Still in the same bucket. - iprevious = iend; + // At the end of this bucket? + if ((icurrent == pbucket->end())) + { + // Find the next non-empty one. + do + { + ++pbucket; + } while (pbucket->empty()); + + iprevious = pbucket->before_begin(); + icurrent = pbucket->begin(); + } } } @@ -988,8 +1000,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -1003,7 +1015,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key_value_pair.first)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -1022,8 +1034,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -1037,7 +1049,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key_value_pair.first)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -1102,7 +1114,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return pnodepool->max_size(); + return pnodepool->max_items(); } //************************************************************************* @@ -1176,9 +1188,10 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_map(pool_t& node_pool, bucket_list_t& buckets) + iunordered_map(pool_t& node_pool, bucket_t* pbuckets_, size_t number_of_buckets) : pnodepool(&node_pool), - pbuckets(&buckets) + pbuckets(pbuckets_), + number_of_buckets(number_of_buckets) { } @@ -1187,19 +1200,37 @@ namespace etl //********************************************************************* void initialise() { - pbuckets->resize(pnodepool->max_size()); - if (!empty()) { - pnodepool->release_all(); - - for (size_t i = 0; i < pbuckets->size(); ++i) + // For each bucket... + for (size_t i = 0; i < number_of_buckets; ++i) { - (*pbuckets)[i].clear(); + bucket_t& bucket = pbuckets[i]; + + if (!bucket.empty()) + { + // For each item in the bucket... + local_iterator it = bucket.begin(); + + while (it != bucket.end()) + { + // Destroy the value contents. + it->key_value_pair.~value_type(); + --construct_count; + + ++it; + } + + // Now it's safe to clear the bucket. + bucket.clear(); + } } + + // Now it's safe to clear the entire pool in one go. + pnodepool->release_all(); } - first = pbuckets->begin(); + first = pbuckets; last = first; } @@ -1208,15 +1239,15 @@ namespace etl //********************************************************************* /// Adjust the first and last markers according to the new entry. //********************************************************************* - void adjust_first_last_markers(bucket_list_iterator ibucket) + void adjust_first_last_markers(bucket_t* pbucket) { - if (ibucket < first) + if (pbucket < first) { - first = ibucket; + first = pbucket; } - else if (ibucket > last) + else if (pbucket > last) { - last = ibucket; + last = pbucket; } } @@ -1227,17 +1258,23 @@ namespace etl pool_t* pnodepool; /// The bucket list. - bucket_list_t* pbuckets; + bucket_t* pbuckets; - /// The first and last iterators to buckets with values. - bucket_list_iterator first; - bucket_list_iterator last; + /// The number of buckets. + const size_t number_of_buckets; + + /// The first and last pointers to buckets with values. + bucket_t* first; + bucket_t* last; /// The function that creates the hashes. hasher key_hash_function; /// The function that compares the keys for equality. key_equal key_equal_function; + + /// For library debugging purposes only. + etl::debug_count construct_count; }; //*************************************************************************** diff --git a/src/iunordered_multimap.h b/src/iunordered_multimap.h index 2d2ba701..7319a624 100644 --- a/src/iunordered_multimap.h +++ b/src/iunordered_multimap.h @@ -37,6 +37,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "type_traits.h" #include "parameter_type.h" #include "hash.h" @@ -47,6 +48,7 @@ SOFTWARE. #include "intrusive_forward_list.h" #include "exception.h" #include "error_handler.h" +#include "debug_count.h" #undef ETL_FILE #define ETL_FILE "25" @@ -149,10 +151,7 @@ namespace etl private: typedef etl::intrusive_forward_list bucket_t; - typedef etl::ipool pool_t; - typedef etl::ivector bucket_list_t; - - typedef typename bucket_list_t::iterator bucket_list_iterator; + typedef etl::ipool pool_t; public: @@ -185,8 +184,8 @@ namespace etl //********************************* iterator(const iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -197,19 +196,19 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -227,8 +226,8 @@ namespace etl //********************************* iterator operator =(const iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -284,9 +283,9 @@ namespace etl private: //********************************* - iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -300,13 +299,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -315,8 +314,8 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; + bucket_t* pbuckets_end; + bucket_t* pbucket; local_iterator inode; }; @@ -346,16 +345,16 @@ namespace etl //********************************* const_iterator(const typename iunordered_multimap::iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } //********************************* const_iterator(const const_iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -366,20 +365,20 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -397,8 +396,8 @@ namespace etl //********************************* const_iterator operator =(const const_iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -436,9 +435,9 @@ namespace etl private: //********************************* - const_iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + const_iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -452,13 +451,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -467,8 +466,8 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; + bucket_t* pbuckets_end; + bucket_t* pbucket; local_iterator inode; }; @@ -480,7 +479,7 @@ namespace etl //********************************************************************* iterator begin() { - return iterator(pbuckets->end(), first, first->begin()); + return iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -489,7 +488,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -498,7 +497,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -507,7 +506,7 @@ namespace etl //********************************************************************* local_iterator begin(size_t i) { - return (*pbuckets)[i].begin(); + return pbuckets[i].begin(); } //********************************************************************* @@ -516,7 +515,7 @@ namespace etl //********************************************************************* local_const_iterator begin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -525,7 +524,7 @@ namespace etl //********************************************************************* local_const_iterator cbegin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -534,7 +533,7 @@ namespace etl //********************************************************************* iterator end() { - return iterator(pbuckets->end(), last, last->end()); + return iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -543,7 +542,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -552,7 +551,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -561,7 +560,7 @@ namespace etl //********************************************************************* local_iterator end(size_t i) { - return (*pbuckets)[i].end(); + return pbuckets[i].end(); } //********************************************************************* @@ -570,7 +569,7 @@ namespace etl //********************************************************************* local_const_iterator end(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -579,7 +578,7 @@ namespace etl //********************************************************************* local_const_iterator cend(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -588,7 +587,7 @@ namespace etl //********************************************************************* size_type bucket(key_value_parameter_t key) const { - return key_hash_function(key) % pbuckets->size(); + return key_hash_function(key) % number_of_buckets; } //********************************************************************* @@ -599,7 +598,7 @@ namespace etl { size_t index = bucket(key); - return std::distance((*pbuckets)[index].begin(), (*pbuckets)[index].end()); + return std::distance(pbuckets[index].begin(), pbuckets[index].end()); } //********************************************************************* @@ -608,7 +607,7 @@ namespace etl //********************************************************************* size_type max_bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -617,7 +616,7 @@ namespace etl //********************************************************************* size_type bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -630,7 +629,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(unordered_multimap_iterator)); ETL_ASSERT(size_t(count) <= max_size() , ETL_ERROR(unordered_multimap_full)); @@ -649,9 +648,9 @@ namespace etl /// If asserts or exceptions are enabled, emits unordered_multimap_full if the unordered_multimap is already full. ///\param value The value to insert. //********************************************************************* - std::pair insert(const value_type& key_value_pair) + iterator insert(const value_type& key_value_pair) { - std::pair result(end(), false); + iterator result = end(); ETL_ASSERT(!full(), ETL_ERROR(unordered_multimap_full)); @@ -662,22 +661,23 @@ namespace etl size_t index = bucket(key); // Get the bucket & bucket iterator. - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // The first one in the bucket? if (bucket.empty()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key_value_pair)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key_value_pair) value_type(key_value_pair); + ++construct_count; // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); - result.first = iterator(pbuckets->end(), ibucket, ibucket->begin()); - result.second = true; + result = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin()); - adjust_first_last_markers(ibucket); + adjust_first_last_markers(pbucket); } else { @@ -698,14 +698,15 @@ namespace etl } // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key_value_pair)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key_value_pair) value_type(key_value_pair); + ++construct_count; // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); ++inode_previous; - result.first = iterator(pbuckets->end(), ibucket, inode_previous); - result.second = true; + result = iterator((pbuckets + number_of_buckets), pbucket, inode_previous); } return result; @@ -719,7 +720,7 @@ namespace etl //********************************************************************* iterator insert(const_iterator position, const value_type& key_value_pair) { - return insert(key_value_pair).first; + return insert(key_value_pair); } //********************************************************************* @@ -748,7 +749,7 @@ namespace etl size_t count = 0; size_t bucket_id = bucket(key); - bucket_t& bucket = (*pbuckets)[bucket_id]; + bucket_t& bucket = pbuckets[bucket_id]; local_iterator iprevious = bucket.before_begin(); local_iterator icurrent = bucket.begin(); @@ -757,9 +758,12 @@ namespace etl { if (icurrent->key_value_pair.first == key) { - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. ++count; icurrent = iprevious; + --construct_count; } else { @@ -779,20 +783,23 @@ namespace etl iterator erase(const_iterator ielement) { // Make a note of the next one. - iterator inext(pbuckets->end(), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); + iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); ++inext; - bucket_t& bucket = ielement.get_bucket(); - local_iterator icurrent = ielement.get_local_iterator(); + bucket_t& bucket = ielement.get_bucket(); local_iterator iprevious = bucket.before_begin(); + local_iterator icurrent = ielement.get_local_iterator(); - // Find the node we're interested in. + // Find the node previous to the one we're interested in. while (iprevious->etl_next != &*icurrent) { ++iprevious; } - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; return inext; } @@ -807,48 +814,45 @@ namespace etl iterator erase(const_iterator first, const_iterator last) { // Make a note of the last. - iterator result(pbuckets->end(), last.get_bucket_list_iterator(), last.get_local_iterator()); + iterator result((pbuckets + number_of_buckets), last.get_bucket_list_iterator(), last.get_local_iterator()); // Get the starting point. - bucket_list_iterator ibucket = first.get_bucket_list_iterator(); - local_iterator ifirst = first.get_local_iterator(); - local_iterator iprevious = ibucket->before_begin(); - local_iterator iend; + bucket_t* pbucket = first.get_bucket_list_iterator(); + local_iterator iprevious = pbucket->before_begin(); + local_iterator icurrent = first.get_local_iterator(); + local_iterator iend = last.get_local_iterator(); // Note: May not be in the same bucket as icurrent. - // Find the first node we're interested in. - while (iprevious->etl_next != &*ifirst) + // Find the node previous to the first one. + while (iprevious->etl_next != &*icurrent) { ++iprevious; } - iend = iprevious; - iend++; - - while (first != last) + while (icurrent != iend) { - // Find how far we can go in this bucket. - while ((first != last) && (iend != ibucket->end())) - { - ++first; - ++iend; - } - // Erase the range. - ibucket->erase_after(iprevious, iend); + local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. + icurrent->key_value_pair.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; - // At the end of this bucket? - if (iend == ibucket->end()) + icurrent = inext; + + // Are we there yet? + if (icurrent != iend) { - // Move on to the next bucket. - ++ibucket; - iprevious = ibucket->before_begin(); - iend = iprevious; - ++iend; - } - else - { - // Still in the same bucket. - iprevious = iend; + // At the end of this bucket? + if ((icurrent == pbucket->end())) + { + // Find the next non-empty one. + do + { + ++pbucket; + } while (pbucket->empty()); + + iprevious = pbucket->before_begin(); + icurrent = pbucket->begin(); + } } } @@ -898,8 +902,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -913,7 +917,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key_value_pair.first)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -932,8 +936,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -947,7 +951,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key_value_pair.first)) { - return const_iterator(pbuckets->end(), ibucket, inode); + return const_iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -1022,7 +1026,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return pnodepool->max_size(); + return pnodepool->max_items(); } //************************************************************************* @@ -1096,9 +1100,10 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_multimap(pool_t& node_pool, bucket_list_t& buckets) + iunordered_multimap(pool_t& node_pool, bucket_t* pbuckets_, size_t number_of_buckets) : pnodepool(&node_pool), - pbuckets(&buckets) + pbuckets(pbuckets_), + number_of_buckets(number_of_buckets) { } @@ -1107,20 +1112,37 @@ namespace etl //********************************************************************* void initialise() { - pbuckets->resize(pnodepool->max_size()); - if (!empty()) { - pnodepool->release_all(); - - for (size_t i = 0; i < pbuckets->size(); ++i) + // For each bucket... + for (size_t i = 0; i < number_of_buckets; ++i) { - (*pbuckets)[i].clear(); + bucket_t& bucket = pbuckets[i]; + + if (!bucket.empty()) + { + // For each item in the bucket... + local_iterator it = bucket.begin(); + + while (it != bucket.end()) + { + // Destroy the value contents. + it->key_value_pair.~value_type(); + ++it; + --construct_count; + } + + // Now it's safe to clear the bucket. + bucket.clear(); + } } + + // Now it's safe to clear the entire pool in one go. + pnodepool->release_all(); } - first = pbuckets->begin(); - last = first; + first = pbuckets; + last = first; } private: @@ -1128,15 +1150,15 @@ namespace etl //********************************************************************* /// Adjust the first and last markers according to the new entry. //********************************************************************* - void adjust_first_last_markers(bucket_list_iterator ibucket) + void adjust_first_last_markers(bucket_t* pbucket) { - if (ibucket < first) + if (pbucket < first) { - first = ibucket; + first = pbucket; } - else if (ibucket > last) + else if (pbucket > last) { - last = ibucket; + last = pbucket; } } @@ -1147,17 +1169,23 @@ namespace etl pool_t* pnodepool; /// The bucket list. - bucket_list_t* pbuckets; + bucket_t* pbuckets; + + /// The number of buckets. + const size_t number_of_buckets; /// The first and last iterators to buckets with values. - bucket_list_iterator first; - bucket_list_iterator last; + bucket_t* first; + bucket_t* last; /// The function that creates the hashes. hasher key_hash_function; /// The function that compares the keys for equality. key_equal key_equal_function; + + /// For library debugging purposes only. + etl::debug_count construct_count; }; //*************************************************************************** diff --git a/src/iunordered_multiset.h b/src/iunordered_multiset.h index 995836b5..f1966559 100644 --- a/src/iunordered_multiset.h +++ b/src/iunordered_multiset.h @@ -37,6 +37,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "type_traits.h" #include "parameter_type.h" #include "hash.h" @@ -47,6 +48,7 @@ SOFTWARE. #include "intrusive_forward_list.h" #include "exception.h" #include "error_handler.h" +#include "debug_count.h" #undef ETL_FILE #define ETL_FILE "26" @@ -146,10 +148,7 @@ namespace etl private: typedef etl::intrusive_forward_list bucket_t; - typedef etl::ipool pool_t; - typedef etl::ivector bucket_list_t; - - typedef typename bucket_list_t::iterator bucket_list_iterator; + typedef etl::ipool pool_t; public: @@ -181,8 +180,8 @@ namespace etl //********************************* iterator(const iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -193,19 +192,19 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -223,8 +222,8 @@ namespace etl //********************************* iterator operator =(const iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -280,9 +279,9 @@ namespace etl private: //********************************* - iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -296,13 +295,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -311,9 +310,9 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; - local_iterator inode; + bucket_t* pbuckets_end; + bucket_t* pbucket; + local_iterator inode; }; //********************************************************************* @@ -341,16 +340,16 @@ namespace etl //********************************* const_iterator(const typename iunordered_multiset::iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } //********************************* const_iterator(const const_iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -361,20 +360,20 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -392,8 +391,8 @@ namespace etl //********************************* const_iterator operator =(const const_iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -431,9 +430,9 @@ namespace etl private: //********************************* - const_iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + const_iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -447,13 +446,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -462,9 +461,9 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; - local_iterator inode; + bucket_t* pbuckets_end; + bucket_t* pbucket; + local_iterator inode; }; typedef typename std::iterator_traits::difference_type difference_type; @@ -475,7 +474,7 @@ namespace etl //********************************************************************* iterator begin() { - return iterator(pbuckets->end(), first, first->begin()); + return iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -484,7 +483,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -493,7 +492,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator((pbuckets + number_of_buckets), first, first->begin()); } //********************************************************************* @@ -502,7 +501,7 @@ namespace etl //********************************************************************* local_iterator begin(size_t i) { - return (*pbuckets)[i].begin(); + return pbuckets[i].begin(); } //********************************************************************* @@ -511,7 +510,7 @@ namespace etl //********************************************************************* local_const_iterator begin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -520,7 +519,7 @@ namespace etl //********************************************************************* local_const_iterator cbegin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -529,7 +528,7 @@ namespace etl //********************************************************************* iterator end() { - return iterator(pbuckets->end(), last, last->end()); + return iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -538,7 +537,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -547,7 +546,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator((pbuckets + number_of_buckets), last, last->end()); } //********************************************************************* @@ -556,7 +555,7 @@ namespace etl //********************************************************************* local_iterator end(size_t i) { - return (*pbuckets)[i].end(); + return pbuckets[i].end(); } //********************************************************************* @@ -565,7 +564,7 @@ namespace etl //********************************************************************* local_const_iterator end(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -574,7 +573,7 @@ namespace etl //********************************************************************* local_const_iterator cend(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -583,7 +582,7 @@ namespace etl //********************************************************************* size_type bucket(key_value_parameter_t key) const { - return key_hash_function(key) % pbuckets->size(); + return key_hash_function(key) % number_of_buckets; } //********************************************************************* @@ -594,7 +593,7 @@ namespace etl { size_t index = bucket(key); - return std::distance((*pbuckets)[index].begin(), (*pbuckets)[index].end()); + return std::distance(pbuckets[index].begin(), pbuckets[index].end()); } //********************************************************************* @@ -603,7 +602,7 @@ namespace etl //********************************************************************* size_type max_bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -612,7 +611,7 @@ namespace etl //********************************************************************* size_type bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -625,7 +624,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(unordered_multiset_iterator)); ETL_ASSERT(size_t(count) <= max_size() , ETL_ERROR(unordered_multiset_full)); @@ -654,22 +653,24 @@ namespace etl size_t index = bucket(key); // Get the bucket & bucket iterator. - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // The first one in the bucket? if (bucket.empty()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key) value_type(key); + ++construct_count; // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); - result.first = iterator(pbuckets->end(), ibucket, ibucket->begin()); + result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin()); result.second = true; - adjust_first_last_markers(ibucket); + adjust_first_last_markers(pbucket); } else { @@ -690,13 +691,15 @@ namespace etl } // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key) value_type(key); + ++construct_count; // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); ++inode_previous; - result.first = iterator(pbuckets->end(), ibucket, inode_previous); + result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous); result.second = true; } @@ -740,7 +743,7 @@ namespace etl size_t count = 0; size_t bucket_id = bucket(key); - bucket_t& bucket = (*pbuckets)[bucket_id]; + bucket_t& bucket = pbuckets[bucket_id]; local_iterator iprevious = bucket.before_begin(); local_iterator icurrent = bucket.begin(); @@ -749,9 +752,12 @@ namespace etl { if (icurrent->key == key) { - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. ++count; icurrent = iprevious; + --construct_count; } else { @@ -771,20 +777,23 @@ namespace etl iterator erase(const_iterator ielement) { // Make a note of the next one. - iterator inext(pbuckets->end(), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); + iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); ++inext; - bucket_t& bucket = ielement.get_bucket(); - local_iterator icurrent = ielement.get_local_iterator(); + bucket_t& bucket = ielement.get_bucket(); local_iterator iprevious = bucket.before_begin(); + local_iterator icurrent = ielement.get_local_iterator(); - // Find the node we're interested in. + // Find the node previous to the one we're interested in. while (iprevious->etl_next != &*icurrent) { ++iprevious; } - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; return inext; } @@ -799,48 +808,45 @@ namespace etl iterator erase(const_iterator first, const_iterator last) { // Make a note of the last. - iterator result(pbuckets->end(), last.get_bucket_list_iterator(), last.get_local_iterator()); + iterator result((pbuckets + number_of_buckets), last.get_bucket_list_iterator(), last.get_local_iterator()); // Get the starting point. - bucket_list_iterator ibucket = first.get_bucket_list_iterator(); - local_iterator ifirst = first.get_local_iterator(); - local_iterator iprevious = ibucket->before_begin(); - local_iterator iend; + bucket_t* pbucket = first.get_bucket_list_iterator(); + local_iterator iprevious = pbucket->before_begin(); + local_iterator icurrent = first.get_local_iterator(); + local_iterator iend = last.get_local_iterator(); // Note: May not be in the same bucket as icurrent. - // Find the first node we're interested in. - while (iprevious->etl_next != &*ifirst) + // Find the node previous to the first one. + while (iprevious->etl_next != &*icurrent) { ++iprevious; } - iend = iprevious; - iend++; - - while (first != last) + while (icurrent != iend) { - // Find how far we can go in this bucket. - while ((first != last) && (iend != ibucket->end())) - { - ++first; - ++iend; - } - // Erase the range. - ibucket->erase_after(iprevious, iend); + local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; - // At the end of this bucket? - if (iend == ibucket->end()) + icurrent = inext; + + // Are we there yet? + if (icurrent != iend) { - // Move on to the next bucket. - ++ibucket; - iprevious = ibucket->before_begin(); - iend = iprevious; - ++iend; - } - else - { - // Still in the same bucket. - iprevious = iend; + // At the end of this bucket? + if ((icurrent == pbucket->end())) + { + // Find the next non-empty one. + do + { + ++pbucket; + } while (pbucket->empty()); + + iprevious = pbucket->before_begin(); + icurrent = pbucket->begin(); + } } } @@ -890,8 +896,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -905,7 +911,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -924,8 +930,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -939,7 +945,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator((pbuckets + number_of_buckets), pbucket, inode); } ++inode; @@ -1014,7 +1020,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return pnodepool->max_size(); + return pnodepool->max_items(); } //************************************************************************* @@ -1088,9 +1094,10 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_multiset(pool_t& node_pool, bucket_list_t& buckets) + iunordered_multiset(pool_t& node_pool, bucket_t* pbuckets_, size_t number_of_buckets) : pnodepool(&node_pool), - pbuckets(&buckets) + pbuckets(pbuckets_), + number_of_buckets(number_of_buckets) { } @@ -1099,20 +1106,37 @@ namespace etl //********************************************************************* void initialise() { - pbuckets->resize(pnodepool->max_size()); - if (!empty()) { - pnodepool->release_all(); - - for (size_t i = 0; i < pbuckets->size(); ++i) + // For each bucket... + for (size_t i = 0; i < number_of_buckets; ++i) { - (*pbuckets)[i].clear(); + bucket_t& bucket = pbuckets[i]; + + if (!bucket.empty()) + { + // For each item in the bucket... + local_iterator it = bucket.begin(); + + while (it != bucket.end()) + { + // Destroy the value contents. + it->key.~value_type(); + ++it; + --construct_count; + } + + // Now it's safe to clear the bucket. + bucket.clear(); + } } + + // Now it's safe to clear the entire pool in one go. + pnodepool->release_all(); } - first = pbuckets->begin(); - last = first; + first = pbuckets; + last = first; } private: @@ -1120,15 +1144,15 @@ namespace etl //********************************************************************* /// Adjust the first and last markers according to the new entry. //********************************************************************* - void adjust_first_last_markers(bucket_list_iterator ibucket) + void adjust_first_last_markers(bucket_t* pbucket) { - if (ibucket < first) + if (pbucket < first) { - first = ibucket; + first = pbucket; } - else if (ibucket > last) + else if (pbucket > last) { - last = ibucket; + last = pbucket; } } @@ -1139,17 +1163,23 @@ namespace etl pool_t* pnodepool; /// The bucket list. - bucket_list_t* pbuckets; + bucket_t* pbuckets; + + /// The number of buckets. + const size_t number_of_buckets; /// The first and last iterators to buckets with values. - bucket_list_iterator first; - bucket_list_iterator last; + bucket_t* first; + bucket_t* last; /// The function that creates the hashes. hasher key_hash_function; /// The function that compares the keys for equality. key_equal key_equal_function; + + /// For library debugging purposes only. + etl::debug_count construct_count; }; //*************************************************************************** diff --git a/src/iunordered_set.h b/src/iunordered_set.h index e11ac9c6..789375bb 100644 --- a/src/iunordered_set.h +++ b/src/iunordered_set.h @@ -37,6 +37,7 @@ SOFTWARE. #include #include +#include "platform.h" #include "type_traits.h" #include "parameter_type.h" #include "hash.h" @@ -47,6 +48,7 @@ SOFTWARE. #include "intrusive_forward_list.h" #include "exception.h" #include "error_handler.h" +#include "debug_count.h" #undef ETL_FILE #define ETL_FILE "23" @@ -146,10 +148,7 @@ namespace etl private: typedef etl::intrusive_forward_list bucket_t; - typedef etl::ipool pool_t; - typedef etl::ivector bucket_list_t; - - typedef typename bucket_list_t::iterator bucket_list_iterator; + typedef etl::ipool pool_t; public: @@ -181,8 +180,8 @@ namespace etl //********************************* iterator(const iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -193,19 +192,19 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -223,8 +222,8 @@ namespace etl //********************************* iterator operator =(const iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -280,9 +279,9 @@ namespace etl private: //********************************* - iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -296,13 +295,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -311,8 +310,8 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; + bucket_t* pbuckets_end; + bucket_t* pbucket; local_iterator inode; }; @@ -341,16 +340,16 @@ namespace etl //********************************* const_iterator(const typename iunordered_set::iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } //********************************* const_iterator(const const_iterator& other) - : ibuckets_end(other.ibuckets_end), - ibucket(other.ibucket), + : pbuckets_end(other.pbuckets_end), + pbucket(other.pbucket), inode(other.inode) { } @@ -361,20 +360,20 @@ namespace etl ++inode; // The end of this node list? - if (inode == ibucket->end()) + if (inode == pbucket->end()) { // Search for the next non-empty bucket. - ++ibucket; - while ((ibucket != ibuckets_end) && (ibucket->empty())) + ++pbucket; + while ((pbucket != pbuckets_end) && (pbucket->empty())) { - ++ibucket; + ++pbucket; } // If not past the end, get the first node in the bucket. - if (ibucket != ibuckets_end) + if (pbucket != pbuckets_end) { - inode = ibucket->begin(); + inode = pbucket->begin(); } } @@ -392,8 +391,8 @@ namespace etl //********************************* const_iterator operator =(const const_iterator& other) { - ibuckets_end = other.ibuckets_end; - ibucket = other.ibucket; + pbuckets_end = other.pbuckets_end; + pbucket = other.pbucket; inode = other.inode; return *this; } @@ -431,9 +430,9 @@ namespace etl private: //********************************* - const_iterator(bucket_list_iterator ibuckets_end, bucket_list_iterator ibucket, local_iterator inode) - : ibuckets_end(ibuckets_end), - ibucket(ibucket), + const_iterator(bucket_t* pbuckets_end, bucket_t* pbucket, local_iterator inode) + : pbuckets_end(pbuckets_end), + pbucket(pbucket), inode(inode) { } @@ -447,13 +446,13 @@ namespace etl //********************************* bucket_t& get_bucket() { - return *ibucket; + return *pbucket; } //********************************* - bucket_list_iterator& get_bucket_list_iterator() + bucket_t*& get_bucket_list_iterator() { - return ibucket; + return pbucket; } //********************************* @@ -462,8 +461,8 @@ namespace etl return inode; } - bucket_list_iterator ibuckets_end; - bucket_list_iterator ibucket; + bucket_t* pbuckets_end; + bucket_t* pbucket; local_iterator inode; }; @@ -475,7 +474,7 @@ namespace etl //********************************************************************* iterator begin() { - return iterator(pbuckets->end(), first, first->begin()); + return iterator(pbuckets + number_of_buckets, first, first->begin()); } //********************************************************************* @@ -484,7 +483,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator(pbuckets + number_of_buckets, first, first->begin()); } //********************************************************************* @@ -493,7 +492,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return const_iterator(pbuckets->end(), first, first->begin()); + return const_iterator(pbuckets + number_of_buckets, first, first->begin()); } //********************************************************************* @@ -502,7 +501,7 @@ namespace etl //********************************************************************* local_iterator begin(size_t i) { - return (*pbuckets)[i].begin(); + return pbuckets[i].begin(); } //********************************************************************* @@ -511,7 +510,7 @@ namespace etl //********************************************************************* local_const_iterator begin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -520,7 +519,7 @@ namespace etl //********************************************************************* local_const_iterator cbegin(size_t i) const { - return (*pbuckets)[i].cbegin(); + return pbuckets[i].cbegin(); } //********************************************************************* @@ -529,7 +528,7 @@ namespace etl //********************************************************************* iterator end() { - return iterator(pbuckets->end(), last, last->end()); + return iterator(pbuckets + number_of_buckets, last, last->end()); } //********************************************************************* @@ -538,7 +537,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator(pbuckets + number_of_buckets, last, last->end()); } //********************************************************************* @@ -547,7 +546,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return const_iterator(pbuckets->end(), last, last->end()); + return const_iterator(pbuckets + number_of_buckets, last, last->end()); } //********************************************************************* @@ -556,7 +555,7 @@ namespace etl //********************************************************************* local_iterator end(size_t i) { - return (*pbuckets)[i].end(); + return pbuckets[i].end(); } //********************************************************************* @@ -565,7 +564,7 @@ namespace etl //********************************************************************* local_const_iterator end(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -574,7 +573,7 @@ namespace etl //********************************************************************* local_const_iterator cend(size_t i) const { - return (*pbuckets)[i].cend(); + return pbuckets[i].cend(); } //********************************************************************* @@ -583,7 +582,7 @@ namespace etl //********************************************************************* size_type bucket(key_value_parameter_t key) const { - return key_hash_function(key) % pbuckets->size(); + return key_hash_function(key) % number_of_buckets; } //********************************************************************* @@ -594,7 +593,7 @@ namespace etl { size_t index = bucket(key); - return std::distance((*pbuckets)[index].begin(), (*pbuckets)[index].end()); + return std::distance(pbuckets[index].begin(), pbuckets[index].end()); } //********************************************************************* @@ -603,7 +602,7 @@ namespace etl //********************************************************************* size_type max_bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -612,7 +611,7 @@ namespace etl //********************************************************************* size_type bucket_count() const { - return max_size(); + return number_of_buckets; } //********************************************************************* @@ -625,7 +624,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(count >= 0, ETL_ERROR(unordered_set_iterator)); ETL_ASSERT(size_t(count) <= max_size() , ETL_ERROR(unordered_set_full)); @@ -654,22 +653,24 @@ namespace etl size_t index = bucket(key); // Get the bucket & bucket iterator. - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // The first one in the bucket? if (bucket.empty()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key) value_type(key); + ++construct_count; // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); - result.first = iterator(pbuckets->end(), ibucket, ibucket->begin()); + result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin()); result.second = true; - adjust_first_last_markers(ibucket); + adjust_first_last_markers(pbucket); } else { @@ -693,13 +694,15 @@ namespace etl if (inode == bucket.end()) { // Get a new node. - node_t& node = *pnodepool->allocate(node_t(key)); + node_t& node = *pnodepool->allocate(); + ::new (&node.key) value_type(key); + ++construct_count; // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); ++inode_previous; - result.first = iterator(pbuckets->end(), ibucket, inode_previous); + result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous); result.second = true; } } @@ -742,23 +745,28 @@ namespace etl size_t erase(key_value_parameter_t key) { size_t count = 0; - size_t bucket_id = bucket(key); + size_t index = bucket(key); - bucket_t& bucket = (*pbuckets)[bucket_id]; + bucket_t& bucket = pbuckets[index]; local_iterator iprevious = bucket.before_begin(); - local_iterator icurrent = bucket.begin(); + local_iterator icurrent = bucket.begin(); + // Search for the key, if we have it. while ((icurrent != bucket.end()) && (icurrent->key != key)) { ++iprevious; ++icurrent; } + // Did we find it? if (icurrent != bucket.end()) { - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. count = 1; + --construct_count; } return count; @@ -771,20 +779,23 @@ namespace etl iterator erase(const_iterator ielement) { // Make a note of the next one. - iterator inext(pbuckets->end(), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); + iterator inext((pbuckets + number_of_buckets), ielement.get_bucket_list_iterator(), ielement.get_local_iterator()); ++inext; - bucket_t& bucket = ielement.get_bucket(); - local_iterator icurrent = ielement.get_local_iterator(); + bucket_t& bucket = ielement.get_bucket(); local_iterator iprevious = bucket.before_begin(); + local_iterator icurrent = ielement.get_local_iterator(); - // Find the node we're interested in. + // Find the node previous to the one we're interested in. while (iprevious->etl_next != &*icurrent) { ++iprevious; } - bucket.erase_after(iprevious); + bucket.erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; return inext; } @@ -799,48 +810,45 @@ namespace etl iterator erase(const_iterator first, const_iterator last) { // Make a note of the last. - iterator result(pbuckets->end(), last.get_bucket_list_iterator(), last.get_local_iterator()); + iterator result((pbuckets + number_of_buckets), last.get_bucket_list_iterator(), last.get_local_iterator()); // Get the starting point. - bucket_list_iterator ibucket = first.get_bucket_list_iterator(); - local_iterator ifirst = first.get_local_iterator(); - local_iterator iprevious = ibucket->before_begin(); - local_iterator iend; + bucket_t* pbucket = first.get_bucket_list_iterator(); + local_iterator iprevious = pbucket->before_begin(); + local_iterator icurrent = first.get_local_iterator(); + local_iterator iend = last.get_local_iterator(); // Note: May not be in the same bucket as icurrent. - // Find the first node we're interested in. - while (iprevious->etl_next != &*ifirst) + // Find the node previous to the first one. + while (iprevious->etl_next != &*icurrent) { ++iprevious; } - iend = iprevious; - iend++; - - while (first != last) + while (icurrent != iend) { - // Find how far we can go in this bucket. - while ((first != last) && (iend != ibucket->end())) - { - ++first; - ++iend; - } - // Erase the range. - ibucket->erase_after(iprevious, iend); + local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. + icurrent->key.~value_type(); // Destroy the value. + pnodepool->release(&*icurrent); // Release it back to the pool. + --construct_count; - // At the end of this bucket? - if (iend == ibucket->end()) + icurrent = inext; + + // Are we there yet? + if (icurrent != iend) { - // Move on to the next bucket. - ++ibucket; - iprevious = ibucket->before_begin(); - iend = iprevious; - ++iend; - } - else - { - // Still in the same bucket. - iprevious = iend; + // At the end of this bucket? + if ((icurrent == pbucket->end())) + { + // Find the next non-empty one. + do + { + ++pbucket; + } while (pbucket->empty()); + + iprevious = pbucket->before_begin(); + icurrent = pbucket->begin(); + } } } @@ -874,8 +882,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -889,7 +897,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator(pbuckets + number_of_buckets, pbucket, inode); } ++inode; @@ -908,8 +916,8 @@ namespace etl { size_t index = bucket(key); - bucket_list_iterator ibucket = pbuckets->begin() + index; - bucket_t& bucket = *ibucket; + bucket_t* pbucket = pbuckets + index; + bucket_t& bucket = *pbucket; // Is the bucket not empty? if (!bucket.empty()) @@ -923,7 +931,7 @@ namespace etl // Do we have this one? if (key_equal_function(key, inode->key)) { - return iterator(pbuckets->end(), ibucket, inode); + return iterator(pbuckets + number_of_buckets, pbucket, inode); } ++inode; @@ -988,7 +996,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return pnodepool->max_size(); + return pnodepool->max_items(); } //************************************************************************* @@ -1062,9 +1070,10 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_set(pool_t& node_pool, bucket_list_t& buckets) + iunordered_set(pool_t& node_pool, bucket_t* pbuckets_, size_t number_of_buckets) : pnodepool(&node_pool), - pbuckets(&buckets) + pbuckets(pbuckets_), + number_of_buckets(number_of_buckets) { } @@ -1073,20 +1082,37 @@ namespace etl //********************************************************************* void initialise() { - pbuckets->resize(pnodepool->max_size()); - if (!empty()) { - pnodepool->release_all(); - - for (size_t i = 0; i < pbuckets->size(); ++i) + // For each bucket... + for (size_t i = 0; i < number_of_buckets; ++i) { - (*pbuckets)[i].clear(); + bucket_t& bucket = pbuckets[i]; + + if (!bucket.empty()) + { + // For each item in the bucket... + local_iterator it = bucket.begin(); + + while (it != bucket.end()) + { + // Destroy the value contents. + it->key.~value_type(); + ++it; + --construct_count; + } + + // Now it's safe to clear the bucket. + bucket.clear(); + } } + + // Now it's safe to clear the entire pool in one go. + pnodepool->release_all(); } - first = pbuckets->begin(); - last = first; + first = pbuckets; + last = first; } private: @@ -1094,15 +1120,15 @@ namespace etl //********************************************************************* /// Adjust the first and last markers according to the new entry. //********************************************************************* - void adjust_first_last_markers(bucket_list_iterator ibucket) + void adjust_first_last_markers(bucket_t* pbucket) { - if (ibucket < first) + if (pbucket < first) { - first = ibucket; + first = pbucket; } - else if (ibucket > last) + else if (pbucket > last) { - last = ibucket; + last = pbucket; } } @@ -1113,17 +1139,23 @@ namespace etl pool_t* pnodepool; /// The bucket list. - bucket_list_t* pbuckets; + bucket_t* pbuckets; + + /// The number of buckets. + const size_t number_of_buckets; /// The first and last iterators to buckets with values. - bucket_list_iterator first; - bucket_list_iterator last; + bucket_t* first; + bucket_t* last; /// The function that creates the hashes. hasher key_hash_function; /// The function that compares the keys for equality. key_equal key_equal_function; + + /// For library debugging purposes only. + etl::debug_count construct_count; }; //*************************************************************************** diff --git a/src/ivector.h b/src/ivector.h index 0dfe8491..056ebd7c 100644 --- a/src/ivector.h +++ b/src/ivector.h @@ -43,6 +43,7 @@ SOFTWARE. #include "type_traits.h" #include "parameter_type.h" #include "error_handler.h" +#include "memory.h" #ifdef ETL_COMPILER_GCC #pragma GCC diagnostic ignored "-Wunused-variable" @@ -72,14 +73,6 @@ namespace etl typedef size_t size_type; typedef typename std::iterator_traits::difference_type difference_type; - private: - - // Type trait to allow selection of simple algorithms for simple types. - template - struct is_simple_type : integral_constant::value || etl::is_pointer::value> - { - }; - protected: typedef typename parameter_type::type parameter_t; @@ -92,7 +85,7 @@ namespace etl //********************************************************************* iterator begin() { - return &p_buffer[0]; + return p_buffer; } //********************************************************************* @@ -101,7 +94,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return &p_buffer[0]; + return p_buffer; } //********************************************************************* @@ -110,7 +103,7 @@ namespace etl //********************************************************************* iterator end() { - return &p_buffer[current_size]; + return p_end; } //********************************************************************* @@ -119,7 +112,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return &p_buffer[current_size]; + return p_end; } //********************************************************************* @@ -128,7 +121,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return &p_buffer[0]; + return p_buffer; } //********************************************************************* @@ -137,7 +130,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return &p_buffer[current_size]; + return p_end; } //********************************************************************* @@ -202,32 +195,7 @@ namespace etl //********************************************************************* void resize(size_t new_size) { - ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full)); - - // Choose the algorithm according to type. - // The unused branch should be optimised away. - if (is_simple_type::value) - { - current_size = new_size; - } - else - { - // Size up or size down? - if (new_size > current_size) - { - while (current_size < new_size) - { - create_element(); - } - } - else if (new_size < current_size) - { - while (current_size > new_size) - { - destroy_element(); - } - } - } + resize(new_size, T()); } //********************************************************************* @@ -237,41 +205,72 @@ namespace etl ///\param new_size The new size. ///\param value The value to fill new elements with. Default = default constructed value. //********************************************************************* - void resize(size_t new_size, T value) + template + typename etl::enable_if::value, void>::type + resize(size_t new_size, T value) { ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full)); - // Choose the algorithm according to type. - // The unused branch should be optimised away. - if (is_simple_type::value) - { - // Size up if necessary. - while (current_size < new_size) - { - p_buffer[current_size++] = value; - } + const size_t current_size = size(); + size_t delta = (current_size < new_size) ? new_size - current_size : current_size - new_size; - current_size = new_size; + if (current_size < new_size) + { + std::fill_n(p_end, delta, value); +#if defined(ETL_DEBUG) + construct_count += delta; +#endif } else { - // Size up? - if (new_size > current_size) - { - while (current_size < new_size) - { - create_element(value); - } - } - // Size down? - else if (new_size < current_size) - { - while (current_size > new_size) - { - destroy_element(); - } - } + p_end -= delta; +#if defined(ETL_DEBUG) + construct_count -= delta; +#endif } + + p_end = p_buffer + new_size; + } + + //********************************************************************* + /// Resizes the vector. + /// If asserts or exceptions are enabled and the new size is larger than the + /// maximum then a vector_full is thrown. + ///\param new_size The new size. + ///\param value The value to fill new elements with. Default = default constructed value. + //********************************************************************* + template + typename etl::enable_if::value, void>::type + resize(size_t new_size, T value) + { + ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full)); + + const size_t current_size = size(); + size_t delta = (current_size < new_size) ? new_size - current_size : current_size - new_size; + + if (current_size < new_size) + { + etl::uninitialized_fill_n(p_end, delta, value); +#if defined(ETL_DEBUG) + construct_count += delta; +#endif + } + else + { + etl::destroy_n(p_end - delta, delta); +#if defined(ETL_DEBUG) + construct_count -= delta; +#endif + } + + p_end = p_buffer + new_size; + } + + //********************************************************************* + /// Does nothing. + //********************************************************************* + void reserve(size_t) + { } //********************************************************************* @@ -302,7 +301,7 @@ namespace etl //********************************************************************* reference at(size_t i) { - ETL_ASSERT(i < current_size, ETL_ERROR(vector_out_of_bounds)); + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); return p_buffer[i]; } @@ -314,7 +313,7 @@ namespace etl //********************************************************************* const_reference at(size_t i) const { - ETL_ASSERT(i < current_size, ETL_ERROR(vector_out_of_bounds)); + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); return p_buffer[i]; } @@ -324,7 +323,7 @@ namespace etl //********************************************************************* reference front() { - return p_buffer[0]; + return *p_buffer; } //********************************************************************* @@ -333,7 +332,7 @@ namespace etl //********************************************************************* const_reference front() const { - return p_buffer[0]; + return *p_buffer; } //********************************************************************* @@ -342,7 +341,7 @@ namespace etl //********************************************************************* reference back() { - return p_buffer[current_size - 1]; + return *(p_end - 1); } //********************************************************************* @@ -351,7 +350,7 @@ namespace etl //********************************************************************* const_reference back() const { - return p_buffer[current_size - 1]; + return *(p_end - 1); } //********************************************************************* @@ -382,30 +381,18 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(static_cast(count) <= MAX_SIZE, ETL_ERROR(vector_full)); #endif initialise(); - // Choose the algorithm according to type. - // The unused branch should be optimised away. - if (is_simple_type::value) - { - while (first != last) - { - p_buffer[current_size++] = *first++; - } - } - else - { - while (first != last) - { - create_element(*first); - ++first; - } - } +#if defined(ETL_DEBUG) + p_end = etl::uninitialized_copy(first, last, p_buffer, construct_count); +#else + p_end = etl::uninitialized_copy(first, last, p_buffer); +#endif } //********************************************************************* @@ -416,28 +403,15 @@ namespace etl //********************************************************************* void assign(size_t n, parameter_t value) { - initialise(); - ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(vector_full)); - // Choose the algorithm according to type. - // The unused branch should be optimised away. - if (is_simple_type::value) - { - while (n > 0) - { - p_buffer[current_size++] = value; - --n; - } - } - else - { - while (n > 0) - { - create_element(value); - --n; - } - } + initialise(); + +#if defined(ETL_DEBUG) + p_end = etl::uninitialized_fill_n(p_buffer, n, value, construct_count); +#else + p_end = etl::uninitialized_fill_n(p_buffer, n, value); +#endif } //************************************************************************* @@ -455,9 +429,10 @@ namespace etl void push_back() { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size != MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full)); #endif - create_element(); + + create_back(); } //********************************************************************* @@ -468,9 +443,9 @@ namespace etl void push_back(parameter_t value) { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size != MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full)); #endif - create_element(value); + create_back(value); } //************************************************************************* @@ -480,9 +455,9 @@ namespace etl void pop_back() { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size > 0, ETL_ERROR(vector_empty)); + ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty)); #endif - destroy_element(); + destroy_back(); } //********************************************************************* @@ -493,17 +468,17 @@ namespace etl //********************************************************************* iterator insert(iterator position, parameter_t value) { - ETL_ASSERT((current_size)+1 <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() + 1 <= MAX_SIZE, ETL_ERROR(vector_full)); - if (position != end()) + if (position == end()) { - create_element(); - std::copy_backward(position, end() - 1, end()); - *position = value; + create_back(value); } else { - create_element(value); + create_back(back()); + std::copy_backward(position, p_end - 1, p_end); + *position = value; } return position; @@ -516,55 +491,113 @@ namespace etl ///\param n The number of elements to add. ///\param value The value to insert. //********************************************************************* - void insert(iterator position, size_t n, parameter_t value) + template + typename etl::enable_if::value, void>::type + insert(iterator position, size_t n, parameter_t value) { - ETL_ASSERT((current_size)+1 <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT((size() + n) <= MAX_SIZE, ETL_ERROR(vector_full)); - if (position == end()) + std::copy_backward(position, p_end, p_end + n); + std::fill_n(position, n, value); + + construct_count += n; + p_end += n; + } + + //********************************************************************* + /// Inserts 'n' values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + ///\param position The position to insert before. + ///\param n The number of elements to add. + ///\param value The value to insert. + //********************************************************************* + template + typename etl::enable_if::value, void>::type + insert(iterator position, size_t n, parameter_t value) + { + ETL_ASSERT((size() + n) <= MAX_SIZE, ETL_ERROR(vector_full)); + + size_t insert_n = n; + size_t insert_begin = std::distance(begin(), position); + size_t insert_end = insert_begin + insert_n; + + // Copy old data. + size_t copy_old_n; + size_t construct_old_n; + iterator p_construct_old; + + if (insert_end > size()) { - while (n > 0) - { - create_element(value); - --n; - } + copy_old_n = 0; + construct_old_n = size() - insert_begin; + p_construct_old = p_buffer + insert_end; } else { - // Create copy (backwards). - size_t n_insert = n; - size_t from = size() - 1; - size_t to = from + n_insert; - size_t n_move = std::distance(position, end()); - size_t n_create_copy = std::min(n_insert, n_move); + copy_old_n = size() - insert_begin - insert_n; + construct_old_n = insert_n; + p_construct_old = p_end; + } - for (size_t i = 0; i < n_create_copy; ++i) - { - create_element_at(to--, p_buffer[from--]); - } + size_t copy_new_n = construct_old_n; + size_t construct_new_n = insert_n - copy_new_n; - // Copy old. - size_t insert_index = std::distance(begin(), position); - from = insert_index; - to = from + n_insert; - size_t n_copy_old = (size() > n_insert) ? size() - n_insert : 0; - etl::copy_n(&p_buffer[from], n_copy_old, &p_buffer[to]); +#if defined(ETL_DEBUG) + // Construct old. + etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count); - // Copy new. - to = insert_index; - - size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0; - size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0; - std::fill_n(&p_buffer[to], n_copy_new, value); + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); - // Create new. - to = size(); + // Construct new. + etl::uninitialized_fill_n(p_end, construct_new_n, value, construct_count); - for (size_t i = 0; i < n_create_new; ++i) - { - create_element_at(to++, value); - } + // Copy new. + std::fill_n(p_buffer + insert_begin, copy_new_n, value); +#else + // Construct old. + etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); - current_size += n_insert; + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); + + // Construct new. + etl::uninitialized_fill_n(p_end, construct_new_n, value); + + // Copy new. + std::fill_n(p_buffer + insert_begin, copy_new_n, value); +#endif + + p_end += n; + } + + //********************************************************************* + /// Inserts a range of values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + /// For fundamental and pointer types. + ///\param position The position to insert before. + ///\param first The first element to add. + ///\param last The last + 1 element to add. + //********************************************************************* + template + typename etl::enable_if::value, void>::type + insert(iterator position, TIterator first, TIterator last) + { + size_t count = std::distance(first, last); + + ETL_ASSERT((size() + count) <= MAX_SIZE, ETL_ERROR(vector_full)); + + construct_count += count; + + if (position == end()) + { + p_end = std::copy(first, last, p_end); + } + else + { + std::copy_backward(position, p_end, p_end + count); + std::copy(first, last, position); + p_end += count; } } @@ -576,125 +609,68 @@ namespace etl ///\param first The first element to add. ///\param last The last + 1 element to add. //********************************************************************* - template - typename etl::enable_if::value_type>::value, void>::type - insert(iterator position, TIterator first, TIterator last) + template + typename etl::enable_if::value, void>::type + insert(iterator position, TIterator first, TIterator last) { size_t count = std::distance(first, last); - ETL_ASSERT((current_size)+count <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT((size() + count) <= MAX_SIZE, ETL_ERROR(vector_full)); - if (position == end()) + size_t insert_n = count; + size_t insert_begin = std::distance(begin(), position); + size_t insert_end = insert_begin + insert_n; + + // Copy old data. + size_t copy_old_n; + size_t construct_old_n; + iterator p_construct_old; + + if (insert_end > size()) { - while (first != last) - { - p_buffer[current_size++] = *first++; - } + copy_old_n = 0; + construct_old_n = size() - insert_begin; + p_construct_old = p_buffer + insert_end; } else { - size_t insert_index = std::distance(begin(), position); - size_t n_insert = count; - - // Create copy (backwards). - size_t from = size() - 1; - size_t to = from + n_insert; - size_t n_move = std::distance(position, end()); - size_t n_create_copy = std::min(n_insert, n_move); - - for (size_t i = 0; i < n_create_copy; ++i) - { - p_buffer[to--] = p_buffer[from--]; - } - - // Copy old. - from = insert_index; - to = from + n_insert; - size_t n_copy_old = (size() > n_insert) ? size() - n_insert : 0; - etl::copy_n(&p_buffer[from], n_copy_old, &p_buffer[to]); - - // Copy new. - to = insert_index; - size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0; - size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0; - etl::copy_n(first, n_copy_new, &p_buffer[to]); - first += n_copy_new; - - // Create new. - to = size(); - for (size_t i = 0; i < n_create_new; ++i) - { - p_buffer[to++] = *first++; - } - - current_size += n_insert; + copy_old_n = size() - insert_begin - insert_n; + construct_old_n = insert_n; + p_construct_old = p_end; } + + size_t copy_new_n = construct_old_n; + size_t construct_new_n = insert_n - copy_new_n; + +#if defined(ETL_DEBUG) + // Construct old. + etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count); + + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); + + // Construct new. + etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end, construct_count); + + // Copy new. + etl::copy_n(first, copy_new_n, p_buffer + insert_begin); +#else + // Construct old. + etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); + + // Copy old. + etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); + + // Construct new. + etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end); + + // Copy new. + etl::copy_n(first, copy_new_n, p_buffer + insert_begin); +#endif + + p_end += count; } - //********************************************************************* - /// Inserts a range of values to the vector. - /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. - /// For non-fundamental types. - ///\param position The position to insert before. - ///\param first The first element to add. - ///\param last The last + 1 element to add. - //********************************************************************* - template - typename etl::enable_if::value_type>::value, void>::type - insert(iterator position, TIterator first, TIterator last) - { - size_t count = std::distance(first, last); - - ETL_ASSERT((current_size)+count <= MAX_SIZE, ETL_ERROR(vector_full)); - - if (position == end()) - { - while (first != last) - { - create_element(*first); - ++first; - } - } - else - { - size_t insert_index = std::distance(begin(), position); - size_t n_insert = count; - - // Create copy (backwards). - size_t from = size() - 1; - size_t to = from + n_insert; - size_t n_move = std::distance(position, end()); - size_t n_create_copy = std::min(n_insert, n_move); - for (size_t i = 0; i < n_create_copy; ++i) - { - create_element_at(to--, p_buffer[from--]); - } - - // Copy old. - from = insert_index; - to = from + n_insert; - size_t n_copy_old = (size() > n_insert) ? size() - n_insert : 0; - etl::copy_n(&p_buffer[from], n_copy_old, &p_buffer[to]); - - // Copy new. - to = insert_index; - size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0; - size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0; - etl::copy_n(first, n_copy_new, &p_buffer[to]); - first += n_copy_new; - - // Create new. - to = size(); - for (size_t i = 0; i < n_create_new; ++i) - { - create_element_at(to++, *first); - ++first; - } - - current_size += n_insert; - } - } - //********************************************************************* /// Erases an element. ///\param i_element Iterator to the element. @@ -703,8 +679,8 @@ namespace etl iterator erase(iterator i_element) { std::copy(i_element + 1, end(), i_element); - destroy_element(); - + destroy_back(); + return i_element; } @@ -716,23 +692,53 @@ namespace etl ///\param last Iterator to the last element. ///\return An iterator pointing to the element that followed the erased element. //********************************************************************* - iterator erase(iterator first, iterator last) + template + typename etl::enable_if::value, iterator>::type + erase(iterator first, iterator last) { - std::copy(last, end(), first); - size_t n_delete = std::distance(first, last); - - if (is_simple_type::value) + if (first == begin() && last == end()) { - // Just adjust the count. - current_size -= n_delete; + clear(); } else { + std::copy(last, end(), first); + size_t n_delete = std::distance(first, last); + construct_count -= n_delete; + p_end -= n_delete; + } + + return first; + } + + //********************************************************************* + /// Erases a range of elements. + /// The range includes all the elements between first and last, including the + /// element pointed by first, but not the one pointed by last. + ///\param first Iterator to the first element. + ///\param last Iterator to the last element. + ///\return An iterator pointing to the element that followed the erased element. + //********************************************************************* + template + typename etl::enable_if::value, iterator>::type + erase(iterator first, iterator last) + { + if (first == begin() && last == end()) + { + clear(); + } + else + { + std::copy(last, end(), first); + size_t n_delete = std::distance(first, last); + // Destroy the elements left over at the end. - while (n_delete-- > 0) - { - destroy_element(); - } +#if defined(ETL_DEBUG) + etl::destroy(p_end - n_delete, p_end, construct_count); +#else + etl::destroy(p_end - n_delete, p_end); +#endif + p_end -= n_delete; } return first; @@ -751,14 +757,51 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the vector. + ///\return The current size of the vector. + //************************************************************************* + size_type size() const + { + return size_t(p_end - p_buffer); + } + + //************************************************************************* + /// Checks the 'empty' state of the vector. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return (p_end == p_buffer); + } + + //************************************************************************* + /// Checks the 'full' state of the vector. + ///\return true if full. + //************************************************************************* + bool full() const + { + return size() == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - ivector(T* p_buffer, size_t MAX_SIZE) + ivector(T* p_buffer_, size_t MAX_SIZE) : vector_base(MAX_SIZE), - p_buffer(p_buffer) + p_buffer(p_buffer_), + p_end(p_buffer_) { } @@ -767,55 +810,58 @@ namespace etl //********************************************************************* void initialise() { - // Choose the algorithm according to type. - // The unused branch should be optimised away. - if (is_simple_type::value) - { - current_size = 0; - } - else - { - while (current_size > 0) - { - destroy_element(); - } - } +#if defined(ETL_DEBUG) + etl::destroy(p_buffer, p_end, construct_count); +#else + etl::destroy(p_buffer, p_end); +#endif + + p_end = p_buffer; } - T* p_buffer; - private: + pointer p_buffer; ///< Pointer to the start of the buffer. + pointer p_end; ///< Pointer to one past the last element in the buffer. + //********************************************************************* /// Create a new element with a default value at the back. //********************************************************************* - inline void create_element() + inline void create_back() { - new(&p_buffer[current_size++]) T(); +#if defined(ETL_DEBUG) + etl::create_value_at(p_end, construct_count); +#else + etl::create_value_at(p_end); +#endif + ++p_end; } //********************************************************************* /// Create a new element with a value at the back //********************************************************************* - inline void create_element(parameter_t value) + inline void create_back(parameter_t value) { - new(&p_buffer[current_size++]) T(value); - } - - //********************************************************************* - /// Create a new element with a value at the index - //********************************************************************* - inline void create_element_at(size_t index, parameter_t value) - { - new(&p_buffer[index]) T(value); +#if defined(ETL_DEBUG) + etl::create_copy_at(p_end, value, construct_count); +#else + etl::create_copy_at(p_end, value); +#endif + ++p_end; } //********************************************************************* /// Destroy an element at the back. //********************************************************************* - inline void destroy_element() + inline void destroy_back() { - p_buffer[--current_size].~T(); + --p_end; + +#if defined(ETL_DEBUG) + etl::destroy_at(p_end, construct_count); +#else + etl::destroy_at(p_end); +#endif } // Disable copy construction. diff --git a/src/ivectorpointer.h b/src/ivectorpointer.h new file mode 100644 index 00000000..594af73a --- /dev/null +++ b/src/ivectorpointer.h @@ -0,0 +1,531 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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_IVECTOR_POINTER__ +#define __ETL_IVECTOR_POINTER__ + +#ifndef __ETL_IN_IVECTOR_H__ +#error This header is a private element of etl::ivector +#endif + +namespace etl +{ + //*************************************************************************** + /// The base class for specifically sized vectors. + /// Can be used as a reference type for all vectors containing a specific pointer type. + ///\ingroup vector + //*************************************************************************** + template ::value, void>::type*/> + class ivector : public ivector + { + private: + + // Stops warning messages about unused template parameter. + //const bool not_void_ptr = typedef etl::is_same::value; + + public: + + typedef T* value_type; + typedef T*& reference; + typedef const T* const & const_reference; + typedef T** pointer; + typedef const T* const * const_pointer; + typedef T** iterator; + typedef const T* const * const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef size_t size_type; + typedef typename std::iterator_traits::difference_type difference_type; + + protected: + + typedef value_type parameter_t; + + private: + + typedef ivector base_t; + + public: + + //********************************************************************* + /// Returns an iterator to the beginning of the vector. + ///\return An iterator to the beginning of the vector. + //********************************************************************* + iterator begin() + { + return iterator(base_t::begin()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the vector. + ///\return A const iterator to the beginning of the vector. + //********************************************************************* + const_iterator begin() const + { + return const_iterator(base_t::begin()); + } + + //********************************************************************* + /// Returns an iterator to the end of the vector. + ///\return An iterator to the end of the vector. + //********************************************************************* + iterator end() + { + return iterator(base_t::end()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the vector. + ///\return A const iterator to the end of the vector. + //********************************************************************* + const_iterator end() const + { + return const_iterator(base_t::end()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the vector. + ///\return A const iterator to the beginning of the vector. + //********************************************************************* + const_iterator cbegin() const + { + return const_iterator(base_t::cbegin()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the vector. + ///\return A const iterator to the end of the vector. + //********************************************************************* + const_iterator cend() const + { + return const_iterator(base_t::cend()); + } + + //********************************************************************* + /// Returns an reverse iterator to the reverse beginning of the vector. + ///\return Iterator to the reverse beginning of the vector. + //********************************************************************* + reverse_iterator rbegin() + { + return reverse_iterator(iterator(base_t::end())); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the vector. + ///\return Const iterator to the reverse beginning of the vector. + //********************************************************************* + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(const_iterator(base_t::end())); + } + + //********************************************************************* + /// Returns a reverse iterator to the end + 1 of the vector. + ///\return Reverse iterator to the end + 1 of the vector. + //********************************************************************* + reverse_iterator rend() + { + return reverse_iterator(iterator(base_t::begin())); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the vector. + ///\return Const reverse iterator to the end + 1 of the vector. + //********************************************************************* + const_reverse_iterator rend() const + { + return const_reverse_iterator(const_iterator(base_t::begin())); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the vector. + ///\return Const reverse iterator to the reverse beginning of the vector. + //********************************************************************* + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(const_iterator(base_t::cend())); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the vector. + ///\return Const reverse iterator to the end + 1 of the vector. + //********************************************************************* + const_reverse_iterator crend() const + { + return const_reverse_iterator(const_iterator(base_t::cbegin())); + } + + //********************************************************************* + /// Resizes the vector. + /// If asserts or exceptions are enabled and the new size is larger than the + /// maximum then a vector_full is thrown. + ///\param new_size The new size. + //********************************************************************* + void resize(size_t new_size) + { + base_t::resize(new_size); + } + + //********************************************************************* + /// Resizes the vector. + /// If asserts or exceptions are enabled and the new size is larger than the + /// maximum then a vector_full is thrown. + ///\param new_size The new size. + ///\param value The value to fill new elements with. Default = default constructed value. + //********************************************************************* + void resize(size_t new_size, value_type value) + { + base_t::resize(new_size, value); + } + + //********************************************************************* + /// Returns a reference to the value at index 'i' + ///\param i The index. + ///\return A reference to the value at index 'i' + //********************************************************************* + reference operator [](size_t i) + { + return reference(base_t::operator[](i)); + } + + //********************************************************************* + /// Returns a const reference to the value at index 'i' + ///\param i The index. + ///\return A const reference to the value at index 'i' + //********************************************************************* + const_reference operator [](size_t i) const + { + return const_reference(base_t::operator[](i)); + } + + //********************************************************************* + /// Returns a reference to the value at index 'i' + /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. + ///\param i The index. + ///\return A reference to the value at index 'i' + //********************************************************************* + reference at(size_t i) + { + return reference(base_t::at(i)); + } + + //********************************************************************* + /// Returns a const reference to the value at index 'i' + /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. + ///\param i The index. + ///\return A const reference to the value at index 'i' + //********************************************************************* + const_reference at(size_t i) const + { + return const_reference(base_t::at(i)); + } + + //********************************************************************* + /// Returns a reference to the first element. + ///\return A reference to the first element. + //********************************************************************* + reference front() + { + return reference(base_t::front()); + } + + //********************************************************************* + /// Returns a const reference to the first element. + ///\return A const reference to the first element. + //********************************************************************* + const_reference front() const + { + return const_reference(base_t::front()); + } + + //********************************************************************* + /// Returns a reference to the last element. + ///\return A reference to the last element. + //********************************************************************* + reference back() + { + return reference(base_t::back()); + } + + //********************************************************************* + /// Returns a const reference to the last element. + ///\return A const reference to the last element. + //********************************************************************* + const_reference back() const + { + return const_reference(base_t::back()); + } + + //********************************************************************* + /// Returns a pointer to the beginning of the vector data. + ///\return A pointer to the beginning of the vector data. + //********************************************************************* + pointer data() + { + return pointer(base_t::data()); + } + + //********************************************************************* + /// Returns a const pointer to the beginning of the vector data. + ///\return A const pointer to the beginning of the vector data. + //********************************************************************* + const_pointer data() const + { + return const_pointer(base_t::data()); + } + + //********************************************************************* + /// Assigns values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + /// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed. + ///\param first The iterator to the first element. + ///\param last The iterator to the last element + 1. + //********************************************************************* + template + void assign(TIterator first, TIterator last) + { + base_t::initialise(); + + while (first != last) + { + p_buffer[current_size++] = (void*)*first++; + } + } + + //********************************************************************* + /// Assigns values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + ///\param n The number of elements to add. + ///\param value The value to insert for each element. + //********************************************************************* + void assign(size_t n, parameter_t value) + { + base_t::assign(n, value); + } + + //************************************************************************* + /// Clears the vector. + //************************************************************************* + void clear() + { + base_t::clear(); + } + + //************************************************************************* + /// Increases the size of the vector by one, but does not initialise the new element. + /// If asserts or exceptions are enabled, throws a vector_full if the vector is already full. + //************************************************************************* + void push_back() + { + base_t::push_back(); + } + + //********************************************************************* + /// Inserts a value at the end of the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. + ///\param value The value to add. + //********************************************************************* + void push_back(parameter_t value) + { + base_t::push_back(value); + } + + //************************************************************************* + /// Removes an element from the end of the vector. + /// Does nothing if the vector is empty. + //************************************************************************* + void pop_back() + { + base_t::pop_back(); + } + + //********************************************************************* + /// Inserts a value to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. + ///\param position The position to insert before. + ///\param value The value to insert. + //********************************************************************* + iterator insert(iterator position, parameter_t value) + { + return iterator(base_t::insert(base_t::iterator(position), value)); + } + + //********************************************************************* + /// Inserts 'n' values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + ///\param position The position to insert before. + ///\param n The number of elements to add. + ///\param value The value to insert. + //********************************************************************* + void insert(iterator position, size_t n, parameter_t value) + { + base_t::insert(base_t::iterator(position), n, value); + } + + //********************************************************************* + /// Inserts a range of values to the vector. + /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. + ///\param position The position to insert before. + ///\param first The first element to add. + ///\param last The last + 1 element to add. + //********************************************************************* + template + void insert(iterator position, TIterator first, TIterator last) + { + base_t::insert(base_t::iterator(position), first, last); + } + + //********************************************************************* + /// Erases an element. + ///\param i_element Iterator to the element. + ///\return An iterator pointing to the element that followed the erased element. + //********************************************************************* + iterator erase(iterator i_element) + { + return iterator(base_t::erase(base_t::iterator(i_element))); + } + + //********************************************************************* + /// Erases a range of elements. + /// The range includes all the elements between first and last, including the + /// element pointed by first, but not the one pointed by last. + ///\param first Iterator to the first element. + ///\param last Iterator to the last element. + ///\return An iterator pointing to the element that followed the erased element. + //********************************************************************* + iterator erase(iterator first, iterator last) + { + return iterator(base_t::erase(base_t::iterator(first), base_t::iterator(last))); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ivector& operator = (const ivector& rhs) + { + if (&rhs != this) + { + assign(rhs.cbegin(), rhs.cend()); + } + + return *this; + } + + protected: + + //********************************************************************* + /// Constructor. + //********************************************************************* + ivector(void** p_buffer, size_t MAX_SIZE) + : ivector(p_buffer, MAX_SIZE) + { + } + }; + + //*************************************************************************** + /// Equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the arrays are equal, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator ==(const etl::ivector& lhs, const etl::ivector& rhs) + { + return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + //*************************************************************************** + /// Not equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the arrays are not equal, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator !=(const etl::ivector& lhs, const etl::ivector& rhs) + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// Less than operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically less than the second, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator <(const etl::ivector& lhs, const etl::ivector& rhs) + { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + //*************************************************************************** + /// Greater than operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically greater than the second, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator >(const etl::ivector& lhs, const etl::ivector& rhs) + { + return (rhs < lhs); + } + + //*************************************************************************** + /// Less than or equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexigraphically less than or equal to the second, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator <=(const etl::ivector& lhs, const etl::ivector& rhs) + { + return !(lhs > rhs); + } + + //*************************************************************************** + /// Greater than or equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexigraphically greater than or equal to the second, otherwise false + ///\ingroup vector + //*************************************************************************** + template + bool operator >=(const etl::ivector& lhs, const etl::ivector& rhs) + { + return !(lhs < rhs); + } +} + +#endif diff --git a/src/jenkins.h b/src/jenkins.h index 7dace164..c9daa4e5 100644 --- a/src/jenkins.h +++ b/src/jenkins.h @@ -39,35 +39,69 @@ SOFTWARE. #include "type_traits.h" #include "error_handler.h" #include "ihash.h" +#include "frame_check_sequence.h" #if defined(ETL_COMPILER_KEIL) -#pragma diag_suppress 1300 +#pragma diag_suppress 1300 #endif -///\defgroup jenkins Jenkins 32 & 64 bit hash calculations +///\defgroup jenkins Jenkins 32 hash calculation ///\ingroup maths namespace etl { //*************************************************************************** - /// Calculates the jenkins hash. - ///\ingroup jenkins + /// Jenkins policy. + /// Calculates 32 bit Jenkins hash. //*************************************************************************** - template - class jenkins + struct jenkins_policy + { + typedef uint32_t value_type; + + inline uint32_t initial() + { + is_finalised = false; + + return 0; + } + + inline uint32_t add(value_type hash, uint8_t value) const + { + ETL_ASSERT(!is_finalised, ETL_ERROR(hash_finalised)); + + hash += value; + hash += (hash << 10); + hash ^= (hash >> 6); + + return hash; + } + + inline uint32_t final(value_type hash) + { + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + is_finalised = true; + + return hash; + } + + bool is_finalised; + }; + + //************************************************************************* + /// jenkins + //************************************************************************* + class jenkins : public etl::frame_check_sequence { public: - STATIC_ASSERT((etl::is_same::value || etl::is_same::value), "Only 32 & 64 bit types supported"); - - typedef THash value_type; - //************************************************************************* /// Default constructor. //************************************************************************* jenkins() { - reset(); + this->reset(); } //************************************************************************* @@ -78,90 +112,9 @@ namespace etl template jenkins(TIterator begin, const TIterator end) { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Incompatible type"); - - reset(); - - while (begin != end) - { - hash += *begin++; - hash += (hash << 10); - hash ^= (hash >> 6); - } + this->reset(); + this->add(begin, end); } - - //************************************************************************* - /// Resets the CRC to the initial state. - //************************************************************************* - void reset() - { - hash = 0; - is_finalised = false; - } - - //************************************************************************* - /// Adds a range. - /// \param begin - /// \param end - //************************************************************************* - template - void add(TIterator begin, const TIterator end) - { - STATIC_ASSERT(sizeof(typename std::iterator_traits::value_type) == 1, "Incompatible type"); - ETL_ASSERT(!is_finalised, ETL_ERROR(hash_finalised)); - - while (begin != end) - { - hash += *begin++; - hash += (hash << 10); - hash ^= (hash >> 6); - } - } - - //************************************************************************* - /// \param value The char to add to the jenkins. - //************************************************************************* - void add(uint8_t value) - { - ETL_ASSERT(!is_finalised, ETL_ERROR(hash_finalised)); - - hash += value; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - //************************************************************************* - /// Gets the jenkins value. - //************************************************************************* - value_type value() - { - finalise(); - return hash; - } - - //************************************************************************* - /// Conversion operator to value_type. - //************************************************************************* - operator value_type () - { - return value(); - } - - private: - - void finalise() - { - if (!is_finalised) - { - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - is_finalised = true; - } - } - - value_type hash; - bool is_finalised; }; } diff --git a/src/largest.h b/src/largest.h index 9eae7abd..bb4ddce9 100644 --- a/src/largest.h +++ b/src/largest.h @@ -38,24 +38,24 @@ SOFTWARE. namespace etl { - //*************************************************************************** - /// Template to determine the largest type and size. + //*************************************************************************** + /// Template to determine the largest type and size. /// Supports up to 16 types. - /// Defines 'value_type' which is the type of the largest parameter. - /// Defines 'size' which is the size of the largest parameter. + /// Defines 'value_type' which is the type of the largest parameter. + /// Defines 'size' which is the size of the largest parameter. ///\ingroup largest - //*************************************************************************** - template - struct largest_type - { - private: + //*************************************************************************** + template + struct largest_type + { + private: // Declaration. - template - struct choose_type; + template + struct choose_type; // Specialisation for 'true'. // Defines 'type' as 'TrueType'. @@ -65,49 +65,49 @@ namespace etl typedef TrueType type; }; - // Specialisation for 'false'. + // Specialisation for 'false'. // Defines 'type' as 'FalseType'. template struct choose_type - { + { typedef FalseType type; - }; + }; - public: + public: - // Define 'largest_other' as 'largest_type' with all but the first parameter. - typedef typename largest_type::type largest_other; + // Define 'largest_other' as 'largest_type' with all but the first parameter. + typedef typename largest_type::type largest_other; - // Set 'type' to be the largest of the first parameter and any of the others. + // Set 'type' to be the largest of the first parameter and any of the others. // This is recursive. typedef typename choose_type<(sizeof(T1) > sizeof(largest_other)), // Boolean - T1, // TrueType - largest_other> // FalseType - ::type type; // The largest type of the two. + T1, // TrueType + largest_other> // FalseType + ::type type; // The largest type of the two. - // The size of the largest type. - enum - { - size = sizeof(type) - }; - }; + // The size of the largest type. + enum + { + size = sizeof(type) + }; + }; //*************************************************************************** - // Specialisation for one template parameter. - //*************************************************************************** - template - struct largest_type - { - typedef T1 type; + // Specialisation for one template parameter. + //*************************************************************************** + template + struct largest_type + { + typedef T1 type; - enum - { - size = sizeof(type) - }; - }; + enum + { + size = sizeof(type) + }; + }; //*************************************************************************** /// Template to determine the largest alignment. diff --git a/src/list.h b/src/list.h index 361d1a87..b85a74b2 100644 --- a/src/list.h +++ b/src/list.h @@ -74,6 +74,14 @@ namespace etl ilist::initialise(); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~list() + { + ilist::initialise(); + } + //************************************************************************* /// Construct from size. //************************************************************************* diff --git a/src/map.h b/src/map.h index 9ec0c71e..b489e1a3 100644 --- a/src/map.h +++ b/src/map.h @@ -72,7 +72,7 @@ namespace etl map(const map& other) : imap(node_pool, MAX_SIZE) { - imap::assign(other.cbegin(), other.cend()); + imap::assign(other.cbegin(), other.cend()); } //************************************************************************* @@ -88,6 +88,14 @@ namespace etl imap::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~map() + { + imap::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 00000000..1e05579e --- /dev/null +++ b/src/memory.h @@ -0,0 +1,667 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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_MEMORY__ +#define __ETL_MEMORY__ + +#include +#include + +#include "type_traits.h" + +///\defgroup memory memory +///\ingroup etl +namespace etl +{ + //***************************************************************************** + /// Gets the address of an object. + ///\ingroup memory + //***************************************************************************** + template + T* addressof(T& t) + { + return reinterpret_cast(&const_cast(reinterpret_cast(t))); + } + + //***************************************************************************** + /// Fills uninitialised memory range with a value. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value) + { + std::fill(o_begin, o_end, value); + + return o_end; + } + + //***************************************************************************** + /// Fills uninitialised memory range with a value. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type(value); + ++o_begin; + } + + return o_end; + } + + //***************************************************************************** + /// Fills uninitialised memory range with a value. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count) + { + count += std::distance(o_begin, o_end); + + std::fill(o_begin, o_end, value); + + return o_end; + } + + //***************************************************************************** + /// Fills uninitialised memory range with a value. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count) + { + count += std::distance(o_begin, o_end); + + etl::uninitialized_fill(o_begin, o_end, value); + + return o_end; + } + + //***************************************************************************** + /// Fills uninitialised memory with N values. + ///\ingroup memory + //***************************************************************************** + template + inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value) + { + return etl::uninitialized_fill(o_begin, o_begin + n, value); + } + + //***************************************************************************** + /// Fills uninitialised memory with N values. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count) + { + count += n; + + return etl::uninitialized_fill(o_begin, o_begin + n, value); + } + + //***************************************************************************** + /// Copies a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin) + { + return std::copy(i_begin, i_end, o_begin); + } + + //***************************************************************************** + /// Copies a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin) + { + typedef typename std::iterator_traits::value_type value_type; + + TOutputIterator o_end = o_begin; + + while (i_begin != i_end) + { + ::new (static_cast(etl::addressof(*o_end))) value_type(*i_begin); + ++i_begin; + ++o_end; + } + + return o_end; + } + + //***************************************************************************** + /// Copies a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count) + { + TOutputIterator o_end = std::copy(i_begin, i_end, o_begin); + count += std::distance(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Copies a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count) + { + TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin); + + count += std::distance(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Copies N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin) + { + return etl::uninitialized_copy(i_begin, i_begin + n, o_begin); + } + + //***************************************************************************** + /// Copies N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count) + { + count += n; + + return etl::uninitialized_copy(i_begin, i_begin + n, o_begin); + } + + //***************************************************************************** + /// Default contruct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + create_default_at(T* /*p*/) + { + } + + //***************************************************************************** + /// Default contruct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + create_default_at(T* /*p*/, TCounter& count) + { + ++count; + } + + //***************************************************************************** + /// Default contruct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + create_default_at(T* p) + { + ::new (p) T; + } + + //***************************************************************************** + /// Default contruct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + create_default_at(T* p, TCounter& count) + { + ::new (p) T; + ++count; + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_default_construct(TOutputIterator /*o_begin*/, TOutputIterator /*o_end*/) + { + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type; + ++o_begin; + } + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count) + { + count = std::distance(o_begin, o_end); + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count) + { + count += std::distance(o_begin, o_end); + + etl::uninitialized_default_construct(o_begin, o_end); + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_default_construct_n(TOutputIterator o_begin, TSize n) + { + TOutputIterator o_end = o_begin + n; + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_default_construct_n(TOutputIterator o_begin, TSize n) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_default_construct(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count) + { + TOutputIterator o_end = o_begin + n; + + count += n; + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TOutputIterator>::type + uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_default_construct(o_begin, o_end); + + count += n; + + return o_end; + } + + //***************************************************************************** + /// Value construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + inline void create_value_at(T* p) + { + ::new (p) T(); + } + + //***************************************************************************** + /// Value construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + inline void create_value_at(T* p, TCounter& count) + { + ::new (p) T(); + ++count; + } + + //***************************************************************************** + /// Copy construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + inline void create_copy_at(T* p, const T& value) + { + ::new (p) T(value); + } + + //***************************************************************************** + /// Copy construct an item at address p. + ///\ingroup memory + //***************************************************************************** + template + inline void create_copy_at(T* p, const T& value, TCounter& count) + { + ::new (p) T(value); + ++count; + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end) + { + typedef typename std::iterator_traits::value_type value_type; + + std::fill(o_begin, o_end, value_type()); + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end) + { + typedef typename std::iterator_traits::value_type value_type; + + while (o_begin != o_end) + { + ::new (static_cast(etl::addressof(*o_begin))) value_type(); + ++o_begin; + } + } + + //***************************************************************************** + /// Default initialises a range of objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count) + { + count += std::distance(o_begin, o_end); + + etl::uninitialized_value_construct(o_begin, o_end); + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_value_construct(o_begin, o_end); + + return o_end; + } + + //***************************************************************************** + /// Default initialises N objects to uninitialised memory. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count) + { + TOutputIterator o_end = o_begin + n; + + etl::uninitialized_value_construct(o_begin, o_end); + + count += n; + + return o_end; + } + + //***************************************************************************** + /// Destroys an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + destroy_at(T* /*p*/) + { + } + + //***************************************************************************** + /// Destroys an item at address p. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + destroy_at(T* p) + { + p->~T(); + } + + //***************************************************************************** + /// Destroys an item at address p. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + destroy_at(T* /*p*/, TCounter& count) + { + --count; + } + + //***************************************************************************** + /// Destroys an item at address p. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value, void>::type + destroy_at(T* p, TCounter& count) + { + p->~T(); + --count; + } + + //***************************************************************************** + /// Destroys a range of items. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + destroy(TIterator /*i_begin*/, TIterator /*i_end*/) + { + } + + //***************************************************************************** + /// Destroys a range of items. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + destroy(TIterator i_begin, TIterator i_end) + { + while (i_begin != i_end) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + } + } + + //***************************************************************************** + /// Destroys a range of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + destroy(TIterator i_begin, TIterator i_end, TCounter& count) + { + count -= std::distance(i_begin, i_end); + } + + //***************************************************************************** + /// Destroys a range of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, void>::type + destroy(TIterator i_begin, TIterator i_end, TCounter& count) + { + count -= std::distance(i_begin, i_end); + + while (i_begin != i_end) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + } + } + + //***************************************************************************** + /// Destroys a number of items. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TIterator>::type + destroy_n(TIterator i_begin, TSize n) + { + return i_begin + n; + } + + //***************************************************************************** + /// Destroys a number of items. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TIterator>::type + destroy_n(TIterator i_begin, TSize n) + { + while (n > 0) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + --n; + } + + return i_begin; + } + + //***************************************************************************** + /// Destroys a number of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TIterator>::type + destroy_n(TIterator i_begin, TSize n, TCounter& count) + { + count -= n; + return i_begin + n; + } + + //***************************************************************************** + /// Destroys a number of items. + /// Debug counter version. + ///\ingroup memory + //***************************************************************************** + template + typename etl::enable_if::value_type>::value, TIterator>::type + destroy_n(TIterator i_begin, TSize n, TCounter& count) + { + count -= n; + + while (n > 0) + { + etl::destroy_at(etl::addressof(*i_begin)); + ++i_begin; + --n; + } + + return i_begin; + } +} + +#endif diff --git a/src/multimap.h b/src/multimap.h index 06658b4b..57299b49 100644 --- a/src/multimap.h +++ b/src/multimap.h @@ -68,7 +68,7 @@ namespace etl //************************************************************************* /// Copy constructor. //************************************************************************* - explicit multimap(const multimap& other) + multimap(const multimap& other) : imultimap(node_pool, MAX_SIZE) { imultimap::assign(other.cbegin(), other.cend()); @@ -87,6 +87,14 @@ namespace etl imultimap::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~multimap() + { + imultimap::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* diff --git a/src/multiset.h b/src/multiset.h index 0668f9a8..e3142a8a 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -68,7 +68,7 @@ namespace etl //************************************************************************* /// Copy constructor. //************************************************************************* - explicit multiset(const multiset& other) + multiset(const multiset& other) : imultiset(node_pool, MAX_SIZE) { imultiset::assign(other.cbegin(), other.cend()); @@ -87,6 +87,14 @@ namespace etl imultiset::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~multiset() + { + imultiset::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* diff --git a/src/nullptr.h b/src/nullptr.h index 84979c79..fb523714 100644 --- a/src/nullptr.h +++ b/src/nullptr.h @@ -37,7 +37,7 @@ SOFTWARE. /// A definition of nullptr for compilers that don't support it as standard. ///\ingroup utilities -#if defined(NO_NULLPTR_SUPPORT) +#if defined(ETL_NO_NULLPTR_SUPPORT) namespace std { //***************************************************************************** diff --git a/src/optional.h b/src/optional.h index 3fb1c47c..7b5a9e5c 100644 --- a/src/optional.h +++ b/src/optional.h @@ -31,6 +31,7 @@ SOFTWARE. #ifndef __ETL_OPTIONAL__ #define __ETL_OPTIONAL__ +#include "platform.h" #include "alignment.h" #include "type_traits.h" #include "exception.h" @@ -128,7 +129,7 @@ namespace etl { if (valid) { - new (storage.template get_address()) T(other.value()); + ::new (storage.template get_address()) T(other.value()); } } @@ -137,7 +138,7 @@ namespace etl //*************************************************************************** optional(const T& value) { - new (storage.template get_address()) T(value); + ::new (storage.template get_address()) T(value); valid = true; } @@ -186,7 +187,7 @@ namespace etl } else { - new (storage.template get_address()) T(other.value()); + ::new (storage.template get_address()) T(other.value()); valid = true; } } @@ -206,7 +207,7 @@ namespace etl } else { - new (storage.template get_address()) T(value); + ::new (storage.template get_address()) T(value); valid = true; } @@ -218,7 +219,7 @@ namespace etl //*************************************************************************** T* operator ->() { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif @@ -230,7 +231,7 @@ namespace etl //*************************************************************************** const T* operator ->() const { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif @@ -242,7 +243,7 @@ namespace etl //*************************************************************************** T& operator *() { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif @@ -254,7 +255,7 @@ namespace etl //*************************************************************************** const T& operator *() const { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif @@ -274,7 +275,7 @@ namespace etl //*************************************************************************** T& value() { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif @@ -286,7 +287,7 @@ namespace etl //*************************************************************************** const T& value() const { -#ifdef _DEBUG +#if defined(ETL_DEBUG) ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); #endif diff --git a/src/pearson.cpp b/src/pearson.cpp index ce4742dd..94c5ec0f 100644 --- a/src/pearson.cpp +++ b/src/pearson.cpp @@ -30,6 +30,11 @@ SOFTWARE. #include +#include "platform.h" +#include "static_assert.h" + +STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); + namespace etl { //*************************************************************************** diff --git a/src/pearson.h b/src/pearson.h index 4952d889..b724f05a 100644 --- a/src/pearson.h +++ b/src/pearson.h @@ -41,6 +41,8 @@ SOFTWARE. #include "array.h" #include "container.h" +STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 1300 #endif diff --git a/src/platform.h b/src/platform.h index 13650550..6382b37c 100644 --- a/src/platform.h +++ b/src/platform.h @@ -28,46 +28,63 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -// Define the platform. -// For FreeRTOS you must define ETL_PLATFORM_FREERTOS in the project settings. -#if defined(__linux__) -#define ETL_PLATFORM_LINUX -#elif defined(WIN32) || defined(WIN64) -#define ETL_PLATFORM_WINDOWS -#elif defined(__VXWORKS__) || defined(_WRS_VXWORKS_MAJOR) -#define ETL_PLATFORM_VXWORKS -#elif defined(__QNX__) || defined(__QNXNTO__) -#define ETL_PLATFORM_QNX -#elif defined(_WIN32_WCE) -#define ETL_PLATFORM_WINDOWS_CE -#else -#define ETL_PLATFORM_GENERIC -#endif +#include +#include // Define the compiler. #if defined(__IAR_SYSTEMS_ICC__) -#define ETL_COMPILER_IAR + #define ETL_COMPILER_IAR #elif defined(__KEIL__) && !defined(__GNUC__) -#define ETL_COMPILER_KEIL + #define ETL_COMPILER_KEIL #elif defined(__ghs__) -#define ETL_COMPILER_GREEN_HILLS + #define ETL_COMPILER_GREEN_HILLS #elif defined(__INTEL_COMPILER) -#define ETL_COMPILER_INTEL + #define ETL_COMPILER_INTEL #elif defined(_MSC_VER) -#define ETL_COMPILER_MICROSOFT + #define ETL_COMPILER_MICROSOFT #elif defined(__GNUC__) -#define ETL_COMPILER_GCC + #define ETL_COMPILER_GCC #elif defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) -#define ETL_COMPILER_TI_MSP430 + #define ETL_COMPILER_TI_MSP430 +#elif defined(_MRI) + #define ETL_COMPILER_MICROTEC +#elif defined(__HIGHC__) + #define ETL_COMPILER_METAWARE_HIGH +#elif defined(__llvm__) + #define ETL_COMPILER_LLVM +#elif defined(__KCC_VERSION) + #define ETL_COMPILER_KAI +#elif defined(_COMO__) + #define ETL_COMPILER_COMEAU +#elif defined(__BORLANDC__) + #define ETL_COMPILER_BORLAND +#elif defined(__CC_ARM) + #define ETL_COMPILER_ARM +#elif defined(__MRC__) + #define ETL_COMPILER_MPW #else -#define ETL_COMPILER_GENERIC + #define ETL_COMPILER_GENERIC #endif +// Check to see if the compiler supports nullptr and large character types. #if (defined(ETL_COMPILER_MICROSOFT) && (_MSC_VER < 1600)) || \ defined(ETL_COMPILER_KEIL) || \ defined(ETL_COMPILER_TI_MSP430) || \ defined(ETL_COMPILER_IAR) || \ (defined(ETL_COMPILER_GCC) && (__cplusplus < 201103L)) -#define NO_NULLPTR_SUPPORT -#define NO_LARGE_CHAR_SUPPORT + #define ETL_NO_NULLPTR_SUPPORT + #define ETL_NO_LARGE_CHAR_SUPPORT #endif + +// Check to see if the compiler supports static_assert. +#if (defined(ETL_COMPILER_MICROSOFT) && (_MSC_VER >= 1600)) || \ + (defined(ETL_COMPILER_GCC) && (__cplusplus >= 201103L)) +#define ETL_STATIC_ASSERT_SUPPORTED +#endif + +// Some targets do not support 8bit types. +#define ETL_8BIT_SUPPORT (CHAR_BIT == 8) + +#if defined(_DEBUG) || defined(DEBUG) + #define ETL_DEBUG +#endif \ No newline at end of file diff --git a/src/pool.h b/src/pool.h index eb98e2ec..52eb8446 100644 --- a/src/pool.h +++ b/src/pool.h @@ -33,10 +33,12 @@ SOFTWARE. #include "alignment.h" #include "array.h" -#include "bitset.h" +#include "container.h" +#include "integral_limits.h" #include "ipool.h" #include +#include //***************************************************************************** ///\defgroup pool pool @@ -51,7 +53,7 @@ namespace etl ///\ingroup pool //************************************************************************* template - class pool : public ipool + class pool : public ipool { public: @@ -61,25 +63,29 @@ namespace etl /// Constructor //************************************************************************* pool() - : ipool(reinterpret_cast(&buffer[0]), in_use, SIZE) + : ipool(reinterpret_cast(&buffer[0]), ELEMENT_SIZE, SIZE) { } - //************************************************************************* - /// Destructor - //************************************************************************* ~pool() { - ipool::release_all(); + } private: - ///< The memory for the pool of objects. - typename etl::aligned_storage::value>::type buffer[SIZE]; + // The pool element. + union Element + { + uint32_t next; ///< Index of the next free element. + char value[sizeof(T)]; ///< Storage for value type. + typename etl::type_with_alignment::value>::type dummy; ///< Dummy item to get correct alignment. + }; - ///< The set of flags that indicate which items are free in the pool. - bitset in_use; + ///< The memory for the pool of objects. + typename etl::aligned_storage::value>::type buffer[SIZE]; + + static const uint32_t ELEMENT_SIZE = sizeof(Element); // Should not be copied. pool(const pool&); diff --git a/src/private/deque_base.h b/src/private/deque_base.h index 79755433..cd6fe64e 100644 --- a/src/private/deque_base.h +++ b/src/private/deque_base.h @@ -39,6 +39,7 @@ SOFTWARE. #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "1" @@ -168,9 +169,10 @@ namespace etl { } - 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. + 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. + etl::debug_count construct_count; ///< Internal debugging. }; } diff --git a/src/private/flat_map_base.h b/src/private/flat_map_base.h index 16fd8587..420ad2a9 100644 --- a/src/private/flat_map_base.h +++ b/src/private/flat_map_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "2" @@ -98,71 +99,9 @@ namespace etl 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; + etl::debug_count construct_count; ///< Internal debugging. }; } diff --git a/src/private/flat_multimap_base.h b/src/private/flat_multimap_base.h index eb9840f2..3b65031c 100644 --- a/src/private/flat_multimap_base.h +++ b/src/private/flat_multimap_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "3" @@ -84,71 +85,9 @@ namespace etl 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; + etl::debug_count construct_count; }; } diff --git a/src/private/flat_multiset_base.h b/src/private/flat_multiset_base.h index 4b495ddf..b2408b15 100644 --- a/src/private/flat_multiset_base.h +++ b/src/private/flat_multiset_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "4" @@ -84,71 +85,18 @@ namespace etl 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: protected: + etl::debug_count construct_count; + //************************************************************************* /// Constructor. //************************************************************************* - flat_multiset_base(vector_base& vbase) - : vbase(vbase) + flat_multiset_base() { } - - vector_base& vbase; }; } diff --git a/src/private/flat_set_base.h b/src/private/flat_set_base.h index 22d1c58f..33deaf5a 100644 --- a/src/private/flat_set_base.h +++ b/src/private/flat_set_base.h @@ -38,8 +38,8 @@ SOFTWARE. #include #include "../exception.h" -#include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "5" @@ -98,71 +98,9 @@ namespace etl 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; + etl::debug_count construct_count; }; } diff --git a/src/private/forward_list_base.h b/src/private/forward_list_base.h index d11fd82e..9364a9b7 100644 --- a/src/private/forward_list_base.h +++ b/src/private/forward_list_base.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "6" @@ -111,14 +112,14 @@ namespace etl //************************************************************************* /// The node element in the forward_list. //************************************************************************* - struct Node + struct node_t { - Node() + node_t() : next(nullptr) { } - Node* next; + node_t* next; }; public: @@ -130,7 +131,7 @@ namespace etl //************************************************************************* size_type size() const { - return current_size; + return p_node_pool->size(); } //************************************************************************* @@ -146,7 +147,7 @@ namespace etl //************************************************************************* bool empty() const { - return current_size == 0; + return p_node_pool->empty(); } //************************************************************************* @@ -154,7 +155,7 @@ namespace etl //************************************************************************* bool full() const { - return current_size == MAX_SIZE; + return p_node_pool->full(); } //************************************************************************* @@ -163,7 +164,7 @@ namespace etl //************************************************************************* size_t available() const { - return max_size() - size(); + return p_node_pool->available(); } //************************************************************************* @@ -176,9 +177,9 @@ namespace etl return; } - Node* p_last = &start_node; - Node* p_current = p_last->next; - Node* p_next = p_current->next; + node_t* p_last = &start_node; + node_t* p_current = p_last->next; + node_t* p_next = p_current->next; p_current->next = nullptr; @@ -199,9 +200,8 @@ namespace etl //************************************************************************* /// The constructor that is called from derived classes. //************************************************************************* - forward_list_base(size_type max_size) - : next_free(0), - current_size(0), + forward_list_base(etl::ipool& node_pool, size_type max_size) + : p_node_pool(&node_pool), MAX_SIZE(max_size) { } @@ -209,7 +209,7 @@ namespace etl //************************************************************************* /// Get the head node. //************************************************************************* - Node& get_head() + node_t& get_head() { return *start_node.next; } @@ -217,7 +217,7 @@ namespace etl //************************************************************************* /// Get the head node. //************************************************************************* - const Node& get_head() const + const node_t& get_head() const { return *start_node.next; } @@ -225,17 +225,13 @@ namespace etl //************************************************************************* /// Insert a node. //************************************************************************* - void insert_node_after(Node& position, Node& node) + inline void insert_node_after(node_t& position, node_t& node) { // Connect to the forward_list. - node.next = position.next; - + join(&node, position.next); join(&position, &node); - - // One more. - ++current_size; } - + //************************************************************************* /// Is the forward_list a trivial length? //************************************************************************* @@ -247,15 +243,15 @@ namespace etl //************************************************************************* /// Join two nodes. //************************************************************************* - void join(Node* left, Node* right) + void join(node_t* left, node_t* 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. + node_t start_node; ///< The node that acts as the forward_list start. + etl::ipool* p_node_pool; ///< The pool of data nodes used in the list. + const size_type MAX_SIZE; ///< The maximum size of the forward_list. + etl::debug_count construct_count; ///< Internal debugging. }; } diff --git a/src/private/ivectorpointer.h b/src/private/ivectorpointer.h index e8bc9462..da1ae67b 100644 --- a/src/private/ivectorpointer.h +++ b/src/private/ivectorpointer.h @@ -312,7 +312,7 @@ namespace etl while (first != last) { - p_buffer[current_size++] = (void*)*first++; + *p_end++ = (void*)*first++; } } @@ -456,7 +456,7 @@ namespace etl template bool operator ==(const etl::ivector& lhs, const etl::ivector& rhs) { - return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + return pvoidvector_equal(lhs, rhs); } //*************************************************************************** @@ -469,7 +469,7 @@ namespace etl template bool operator !=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs == rhs); + return pvoidvector_not_equal(lhs, rhs); } //*************************************************************************** @@ -482,7 +482,7 @@ namespace etl template bool operator <(const etl::ivector& lhs, const etl::ivector& rhs) { - return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + return pvoidvector_less_than(lhs, rhs); } //*************************************************************************** @@ -495,7 +495,7 @@ namespace etl template bool operator >(const etl::ivector& lhs, const etl::ivector& rhs) { - return (rhs < lhs); + return pvoidvector_greater_than(lhs, rhs); } //*************************************************************************** @@ -508,7 +508,7 @@ namespace etl template bool operator <=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs > rhs); + return pvoidvector_less_than_equal(lhs, rhs); } //*************************************************************************** @@ -521,7 +521,40 @@ namespace etl template bool operator >=(const etl::ivector& lhs, const etl::ivector& rhs) { - return !(lhs < rhs); + return pvoidvector_greater_than_equal(lhs, rhs); + } + + //*************************************************************************** + // Helper functions + //*************************************************************************** + inline bool pvoidvector_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator ==(lhs, rhs); + } + + inline bool pvoidvector_not_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator !=(lhs, rhs); + } + + inline bool pvoidvector_less_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator <(lhs, rhs); + } + + inline bool pvoidvector_greater_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator >(lhs, rhs); + } + + inline bool pvoidvector_less_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator <=(lhs, rhs); + } + + inline bool pvoidvector_greater_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return operator >=(lhs, rhs); } } diff --git a/src/private/list_base.h b/src/private/list_base.h index 1b363a4b..2b3ca1e1 100644 --- a/src/private/list_base.h +++ b/src/private/list_base.h @@ -36,8 +36,10 @@ SOFTWARE. #define __ETL_LIST_BASE__ #include +#include "pool.h" #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "7" @@ -141,7 +143,7 @@ namespace etl //*********************************************************************** /// Reverses the previous & next pointers. //*********************************************************************** - void reverse() + inline void reverse() { std::swap(previous, next); } @@ -163,21 +165,18 @@ namespace etl node_t* 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. + { + node_t* p_temp = p_node->previous; + p_node->previous = p_node->next; + p_node->next = p_temp; + p_node = p_node->previous; } // Terminal node. - p_node->reverse(); - } - - //************************************************************************* - /// Gets the size of the list. - //************************************************************************* - size_type size() const - { - return current_size; + node_t* p_temp = p_node->previous; + p_node->previous = p_node->next; + p_node->next = p_temp; + p_node = p_node->previous; } //************************************************************************* @@ -188,12 +187,20 @@ namespace etl return MAX_SIZE; } + //************************************************************************* + /// Gets the size of the list. + //************************************************************************* + size_type size() const + { + return p_node_pool->size(); + } + //************************************************************************* /// Checks to see if the list is empty. //************************************************************************* bool empty() const { - return current_size == 0; + return p_node_pool->empty(); } //************************************************************************* @@ -201,7 +208,7 @@ namespace etl //************************************************************************* bool full() const { - return current_size == MAX_SIZE; + return p_node_pool->size() == MAX_SIZE; } //************************************************************************* @@ -213,6 +220,15 @@ namespace etl return max_size() - size(); } + //************************************************************************* + /// Is the list a trivial length? + //************************************************************************* + bool is_trivial_list() const + { + return (size() < 2); + } + + protected: //************************************************************************* @@ -255,17 +271,6 @@ namespace etl // 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); } //************************************************************************* @@ -280,17 +285,18 @@ namespace etl //************************************************************************* /// The constructor that is called from derived classes. //************************************************************************* - list_base(size_type max_size) - : current_size(0), + list_base(etl::ipool& node_pool, + size_type max_size) + : p_node_pool(&node_pool), MAX_SIZE(max_size) { } - - node_t 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. + etl::ipool* p_node_pool; ///< The pool of data nodes used in the list. + node_t terminal_node; ///< The node that acts as the list start and end. + const size_type MAX_SIZE; ///< The maximum size of the list. + etl::debug_count construct_count; ///< Internal debugging. }; } diff --git a/src/private/map_base.h b/src/private/map_base.h index 539554a1..d10df500 100644 --- a/src/private/map_base.h +++ b/src/private/map_base.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "8" @@ -178,25 +179,30 @@ namespace etl /// Constructor //*********************************************************************** Node() : - weight(kNeither), - dir(kNeither) + weight(uint_least8_t(kNeither)), + dir(uint_least8_t(kNeither)) { } + ~Node() + { + + } + //*********************************************************************** /// Marks the node as a leaf. //*********************************************************************** void mark_as_leaf() { - weight = kNeither; - dir = kNeither; + weight = uint_least8_t(kNeither); + dir = uint_least8_t(kNeither); children[0] = nullptr; children[1] = nullptr; } Node* children[2]; - uint8_t weight; - uint8_t dir; + uint_least8_t weight; + uint_least8_t dir; }; //************************************************************************* @@ -222,12 +228,12 @@ namespace etl while (weight_node) { // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) + if (uint_least8_t(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; + weight_node->weight = uint_least8_t(kNeither); } else { @@ -245,14 +251,14 @@ namespace etl } // while(weight_node) // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) + if (uint_least8_t(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; + critical_node->weight = uint_least8_t(kNeither); } // Rotate is required to balance the tree at the critical node else @@ -276,7 +282,7 @@ namespace etl //************************************************************************* /// Rotate two nodes at the position provided the to balance the tree //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) + void rotate_2node(Node*& position, uint_least8_t dir) { // A C A B // B C -> A E OR B C -> D A @@ -296,17 +302,17 @@ namespace etl // New root now becomes parent of current position new_root->children[1 - dir] = position; // Clear weight factor from current position - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); // Newly detached right now becomes current position position = new_root; // Clear weight factor from new root - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); } //************************************************************************* /// Rotate three nodes at the position provided the to balance the tree //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third) { // __A__ __E__ __A__ __D__ // _B_ C -> B A OR B _C_ -> A C @@ -323,7 +329,7 @@ namespace etl // 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; + position->children[dir]->weight = third != uint_least8_t(kNeither) && third != dir ? dir : uint_least8_t(kNeither); // Detach new root from its tree (replace with new roots child) position->children[dir]->children[1 - dir] = @@ -331,7 +337,7 @@ namespace etl // 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; + position->weight = third != uint_least8_t(kNeither) && third == dir ? 1 - dir : uint_least8_t(kNeither); // Move new root's right tree to current roots left tree position->children[dir] = new_root->children[1 - dir]; @@ -340,7 +346,7 @@ namespace etl // Replace current position with new root position = new_root; // Clear weight factor for new current position - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); } //************************************************************************* @@ -419,6 +425,7 @@ namespace etl 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. + etl::debug_count construct_count; }; } diff --git a/src/private/multimap_base.h b/src/private/multimap_base.h index 02b85f94..845d6241 100644 --- a/src/private/multimap_base.h +++ b/src/private/multimap_base.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "9" @@ -162,9 +163,9 @@ namespace etl protected: - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; + static const uint_least8_t kLeft = 0; + static const uint_least8_t kRight = 1; + static const uint_least8_t kNeither = 2; //************************************************************************* /// The node element in the multimap. @@ -194,8 +195,8 @@ namespace etl Node* parent; Node* children[2]; - uint8_t weight; - uint8_t dir; + uint_least8_t weight; + uint_least8_t dir; }; //************************************************************************* @@ -275,7 +276,7 @@ namespace etl //************************************************************************* /// Rotate two nodes at the position provided the to balance the tree //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) + void rotate_2node(Node*& position, uint_least8_t dir) { // A C A B // B C -> A E OR B C -> D A @@ -316,7 +317,7 @@ namespace etl //************************************************************************* /// Rotate three nodes at the position provided the to balance the tree //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third) { // __A__ __E__ __A__ __D__ // _B_ C -> B A OR B _C_ -> A C @@ -580,6 +581,7 @@ namespace etl 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. + etl::debug_count construct_count; }; } diff --git a/src/private/multiset_base.h b/src/private/multiset_base.h index 5b9a1d36..d7573d65 100644 --- a/src/private/multiset_base.h +++ b/src/private/multiset_base.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "10" @@ -162,9 +163,9 @@ namespace etl protected: - static const uint8_t kLeft = 0; - static const uint8_t kRight = 1; - static const uint8_t kNeither = 2; + static const uint_least8_t kLeft = 0; + static const uint_least8_t kRight = 1; + static const uint_least8_t kNeither = 2; //************************************************************************* /// The node element in the multiset. @@ -194,8 +195,8 @@ namespace etl Node* parent; Node* children[2]; - uint8_t weight; - uint8_t dir; + uint_least8_t weight; + uint_least8_t dir; }; //************************************************************************* @@ -482,7 +483,7 @@ namespace etl //************************************************************************* /// Rotate two nodes at the position provided the to balance the tree //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) + void rotate_2node(Node*& position, uint_least8_t dir) { // A C A B // B C -> A E OR B C -> D A @@ -523,7 +524,7 @@ namespace etl //************************************************************************* /// Rotate three nodes at the position provided the to balance the tree //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third) { // __A__ __E__ __A__ __D__ // _B_ C -> B A OR B _C_ -> A C @@ -579,6 +580,7 @@ namespace etl 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. + etl::debug_count construct_count; }; } diff --git a/src/private/pool_base.h b/src/private/pool_base.h deleted file mode 100644 index 7a358166..00000000 --- a/src/private/pool_base.h +++ /dev/null @@ -1,159 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -http://www.etlcpp.com - -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" -#include "../error_handler.h" -#include "../error_handler.h" - -#undef ETL_FILE -#define ETL_FILE "11" - -namespace etl -{ - //*************************************************************************** - /// The base class for pool exceptions. - ///\ingroup pool - //*************************************************************************** - class pool_exception : public exception - { - public: - - pool_exception(string_type what, string_type file_name, numeric_type line_number) - : exception(what, file_name, line_number) - {} - }; - - //*************************************************************************** - /// The exception thrown when the pool has no more free items. - ///\ingroup pool - //*************************************************************************** - class pool_no_allocation : public pool_exception - { - public: - - explicit pool_no_allocation(string_type file_name, numeric_type line_number) - : pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_FILE"A"), file_name, line_number) - {} - }; - - //*************************************************************************** - /// 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(string_type file_name, numeric_type line_number) - : pool_exception(ETL_ERROR_TEXT("pool:notinpool", ETL_FILE"B"), file_name, line_number) - {} - }; - - //************************************************************************* - /// The base class for all templated pool types. - ///\ingroup pool - //************************************************************************* - class pool_base - { - public: - - //************************************************************************* - /// Returns the maximum number of items in the pool. - //************************************************************************* - size_t max_size() const - { - return MAX_SIZE; - } - - //************************************************************************* - /// Returns the number of free items in the pool. - //************************************************************************* - size_t available() const - { - return MAX_SIZE - items_allocated; - } - - //************************************************************************* - /// Returns the number of allocated items in the pool. - //************************************************************************* - size_t size() const - { - return items_allocated; - } - - //************************************************************************* - /// Checks to see if there are no allocated items in the pool. - /// \return true if there are none allocated. - //************************************************************************* - bool empty() const - { - return items_allocated == 0; - } - - //************************************************************************* - /// Checks to see if there are no free items in the pool. - /// \return true if there are none free. - //************************************************************************* - bool full() 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. - }; -} - -#undef ETL_FILE - -#endif - diff --git a/src/private/pvoidvector.cpp b/src/private/pvoidvector.cpp new file mode 100644 index 00000000..6b74805d --- /dev/null +++ b/src/private/pvoidvector.cpp @@ -0,0 +1,107 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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. +******************************************************************************/ + +#include "pvoidvector.h" + +namespace etl +{ + //*************************************************************************** + /// Equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the arrays are equal, otherwise false + ///\ingroup vector + //*************************************************************************** + bool operator ==(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + //*************************************************************************** + /// Not equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the arrays are not equal, otherwise false + ///\ingroup vector + //*************************************************************************** + bool operator !=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// Less than operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically less than the second, otherwise false + ///\ingroup vector + //*************************************************************************** + inline bool operator <(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + //*************************************************************************** + /// Greater than operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically greater than the second, otherwise false + ///\ingroup vector + //*************************************************************************** + bool operator >(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return (rhs < lhs); + } + + //*************************************************************************** + /// Less than or equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically less than or equal to the second, otherwise false + ///\ingroup vector + //*************************************************************************** + bool operator <=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return !(lhs > rhs); + } + + //*************************************************************************** + /// Greater than or equal operator. + ///\param lhs Reference to the first vector. + ///\param rhs Reference to the second vector. + ///\return true if the first vector is lexicographically greater than or equal to the second, otherwise false + ///\ingroup vector + //*************************************************************************** + bool operator >=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs) + { + return !(lhs < rhs); + } +} + diff --git a/src/private/pvoidvector.h b/src/private/pvoidvector.h index 67fdd4ef..77ba1721 100644 --- a/src/private/pvoidvector.h +++ b/src/private/pvoidvector.h @@ -82,7 +82,7 @@ namespace etl //********************************************************************* iterator begin() { - return &p_buffer[0]; + return p_buffer; } //********************************************************************* @@ -91,7 +91,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return const_iterator(&p_buffer[0]); + return const_iterator(p_buffer); } //********************************************************************* @@ -100,7 +100,7 @@ namespace etl //********************************************************************* iterator end() { - return &p_buffer[current_size]; + return p_end; } //********************************************************************* @@ -109,7 +109,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return const_iterator(&p_buffer[current_size]); + return const_iterator(p_end); } //********************************************************************* @@ -118,7 +118,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return const_iterator(&p_buffer[0]); + return const_iterator(p_buffer); } //********************************************************************* @@ -127,7 +127,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return const_iterator(&p_buffer[current_size]); + return const_iterator(p_end); } //********************************************************************* @@ -194,7 +194,7 @@ namespace etl { ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full)); - current_size = new_size; + p_end = p_buffer + new_size; } //********************************************************************* @@ -208,13 +208,15 @@ namespace etl { ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full)); + pointer p_new_end = p_buffer + new_size; + // Size up if necessary. - while (current_size < new_size) + if (p_end < p_new_end) { - p_buffer[current_size++] = value; + std::fill(p_end, p_new_end, value); } - current_size = new_size; + p_end = p_new_end; } //********************************************************************* @@ -245,7 +247,7 @@ namespace etl //********************************************************************* reference at(size_t i) { - ETL_ASSERT(i < current_size, ETL_ERROR(vector_out_of_bounds)); + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); return p_buffer[i]; } @@ -257,7 +259,7 @@ namespace etl //********************************************************************* const_reference at(size_t i) const { - ETL_ASSERT(i < current_size, ETL_ERROR(vector_out_of_bounds)); + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); return const_reference(p_buffer[i]); } @@ -285,7 +287,7 @@ namespace etl //********************************************************************* reference back() { - return p_buffer[current_size - 1]; + return *(p_end -1); } //********************************************************************* @@ -294,7 +296,7 @@ namespace etl //********************************************************************* const_reference back() const { - return const_reference(p_buffer[current_size - 1]); + return const_reference(*(p_end - 1)); } //********************************************************************* @@ -325,7 +327,7 @@ namespace etl template void assign(TIterator first, TIterator last) { -#ifdef _DEBUG +#if defined(ETL_DEBUG) difference_type count = std::distance(first, last); ETL_ASSERT(static_cast(count) <= MAX_SIZE, ETL_ERROR(vector_full)); #endif @@ -334,7 +336,7 @@ namespace etl while (first != last) { - p_buffer[current_size++] = const_cast(*first++); + *p_end++ = const_cast(*first++); } } @@ -352,7 +354,7 @@ namespace etl for (size_t current_size = 0; current_size < n; ++current_size) { - p_buffer[current_size] = value; + *p_end++ = value; } } @@ -371,10 +373,10 @@ namespace etl void push_back() { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size != MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full)); #endif - ++current_size; + ++p_end; } //********************************************************************* @@ -385,9 +387,9 @@ namespace etl void push_back(value_type value) { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size != MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full)); #endif - p_buffer[current_size++] = value; + *p_end++ = value; } //************************************************************************* @@ -397,9 +399,9 @@ namespace etl void pop_back() { #if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(current_size > 0, ETL_ERROR(vector_empty)); + ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty)); #endif - --current_size; + --p_end; } //********************************************************************* @@ -410,17 +412,17 @@ namespace etl //********************************************************************* iterator insert(iterator position, value_type value) { - ETL_ASSERT((current_size)+1 <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT(size() + 1 <= MAX_SIZE, ETL_ERROR(vector_full)); if (position != end()) { - ++current_size; + ++p_end; std::copy_backward(position, end() - 1, end()); *position = value; } else { - p_buffer[current_size++] = value; + *p_end++ = value; } return position; @@ -435,53 +437,12 @@ namespace etl //********************************************************************* void insert(iterator position, size_t n, value_type value) { - ETL_ASSERT((current_size)+1 <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT((size() + 1) <= MAX_SIZE, ETL_ERROR(vector_full)); - if (position == end()) - { - while (n > 0) - { - p_buffer[current_size++] = value; - --n; - } - } - else - { - // Create copy (backwards). - size_t n_insert = n; - size_t from = size() - 1; - size_t to = from + n_insert; - size_t n_move = std::distance(position, end()); - size_t n_create_copy = std::min(n_insert, n_move); + std::copy_backward(position, p_end, p_end + n); + std::fill_n(position, n, value); - for (size_t i = 0; i < n_create_copy; ++i) - { - p_buffer[to--] = p_buffer[from--]; - } - - // Copy old. - size_t insert_index = std::distance(begin(), position); - from = insert_index; - to = from + n_insert; - size_t n_copy_old = (size() > n_insert) ? size() - n_insert : 0; - etl::copy_n(&p_buffer[from], n_copy_old, &p_buffer[to]); - - // Copy new. - to = insert_index; - - size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0; - size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0; - std::fill_n(&p_buffer[to], n_copy_new, value); - - // Create new. - to = size(); - for (size_t i = 0; i < n_create_new; ++i) - { - p_buffer[to++] = value; - } - - current_size += n_insert; - } + p_end += n; } //********************************************************************* @@ -497,52 +458,11 @@ namespace etl { size_t count = std::distance(first, last); - ETL_ASSERT((current_size)+count <= MAX_SIZE, ETL_ERROR(vector_full)); + ETL_ASSERT((size() + count) <= MAX_SIZE, ETL_ERROR(vector_full)); - if (position == end()) - { - while (first != last) - { - p_buffer[current_size++] = *first++; - } - } - else - { - size_t insert_index = std::distance(begin(), position); - size_t n_insert = count; - - // Create copy (backwards). - size_t from = size() - 1; - size_t to = from + n_insert; - size_t n_move = std::distance(position, end()); - size_t n_create_copy = std::min(n_insert, n_move); - for (size_t i = 0; i < n_create_copy; ++i) - { - p_buffer[to--] = p_buffer[from--]; - } - - // Copy old. - from = insert_index; - to = from + n_insert; - size_t n_copy_old = (size() > n_insert) ? size() - n_insert : 0; - etl::copy_n(&p_buffer[from], n_copy_old, &p_buffer[to]); - - // Copy new. - to = insert_index; - size_t n_create_new = (n_insert > n_create_copy) ? n_insert - n_create_copy : 0; - size_t n_copy_new = (n_insert > n_create_new) ? n_insert - n_create_new : 0; - etl::copy_n(first, n_copy_new, &p_buffer[to]); - first += n_copy_new; - - // Create new. - to = size(); - for (size_t i = 0; i < n_create_new; ++i) - { - p_buffer[to++] = *first++; - } - - current_size += n_insert; - } + std::copy_backward(position, p_end, p_end + count); + std::copy(first, last, position); + p_end += count; } //********************************************************************* @@ -553,7 +473,7 @@ namespace etl iterator erase(iterator i_element) { std::copy(i_element + 1, end(), i_element); - --current_size; + --p_end; return i_element; } @@ -572,7 +492,7 @@ namespace etl size_t n_delete = std::distance(first, last); // Just adjust the count. - current_size -= n_delete; + p_end -= n_delete; return first; } @@ -590,14 +510,51 @@ namespace etl return *this; } + //************************************************************************* + /// Gets the current size of the vector. + ///\return The current size of the vector. + //************************************************************************* + size_type size() const + { + return size_t(p_end - p_buffer); + } + + //************************************************************************* + /// Checks the 'empty' state of the vector. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return (p_end == p_buffer); + } + + //************************************************************************* + /// Checks the 'full' state of the vector. + ///\return true if full. + //************************************************************************* + bool full() const + { + return size() == MAX_SIZE; + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return max_size() - size(); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - pvoidvector(void** p_buffer, size_t MAX_SIZE) + pvoidvector(void** p_buffer_, size_t MAX_SIZE) : vector_base(MAX_SIZE), - p_buffer(p_buffer) + p_buffer(p_buffer_), + p_end(p_buffer_) { } @@ -606,16 +563,31 @@ namespace etl //********************************************************************* void initialise() { - current_size = 0; + p_end = p_buffer; } void** p_buffer; + void** p_end; private: // Disable copy construction. pvoidvector(const pvoidvector&); }; + + bool pvoidvector_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_not_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_less_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_greater_than(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_less_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool pvoidvector_greater_than_equal(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + + bool operator ==(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator !=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator <(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator >(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator <=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); + bool operator >=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs); } #ifdef ETL_COMPILER_MICROSOFT diff --git a/src/private/queue_base.h b/src/private/queue_base.h index c7a0aadc..78627097 100644 --- a/src/private/queue_base.h +++ b/src/private/queue_base.h @@ -39,6 +39,7 @@ SOFTWARE. #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "13" @@ -153,10 +154,11 @@ namespace etl { } - 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. + 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. + etl::debug_count construct_count; ///< For internal debugging purposes. }; } diff --git a/src/private/set_base.h b/src/private/set_base.h index 32a72c2f..0fa929dd 100644 --- a/src/private/set_base.h +++ b/src/private/set_base.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #define ETL_FILE "14" @@ -194,8 +195,8 @@ namespace etl } Node* children[2]; - uint8_t weight; - uint8_t dir; + uint_least8_t weight; + uint_least8_t dir; }; //************************************************************************* @@ -260,12 +261,12 @@ namespace etl while (weight_node) { // Keep going until we reach a terminal node (dir == kNeither) - if (kNeither != weight_node->dir) + if (uint_least8_t(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; + weight_node->weight = uint_least8_t(kNeither); } else { @@ -283,14 +284,14 @@ namespace etl } // while(weight_node) // Step 2: Update weight for critical_node or rotate tree to balance node - if (kNeither == critical_node->weight) + if (uint_least8_t(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; + critical_node->weight = uint_least8_t(kNeither); } // Rotate is required to balance the tree at the critical node else @@ -348,7 +349,7 @@ namespace etl //************************************************************************* /// Rotate two nodes at the position provided the to balance the tree //************************************************************************* - void rotate_2node(Node*& position, uint8_t dir) + void rotate_2node(Node*& position, uint_least8_t dir) { // A C A B // B C -> A E OR B C -> D A @@ -368,17 +369,17 @@ namespace etl // New root now becomes parent of current position new_root->children[1 - dir] = position; // Clear weight factor from current position - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); // Newly detached right now becomes current position position = new_root; // Clear weight factor from new root - position->weight = kNeither; + position->weight = uint_least8_t(kNeither); } //************************************************************************* /// Rotate three nodes at the position provided the to balance the tree //************************************************************************* - void rotate_3node(Node*& position, uint8_t dir, uint8_t third) + void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third) { // __A__ __E__ __A__ __D__ // _B_ C -> B A OR B _C_ -> A C @@ -395,7 +396,7 @@ namespace etl // 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; + position->children[dir]->weight = third != uint_least8_t(kNeither) && third != dir ? dir : uint_least8_t(kNeither); // Detach new root from its tree (replace with new roots child) position->children[dir]->children[1 - dir] = @@ -403,7 +404,7 @@ namespace etl // 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; + position->weight = third != uint_least8_t(kNeither) && third == dir ? 1 - dir : uint_least8_t(kNeither); // Move new root's right tree to current roots left tree position->children[dir] = new_root->children[1 - dir]; @@ -412,13 +413,14 @@ namespace etl // Replace current position with new root position = new_root; // Clear weight factor for new current position - position->weight = kNeither; + position->weight = uint_least8_t(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. + etl::debug_count construct_count; }; } diff --git a/src/private/stack_base.h b/src/private/stack_base.h index e3e6c556..60807a30 100644 --- a/src/private/stack_base.h +++ b/src/private/stack_base.h @@ -39,6 +39,7 @@ SOFTWARE. #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #define ETL_FILE "15" @@ -152,9 +153,10 @@ namespace etl { } - 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. + 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. + etl::debug_count construct_count; ///< For internal debugging purposes. }; } diff --git a/src/private/string_base.h b/src/private/string_base.h index f3e84212..98f15131 100644 --- a/src/private/string_base.h +++ b/src/private/string_base.h @@ -42,7 +42,7 @@ SOFTWARE. #include "../exception.h" #include "../error_handler.h" -#define ETL_FILE "24" +#define ETL_FILE "27" #ifdef ETL_COMPILER_MICROSOFT #undef max @@ -116,7 +116,10 @@ namespace etl typedef size_t size_type; - static const size_t npos = etl::integral_limits::max; + enum + { + npos = etl::integral_limits::max + }; //************************************************************************* /// Gets the current size of the string. diff --git a/src/private/vector_base.h b/src/private/vector_base.h index 4c78b41b..44fb0673 100644 --- a/src/private/vector_base.h +++ b/src/private/vector_base.h @@ -39,6 +39,7 @@ SOFTWARE. #include "../exception.h" #include "../error_handler.h" +#include "../debug_count.h" #define ETL_FILE "17" @@ -110,33 +111,6 @@ namespace etl 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. @@ -155,28 +129,18 @@ namespace etl 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) + : MAX_SIZE(max_size) { } - size_type current_size; ///(this); + uint32_t seed = static_cast(n); + initialise(seed); + } + + //*************************************************************************** + /// Constructor with seed value. + ///\param seed The new seed value. + //*************************************************************************** + random_xorshift::random_xorshift(uint32_t seed) + { + initialise(seed); + } + + //*************************************************************************** + /// Initialises the sequence with a new seed value. + ///\param seed The new seed value. + //*************************************************************************** + void random_xorshift::initialise(uint32_t seed) + { + // Add the first four primes to ensure that the seed isn't zero. + state[0] = seed + 3; + state[1] = seed + 5; + state[2] = seed + 7; + state[3] = seed + 11; + } + + //*************************************************************************** + /// Get the next random_xorshift number. + //*************************************************************************** + uint32_t random_xorshift::operator()() + { + uint32_t n = state[3]; + n ^= n << 11; + n ^= n >> 8; + state[3] = state[2]; + state[2] = state[1]; + state[1] = state[0]; + n ^= state[0]; + n ^= state[0] >> 19; + state[0] = n; + + return n; + } +} \ No newline at end of file diff --git a/src/random.h b/src/random.h new file mode 100644 index 00000000..f85ca167 --- /dev/null +++ b/src/random.h @@ -0,0 +1,72 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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_RANDOM__ +#define __ETL_RANDOM__ + +#include + +namespace etl +{ + //*************************************************************************** + /// The base for all 32 bit random number generators. + //*************************************************************************** + class random + { + public: + + virtual ~random() + { + } + + virtual uint32_t operator()() = 0; + }; + + //*************************************************************************** + /// A 32 bit random number generator. + /// Uses a 128 bit XOR shift algorithm. + /// https://en.wikipedia.org/wiki/Xorshift + //*************************************************************************** + class random_xorshift : public random + { + public: + + random_xorshift(); + random_xorshift(uint32_t seed); + void initialise(uint32_t seed); + uint32_t operator()(); + + private: + + uint32_t state[4]; + }; +} + +#endif \ No newline at end of file diff --git a/src/ratio.h b/src/ratio.h new file mode 100644 index 00000000..c0f03436 --- /dev/null +++ b/src/ratio.h @@ -0,0 +1,94 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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_RATIO__ +#define __ETL_RATIO__ + +#include + +///\defgroup ratio ratio +///\ingroup utilities + +namespace etl +{ + template + struct ratio + { + static const std::intmax_t num = NUM; + static const std::intmax_t den = DEN; + }; + + #if INT_MAX > INT32_MAX + typedef ratio<1, 1000000000000000000000000> yocto; + typedef ratio<1, 1000000000000000000000> zepto; + typedef ratio<1, 1000000000000000000> atto + typedef ratio<1, 1000000000000000> femto + typedef ratio<1, 1000000000000> pico; + #endif + + #if (INT_MAX >= INT32_MAX) + typedef ratio<1, 1000000000> nano; + typedef ratio<1, 1000000> micro; + #endif + + #if (INT_MAX >= INT16_MAX) + typedef ratio<1, 1000> milli; + typedef ratio<1, 100> centi; + typedef ratio<1, 10> deci; + typedef ratio<10, 1> deca; + typedef ratio<100, 1> hecto + typedef ratio<1000, 1> kilo + #endif + + #if (INT_MAX >= INT32_MAX) + typedef ratio<1000000, 1> mega; + typedef ratio<1000000000, 1> giga; + #endif + + #if INT_MAX > INT32_MAX + typedef ratio<1000000000000, 1> tera; + typedef ratio<1000000000000000, 1> peta; + typedef ratio<1000000000000000000, 1> exa; + typedef ratio<1000000000000000000000, 1> zetta; + typedef ratio<1000000000000000000000000, 1> yotta; + #endif + + /// An approximation of PI to 6 digits. + typedef ratio<355, 113> ratio_pi; + + /// An approximation of root 2. + typedef ratio<239, 169> ratio_root2; + + /// An approximation of e. + typedef ratio<326, 120> ratio_e; +} + +#endif + diff --git a/src/set.h b/src/set.h index 3fb2ec2f..785be240 100644 --- a/src/set.h +++ b/src/set.h @@ -69,7 +69,7 @@ namespace etl //************************************************************************* /// Copy constructor. //************************************************************************* - explicit set(const set& other) + set(const set& other) : iset(node_pool, MAX_SIZE) { iset::assign(other.cbegin(), other.cend()); @@ -88,6 +88,14 @@ namespace etl iset::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~set() + { + iset::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* diff --git a/src/smallest.h b/src/smallest.h index 6419c607..d3a4b947 100644 --- a/src/smallest.h +++ b/src/smallest.h @@ -154,6 +154,48 @@ namespace etl { typedef uint_least64_t type; }; + + //************************************************************************* + // Determine the type to hold the number of bits based on the index. + //************************************************************************* + template + struct best_fit_int_type; + + //************************************************************************* + // Less than or equal to 8 bits. + //************************************************************************* + template <> + struct best_fit_int_type<0> + { + typedef int_least8_t type; + }; + + //************************************************************************* + // 9 to 16 bits. + //************************************************************************* + template <> + struct best_fit_int_type<1> + { + typedef int_least16_t type; + }; + + //************************************************************************* + // 17 to 31 bits. + //************************************************************************* + template <> + struct best_fit_int_type<2> + { + typedef int_least32_t type; + }; + + //************************************************************************* + // Greater than 32 bits. + //************************************************************************* + template <> + struct best_fit_int_type<3> + { + typedef int_least64_t type; + }; } //*************************************************************************** @@ -168,12 +210,77 @@ namespace etl private: // Determines the index of the best unsigned type for the required number of bits. - static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) + ((NBITS > 16) ? 1 : 0) + ((NBITS > 32) ? 1 : 0); + static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) + + ((NBITS > 16) ? 1 : 0) + + ((NBITS > 32) ? 1 : 0); public: typedef typename __private_smallest__::best_fit_uint_type::type type; }; + + //*************************************************************************** + /// Template to determine the smallest signed int type that can contain a + /// value with the specified number of bits. + /// Defines 'type' which is the type of the smallest signed integer. + ///\ingroup smallest + //*************************************************************************** + template + struct smallest_int_for_bits + { + private: + + // Determines the index of the best unsigned type for the required number of bits. + static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) + + ((NBITS > 16) ? 1 : 0) + + ((NBITS > 32) ? 1 : 0); + + public: + + typedef typename __private_smallest__::best_fit_int_type::type type; + }; + + //*************************************************************************** + /// Template to determine the smallest unsigned int type that can contain the + /// specified unsigned value. + /// Defines 'type' which is the type of the smallest unsigned integer. + ///\ingroup smallest + //*************************************************************************** + template + struct smallest_uint_for_value + { + private: + + // Determines the index of the best unsigned type for the required value. + static const int TYPE_INDEX = ((VALUE > UINT8_MAX) ? 1 : 0) + + ((VALUE > UINT16_MAX) ? 1 : 0) + + ((VALUE > UINT32_MAX) ? 1 : 0); + + public: + + typedef typename __private_smallest__::best_fit_uint_type::type type; + }; + + //*************************************************************************** + /// Template to determine the smallest int type that can contain the + /// specified signed value. + /// Defines 'type' which is the type of the smallest signed integer. + ///\ingroup smallest + //*************************************************************************** + template + struct smallest_int_for_value + { + private: + + // Determines the index of the best signed type for the required value. + static const int TYPE_INDEX = (((VALUE > INT8_MAX) || (VALUE < INT8_MIN)) ? 1 : 0) + + (((VALUE > INT16_MAX) || (VALUE < INT16_MIN)) ? 1 : 0) + + (((VALUE > INT32_MAX) || (VALUE < INT32_MIN)) ? 1 : 0); + + public: + + typedef typename __private_smallest__::best_fit_int_type::type type; + }; } #endif diff --git a/src/static_assert.h b/src/static_assert.h index 575b9c2b..ced509aa 100644 --- a/src/static_assert.h +++ b/src/static_assert.h @@ -31,9 +31,7 @@ SOFTWARE. #include "platform.h" -#if defined(ETL_COMPILER_MICROSOFT) - #define STATIC_ASSERT(Condition, Message) static_assert(Condition, Message) -#elif defined(ETL_COMPILER_GCC) +#if defined(ETL_STATIC_ASSERT_SUPPORTED) #define STATIC_ASSERT(Condition, Message) static_assert(Condition, Message) #else template @@ -42,12 +40,13 @@ SOFTWARE. template <> struct STATIC_ASSERT_FAILED {}; - #define ETL_FCAT(a,b) a##b - #define ETL_ACAT(a,b) ETL_FCAT(a,b) - #define STATIC_ASSERT(cond,msg) \ - enum \ - { ETL_ACAT(dummy,__LINE__)=sizeof(STATIC_ASSERT_FAILED<(bool)(cond)>) \ - } + #define ETL_SA1(a,b) a##b + #define ETL_SA2(a,b) ETL_SA1(a,b) + #define STATIC_ASSERT(Condition, Message) \ + enum \ + { \ + ETL_SA2(dummy, __LINE__) = sizeof(STATIC_ASSERT_FAILED<(bool)(Condition)>) \ + } #endif #endif diff --git a/src/type_def.h b/src/type_def.h index 66d6156e..e35257b1 100644 --- a/src/type_def.h +++ b/src/type_def.h @@ -41,7 +41,7 @@ namespace etl ///\code /// // Short form. /// ETL_TYPEDEF(int, mytype); - /// + /// /// // Long form. /// class mytype_t_tag; /// typedef etl::type_def mytype_t_tag; @@ -243,7 +243,13 @@ namespace etl } //********************************************************************* - TValue get() const + TValue& get() + { + return value; + } + + //********************************************************************* + const TValue& get() const { return value; } diff --git a/src/type_traits.h b/src/type_traits.h index bef809ae..8d08e219 100644 --- a/src/type_traits.h +++ b/src/type_traits.h @@ -232,6 +232,32 @@ namespace etl template struct is_reference : false_type {}; template struct is_reference : true_type {}; + /// is_pod + /// For C++03, only fundamental and pointers types are recognised. + ///\ingroup type_traits + template struct is_pod : etl::integral_constant::value || + etl::is_pointer::value> {}; + + /// has_trivial_constructor + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct has_trivial_constructor : etl::is_pod {}; + + /// has_trivial_copy_constructor + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct has_trivial_copy_constructor : etl::is_pod {}; + + /// has_trivial_destructor + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct has_trivial_destructor : etl::is_pod {}; + + /// has_trivial_assignment + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct has_trivial_assignment : etl::is_pod {}; + /// conditional ///\ingroup type_traits template struct conditional { typedef T type; }; @@ -242,19 +268,16 @@ namespace etl template struct make_signed { typedef T type; }; template <> struct make_signed { typedef signed char type; }; template <> struct make_signed { typedef signed char type; }; -#if defined(ETL_COMPILER_GCC) + template <> struct make_signed { - typedef wchar_t type; + typedef typename etl::conditional::type>::type type; }; -#else - template <> struct make_signed - { - typedef etl::conditional::type>::type>::type type; - }; -#endif + template <> struct make_signed { typedef short type; }; template <> struct make_signed { typedef int type; }; template <> struct make_signed { typedef long type; }; @@ -269,19 +292,16 @@ namespace etl template <> struct make_unsigned { typedef unsigned char type; }; template <> struct make_unsigned { typedef unsigned char type; }; template <> struct make_unsigned { typedef unsigned short type; }; -#if defined(ETL_COMPILER_GCC) && !defined(ETL_PLATFORM_LINUX) + template <> struct make_unsigned { - typedef wchar_t type; + typedef typename etl::conditional::type>::type type; }; -#else - template <> struct make_unsigned - { - typedef etl::conditional::type>::type>::type type; - }; -#endif + template <> struct make_unsigned { typedef unsigned int type; }; template <> struct make_unsigned { typedef unsigned long type; }; template <> struct make_unsigned { typedef unsigned long long type; }; diff --git a/src/u16string.h b/src/u16string.h index a7ca2b57..95766d2b 100644 --- a/src/u16string.h +++ b/src/u16string.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" #include "basic_string.h" +#include "hash.h" #if defined(ETL_COMPILER_MICROSOFT) #undef min @@ -180,6 +181,19 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; + + //************************************************************************* + /// Hash function. + //************************************************************************* + template <> + struct hash + { + size_t operator()(const etl::iu16string& text) const + { + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); + } + }; } #if defined(ETL_COMPILER_MICROSOFT) diff --git a/src/u32string.h b/src/u32string.h index 5890f1c7..4493acad 100644 --- a/src/u32string.h +++ b/src/u32string.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" #include "basic_string.h" +#include "hash.h" #if defined(ETL_COMPILER_MICROSOFT) #undef min @@ -180,6 +181,19 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; + + //************************************************************************* + /// Hash function. + //************************************************************************* + template <> + struct hash + { + size_t operator()(const etl::iu32string& text) const + { + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); + } + }; } #if defined(ETL_COMPILER_MICROSOFT) diff --git a/src/unordered_map.h b/src/unordered_map.h index e4c1f1ea..dcc34abf 100644 --- a/src/unordered_map.h +++ b/src/unordered_map.h @@ -38,7 +38,7 @@ SOFTWARE. #include "iunordered_map.h" #include "container.h" #include "pool.h" -#include "vector.h" +#include "array.h" #include "intrusive_forward_list.h" #include "hash.h" @@ -53,7 +53,7 @@ namespace etl //************************************************************************* /// A templated unordered_map implementation that uses a fixed size buffer. //************************************************************************* - template , typename TKeyEqual = std::equal_to > + template , typename TKeyEqual = std::equal_to > class unordered_map : public iunordered_map { private: @@ -62,13 +62,14 @@ namespace etl public: - static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_BUCKETS = MAX_BUCKETS_; //************************************************************************* /// Default constructor. //************************************************************************* unordered_map() - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS_) { base::initialise(); } @@ -77,9 +78,9 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_map(const unordered_map& other) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS_) { - base::assign(other.cbegin(), other.cend()); + base::assign(other.cbegin(), other.cend()); } //************************************************************************* @@ -90,11 +91,19 @@ namespace etl //************************************************************************* template unordered_map(TIterator first, TIterator last) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS_) { base::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~unordered_map() + { + base::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -115,7 +124,7 @@ namespace etl etl::pool node_pool; /// The buckets of node lists. - etl::vector, MAX_SIZE> buckets; + etl::intrusive_forward_list buckets[MAX_BUCKETS_]; }; } diff --git a/src/unordered_multimap.h b/src/unordered_multimap.h index 14746fee..6c264bee 100644 --- a/src/unordered_multimap.h +++ b/src/unordered_multimap.h @@ -53,7 +53,7 @@ namespace etl //************************************************************************* /// A templated unordered_multimap implementation that uses a fixed size buffer. //************************************************************************* - template , typename TKeyEqual = std::equal_to > + template , typename TKeyEqual = std::equal_to > class unordered_multimap : public iunordered_multimap { private: @@ -62,13 +62,14 @@ namespace etl public: - static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_BUCKETS = MAX_BUCKETS_; //************************************************************************* /// Default constructor. //************************************************************************* unordered_multimap() - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::initialise(); } @@ -77,7 +78,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_multimap(const unordered_multimap& other) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(other.cbegin(), other.cend()); } @@ -90,11 +91,19 @@ namespace etl //************************************************************************* template unordered_multimap(TIterator first, TIterator last) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~unordered_multimap() + { + base::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -115,7 +124,7 @@ namespace etl etl::pool node_pool; /// The buckets of node lists. - etl::vector, MAX_SIZE> buckets; + etl::intrusive_forward_list buckets[MAX_BUCKETS_]; }; } diff --git a/src/unordered_multiset.h b/src/unordered_multiset.h index c4e1ce37..f061b1ae 100644 --- a/src/unordered_multiset.h +++ b/src/unordered_multiset.h @@ -53,7 +53,7 @@ namespace etl //************************************************************************* /// A templated unordered_multiset implementation that uses a fixed size buffer. //************************************************************************* - template , typename TKeyEqual = std::equal_to > + template , typename TKeyEqual = std::equal_to > class unordered_multiset : public iunordered_multiset { private: @@ -63,12 +63,14 @@ namespace etl public: static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_BUCKETS = MAX_BUCKETS_; + //************************************************************************* /// Default constructor. //************************************************************************* unordered_multiset() - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::initialise(); } @@ -77,7 +79,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_multiset(const unordered_multiset& other) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(other.cbegin(), other.cend()); } @@ -90,11 +92,19 @@ namespace etl //************************************************************************* template unordered_multiset(TIterator first, TIterator last) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~unordered_multiset() + { + base::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -115,7 +125,7 @@ namespace etl etl::pool node_pool; /// The buckets of node lists. - etl::vector, MAX_SIZE> buckets; + etl::intrusive_forward_list buckets[MAX_BUCKETS_]; }; } diff --git a/src/unordered_set.h b/src/unordered_set.h index e9171566..ac5912e3 100644 --- a/src/unordered_set.h +++ b/src/unordered_set.h @@ -53,7 +53,7 @@ namespace etl //************************************************************************* /// A templated unordered_set implementation that uses a fixed size buffer. //************************************************************************* - template , typename TKeyEqual = std::equal_to > + template , typename TKeyEqual = std::equal_to > class unordered_set : public iunordered_set { private: @@ -62,13 +62,14 @@ namespace etl public: - static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_SIZE = MAX_SIZE_; + static const size_t MAX_BUCKETS = MAX_BUCKETS_; //************************************************************************* /// Default constructor. //************************************************************************* unordered_set() - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::initialise(); } @@ -77,7 +78,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_set(const unordered_set& other) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(other.cbegin(), other.cend()); } @@ -90,11 +91,19 @@ namespace etl //************************************************************************* template unordered_set(TIterator first, TIterator last) - : base(node_pool, buckets) + : base(node_pool, buckets, MAX_BUCKETS) { base::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~unordered_set() + { + base::initialise(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -115,7 +124,7 @@ namespace etl etl::pool node_pool; /// The buckets of node lists. - etl::vector, MAX_SIZE> buckets; + etl::intrusive_forward_list buckets[MAX_BUCKETS_]; }; } diff --git a/src/user_type.h b/src/user_type.h new file mode 100644 index 00000000..482efeeb --- /dev/null +++ b/src/user_type.h @@ -0,0 +1,150 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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_USER_TYPE__ +#define __ETL_USER_TYPE__ + +///\defgroup user_type user_type +/// Smart enumerations.
+/// A method of declaring a user type that also contains a set of constants, +/// but are not constrained to just those values. +/// This contrasts with 'enum_type', where the values are expected to only contain +/// those defined as constants. +/// Declaring the enumeration. +///\code +/// ETL_DECLARE_USER_TYPE(CompassDirection, int) +/// ETL_USER_TYPE(North, 0) +/// ETL_USER_TYPE(South, 180) +/// ETL_USER_TYPE(East, 90) +/// ETL_USER_TYPE(West, 270) +/// ETL_END_USER_TYPE(CompassDirection) +///\endcode +/// Using the enumeration. +///\code +/// CompassDirection direction; // Default construction. +/// +/// direction = CompassDirection::North; // Assignment from an enumeration constant; +/// +/// int value = int(direction); // Explicit conversion to 'int'. +/// int value = direction.get(); +/// +/// int& value = direction.get(); // Bind to internal value. +/// const int& value = direction.get(); +/// +/// direction = CompassDirection(value); // Explicit conversion from 'int'. +/// +/// direction = CompassDirection(3); // Explicit conversion from a value. +/// +/// ++direction; // Manipulate the value; +/// direction -= CompassDirection(20); +/// +/// direction = value; // Implicit conversion from 'int'. **** Compilation error **** +/// +///\endcode +///\ingroup utilities + +//***************************************************************************** +// The declaration of the structure. +//***************************************************************************** +#define ETL_DECLARE_USER_TYPE(TypeName, ValueType) \ + struct TypeName \ + { \ + /* Non-volatile definitions.*/ \ + typedef ValueType value_type; \ + TypeName() {} \ + TypeName(const TypeName &other) : value(other.value) {} \ + TypeName& operator=(const TypeName &other) { value = other.value; return *this; } \ + explicit TypeName(ValueType value) : value(value) {} \ + explicit operator ValueType() const { return value; } \ + ValueType& get() { return value; } \ + const ValueType& get() const { return value; } \ + TypeName& operator ++() { ++value; return *this; } \ + TypeName operator ++(int) { TypeName temp(*this); TypeName::operator ++(); return temp; } \ + TypeName& operator --() { --value; return *this; } \ + TypeName operator --(int) { TypeName temp(*this); TypeName::operator --(); return temp; } \ + TypeName& operator +=(const TypeName& rhs) { value += rhs.value; return *this; } \ + TypeName& operator -=(const TypeName& rhs) { value -= rhs.value; return *this; } \ + TypeName& operator *=(const TypeName& rhs) { value *= rhs.value; return *this; } \ + TypeName& operator /=(const TypeName& rhs) { value /= rhs.value; return *this; } \ + TypeName& operator %=(const TypeName& rhs) { value %= rhs.value; return *this; } \ + TypeName& operator &=(const TypeName& rhs) { value &= rhs.value; return *this; } \ + TypeName& operator &=(ValueType mask) { value &= mask; return *this; } \ + TypeName& operator |=(const TypeName& rhs) { value |= rhs.value; return *this; } \ + TypeName& operator |=(ValueType mask) { value &= mask; return *this; } \ + TypeName& operator ^=(const TypeName& rhs) { value ^= rhs.value; return *this; } \ + TypeName& operator ^=(ValueType mask) { value ^= mask; return *this; } \ + TypeName& operator <<=(ValueType distance) { value <<= distance; return *this; } \ + TypeName& operator >>=(ValueType distance) { value >>= distance; return *this; } \ + \ + /* Volatile definitions.*/ \ + TypeName(const volatile TypeName &other) : value(other.value) {} \ + void operator=(const volatile TypeName &other) volatile { value = other.value; } \ + explicit operator ValueType() volatile const { return value; } \ + volatile ValueType& get() volatile { return value; } \ + const volatile ValueType& get() volatile const { return value; } \ + void operator ++() volatile { ++value; } \ + volatile TypeName operator ++(int) volatile { volatile TypeName temp(*this); TypeName::operator ++(); return temp; } \ + void operator --() volatile { --value; } \ + volatile TypeName operator --(int) volatile { volatile TypeName temp(*this); TypeName::operator --(); return temp; } \ + void operator +=(const volatile TypeName& rhs) volatile { value += rhs.value; } \ + void operator -=(const volatile TypeName& rhs) volatile { value -= rhs.value; } \ + void operator *=(const volatile TypeName& rhs) volatile { value *= rhs.value; } \ + void operator /=(const volatile TypeName& rhs) volatile { value /= rhs.value; } \ + void operator %=(const volatile TypeName& rhs) volatile { value %= rhs.value; } \ + void operator &=(const volatile TypeName& rhs) volatile { value &= rhs.value; } \ + void operator &=(ValueType mask) volatile { value &= mask; } \ + void operator |=(const volatile TypeName& rhs) volatile { value |= rhs.value; } \ + void operator |=(ValueType mask) volatile { value &= mask; } \ + void operator ^=(const volatile TypeName& rhs) volatile { value ^= rhs.value; } \ + void operator ^=(ValueType mask) volatile { value ^= mask; } \ + void operator <<=(ValueType distance) volatile { value <<= distance; } \ + void operator >>=(ValueType distance) volatile { value >>= distance; } \ + private: \ + ValueType value; \ + public: \ + enum enum_type \ + { + +//***************************************************************************** +// The predefined constants. +//***************************************************************************** +#define ETL_USER_TYPE(enum_name, value) \ + enum_name = value, + +//***************************************************************************** +// The final section of the structure. +//***************************************************************************** +#define ETL_END_USER_TYPE(TypeName) \ + }; \ + TypeName(enum_type value) : value(static_cast(value)) {} \ + }; + + +#endif diff --git a/src/utility.h b/src/utility.h new file mode 100644 index 00000000..81a27a17 --- /dev/null +++ b/src/utility.h @@ -0,0 +1,74 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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_UTILITY__ +#define __ETL_UTILITY__ + +#include "type_traits.h" + +///\defgroup utility utility +///\ingroup utilities + +namespace etl +{ + //*************************************************************************** + /// exchange + //*************************************************************************** + template + T exchange(T& object, U& new_value) + { + T old_value = object; + object = new_value; + return old_value; + } + + //*************************************************************************** + /// exchange (const) + //*************************************************************************** + template + T exchange(T& object, const U& new_value) + { + T old_value = object; + object = new_value; + return old_value; + } + + //*************************************************************************** + /// as_const + //*************************************************************************** + template + typename etl::add_const::type& as_const(T& t) + { + return t; + } +} + +#endif + diff --git a/src/variant.h b/src/variant.h index 2e8522ec..6b2931eb 100644 --- a/src/variant.h +++ b/src/variant.h @@ -46,7 +46,7 @@ SOFTWARE. #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 940 - #pragma diag_suppress 111 + #pragma diag_suppress 111 #endif #undef ETL_FILE @@ -132,7 +132,7 @@ namespace etl //*************************************************************************** /// The type used for ids. //*************************************************************************** - typedef uint8_t type_id_t; + typedef uint_least8_t type_id_t; //*************************************************************************** /// The id a unsupported types. @@ -196,15 +196,15 @@ namespace etl template struct Type_Id_Lookup { - static const uint8_t type_id = etl::is_same::value ? 0 : - etl::is_same::value ? 1 : - etl::is_same::value ? 2 : - etl::is_same::value ? 3 : - etl::is_same::value ? 4 : - etl::is_same::value ? 5 : - etl::is_same::value ? 6 : - etl::is_same::value ? 7 : - UNSUPPORTED_TYPE_ID; + static const uint_least8_t type_id = etl::is_same::value ? 0 : + etl::is_same::value ? 1 : + etl::is_same::value ? 2 : + etl::is_same::value ? 3 : + etl::is_same::value ? 4 : + etl::is_same::value ? 5 : + etl::is_same::value ? 6 : + etl::is_same::value ? 7 : + UNSUPPORTED_TYPE_ID; }; //*************************************************************************** @@ -225,6 +225,14 @@ namespace etl public: + //*************************************************************************** + /// Destructor. + //*************************************************************************** + ~variant() + { + destruct_current(); + } + //************************************************************************* //**** Reader types ******************************************************* //************************************************************************* @@ -424,7 +432,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -440,7 +448,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -465,7 +473,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -480,7 +488,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -504,7 +512,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -518,7 +526,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -541,7 +549,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -554,7 +562,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -576,7 +584,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -588,7 +596,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -609,7 +617,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -620,7 +628,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -640,7 +648,7 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { switch (typeId) { @@ -650,7 +658,7 @@ namespace etl } } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { switch (typeId) { @@ -669,12 +677,12 @@ namespace etl { public: - TBase& operator()(uint8_t* p_data, uint8_t typeId) + TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) { return reinterpret_cast(*p_data); } - const TBase& operator()(uint8_t* p_data, uint8_t typeId) const + const TBase& operator()(uint_least8_t* p_data, uint_least8_t typeId) const { return reinterpret_cast(*p_data); } @@ -703,7 +711,7 @@ namespace etl { STATIC_ASSERT(Type_Is_Supported::value, "Unsupported type"); - new(static_cast(data)) T(value); + ::new (static_cast(data)) T(value); type_id = Type_Id_Lookup::type_id; } @@ -712,9 +720,21 @@ namespace etl ///\param other The other variant object to copy. //*************************************************************************** variant(const variant& other) - : data(other.data), - type_id(other.type_id) { + switch (other.type_id) + { + case 0: ::new (static_cast(data)) T1(other.get()); break; + case 1: ::new (static_cast(data)) T2(other.get()); break; + case 2: ::new (static_cast(data)) T3(other.get()); break; + case 3: ::new (static_cast(data)) T4(other.get()); break; + case 4: ::new (static_cast(data)) T5(other.get()); break; + case 5: ::new (static_cast(data)) T6(other.get()); break; + case 6: ::new (static_cast(data)) T7(other.get()); break; + case 7: ::new (static_cast(data)) T8(other.get()); break; + default: break; + } + + type_id = other.type_id; } //*************************************************************************** @@ -726,18 +746,37 @@ namespace etl { STATIC_ASSERT(Type_Is_Supported::value, "Unsupported type"); - // Assigning the same type as last time? - if (type_id == Type_Id_Lookup::type_id) + destruct_current(); + ::new (static_cast(data)) T(value); + type_id = Type_Id_Lookup::type_id; + + return *this; + } + + //*************************************************************************** + /// Assignment operator for variant type. + ///\param other The variant to assign. + //*************************************************************************** + variant& operator =(const variant& other) + { + if (this != &other) { - // Do a simple copy. - *static_cast(data) = value; - } - else - { - // We must destruct the old type, as the new one is different. destruct_current(); - new(static_cast(data)) T(value); - type_id = Type_Id_Lookup::type_id; + + switch (other.type_id) + { + case 0: ::new (static_cast(data)) T1(other.get()); break; + case 1: ::new (static_cast(data)) T2(other.get()); break; + case 2: ::new (static_cast(data)) T3(other.get()); break; + case 3: ::new (static_cast(data)) T4(other.get()); break; + case 4: ::new (static_cast(data)) T5(other.get()); break; + case 5: ::new (static_cast(data)) T6(other.get()); break; + case 6: ::new (static_cast(data)) T7(other.get()); break; + case 7: ::new (static_cast(data)) T8(other.get()); break; + default: break; + } + + type_id = other.type_id; } return *this; @@ -915,6 +954,8 @@ namespace etl case 7: { static_cast(data)->~T8(); break; } default: { break; } } + + type_id = UNSUPPORTED_TYPE_ID; } //*************************************************************************** diff --git a/src/vector.h b/src/vector.h index 86a4998e..06c45d89 100644 --- a/src/vector.h +++ b/src/vector.h @@ -115,6 +115,14 @@ namespace etl ivector::assign(other.begin(), other.end()); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~vector() + { + ivector::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* diff --git a/src/wstring.h b/src/wstring.h index 8019a29f..6633173c 100644 --- a/src/wstring.h +++ b/src/wstring.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" #include "basic_string.h" +#include "hash.h" #if defined(ETL_COMPILER_MICROSOFT) #undef min @@ -181,6 +182,19 @@ namespace etl value_type buffer[MAX_SIZE + 1]; }; + + //************************************************************************* + /// Hash function. + //************************************************************************* + template <> + struct hash + { + size_t operator()(const etl::iwstring& text) const + { + return etl::__private_hash__::generic_hash<>(reinterpret_cast(&text[0]), + reinterpret_cast(&text[text.size()])); + } + }; } #if defined(ETL_COMPILER_MICROSOFT) diff --git a/test/Performance/unordered_map/unordered_map.sln b/test/Performance/unordered_map/unordered_map.sln new file mode 100644 index 00000000..b7f0b842 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_map", "unordered_map\unordered_map.vcxproj", "{AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Debug|x64.ActiveCfg = Debug|x64 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Debug|x64.Build.0 = Debug|x64 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Debug|x86.ActiveCfg = Debug|Win32 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Debug|x86.Build.0 = Debug|Win32 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Release|x64.ActiveCfg = Release|x64 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Release|x64.Build.0 = Release|x64 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Release|x86.ActiveCfg = Release|Win32 + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test/Performance/unordered_map/unordered_map/ReadMe.txt b/test/Performance/unordered_map/unordered_map/ReadMe.txt new file mode 100644 index 00000000..bc20f9d5 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : unordered_map Project Overview +======================================================================== + +AppWizard has created this unordered_map application for you. + +This file contains a summary of what you will find in each of the files that +make up your unordered_map application. + + +unordered_map.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +unordered_map.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +unordered_map.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named unordered_map.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/test/Performance/unordered_map/unordered_map/stdafx.cpp b/test/Performance/unordered_map/unordered_map/stdafx.cpp new file mode 100644 index 00000000..291c2903 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// unordered_map.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test/Performance/unordered_map/unordered_map/stdafx.h b/test/Performance/unordered_map/unordered_map/stdafx.h new file mode 100644 index 00000000..b005a839 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/test/Performance/unordered_map/unordered_map/targetver.h b/test/Performance/unordered_map/unordered_map/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/test/Performance/unordered_map/unordered_map/unordered_map.cpp b/test/Performance/unordered_map/unordered_map/unordered_map.cpp new file mode 100644 index 00000000..3c996e63 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/unordered_map.cpp @@ -0,0 +1,82 @@ +// unordered_map.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include +#include + +#include +#include "../../../../src/unordered_map.h" + +LARGE_INTEGER frequency; +LARGE_INTEGER begin; + +void StartTimer() +{ + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&begin); + + frequency.QuadPart /= 1000; +} + +uint64_t StopTimer() +{ + LARGE_INTEGER end; + + QueryPerformanceCounter(&end); + + return (end.QuadPart - begin.QuadPart) / frequency.QuadPart; +} + +const size_t TESTSIZE = 10000000; +const size_t TESTINTERATIONS = 16; + +typedef std::unordered_map Stdmap; +typedef etl::unordered_map Etlmap; + +Stdmap stdmap; +Etlmap etlmap; + +int main() +{ + StartTimer(); + + for (size_t i = 0; i < TESTINTERATIONS; ++i) + { + for (size_t j = 0; j < TESTSIZE; ++j) + { + std::pair ok = stdmap.insert(std::make_pair(uint64_t(j), uint16_t(j))); + } + + for (size_t j = 0; j < TESTSIZE; ++j) + { + stdmap.erase(j); + } + } + + uint64_t time; + + time = StopTimer(); + std::cout << "STD Time = " << time << "ms\n"; + + StartTimer(); + + for (size_t i = 0; i < TESTINTERATIONS; ++i) + { + for (size_t j = 0; j < TESTSIZE; ++j) + { + std::pair ok = etlmap.insert(std::make_pair(uint64_t(j), uint16_t(j))); + } + + for (size_t j = 0; j < TESTSIZE; ++j) + { + etlmap.erase(j); + } + } + + time = StopTimer(); + std::cout << "ETL Time = " << time << "ms\n"; + + return 0; +} + diff --git a/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj b/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj new file mode 100644 index 00000000..a400bbf4 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {AA7F5179-0617-49EC-B6AC-8D71A64D8DC6} + Win32Proj + unordered_map + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ../../../../src;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + true + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj.filters b/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj.filters new file mode 100644 index 00000000..66f299a8 --- /dev/null +++ b/test/Performance/unordered_map/unordered_map/unordered_map.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index 7f58fb61..d8bab481 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -19,6 +19,9 @@ + + + @@ -84,6 +87,8 @@ + + @@ -100,6 +105,7 @@ + @@ -114,6 +120,7 @@ + @@ -132,8 +139,10 @@ + + @@ -172,6 +181,8 @@ + + @@ -183,6 +194,7 @@ + @@ -202,6 +214,7 @@ + @@ -215,14 +228,19 @@ + + + + + @@ -239,6 +257,7 @@ + @@ -259,6 +278,8 @@ + + @@ -278,13 +299,20 @@ + + + + + + + diff --git a/test/codeblocks/ETL.depend b/test/codeblocks/ETL.depend index 22211a47..e5a50fcf 100644 --- a/test/codeblocks/ETL.depend +++ b/test/codeblocks/ETL.depend @@ -2,7 +2,7 @@ 1424729709 source:u:\users\john\documents\programming\github\etl\crc16.cpp -1427746630 +1481841066 1424729709 source:u:\users\john\documents\programming\github\etl\crc16_ccitt.cpp @@ -19,12 +19,12 @@ 1424729709 source:u:\users\john\documents\programming\github\etl\test\main.cpp -1414173716 +/UnitTest++.h> +1452692153 +/UnitTest++.h> 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\unittest++.h "UnitTestPP.h" -1414845610 P.h" +1447740690 P.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\unittestpp.h "Config.h" @@ -34,7 +34,7 @@ "TimeConstraint.h" "ReportAssert.h" -1414845610 ert.h" +1447740690 ert.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\config.h @@ -48,7 +48,7 @@ "MemoryOutStream.h" "Posix/SignalTranslator.h" -1414845610 nalTranslator.h" +1447740690 nalTranslator.h" 1416833496 u:\users\john\documents\programming\github\unittest-cpp\unittest++\testsuite.h @@ -69,7 +69,7 @@ 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\testdetails.h "HelperMacros.h" -1414845610 ros.h" +1447740690 ros.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\helpermacros.h "Config.h" @@ -88,7 +88,7 @@ "HelperMacros.h" -1427741862 > +1482076051 > 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\currenttest.h "HelperMacros.h" @@ -112,26 +112,26 @@ "CurrentTest.h" "ReportAssertImpl.h" -1414927690 ertImpl.h" +1447740690 ertImpl.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.h "Config.h" "TestResults.h" "MemoryOutStream.h" -1414845610 Stream.h" +1447740690 Stream.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\testrunner.h "Test.h" "TestList.h" "CurrentTest.h" -1414845610 st.h" +1447740690 st.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\test.h "TestDetails.h" -1414845610 ls.h" +1447740690 ls.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\testlist.h "HelperMacros.h" @@ -145,18 +145,18 @@ "Posix/TimeHelpers.h" "Win32/TimeHelpers.h" -1414845610 eHelpers.h" +1447740690 eHelpers.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\timehelpers.h -1414845610 h> +1447740690 h> 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\win32\timehelpers.h "../Config.h" "../HelperMacros.h" -1414845610 Macros.h" +1447740690 Macros.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassert.h "HelperMacros.h" @@ -169,7 +169,7 @@ "../integral_limits.h" -1424729709 al_limits.h" +1452516033 al_limits.h" 1424729709 u:\users\john\documents\programming\github\etl\array.h @@ -182,9 +182,9 @@ "static_assert.h" "error_handler.h" -1424729709 dler.h" +1482748240 dler.h" -1427741862 .h" +1481309504 .h" 1424729709 u:\users\john\documents\programming\github\etl\exception.h @@ -193,7 +193,7 @@ "../container.h" -1414586788 ner.h" +1452516033 ner.h" 1424729709 u:\users\john\documents\programming\github\etl\container.h @@ -213,7 +213,7 @@ "../crc64_ecma.h" "../endian.h" -1414929413 ecma.h" +1452701006 ecma.h" 1424729709 u:\users\john\documents\programming\github\etl\crc8_ccitt.h @@ -261,7 +261,7 @@ "../cyclic_value.h" -1415139747 _value.h" +1452516033 _value.h" 1424729709 u:\users\john\documents\programming\github\etl\cyclic_value.h @@ -307,7 +307,7 @@ "nullptr.h" -1424729709 " +1481841437 " 1424729709 u:\users\john\documents\programming\github\etl\nullptr.h @@ -320,7 +320,7 @@ "../enum_type.h" -1414345217 ype.h" +1452516033 ype.h" 1424729709 u:\users\john\documents\programming\github\etl\enum_type.h @@ -329,13 +329,13 @@ "../exception.h" -1424729709 ion.h" +1452516033 ion.h" 1424729709 source:u:\users\john\documents\programming\github\etl\test\test_function.cpp "../function.h" -1414347748 on.h" +1452516033 on.h" 1424729709 u:\users\john\documents\programming\github\etl\function.h @@ -344,12 +344,12 @@ "../largest.h" -1424729709 ts> +1452516033 ts> 1424729709 u:\users\john\documents\programming\github\etl\largest.h "type_traits.h" -1424729709 ts.h" +1482075058 ts.h" 1424729709 source:u:\users\john\documents\programming\github\etl\test\test_list.cpp @@ -383,7 +383,7 @@ -1415009648 +/ReportAssertImpl.h> +1452516033 +/ReportAssertImpl.h> 1424729709 u:\users\john\documents\programming\github\etl\list.h @@ -452,7 +452,7 @@ "../observer.h" -1415136649 er.h" +1452696227 er.h" 1424729709 u:\users\john\documents\programming\github\etl\observer.h @@ -492,7 +492,7 @@ "../queue.h" -1424729709 h" +1482098369 h" 1427740329 u:\users\john\documents\programming\github\etl\queue.h @@ -557,14 +557,14 @@ "../visitor.h" -1414764632 r.h" +1452516033 r.h" 1424729709 u:\users\john\documents\programming\github\etl\visitor.h 1414849210 source:u:\users\john\documents\programming\github\unittest-cpp\unittest++\assertexception.cpp "AssertException.h" -1414845610 eption.h" +1447740690 eption.h" 1414849210 source:u:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.cpp "Checks.h" @@ -577,7 +577,7 @@ 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\compositetestreporter.h "TestReporter.h" -1414845610 ter.h" +1482076051 ter.h" 1414849210 u:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporter.h "HelperMacros.h" @@ -879,7 +879,7 @@ 1414845610 source:/mnt/hgfs/W7 My Documents/Programming/GitHub/unittest-cpp/UnitTest++/Posix/SignalTranslator.cpp "SignalTranslator.h" -1414845610 nslator.h" +1447740690 nslator.h" 1414845610 source:/mnt/hgfs/W7 My Documents/Programming/GitHub/unittest-cpp/UnitTest++/Posix/TimeHelpers.cpp "TimeHelpers.h" @@ -1099,7 +1099,7 @@ "integral_limits.h" -1427740329 limits.h" +1482653105 limits.h" 1424729709 source:u:\users\john\documents\programming\github\etl\test\test_forward_list.cpp @@ -1129,7 +1129,7 @@ "type_traits.h" "parameter_type.h" -1427740329 _type.h" +1479511690 _type.h" 1424729709 u:\users\john\documents\programming\github\etl\forward_list_base.h @@ -1152,7 +1152,7 @@ "type_traits.h" "static_assert.h" -1427740329 sert.h" +1481309477 sert.h" 1424729709 u:\users\john\documents\programming\github\etl\parameter_type.h "type_traits.h" @@ -1175,7 +1175,7 @@ "../fibonacci.h" "../factorial.h" -1424729709 ial.h" +1452700712 ial.h" 1427741862 source:u:\users\john\documents\programming\github\etl\test\test_pool.cpp @@ -1409,7 +1409,7 @@ "../fixed_iterator.h" -1424729709 iterator.h" +1452516033 iterator.h" 1424729709 u:\users\john\documents\programming\github\etl\fixed_iterator.h @@ -1445,7 +1445,7 @@ "data.h" "../flat_map.h" -1424729709 ap.h" +1452516120 ap.h" 1427740329 u:\users\john\documents\programming\github\etl\flat_map.h @@ -1484,7 +1484,7 @@ "data.h" "../flat_set.h" -1424729709 et.h" +1452516033 et.h" 1427740329 u:\users\john\documents\programming\github\etl\flat_set.h @@ -2621,80 +2621,80 @@ 1424726109 /mnt/hgfs/Programming/GitHub/etl/visitor.h -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\assertexception.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\assertexception.cpp "AssertException.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\assertexception.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\assertexception.h "Config.h" "HelperMacros.h" -1457468069 d:\users\john\documents\programming\github\unittest-cpp\unittest++\config.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\config.h -1457468069 d:\users\john\documents\programming\github\unittest-cpp\unittest++\helpermacros.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\helpermacros.h "Config.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.cpp "Checks.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\checks.h "Config.h" "TestResults.h" "MemoryOutStream.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testresults.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testresults.h "HelperMacros.h" -1417970069 d:\users\john\documents\programming\github\unittest-cpp\unittest++\memoryoutstream.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\memoryoutstream.h "Config.h" "HelperMacros.h" -1417970061 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\compositetestreporter.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\compositetestreporter.cpp "CompositeTestReporter.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\compositetestreporter.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\compositetestreporter.h "TestReporter.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporter.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporter.h "HelperMacros.h" -1417970067 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\currenttest.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\currenttest.cpp "CurrentTest.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\currenttest.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\currenttest.h "HelperMacros.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestreporter.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestreporter.cpp "Config.h" "DeferredTestReporter.h" "TestDetails.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestreporter.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestreporter.h "Config.h" "TestReporter.h" "DeferredTestResult.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestresult.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestresult.h "Config.h" "HelperMacros.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testdetails.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testdetails.h "HelperMacros.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestresult.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\deferredtestresult.cpp "Config.h" "DeferredTestResult.h" -1457468069 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\memoryoutstream.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\memoryoutstream.cpp "MemoryOutStream.h" @@ -2702,7 +2702,7 @@ 1417875047 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\signaltranslator.cpp "SignalTranslator.h" -1417871449 d:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\signaltranslator.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\signaltranslator.h @@ -2710,10 +2710,10 @@ "TimeHelpers.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\timehelpers.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\posix\timehelpers.h -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassert.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassert.cpp "ReportAssert.h" "ReportAssertImpl.h" "AssertException.h" @@ -2722,15 +2722,15 @@ "TestDetails.h" "ReportAssertImpl.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassert.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassert.h "HelperMacros.h" -1457468069 d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassertimpl.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\reportassertimpl.h "Config.h" "HelperMacros.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\test.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\test.cpp "Config.h" "Test.h" "TestList.h" @@ -2740,51 +2740,52 @@ "ExecuteTest.h" "Posix/SignalTranslator.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\test.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\test.h "TestDetails.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testlist.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testlist.h "HelperMacros.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\executetest.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\executetest.h "Config.h" "ExceptionMacros.h" "TestDetails.h" "TestResults.h" "MemoryOutStream.h" "AssertException.h" + "RequiredCheckException.h" "CurrentTest.h" "ReportAssertImpl.h" "Posix/SignalTranslator.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\exceptionmacros.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\exceptionmacros.h "Config.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testdetails.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testdetails.cpp "TestDetails.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testlist.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testlist.cpp "TestList.h" "Test.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporter.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporter.cpp "TestReporter.h" -1457465178 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporterstdout.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporterstdout.cpp "TestReporterStdout.h" "TestDetails.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporterstdout.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testreporterstdout.h "TestReporter.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testresults.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testresults.cpp "TestResults.h" "TestReporter.h" "TestDetails.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testrunner.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\testrunner.cpp "TestRunner.h" "TestResults.h" "TestReporter.h" @@ -2793,38 +2794,39 @@ "MemoryOutStream.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testrunner.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testrunner.h "Test.h" "TestList.h" "CurrentTest.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\timehelpers.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\timehelpers.h "Config.h" "Posix/TimeHelpers.h" "Win32/TimeHelpers.h" -1456667834 d:\users\john\documents\programming\github\unittest-cpp\unittest++\win32\timehelpers.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\win32\timehelpers.h "../Config.h" "../HelperMacros.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\timeconstraint.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\timeconstraint.cpp "TimeConstraint.h" "TestResults.h" "MemoryOutStream.h" "CurrentTest.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\timeconstraint.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\timeconstraint.h "TimeHelpers.h" "HelperMacros.h" + "TestDetails.h" -1414845610 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\xmltestreporter.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\xmltestreporter.cpp "Config.h" "XmlTestReporter.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\xmltestreporter.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\xmltestreporter.h "Config.h" "DeferredTestReporter.h" @@ -2862,21 +2864,22 @@ 1450265856 d:\users\john\documents\programming\github\etl\nullptr.h -1450264056 source:d:\users\john\documents\programming\github\etl\test\main.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\main.cpp -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\unittest++.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\unittest++.h "UnitTestPP.h" -1414845610 d:\users\john\documents\programming\github\unittest-cpp\unittest++\unittestpp.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\unittestpp.h "Config.h" "TestMacros.h" "CheckMacros.h" + "RequireMacros.h" "TestRunner.h" "TimeConstraint.h" "ReportAssert.h" -1416829904 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testmacros.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testmacros.h "Config.h" "TestSuite.h" "ExceptionMacros.h" @@ -2886,19 +2889,20 @@ "MemoryOutStream.h" "Posix/SignalTranslator.h" -1416829896 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testsuite.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\testsuite.h -1414927690 d:\users\john\documents\programming\github\unittest-cpp\unittest++\checkmacros.h +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\checkmacros.h "HelperMacros.h" "ExceptionMacros.h" "Checks.h" "AssertException.h" + "RequiredCheckException.h" "MemoryOutStream.h" "TestDetails.h" "CurrentTest.h" "ReportAssertImpl.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp "../src/algorithm.h" "../src/container.h" @@ -2923,7 +2927,7 @@ -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_alignment.cpp +1482624126 source:d:\users\john\documents\programming\github\etl\test\test_alignment.cpp "../src/alignment.h" "../src/type_traits.h" @@ -2939,7 +2943,7 @@ 1450265856 d:\users\john\documents\programming\github\etl\static_assert.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_array.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_array.cpp "../src/array.h" @@ -2947,6 +2951,8 @@ "../src/integral_limits.h" +1479511692 tegral_limits.h" + 1450265856 d:\users\john\documents\programming\github\etl\array.h @@ -2966,7 +2972,7 @@ "type_traits.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_binary.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_binary.cpp @@ -3029,22 +3035,27 @@ "exception.h" "error_handler.h" -1457468093 source:d:\users\john\documents\programming\github\etl\test\test_bitset.cpp +1482623861 source:d:\users\john\documents\programming\github\etl\test\test_bitset.cpp "../src/bitset.h" -1457378733 source:d:\users\john\documents\programming\github\etl\test\test_bloom_filter.cpp +1482623861 tset.h" + +1482612858 source:d:\users\john\documents\programming\github\etl\test\test_bloom_filter.cpp - + "../src/bloom_filter.h" "../src/fnv_1.h" "../src/crc16.h" "../src/crc16_ccitt.h" "../src/crc32.h" + "../src/char_traits.h" + +1482612858 ar_traits.h" 1450265856 d:\users\john\documents\programming\github\etl\bloom_filter.h "parameter_type.h" @@ -3073,7 +3084,7 @@ "static_assert.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_checksum.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_checksum.cpp @@ -3082,18 +3093,22 @@ "../src/checksum.h" "../src/endian.h" +1479511692 dian.h" + 1450265856 d:\users\john\documents\programming\github\etl\checksum.h "static_assert.h" "type_traits.h" "ihash.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_container.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_container.cpp "../src/container.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_crc.cpp +1479511691 ntainer.h" + +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_crc.cpp @@ -3106,6 +3121,8 @@ "../src/crc32.h" "../src/crc64_ecma.h" +1479511691 c64_ecma.h" + 1450265856 d:\users\john\documents\programming\github\etl\crc8_ccitt.h "static_assert.h" @@ -3121,17 +3138,19 @@ "static_assert.h" "type_traits.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_cyclic_value.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_cyclic_value.cpp "../src/cyclic_value.h" +1479511691 clic_value.h" + 1452794793 d:\users\john\documents\programming\github\etl\cyclic_value.h "static_assert.h" "exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp "ExtraCheckMacros.h" "../src/deque.h" @@ -3142,7 +3161,7 @@ -1421962897 d:\users\john\documents\programming\github\etl\test\extracheckmacros.h +1479511691 d:\users\john\documents\programming\github\etl\test\extracheckmacros.h @@ -3175,20 +3194,22 @@ "exception.h" -1456432601 d:\users\john\documents\programming\github\etl\test\data.h +1482185150 d:\users\john\documents\programming\github\etl\test\data.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_endian.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_endian.cpp "../src/endian.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_enum_type.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_enum_type.cpp "../src/enum_type.h" -1457468158 source:d:\users\john\documents\programming\github\etl\test\test_error_handler.cpp +1479511691 um_type.h" + +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_error_handler.cpp @@ -3196,12 +3217,14 @@ "../src/error_handler.h" "../src/exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_exception.cpp +1482625380 ception.h" + +1482625380 source:d:\users\john\documents\programming\github\etl\test\test_exception.cpp "../src/exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_flat_map.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_flat_map.cpp @@ -3213,6 +3236,8 @@ "data.h" "../src/flat_map.h" +1479511691 at_map.h" + 1452796556 d:\users\john\documents\programming\github\etl\flat_map.h @@ -3263,7 +3288,7 @@ "alignment.h" "array.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_flat_set.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_flat_set.cpp @@ -3275,6 +3300,8 @@ "data.h" "../src/flat_set.h" +1479511691 at_set.h" + 1452796556 d:\users\john\documents\programming\github\etl\flat_set.h @@ -3300,7 +3327,7 @@ "ivector.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_fnv_1.cpp +1482623723 source:d:\users\john\documents\programming\github\etl\test\test_fnv_1.cpp @@ -3308,7 +3335,9 @@ "../src/fnv_1.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp +1482623723 v_1.h" + +1482625680 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp "ExtraCheckMacros.h" "data.h" @@ -3359,11 +3388,13 @@ "exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_function.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_function.cpp "../src/function.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_functional.cpp +1479511692 nction.h" + +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_functional.cpp "../src/functional.h" @@ -3372,7 +3403,7 @@ 1450265856 d:\users\john\documents\programming\github\etl\functional.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_hash.cpp +1482624624 source:d:\users\john\documents\programming\github\etl\test\test_hash.cpp @@ -3380,12 +3411,14 @@ "../src/hash.h" +1482624624 sh.h" + 1450265856 d:\users\john\documents\programming\github\etl\hash.h "fnv_1.h" "type_traits.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_instance_count.cpp +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_instance_count.cpp "../src/instance_count.h" @@ -3394,14 +3427,14 @@ 1450265856 d:\users\john\documents\programming\github\etl\instance_count.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_integral_limits.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_integral_limits.cpp "../src/integral_limits.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_io_port.cpp +1482750186 source:d:\users\john\documents\programming\github\etl\test\test_io_port.cpp "../src/io_port.h" @@ -3411,7 +3444,7 @@ "nullptr.h" "parameter_type.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_largest.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_largest.cpp "../src/largest.h" @@ -3419,7 +3452,7 @@ 1450265856 d:\users\john\documents\programming\github\etl\largest.h "type_traits.h" -1457468249 source:d:\users\john\documents\programming\github\etl\test\test_list.cpp +1482625302 source:d:\users\john\documents\programming\github\etl\test\test_list.cpp "ExtraCheckMacros.h" "../src/list.h" @@ -3450,20 +3483,22 @@ "exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_maths.cpp +1482692728 source:d:\users\john\documents\programming\github\etl\test\test_maths.cpp "../src/log.h" "../src/power.h" "../src/fibonacci.h" "../src/factorial.h" +1482692728 ctorial.h" + 1450265856 d:\users\john\documents\programming\github\etl\fibonacci.h 1450265856 d:\users\john\documents\programming\github\etl\factorial.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_numeric.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_numeric.cpp "../src/numeric.h" @@ -3471,21 +3506,25 @@ 1450265856 d:\users\john\documents\programming\github\etl\numeric.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_observer.cpp +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_observer.cpp "../src/observer.h" +1482624916 server.h" + 1450959449 d:\users\john\documents\programming\github\etl\observer.h "vector.h" "exception.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_queue.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_queue.cpp "../src/queue.h" +1479511692 eue.h" + 1450265856 d:\users\john\documents\programming\github\etl\queue.h @@ -3505,17 +3544,19 @@ "exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_smallest.cpp +1482654345 source:d:\users\john\documents\programming\github\etl\test\test_smallest.cpp "../src/smallest.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_stack.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_stack.cpp "data.h" "../src/stack.h" +1479511692 ack.h" + 1450265856 d:\users\john\documents\programming\github\etl\stack.h @@ -3536,29 +3577,35 @@ "exception.h" -1457027610 source:d:\users\john\documents\programming\github\etl\test\test_vector.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_vector.cpp "../src/vector.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_visitor.cpp +1479511692 ctor.h" + +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_visitor.cpp "../src/visitor.h" +1479511692 sitor.h" + 1450265856 d:\users\john\documents\programming\github\etl\visitor.h -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_fixed_iterator.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_fixed_iterator.cpp "../src/fixed_iterator.h" +1479511691 xed_iterator.h" + 1450265856 d:\users\john\documents\programming\github\etl\fixed_iterator.h -1457468069 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\win32\timehelpers.cpp +1482076051 source:d:\users\john\documents\programming\github\unittest-cpp\unittest++\win32\timehelpers.cpp "TimeHelpers.h" @@ -3567,6 +3614,8 @@ "../exception.h" "../error_handler.h" +1482614484 handler.h" + 1450265856 d:\users\john\documents\programming\github\etl\private\flat_map_base.h "../exception.h" @@ -3600,7 +3649,7 @@ "../exception.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_map.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_map.cpp @@ -3611,6 +3660,8 @@ "../src/map.h" +1479511692 p.h" + 1452337350 d:\users\john\documents\programming\github\etl\map.h @@ -3635,7 +3686,7 @@ "../exception.h" "../error_handler.h" -1457464314 source:d:\users\john\documents\programming\github\etl\test\test_optional.cpp +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_optional.cpp @@ -3649,7 +3700,7 @@ "exception.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_pool.cpp +1482750186 source:d:\users\john\documents\programming\github\etl\test\test_pool.cpp "ExtraCheckMacros.h" "data.h" @@ -3657,12 +3708,14 @@ "../src/pool.h" +1482750186 ol.h" + 1450265856 d:\users\john\documents\programming\github\etl\private\queue_base.h "../exception.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_set.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_set.cpp @@ -3673,6 +3726,8 @@ "../src/set.h" +1479511692 t.h" + 1452337350 d:\users\john\documents\programming\github\etl\set.h @@ -3702,12 +3757,12 @@ "../exception.h" "../error_handler.h" -1457463236 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp +1482768991 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp "../src/type_traits.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp +1481841066 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp "ExtraCheckMacros.h" "../src/variant.h" @@ -4784,7 +4839,7 @@ 1452516033 /home/jwellbelove/Programming/etl/visitor.h -1457468232 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_forward_list.cpp +1482799048 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_forward_list.cpp "ExtraCheckMacros.h" "data.h" @@ -4805,48 +4860,55 @@ "type_traits.h" "intrusive_forward_list_link.h" +1453405528 _forward_list_link.h" + 1453324561 d:\users\john\documents\programming\github\etl\intrusive_forward_list_link.h "error_handler.h" "array.h" -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc16.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\crc16.cpp -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc16_ccitt.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\crc16_ccitt.cpp -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc16_kermit.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\crc16_kermit.cpp -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc32.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\crc32.cpp -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc64_ecma.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\crc64_ecma.cpp -1456669289 source:d:\users\john\documents\programming\github\etl\src\crc8_ccitt.cpp +1481309487 source:d:\users\john\documents\programming\github\etl\src\crc8_ccitt.cpp + "platform.h" + "static_assert.h" -1456669289 source:d:\users\john\documents\programming\github\etl\src\error_handler.cpp +1479511689 source:d:\users\john\documents\programming\github\etl\src\error_handler.cpp "error_handler.h" "nullptr.h" -1456669289 d:\users\john\documents\programming\github\etl\src\error_handler.h +1479511689 d:\users\john\documents\programming\github\etl\src\error_handler.h "exception.h" "function.h" -1456669289 d:\users\john\documents\programming\github\etl\src\exception.h +1481841065 d:\users\john\documents\programming\github\etl\src\exception.h -1456669289 d:\users\john\documents\programming\github\etl\src\function.h +1481841065 d:\users\john\documents\programming\github\etl\src\function.h -1457547753 d:\users\john\documents\programming\github\etl\src\nullptr.h +1481308917 d:\users\john\documents\programming\github\etl\src\nullptr.h "platform.h" + -1456669289 source:d:\users\john\documents\programming\github\etl\src\pearson.cpp +1481841066 source:d:\users\john\documents\programming\github\etl\src\pearson.cpp + "platform.h" + "static_assert.h" -1456669289 d:\users\john\documents\programming\github\etl\src\algorithm.h +1479511689 d:\users\john\documents\programming\github\etl\src\algorithm.h @@ -4854,24 +4916,24 @@ "type_traits.h" -1457559890 d:\users\john\documents\programming\github\etl\src\type_traits.h +1481841066 d:\users\john\documents\programming\github\etl\src\type_traits.h "platform.h" "nullptr.h" -1456669289 d:\users\john\documents\programming\github\etl\src\container.h +1482613987 d:\users\john\documents\programming\github\etl\src\container.h -1456669289 d:\users\john\documents\programming\github\etl\src\alignment.h +1481309570 d:\users\john\documents\programming\github\etl\src\alignment.h "type_traits.h" "static_assert.h" -1457463503 d:\users\john\documents\programming\github\etl\src\static_assert.h +1481841065 d:\users\john\documents\programming\github\etl\src\static_assert.h "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\array.h +1479511689 d:\users\john\documents\programming\github\etl\src\array.h @@ -4882,15 +4944,16 @@ "static_assert.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\parameter_type.h +1479511690 d:\users\john\documents\programming\github\etl\src\parameter_type.h "type_traits.h" -1456669289 d:\users\john\documents\programming\github\etl\src\integral_limits.h +1479511690 d:\users\john\documents\programming\github\etl\src\integral_limits.h "type_traits.h" + "platform.h" -1457027659 d:\users\john\documents\programming\github\etl\src\binary.h +1481309537 d:\users\john\documents\programming\github\etl\src\binary.h "type_traits.h" @@ -4899,19 +4962,20 @@ "log.h" "power.h" "smallest.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\log.h +1479511690 d:\users\john\documents\programming\github\etl\src\log.h -1456669289 d:\users\john\documents\programming\github\etl\src\power.h +1479511690 d:\users\john\documents\programming\github\etl\src\power.h "log.h" -1456669289 d:\users\john\documents\programming\github\etl\src\smallest.h +1482653105 d:\users\john\documents\programming\github\etl\src\smallest.h "integral_limits.h" -1457463503 d:\users\john\documents\programming\github\etl\src\bitset.h +1479511689 d:\users\john\documents\programming\github\etl\src\bitset.h @@ -4924,7 +4988,7 @@ "ibitset.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\ibitset.h +1481309224 d:\users\john\documents\programming\github\etl\src\ibitset.h @@ -4932,21 +4996,25 @@ "integral_limits.h" "binary.h" "algorithm.h" + "platform.h" -1457463503 d:\users\john\documents\programming\github\etl\src\fnv_1.h +1481841066 d:\users\john\documents\programming\github\etl\src\fnv_1.h "platform.h" "static_assert.h" "type_traits.h" "ihash.h" + "frame_check_sequence.h" -1456669289 d:\users\john\documents\programming\github\etl\src\ihash.h +1481872412 ck_sequence.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\ihash.h "exception.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\bloom_filter.h +1479511689 d:\users\john\documents\programming\github\etl\src\bloom_filter.h "parameter_type.h" "bitset.h" "type_traits.h" @@ -4954,66 +5022,67 @@ "log.h" "power.h" -1457463503 d:\users\john\documents\programming\github\etl\src\crc16.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc16.h "platform.h" "frame_check_sequence.h" -1456669289 d:\users\john\documents\programming\github\etl\src\frame_check_sequence.h +1481841065 d:\users\john\documents\programming\github\etl\src\frame_check_sequence.h + "platform.h" "static_assert.h" "type_traits.h" "binary.h" -1457463503 d:\users\john\documents\programming\github\etl\src\crc16_ccitt.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc16_ccitt.h "platform.h" "frame_check_sequence.h" -1457463503 d:\users\john\documents\programming\github\etl\src\crc32.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc32.h "platform.h" "frame_check_sequence.h" -1456953131 d:\users\john\documents\programming\github\etl\src\checksum.h +1479511689 d:\users\john\documents\programming\github\etl\src\checksum.h "binary.h" "frame_check_sequence.h" -1456669289 d:\users\john\documents\programming\github\etl\src\endian.h +1481309464 d:\users\john\documents\programming\github\etl\src\endian.h "enum_type.h" -1456669289 d:\users\john\documents\programming\github\etl\src\enum_type.h +1479511689 d:\users\john\documents\programming\github\etl\src\enum_type.h -1457463503 d:\users\john\documents\programming\github\etl\src\crc8_ccitt.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc8_ccitt.h "platform.h" "frame_check_sequence.h" -1457463503 d:\users\john\documents\programming\github\etl\src\crc16_kermit.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc16_kermit.h "platform.h" "frame_check_sequence.h" -1457463503 d:\users\john\documents\programming\github\etl\src\crc64_ecma.h +1479511689 d:\users\john\documents\programming\github\etl\src\crc64_ecma.h "platform.h" "frame_check_sequence.h" -1456669289 d:\users\john\documents\programming\github\etl\src\cyclic_value.h +1479511689 d:\users\john\documents\programming\github\etl\src\cyclic_value.h "static_assert.h" "exception.h" -1456669289 d:\users\john\documents\programming\github\etl\src\deque.h +1479511689 d:\users\john\documents\programming\github\etl\src\deque.h @@ -5023,7 +5092,7 @@ "alignment.h" "array.h" -1457468266 d:\users\john\documents\programming\github\etl\src\ideque.h +1482624126 d:\users\john\documents\programming\github\etl\src\ideque.h "algorithm.h" @@ -5032,22 +5101,22 @@ "parameter_type.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\deque_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\deque_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\fixed_iterator.h +1482624125 d:\users\john\documents\programming\github\etl\src\fixed_iterator.h -1456669289 d:\users\john\documents\programming\github\etl\src\flat_map.h +1479511690 d:\users\john\documents\programming\github\etl\src\flat_map.h "iflat_map.h" "vector.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iflat_map.h +1482748252 d:\users\john\documents\programming\github\etl\src\iflat_map.h @@ -5059,13 +5128,13 @@ "ivector.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\flat_map_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\flat_map_base.h "../exception.h" "../ivector.h" "../error_handler.h" -1457595336 d:\users\john\documents\programming\github\etl\src\ivector.h +1482748239 d:\users\john\documents\programming\github\etl\src\ivector.h @@ -5076,13 +5145,16 @@ "type_traits.h" "parameter_type.h" "error_handler.h" + "private/ivectorpointer.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\vector_base.h +1482748239 vectorpointer.h" + +1479511691 d:\users\john\documents\programming\github\etl\src\private\vector_base.h "../exception.h" "../error_handler.h" -1456953131 d:\users\john\documents\programming\github\etl\src\vector.h +1481841065 d:\users\john\documents\programming\github\etl\src\vector.h @@ -5091,14 +5163,14 @@ "alignment.h" "array.h" -1456669289 d:\users\john\documents\programming\github\etl\src\flat_set.h +1479511690 d:\users\john\documents\programming\github\etl\src\flat_set.h "iflat_set.h" "vector.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iflat_set.h +1482748239 d:\users\john\documents\programming\github\etl\src\iflat_set.h @@ -5110,39 +5182,40 @@ "ivector.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\flat_set_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\flat_set_base.h "../exception.h" "../ivector.h" "../error_handler.h" -1456953131 d:\users\john\documents\programming\github\etl\src\forward_list.h +1479511690 d:\users\john\documents\programming\github\etl\src\forward_list.h "pool.h" "iforward_list.h" "container.h" -1456669289 d:\users\john\documents\programming\github\etl\src\pool.h +1479511690 d:\users\john\documents\programming\github\etl\src\pool.h "alignment.h" "array.h" "bitset.h" "ipool.h" -1456669289 d:\users\john\documents\programming\github\etl\src\ipool.h +1481841065 d:\users\john\documents\programming\github\etl\src\ipool.h "private/pool_base.h" "nullptr.h" "ibitset.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\pool_base.h +1479511691 d:\users\john\documents\programming\github\etl\src\private\pool_base.h "../exception.h" "../error_handler.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iforward_list.h +1482748239 d:\users\john\documents\programming\github\etl\src\iforward_list.h + "platform.h" @@ -5153,21 +5226,24 @@ "type_traits.h" "parameter_type.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\forward_list_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\forward_list_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\functional.h +1479511690 d:\users\john\documents\programming\github\etl\src\functional.h -1456669289 d:\users\john\documents\programming\github\etl\src\hash.h +1481841145 d:\users\john\documents\programming\github\etl\src\hash.h + "fnv_1.h" "type_traits.h" + "static_assert.h" -1456669289 d:\users\john\documents\programming\github\etl\src\instance_count.h +1479511690 d:\users\john\documents\programming\github\etl\src\instance_count.h -1456953131 d:\users\john\documents\programming\github\etl\src\intrusive_forward_list.h +1482748239 d:\users\john\documents\programming\github\etl\src\intrusive_forward_list.h + "platform.h" @@ -5178,29 +5254,33 @@ "error_handler.h" "intrusive_links.h" "algorithm.h" + "private/counter_type.h" -1457466644 d:\users\john\documents\programming\github\etl\src\intrusive_links.h +1482354421 ounter_type.h" + +1482357841 d:\users\john\documents\programming\github\etl\src\intrusive_links.h + "nullptr.h" "type_traits.h" "exception.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\io_port.h +1479511690 d:\users\john\documents\programming\github\etl\src\io_port.h "nullptr.h" "parameter_type.h" -1456669289 d:\users\john\documents\programming\github\etl\src\largest.h +1479511690 d:\users\john\documents\programming\github\etl\src\largest.h "type_traits.h" -1456953131 d:\users\john\documents\programming\github\etl\src\list.h +1479511690 d:\users\john\documents\programming\github\etl\src\list.h "ilist.h" "container.h" "pool.h" -1456669289 d:\users\john\documents\programming\github\etl\src\ilist.h +1482748239 d:\users\john\documents\programming\github\etl\src\ilist.h @@ -5210,13 +5290,14 @@ "type_traits.h" "parameter_type.h" "pool.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\list_base.h +1479511691 d:\users\john\documents\programming\github\etl\src\private\list_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\map.h +1479511690 d:\users\john\documents\programming\github\etl\src\map.h @@ -5224,7 +5305,7 @@ "container.h" "pool.h" -1456669289 d:\users\john\documents\programming\github\etl\src\imap.h +1479511690 d:\users\john\documents\programming\github\etl\src\imap.h @@ -5234,33 +5315,34 @@ "type_traits.h" "parameter_type.h" "pool.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\map_base.h +1481841066 d:\users\john\documents\programming\github\etl\src\private\map_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\fibonacci.h +1479511689 d:\users\john\documents\programming\github\etl\src\fibonacci.h -1456669289 d:\users\john\documents\programming\github\etl\src\factorial.h +1479511689 d:\users\john\documents\programming\github\etl\src\factorial.h -1456669289 d:\users\john\documents\programming\github\etl\src\numeric.h +1479511690 d:\users\john\documents\programming\github\etl\src\numeric.h -1456669289 d:\users\john\documents\programming\github\etl\src\observer.h +1479511690 d:\users\john\documents\programming\github\etl\src\observer.h "vector.h" "exception.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\optional.h +1482748239 d:\users\john\documents\programming\github\etl\src\optional.h "alignment.h" "type_traits.h" "exception.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\queue.h +1479511691 d:\users\john\documents\programming\github\etl\src\queue.h "iqueue.h" @@ -5268,19 +5350,19 @@ "alignment.h" "array.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iqueue.h +1481841066 d:\users\john\documents\programming\github\etl\src\iqueue.h "private/queue_base.h" "type_traits.h" "parameter_type.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\queue_base.h +1479511691 d:\users\john\documents\programming\github\etl\src\private\queue_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\set.h +1479511691 d:\users\john\documents\programming\github\etl\src\set.h @@ -5288,7 +5370,7 @@ "container.h" "pool.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iset.h +1479511690 d:\users\john\documents\programming\github\etl\src\iset.h @@ -5298,13 +5380,14 @@ "type_traits.h" "parameter_type.h" "pool.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\set_base.h +1482625676 d:\users\john\documents\programming\github\etl\src\private\set_base.h "../exception.h" "../error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\stack.h +1479511691 d:\users\john\documents\programming\github\etl\src\stack.h @@ -5313,19 +5396,19 @@ "alignment.h" "array.h" -1456669289 d:\users\john\documents\programming\github\etl\src\istack.h +1481841066 d:\users\john\documents\programming\github\etl\src\istack.h "private/stack_base.h" "type_traits.h" "parameter_type.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\stack_base.h +1479511691 d:\users\john\documents\programming\github\etl\src\private\stack_base.h "../exception.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_unordered_map.cpp +1482624915 source:d:\users\john\documents\programming\github\etl\test\test_unordered_map.cpp @@ -5338,7 +5421,9 @@ "data.h" "../src/unordered_map.h" -1456669289 d:\users\john\documents\programming\github\etl\src\unordered_map.h +1482624915 ordered_map.h" + +1479511691 d:\users\john\documents\programming\github\etl\src\unordered_map.h @@ -5349,7 +5434,7 @@ "intrusive_forward_list.h" "hash.h" -1456953131 d:\users\john\documents\programming\github\etl\src\iunordered_map.h +1482748240 d:\users\john\documents\programming\github\etl\src\iunordered_map.h @@ -5366,7 +5451,7 @@ "exception.h" "error_handler.h" -1457463503 d:\users\john\documents\programming\github\etl\src\variant.h +1481841437 d:\users\john\documents\programming\github\etl\src\variant.h "platform.h" "array.h" @@ -5377,20 +5462,23 @@ "static_assert.h" "alignment.h" "error_handler.h" + "largest.h" -1456669289 d:\users\john\documents\programming\github\etl\src\visitor.h +1479511691 d:\users\john\documents\programming\github\etl\src\visitor.h -1457570381 d:\users\john\documents\programming\github\etl\src\platform.h +1482759320 d:\users\john\documents\programming\github\etl\src\platform.h + + -1457463956 source:d:\users\john\documents\programming\github\etl\test\murmurhash3.cpp - "MurmurHash3.h" +1481841065 source:d:\users\john\documents\programming\github\etl\test\murmurhash3.cpp + "murmurhash3.h" -1457464314 d:\users\john\documents\programming\github\etl\test\murmurhash3.h +1479511691 d:\users\john\documents\programming\github\etl\test\murmurhash3.h "../src/platform.h" -1457508036 source:d:\users\john\documents\programming\github\etl\test\test_bsd_checksum.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_bsd_checksum.cpp @@ -5398,7 +5486,9 @@ "../src/checksum.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_flat_multimap.cpp +1479511692 ecksum.h" + +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_flat_multimap.cpp @@ -5410,14 +5500,16 @@ "data.h" "../src/flat_multimap.h" -1456669289 d:\users\john\documents\programming\github\etl\src\flat_multimap.h +1479511691 at_multimap.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\flat_multimap.h "iflat_multimap.h" "vector.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iflat_multimap.h +1482748239 d:\users\john\documents\programming\github\etl\src\iflat_multimap.h @@ -5429,13 +5521,13 @@ "ivector.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\flat_multimap_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\flat_multimap_base.h "../exception.h" "../ivector.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_flat_multiset.cpp +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_flat_multiset.cpp @@ -5447,14 +5539,16 @@ "data.h" "../src/flat_multiset.h" -1456669289 d:\users\john\documents\programming\github\etl\src\flat_multiset.h +1479511691 at_multiset.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\flat_multiset.h "iflat_multiset.h" "vector.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iflat_multiset.h +1482748239 d:\users\john\documents\programming\github\etl\src\iflat_multiset.h @@ -5466,19 +5560,21 @@ "ivector.h" "error_handler.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\flat_multiset_base.h +1479511690 d:\users\john\documents\programming\github\etl\src\private\flat_multiset_base.h "../exception.h" "../ivector.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_links.cpp +1482358550 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_links.cpp "ExtraCheckMacros.h" "data.h" "../src/intrusive_links.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_list.cpp +1482358550 trusive_links.h" + +1482840619 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_list.cpp "ExtraCheckMacros.h" "data.h" @@ -5489,7 +5585,8 @@ -1457547716 d:\users\john\documents\programming\github\etl\src\intrusive_list.h +1482748239 d:\users\john\documents\programming\github\etl\src\intrusive_list.h + "platform.h" @@ -5501,8 +5598,9 @@ "intrusive_links.h" "static_assert.h" "algorithm.h" + "private/counter_type.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_jenkins.cpp +1482624277 source:d:\users\john\documents\programming\github\etl\test\test_jenkins.cpp "murmurhash3.h" @@ -5512,7 +5610,7 @@ "../src/jenkins.h" "../src/endian.h" -1457463503 d:\users\john\documents\programming\github\etl\src\jenkins.h +1481872412 d:\users\john\documents\programming\github\etl\src\jenkins.h "platform.h" @@ -5520,8 +5618,9 @@ "type_traits.h" "error_handler.h" "ihash.h" + "frame_check_sequence.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_multimap.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_multimap.cpp @@ -5531,7 +5630,9 @@ "../src/multimap.h" -1456669289 d:\users\john\documents\programming\github\etl\src\multimap.h +1479511692 ltimap.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\multimap.h @@ -5539,7 +5640,7 @@ "container.h" "pool.h" -1457548955 d:\users\john\documents\programming\github\etl\src\imultimap.h +1482098369 d:\users\john\documents\programming\github\etl\src\imultimap.h @@ -5549,13 +5650,14 @@ "type_traits.h" "parameter_type.h" "pool.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\multimap_base.h +1481309650 d:\users\john\documents\programming\github\etl\src\private\multimap_base.h "../exception.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_multiset.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_multiset.cpp @@ -5565,7 +5667,9 @@ "../src/multiset.h" -1457548976 d:\users\john\documents\programming\github\etl\src\multiset.h +1479511692 ltiset.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\multiset.h @@ -5573,7 +5677,7 @@ "container.h" "pool.h" -1457548988 d:\users\john\documents\programming\github\etl\src\imultiset.h +1482098369 d:\users\john\documents\programming\github\etl\src\imultiset.h @@ -5583,13 +5687,14 @@ "type_traits.h" "parameter_type.h" "pool.h" + "platform.h" -1456669289 d:\users\john\documents\programming\github\etl\src\private\multiset_base.h +1481309628 d:\users\john\documents\programming\github\etl\src\private\multiset_base.h "../exception.h" "../error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_murmur3.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_murmur3.cpp "murmurhash3.h" @@ -5599,14 +5704,14 @@ "../src/murmur3.h" "../src/endian.h" -1457463503 d:\users\john\documents\programming\github\etl\src\murmur3.h +1479511690 d:\users\john\documents\programming\github\etl\src\murmur3.h "platform.h" "ihash.h" "binary.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_pearson.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_pearson.cpp @@ -5616,7 +5721,7 @@ "../src/pearson.h" "../src/endian.h" -1457549034 d:\users\john\documents\programming\github\etl\src\pearson.h +1481308892 d:\users\john\documents\programming\github\etl\src\pearson.h "platform.h" "static_assert.h" @@ -5626,19 +5731,21 @@ "array.h" "container.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_priority_queue.cpp +1482624474 source:d:\users\john\documents\programming\github\etl\test\test_priority_queue.cpp "../src/priority_queue.h" -1456669289 d:\users\john\documents\programming\github\etl\src\priority_queue.h +1482624474 iority_queue.h" + +1479511690 d:\users\john\documents\programming\github\etl\src\priority_queue.h "ipriority_queue.h" "container.h" "vector.h" -1456669289 d:\users\john\documents\programming\github\etl\src\ipriority_queue.h +1482748239 d:\users\john\documents\programming\github\etl\src\ipriority_queue.h "type_traits.h" @@ -5646,7 +5753,7 @@ "error_handler.h" "exception.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multimap.cpp +1482625301 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multimap.cpp @@ -5659,7 +5766,9 @@ "data.h" "../src/unordered_multimap.h" -1456669289 d:\users\john\documents\programming\github\etl\src\unordered_multimap.h +1482625301 ordered_multimap.h" + +1479511691 d:\users\john\documents\programming\github\etl\src\unordered_multimap.h @@ -5670,7 +5779,7 @@ "intrusive_forward_list.h" "hash.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iunordered_multimap.h +1482748240 d:\users\john\documents\programming\github\etl\src\iunordered_multimap.h @@ -5687,7 +5796,7 @@ "exception.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multiset.cpp +1482625301 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multiset.cpp @@ -5701,7 +5810,7 @@ "../src/unordered_multiset.h" "../src/checksum.h" -1456669289 d:\users\john\documents\programming\github\etl\src\unordered_multiset.h +1479511691 d:\users\john\documents\programming\github\etl\src\unordered_multiset.h @@ -5712,7 +5821,7 @@ "intrusive_forward_list.h" "hash.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iunordered_multiset.h +1482748239 d:\users\john\documents\programming\github\etl\src\iunordered_multiset.h @@ -5729,7 +5838,7 @@ "exception.h" "error_handler.h" -1457378530 source:d:\users\john\documents\programming\github\etl\test\test_unordered_set.cpp +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_unordered_set.cpp @@ -5742,7 +5851,7 @@ "../src/unordered_set.h" "../src/checksum.h" -1456669289 d:\users\john\documents\programming\github\etl\src\unordered_set.h +1479511691 d:\users\john\documents\programming\github\etl\src\unordered_set.h @@ -5753,7 +5862,7 @@ "intrusive_forward_list.h" "hash.h" -1456669289 d:\users\john\documents\programming\github\etl\src\iunordered_set.h +1482748240 d:\users\john\documents\programming\github\etl\src\iunordered_set.h @@ -5770,7 +5879,7 @@ "exception.h" "error_handler.h" -1456669289 source:d:\users\john\documents\programming\github\etl\test\test_xor_checksum.cpp +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_xor_checksum.cpp @@ -5778,3 +5887,1970 @@ "../src/checksum.h" +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\requiredcheckexception.h + "Config.h" + "HelperMacros.h" + + +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\requiremacros.h + "RequiredCheckTestReporter.h" + +1482076051 heckTestReporter.h" + +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\requiredchecktestreporter.h + "HelperMacros.h" + "ThrowingTestReporter.h" + +1482076051 estReporter.h" + +1482076051 d:\users\john\documents\programming\github\unittest-cpp\unittest++\throwingtestreporter.h + "TestReporter.h" + +1481309504 d:\users\john\documents\programming\github\etl\src\char_traits.h + + "platform.h" + "stdint.h" + "algorithm.h" + +1481841066 d:\users\john\documents\programming\github\etl\src\private\ivectorpointer.h + "pvoidvector.h" + +1482079098 or.h" + +1482748239 d:\users\john\documents\programming\github\etl\src\private\pvoidvector.h + + + + + "../platform.h" + "../algorithm.h" + "vector_base.h" + "../type_traits.h" + "../error_handler.h" + +1482353821 d:\users\john\documents\programming\github\etl\src\private\counter_type.h + +1482079098 source:d:\users\john\documents\programming\github\etl\src\private\pvoidvector.cpp + "pvoidvector.h" + +1479511691 source:d:\users\john\documents\programming\github\etl\test\test_debounce.cpp + + "../src/debounce.h" + +1479511691 bounce.h" + +1481309477 d:\users\john\documents\programming\github\etl\src\debounce.h + + "static_assert.h" + +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_queue.cpp + + "../src/intrusive_queue.h" + "../src/intrusive_links.h" + + +1482354421 d:\users\john\documents\programming\github\etl\src\intrusive_queue.h + + "type_traits.h" + "error_handler.h" + "intrusive_links.h" + "private/counter_type.h" + +1482624474 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_stack.cpp + + "../src/intrusive_stack.h" + "../src/intrusive_links.h" + + +1482354421 d:\users\john\documents\programming\github\etl\src\intrusive_stack.h + + "type_traits.h" + "error_handler.h" + "intrusive_links.h" + "private/counter_type.h" + +1482614415 source:d:\users\john\documents\programming\github\etl\test\test_string_char.cpp + + + + + "../src/cstring.h" + +1482181573 tring.h" + +1482614484 d:\users\john\documents\programming\github\etl\src\cstring.h + "platform.h" + "basic_string.h" + "ibasic_string.h" + "hash.h" + +1479511689 d:\users\john\documents\programming\github\etl\src\basic_string.h + + + + "ibasic_string.h" + "char_traits.h" + "container.h" + "alignment.h" + "array.h" + +1482748239 d:\users\john\documents\programming\github\etl\src\ibasic_string.h + + + + + + "private/string_base.h" + "platform.h" + "algorithm.h" + "type_traits.h" + "error_handler.h" + "algorithm.h" + "char_traits.h" + +1482614484 d:\users\john\documents\programming\github\etl\src\private\string_base.h + + "../platform.h" + "../integral_limits.h" + "../exception.h" + "../error_handler.h" + +1482099557 source:d:\users\john\documents\programming\github\etl\test\test_string_u16.cpp + + + + + "../src/u16string.h" + +1482099557 6string.h" + +1481841066 d:\users\john\documents\programming\github\etl\src\u16string.h + "platform.h" + "basic_string.h" + "hash.h" + +1482099666 source:d:\users\john\documents\programming\github\etl\test\test_string_u32.cpp + + + + + "../src/u32string.h" + +1482099666 2string.h" + +1481841066 d:\users\john\documents\programming\github\etl\src\u32string.h + "platform.h" + "basic_string.h" + "hash.h" + +1482181573 source:d:\users\john\documents\programming\github\etl\test\test_string_wchar_t.cpp + + + + + "../src/wstring.h" + +1481841066 d:\users\john\documents\programming\github\etl\src\wstring.h + "platform.h" + "basic_string.h" + "hash.h" + +1482624916 source:d:\users\john\documents\programming\github\etl\test\test_type_def.cpp + + + "../src/type_def.h" + +1482624916 pe_def.h" + +1481841066 d:\users\john\documents\programming\github\etl\src\type_def.h + +1482074959 source:d:\users\john\documents\programming\github\etl\test\test_utility.cpp + + "../src/utility.h" + +1482074959 ility.h" + +1482075058 d:\users\john\documents\programming\github\etl\src\utility.h + "type_traits.h" + +1479511692 source:d:\users\john\documents\programming\github\etl\test\test_vector_pointer.cpp + + + + + "../src/vector.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/AssertException.cpp + "AssertException.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/AssertException.h + "Config.h" + "HelperMacros.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Config.h + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/HelperMacros.h + "Config.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Checks.cpp + "Checks.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Checks.h + "Config.h" + "TestResults.h" + "MemoryOutStream.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestResults.h + "HelperMacros.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/MemoryOutStream.h + "Config.h" + "HelperMacros.h" + + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/CompositeTestReporter.cpp + "CompositeTestReporter.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/CompositeTestReporter.h + "TestReporter.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestReporter.h + "HelperMacros.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/CurrentTest.cpp + "CurrentTest.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/CurrentTest.h + "HelperMacros.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/DeferredTestReporter.cpp + "Config.h" + "DeferredTestReporter.h" + "TestDetails.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/DeferredTestReporter.h + "Config.h" + "TestReporter.h" + "DeferredTestResult.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/DeferredTestResult.h + "Config.h" + "HelperMacros.h" + + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestDetails.h + "HelperMacros.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/DeferredTestResult.cpp + "Config.h" + "DeferredTestResult.h" + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/MemoryOutStream.cpp + "MemoryOutStream.h" + + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Posix/SignalTranslator.cpp + "SignalTranslator.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Posix/SignalTranslator.h + + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Posix/TimeHelpers.cpp + "TimeHelpers.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Posix/TimeHelpers.h + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ReportAssert.cpp + "ReportAssert.h" + "ReportAssertImpl.h" + "AssertException.h" + "CurrentTest.h" + "TestResults.h" + "TestDetails.h" + "ReportAssertImpl.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ReportAssert.h + "HelperMacros.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ReportAssertImpl.h + "Config.h" + "HelperMacros.h" + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/RequiredCheckException.cpp + "RequiredCheckException.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/RequiredCheckException.h + "Config.h" + "HelperMacros.h" + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/RequiredCheckTestReporter.cpp + "RequiredCheckTestReporter.h" + "CurrentTest.h" + "TestResults.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/RequiredCheckTestReporter.h + "HelperMacros.h" + "ThrowingTestReporter.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ThrowingTestReporter.h + "TestReporter.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Test.cpp + "Config.h" + "Test.h" + "TestList.h" + "TestResults.h" + "AssertException.h" + "MemoryOutStream.h" + "ExecuteTest.h" + "Posix/SignalTranslator.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Test.h + "TestDetails.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestList.h + "HelperMacros.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ExecuteTest.h + "Config.h" + "ExceptionMacros.h" + "TestDetails.h" + "TestResults.h" + "MemoryOutStream.h" + "AssertException.h" + "RequiredCheckException.h" + "CurrentTest.h" + "ReportAssertImpl.h" + "Posix/SignalTranslator.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ExceptionMacros.h + "Config.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestDetails.cpp + "TestDetails.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestList.cpp + "TestList.h" + "Test.h" + + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestReporter.cpp + "TestReporter.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestReporterStdout.cpp + "TestReporterStdout.h" + + "TestDetails.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestReporterStdout.h + "TestReporter.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestResults.cpp + "TestResults.h" + "TestReporter.h" + "TestDetails.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestRunner.cpp + "TestRunner.h" + "TestResults.h" + "TestReporter.h" + "TestReporterStdout.h" + "TimeHelpers.h" + "MemoryOutStream.h" + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestRunner.h + "Test.h" + "TestList.h" + "CurrentTest.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TimeHelpers.h + "Config.h" + "Posix/TimeHelpers.h" + "Win32/TimeHelpers.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/Win32/TimeHelpers.h + "../Config.h" + "../HelperMacros.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/ThrowingTestReporter.cpp + "ThrowingTestReporter.h" + "RequiredCheckException.h" + "ReportAssertImpl.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TimeConstraint.cpp + "TimeConstraint.h" + "TestResults.h" + "MemoryOutStream.h" + "CurrentTest.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TimeConstraint.h + "TimeHelpers.h" + "HelperMacros.h" + "TestDetails.h" + +1482076051 source:/mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/XmlTestReporter.cpp + "Config.h" + "XmlTestReporter.h" + + + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/XmlTestReporter.h + "Config.h" + "DeferredTestReporter.h" + + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/crc16.cpp + + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/crc16_ccitt.cpp + + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/crc16_kermit.cpp + + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/crc32.cpp + + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/crc64_ecma.cpp + + +1481309487 source:/mnt/hgfs/Programming/GitHub/etl/src/crc8_ccitt.cpp + + "platform.h" + "static_assert.h" + +1482759320 /mnt/hgfs/Programming/GitHub/etl/src/platform.h + + + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/static_assert.h + "platform.h" + +1479511689 source:/mnt/hgfs/Programming/GitHub/etl/src/error_handler.cpp + "error_handler.h" + "nullptr.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/error_handler.h + + "exception.h" + "function.h" + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/exception.h + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/function.h + +1481308917 /mnt/hgfs/Programming/GitHub/etl/src/nullptr.h + "platform.h" + + +1481841066 source:/mnt/hgfs/Programming/GitHub/etl/src/pearson.cpp + + "platform.h" + "static_assert.h" + +1482079098 source:/mnt/hgfs/Programming/GitHub/etl/src/private/pvoidvector.cpp + "pvoidvector.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/private/pvoidvector.h + + + + + "../platform.h" + "../algorithm.h" + "vector_base.h" + "../type_traits.h" + "../error_handler.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/algorithm.h + + + + + + "type_traits.h" + +1482922140 /mnt/hgfs/Programming/GitHub/etl/src/type_traits.h + + "platform.h" + "nullptr.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/private/vector_base.h + + "../exception.h" + "../error_handler.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/main.cpp + + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/UnitTest++.h + "UnitTestPP.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/UnitTestPP.h + "Config.h" + "TestMacros.h" + "CheckMacros.h" + "RequireMacros.h" + "TestRunner.h" + "TimeConstraint.h" + "ReportAssert.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestMacros.h + "Config.h" + "TestSuite.h" + "ExceptionMacros.h" + "ExecuteTest.h" + "AssertException.h" + "TestDetails.h" + "MemoryOutStream.h" + "Posix/SignalTranslator.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/TestSuite.h + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/CheckMacros.h + "HelperMacros.h" + "ExceptionMacros.h" + "Checks.h" + "AssertException.h" + "RequiredCheckException.h" + "MemoryOutStream.h" + "TestDetails.h" + "CurrentTest.h" + "ReportAssertImpl.h" + +1482076051 /mnt/hgfs/Programming/GitHub/unittest-cpp/UnitTest++/RequireMacros.h + "RequiredCheckTestReporter.h" + +1481841065 source:/mnt/hgfs/Programming/GitHub/etl/test/murmurhash3.cpp + "murmurhash3.h" + + +1479511691 /mnt/hgfs/Programming/GitHub/etl/test/murmurhash3.h + "../src/platform.h" + + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_algorithm.cpp + + "../src/algorithm.h" + "../src/container.h" + + + + + +1482613987 /mnt/hgfs/Programming/GitHub/etl/src/container.h + + + +1482624126 source:/mnt/hgfs/Programming/GitHub/etl/test/test_alignment.cpp + + "../src/alignment.h" + "../src/type_traits.h" + + + + + +1481309570 /mnt/hgfs/Programming/GitHub/etl/src/alignment.h + + "type_traits.h" + "static_assert.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_array.cpp + + "../src/array.h" + + + + "../src/integral_limits.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/array.h + + + + + "exception.h" + "type_traits.h" + "parameter_type.h" + "static_assert.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/parameter_type.h + "type_traits.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/integral_limits.h + + + "type_traits.h" + "platform.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_binary.cpp + + + + "../src/binary.h" + "../src/bitset.h" + "../src/fnv_1.h" + "../src/integral_limits.h" + +1481309537 /mnt/hgfs/Programming/GitHub/etl/src/binary.h + + + "type_traits.h" + "integral_limits.h" + "static_assert.h" + "log.h" + "power.h" + "smallest.h" + "platform.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/log.h + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/power.h + + "log.h" + +1482653105 /mnt/hgfs/Programming/GitHub/etl/src/smallest.h + + "integral_limits.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/bitset.h + + + + + "platform.h" + "integral_limits.h" + "algorithm.h" + "nullptr.h" + "log.h" + "ibitset.h" + "error_handler.h" + +1481309224 /mnt/hgfs/Programming/GitHub/etl/src/ibitset.h + + + + "exception.h" + "integral_limits.h" + "binary.h" + "algorithm.h" + "platform.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/fnv_1.h + + "platform.h" + "static_assert.h" + "type_traits.h" + "ihash.h" + "frame_check_sequence.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/ihash.h + + + "exception.h" + "error_handler.h" + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/frame_check_sequence.h + + "platform.h" + "static_assert.h" + "type_traits.h" + "binary.h" + +1482623861 source:/mnt/hgfs/Programming/GitHub/etl/test/test_bitset.cpp + + + + + "../src/bitset.h" + +1482612858 source:/mnt/hgfs/Programming/GitHub/etl/test/test_bloom_filter.cpp + + + + "../src/bloom_filter.h" + "../src/fnv_1.h" + "../src/crc16.h" + "../src/crc16_ccitt.h" + "../src/crc32.h" + "../src/char_traits.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/bloom_filter.h + "parameter_type.h" + "bitset.h" + "type_traits.h" + "binary.h" + "log.h" + "power.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc16.h + + + "platform.h" + "frame_check_sequence.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc16_ccitt.h + + + "platform.h" + "frame_check_sequence.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc32.h + + + "platform.h" + "frame_check_sequence.h" + +1481309504 /mnt/hgfs/Programming/GitHub/etl/src/char_traits.h + + "platform.h" + "stdint.h" + "algorithm.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_bsd_checksum.cpp + + + + + + "../src/checksum.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/checksum.h + + "binary.h" + "frame_check_sequence.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_checksum.cpp + + + + + + "../src/checksum.h" + "../src/endian.h" + +1481309464 /mnt/hgfs/Programming/GitHub/etl/src/endian.h + + "enum_type.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/enum_type.h + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_container.cpp + + "../src/container.h" + + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_crc.cpp + + + + + + "../src/crc8_ccitt.h" + "../src/crc16.h" + "../src/crc16_ccitt.h" + "../src/crc16_kermit.h" + "../src/crc32.h" + "../src/crc64_ecma.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc8_ccitt.h + + + "platform.h" + "frame_check_sequence.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc16_kermit.h + + + "platform.h" + "frame_check_sequence.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/crc64_ecma.h + + + "platform.h" + "frame_check_sequence.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_cyclic_value.cpp + + "../src/cyclic_value.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/cyclic_value.h + + + "static_assert.h" + "exception.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_debounce.cpp + + "../src/debounce.h" + +1481309477 /mnt/hgfs/Programming/GitHub/etl/src/debounce.h + + "static_assert.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_deque.cpp + + "ExtraCheckMacros.h" + "../src/deque.h" + "data.h" + + + + + + +1479511691 /mnt/hgfs/Programming/GitHub/etl/test/ExtraCheckMacros.h + + + + + + + + + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/deque.h + + + + + "ideque.h" + "container.h" + "alignment.h" + "array.h" + +1482624126 /mnt/hgfs/Programming/GitHub/etl/src/ideque.h + + + "algorithm.h" + "type_traits.h" + "private/deque_base.h" + "parameter_type.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/deque_base.h + + "../exception.h" + "../error_handler.h" + +1482185150 /mnt/hgfs/Programming/GitHub/etl/test/data.h + + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_endian.cpp + + + "../src/endian.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_enum_type.cpp + + + "../src/enum_type.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_error_handler.cpp + + + + + "../src/error_handler.h" + "../src/exception.h" + +1482625380 source:/mnt/hgfs/Programming/GitHub/etl/test/test_exception.cpp + + + "../src/exception.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_fixed_iterator.cpp + + + + "../src/fixed_iterator.h" + +1482624125 /mnt/hgfs/Programming/GitHub/etl/src/fixed_iterator.h + + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_flat_map.cpp + + + + + + + + + "data.h" + "../src/flat_map.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/flat_map.h + + + + "iflat_map.h" + "vector.h" + +1482748252 /mnt/hgfs/Programming/GitHub/etl/src/iflat_map.h + + + + + + "private/flat_map_base.h" + "type_traits.h" + "parameter_type.h" + "ivector.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/flat_map_base.h + + "../exception.h" + "../ivector.h" + "../error_handler.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/ivector.h + + + + + "platform.h" + "algorithm.h" + "private/vector_base.h" + "type_traits.h" + "parameter_type.h" + "error_handler.h" + "private/ivectorpointer.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/private/ivectorpointer.h + "pvoidvector.h" + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/vector.h + + + + "ivector.h" + "container.h" + "alignment.h" + "array.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_flat_multimap.cpp + + + + + + + + + "data.h" + "../src/flat_multimap.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/flat_multimap.h + + + + "iflat_multimap.h" + "vector.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/iflat_multimap.h + + + + + + "private/flat_multimap_base.h" + "type_traits.h" + "parameter_type.h" + "ivector.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/flat_multimap_base.h + + "../exception.h" + "../ivector.h" + "../error_handler.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_flat_multiset.cpp + + + + + + + + + "data.h" + "../src/flat_multiset.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/flat_multiset.h + + + + "iflat_multiset.h" + "vector.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/iflat_multiset.h + + + + + + "private/flat_multiset_base.h" + "type_traits.h" + "parameter_type.h" + "ivector.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/flat_multiset_base.h + + "../exception.h" + "../ivector.h" + "../error_handler.h" + +1479511691 source:/mnt/hgfs/Programming/GitHub/etl/test/test_flat_set.cpp + + + + + + + + + "data.h" + "../src/flat_set.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/flat_set.h + + + + "iflat_set.h" + "vector.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/iflat_set.h + + + + + + "private/flat_set_base.h" + "type_traits.h" + "parameter_type.h" + "ivector.h" + "error_handler.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/flat_set_base.h + + "../exception.h" + "../ivector.h" + "../error_handler.h" + +1482623723 source:/mnt/hgfs/Programming/GitHub/etl/test/test_fnv_1.cpp + + + + + + "../src/fnv_1.h" + +1482625680 source:/mnt/hgfs/Programming/GitHub/etl/test/test_forward_list.cpp + + "ExtraCheckMacros.h" + "data.h" + "../src/forward_list.h" + + + + + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/forward_list.h + + "pool.h" + "iforward_list.h" + "container.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/pool.h + "alignment.h" + "array.h" + "bitset.h" + "ipool.h" + + +1481841065 /mnt/hgfs/Programming/GitHub/etl/src/ipool.h + + "private/pool_base.h" + "nullptr.h" + "ibitset.h" + "error_handler.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/private/pool_base.h + + "../exception.h" + "../error_handler.h" + "../error_handler.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/iforward_list.h + "platform.h" + + + + + "pool.h" + "nullptr.h" + "private/forward_list_base.h" + "type_traits.h" + "parameter_type.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/private/forward_list_base.h + + "../exception.h" + "../error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_function.cpp + + "../src/function.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_functional.cpp + + "../src/functional.h" + + + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/functional.h + +1482624624 source:/mnt/hgfs/Programming/GitHub/etl/test/test_hash.cpp + + + + + + "../src/hash.h" + +1481841145 /mnt/hgfs/Programming/GitHub/etl/src/hash.h + + + "fnv_1.h" + "type_traits.h" + "static_assert.h" + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_instance_count.cpp + + "../src/instance_count.h" + + + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/instance_count.h + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_integral_limits.cpp + + + + + "../src/integral_limits.h" + +1482799048 source:/mnt/hgfs/Programming/GitHub/etl/test/test_intrusive_forward_list.cpp + + "ExtraCheckMacros.h" + "data.h" + "../src/intrusive_forward_list.h" + + + + + + + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/intrusive_forward_list.h + "platform.h" + + + + + "nullptr.h" + "type_traits.h" + "exception.h" + "error_handler.h" + "intrusive_links.h" + "algorithm.h" + "private/counter_type.h" + +1482357841 /mnt/hgfs/Programming/GitHub/etl/src/intrusive_links.h + + + "nullptr.h" + "type_traits.h" + "exception.h" + "error_handler.h" + +1482353821 /mnt/hgfs/Programming/GitHub/etl/src/private/counter_type.h + +1482358550 source:/mnt/hgfs/Programming/GitHub/etl/test/test_intrusive_links.cpp + + "ExtraCheckMacros.h" + "data.h" + "../src/intrusive_links.h" + +1482840779 source:/mnt/hgfs/Programming/GitHub/etl/test/test_intrusive_list.cpp + + "ExtraCheckMacros.h" + "data.h" + "../src/intrusive_list.h" + + + + + + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/intrusive_list.h + "platform.h" + + + + + "nullptr.h" + "type_traits.h" + "exception.h" + "error_handler.h" + "intrusive_links.h" + "static_assert.h" + "algorithm.h" + "private/counter_type.h" + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_intrusive_queue.cpp + + "../src/intrusive_queue.h" + "../src/intrusive_links.h" + + +1482354421 /mnt/hgfs/Programming/GitHub/etl/src/intrusive_queue.h + + "type_traits.h" + "error_handler.h" + "intrusive_links.h" + "private/counter_type.h" + +1482624474 source:/mnt/hgfs/Programming/GitHub/etl/test/test_intrusive_stack.cpp + + "../src/intrusive_stack.h" + "../src/intrusive_links.h" + + +1482354421 /mnt/hgfs/Programming/GitHub/etl/src/intrusive_stack.h + + "type_traits.h" + "error_handler.h" + "intrusive_links.h" + "private/counter_type.h" + +1482750186 source:/mnt/hgfs/Programming/GitHub/etl/test/test_io_port.cpp + + "../src/io_port.h" + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/io_port.h + + "nullptr.h" + "parameter_type.h" + +1482624277 source:/mnt/hgfs/Programming/GitHub/etl/test/test_jenkins.cpp + + "murmurhash3.h" + + + + + "../src/jenkins.h" + "../src/endian.h" + +1481872412 /mnt/hgfs/Programming/GitHub/etl/src/jenkins.h + + + "platform.h" + "static_assert.h" + "type_traits.h" + "error_handler.h" + "ihash.h" + "frame_check_sequence.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_largest.cpp + + "../src/largest.h" + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/largest.h + "type_traits.h" + +1482625302 source:/mnt/hgfs/Programming/GitHub/etl/test/test_list.cpp + + "ExtraCheckMacros.h" + "../src/list.h" + "data.h" + + + + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/list.h + + "ilist.h" + "container.h" + "pool.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/ilist.h + + + + + "nullptr.h" + "private/list_base.h" + "type_traits.h" + "parameter_type.h" + "pool.h" + "platform.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/private/list_base.h + + "../exception.h" + "../error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_map.cpp + + + + + + + + + "../src/map.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/map.h + + + + "imap.h" + "container.h" + "pool.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/imap.h + + + + + "nullptr.h" + "private/map_base.h" + "type_traits.h" + "parameter_type.h" + "pool.h" + "platform.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/private/map_base.h + + "../exception.h" + "../error_handler.h" + +1482692728 source:/mnt/hgfs/Programming/GitHub/etl/test/test_maths.cpp + + "../src/log.h" + "../src/power.h" + "../src/fibonacci.h" + "../src/factorial.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/fibonacci.h + + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/factorial.h + + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_multimap.cpp + + + + + + + + "../src/multimap.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/multimap.h + + + + "imultimap.h" + "container.h" + "pool.h" + +1482098369 /mnt/hgfs/Programming/GitHub/etl/src/imultimap.h + + + + + "nullptr.h" + "private/multimap_base.h" + "type_traits.h" + "parameter_type.h" + "pool.h" + "platform.h" + +1481309650 /mnt/hgfs/Programming/GitHub/etl/src/private/multimap_base.h + + "../exception.h" + "../error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_multiset.cpp + + + + + + + + "../src/multiset.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/multiset.h + + + + "imultiset.h" + "container.h" + "pool.h" + +1482098369 /mnt/hgfs/Programming/GitHub/etl/src/imultiset.h + + + + + "nullptr.h" + "private/multiset_base.h" + "type_traits.h" + "parameter_type.h" + "pool.h" + "platform.h" + +1481309628 /mnt/hgfs/Programming/GitHub/etl/src/private/multiset_base.h + + "../exception.h" + "../error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_murmur3.cpp + + "murmurhash3.h" + + + + + "../src/murmur3.h" + "../src/endian.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/murmur3.h + + "platform.h" + "ihash.h" + "binary.h" + "error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_numeric.cpp + + "../src/numeric.h" + + + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/numeric.h + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_observer.cpp + + "../src/observer.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/observer.h + + "vector.h" + "exception.h" + "error_handler.h" + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_optional.cpp + + + + "../src/optional.h" + "../src/vector.h" + "data.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/optional.h + "alignment.h" + "type_traits.h" + "exception.h" + "error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_pearson.cpp + + + + + + + "../src/pearson.h" + "../src/endian.h" + +1481308892 /mnt/hgfs/Programming/GitHub/etl/src/pearson.h + + "platform.h" + "static_assert.h" + "type_traits.h" + "endian.h" + "ihash.h" + "array.h" + "container.h" + +1482750186 source:/mnt/hgfs/Programming/GitHub/etl/test/test_pool.cpp + + "ExtraCheckMacros.h" + "data.h" + + + "../src/pool.h" + +1482624474 source:/mnt/hgfs/Programming/GitHub/etl/test/test_priority_queue.cpp + + + "../src/priority_queue.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/priority_queue.h + + + "ipriority_queue.h" + "container.h" + "vector.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/ipriority_queue.h + + + "type_traits.h" + "parameter_type.h" + "error_handler.h" + "exception.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_queue.cpp + + + "../src/queue.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/queue.h + + + "iqueue.h" + "container.h" + "alignment.h" + "array.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/iqueue.h + + "private/queue_base.h" + "type_traits.h" + "parameter_type.h" + "error_handler.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/private/queue_base.h + + "../exception.h" + "../error_handler.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_set.cpp + + + + + + + + + "../src/set.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/set.h + + + + "iset.h" + "container.h" + "pool.h" + +1479511690 /mnt/hgfs/Programming/GitHub/etl/src/iset.h + + + + + "nullptr.h" + "private/set_base.h" + "type_traits.h" + "parameter_type.h" + "pool.h" + "platform.h" + +1482625676 /mnt/hgfs/Programming/GitHub/etl/src/private/set_base.h + + "../exception.h" + "../error_handler.h" + +1482654345 source:/mnt/hgfs/Programming/GitHub/etl/test/test_smallest.cpp + + "../src/smallest.h" + + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_stack.cpp + + + "data.h" + "../src/stack.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/stack.h + + + + "istack.h" + "container.h" + "alignment.h" + "array.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/istack.h + + "private/stack_base.h" + "type_traits.h" + "parameter_type.h" + "error_handler.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/private/stack_base.h + + "../exception.h" + "../error_handler.h" + +1482614415 source:/mnt/hgfs/Programming/GitHub/etl/test/test_string_char.cpp + + + + + "../src/cstring.h" + +1482614484 /mnt/hgfs/Programming/GitHub/etl/src/cstring.h + "platform.h" + "basic_string.h" + "ibasic_string.h" + "hash.h" + +1479511689 /mnt/hgfs/Programming/GitHub/etl/src/basic_string.h + + + + "ibasic_string.h" + "char_traits.h" + "container.h" + "alignment.h" + "array.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/ibasic_string.h + + + + + + "private/string_base.h" + "platform.h" + "algorithm.h" + "type_traits.h" + "error_handler.h" + "algorithm.h" + "char_traits.h" + +1482614484 /mnt/hgfs/Programming/GitHub/etl/src/private/string_base.h + + "../platform.h" + "../integral_limits.h" + "../exception.h" + "../error_handler.h" + +1482099557 source:/mnt/hgfs/Programming/GitHub/etl/test/test_string_u16.cpp + + + + + "../src/u16string.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/u16string.h + "platform.h" + "basic_string.h" + "hash.h" + +1482099666 source:/mnt/hgfs/Programming/GitHub/etl/test/test_string_u32.cpp + + + + + "../src/u32string.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/u32string.h + "platform.h" + "basic_string.h" + "hash.h" + +1482181573 source:/mnt/hgfs/Programming/GitHub/etl/test/test_string_wchar_t.cpp + + + + + "../src/wstring.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/wstring.h + "platform.h" + "basic_string.h" + "hash.h" + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_type_def.cpp + + + "../src/type_def.h" + +1481841066 /mnt/hgfs/Programming/GitHub/etl/src/type_def.h + +1482624915 source:/mnt/hgfs/Programming/GitHub/etl/test/test_unordered_map.cpp + + + + + + + + + + "data.h" + "../src/unordered_map.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/unordered_map.h + + + + "iunordered_map.h" + "container.h" + "pool.h" + "vector.h" + "intrusive_forward_list.h" + "hash.h" + +1482748240 /mnt/hgfs/Programming/GitHub/etl/src/iunordered_map.h + + + + + + "type_traits.h" + "parameter_type.h" + "hash.h" + "nullptr.h" + "ipool.h" + "ivector.h" + "error_handler.h" + "intrusive_forward_list.h" + "exception.h" + "error_handler.h" + +1482625301 source:/mnt/hgfs/Programming/GitHub/etl/test/test_unordered_multimap.cpp + + + + + + + + + + "data.h" + "../src/unordered_multimap.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/unordered_multimap.h + + + + "iunordered_multimap.h" + "container.h" + "pool.h" + "vector.h" + "intrusive_forward_list.h" + "hash.h" + +1482748240 /mnt/hgfs/Programming/GitHub/etl/src/iunordered_multimap.h + + + + + + "type_traits.h" + "parameter_type.h" + "hash.h" + "nullptr.h" + "ipool.h" + "ivector.h" + "error_handler.h" + "intrusive_forward_list.h" + "exception.h" + "error_handler.h" + +1482625301 source:/mnt/hgfs/Programming/GitHub/etl/test/test_unordered_multiset.cpp + + + + + + + + + + "data.h" + "../src/unordered_multiset.h" + "../src/checksum.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/unordered_multiset.h + + + + "iunordered_multiset.h" + "container.h" + "pool.h" + "vector.h" + "intrusive_forward_list.h" + "hash.h" + +1482748239 /mnt/hgfs/Programming/GitHub/etl/src/iunordered_multiset.h + + + + + + "type_traits.h" + "parameter_type.h" + "hash.h" + "nullptr.h" + "ipool.h" + "ivector.h" + "error_handler.h" + "intrusive_forward_list.h" + "exception.h" + "error_handler.h" + +1482624916 source:/mnt/hgfs/Programming/GitHub/etl/test/test_unordered_set.cpp + + + + + + + + + "data.h" + "../src/unordered_set.h" + "../src/checksum.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/unordered_set.h + + + + "iunordered_set.h" + "container.h" + "pool.h" + "vector.h" + "intrusive_forward_list.h" + "hash.h" + +1482748240 /mnt/hgfs/Programming/GitHub/etl/src/iunordered_set.h + + + + + + "type_traits.h" + "parameter_type.h" + "hash.h" + "nullptr.h" + "ipool.h" + "ivector.h" + "error_handler.h" + "intrusive_forward_list.h" + "exception.h" + "error_handler.h" + +1482074959 source:/mnt/hgfs/Programming/GitHub/etl/test/test_utility.cpp + + "../src/utility.h" + +1482075058 /mnt/hgfs/Programming/GitHub/etl/src/utility.h + "type_traits.h" + +1481841066 source:/mnt/hgfs/Programming/GitHub/etl/test/test_variant.cpp + + "ExtraCheckMacros.h" + "../src/variant.h" + + + + +1481841437 /mnt/hgfs/Programming/GitHub/etl/src/variant.h + + "platform.h" + "array.h" + "largest.h" + "exception.h" + "type_traits.h" + "integral_limits.h" + "static_assert.h" + "alignment.h" + "error_handler.h" + "largest.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_vector.cpp + + + + + "../src/vector.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_vector_pointer.cpp + + + + + "../src/vector.h" + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_visitor.cpp + + "../src/visitor.h" + +1479511691 /mnt/hgfs/Programming/GitHub/etl/src/visitor.h + +1479511692 source:/mnt/hgfs/Programming/GitHub/etl/test/test_xor_checksum.cpp + + + + + + "../src/checksum.h" + +1482922480 source:/mnt/hgfs/Programming/GitHub/etl/test/test_type_traits.cpp + + "../src/type_traits.h" + + + diff --git a/test/codeblocks/ETL.layout b/test/codeblocks/ETL.layout index 8fa3ea47..199dbeca 100644 --- a/test/codeblocks/ETL.layout +++ b/test/codeblocks/ETL.layout @@ -1,355 +1,419 @@ - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/data.h b/test/data.h index c256cc4f..15c10dd4 100644 --- a/test/data.h +++ b/test/data.h @@ -40,7 +40,7 @@ class TestDataDC public: TestDataDC() - : value(T()) + : value(T()) { } @@ -89,10 +89,6 @@ class TestDataNDC { public: - TestDataNDC() - : value(T()) - {} - TestDataNDC(const T& value) : value(value) {} diff --git a/test/murmurhash3.cpp b/test/murmurhash3.cpp index 75a6110e..eb453366 100644 --- a/test/murmurhash3.cpp +++ b/test/murmurhash3.cpp @@ -7,7 +7,7 @@ // compile and run any of them on any platform, but your performance with the // non-native version will be less than optimal. -#include "MurmurHash3.h" +#include "murmurhash3.h" //----------------------------------------------------------------------------- // Platform-specific functions and macros diff --git a/test/test_algorithm.cpp b/test/test_algorithm.cpp index 91782b90..9cf62747 100644 --- a/test/test_algorithm.cpp +++ b/test/test_algorithm.cpp @@ -32,6 +32,7 @@ SOFTWARE. #include "../src/container.h" #include +#include #include #include #include @@ -143,6 +144,80 @@ namespace CHECK(!is_sorted); } + //========================================================================= + TEST(copy_4_parameter_random_iterator) + { + int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int data2[] = { 1, 2, 3, 4, 5 }; + + int out1[10]; + int out2[5]; + + int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int check2[] = { 1, 2, 3, 4, 5 }; + int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; + + int* result; + + // Same size. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::end(out1), result); + bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); + CHECK(is_same); + + // Destination smaller. + std::fill(std::begin(out2), std::end(out2), 0); + result = etl::copy(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2)); + CHECK_EQUAL(std::end(out2), result); + is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); + CHECK(is_same); + + // Source smaller. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy(std::begin(data2), std::end(data2), std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::begin(out1) + 5, result); + is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); + CHECK(is_same); + } + + //========================================================================= + TEST(copy_4_parameter_non_random_iterator) + { + std::list data1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + std::list data2 = { 1, 2, 3, 4, 5 }; + + int out1[10]; + int out2[5]; + + int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int check2[] = { 1, 2, 3, 4, 5 }; + int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; + + int* result; + + // Same size. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::end(out1), result); + bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); + CHECK(is_same); + + // Destination smaller. + std::fill(std::begin(out2), std::end(out2), 0); + result = etl::copy(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2)); + CHECK_EQUAL(std::end(out2), result); + is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); + CHECK(is_same); + + // Source smaller. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy(std::begin(data2), std::end(data2), std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::begin(out1) + 5, result); + is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); + CHECK(is_same); + } + //========================================================================= TEST(copy_n) { @@ -150,13 +225,53 @@ namespace int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int* result; + std::copy_n(std::begin(data1), 4, std::begin(data2)); - etl::copy_n(std::begin(data1), 4, std::begin(data3)); + result = etl::copy_n(std::begin(data1), 4, std::begin(data3)); + + CHECK_EQUAL(std::begin(data3) + 4, result); bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3)); CHECK(is_same); } + //========================================================================= + TEST(copy_n_4_parameter) + { + int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + int out1[10]; + int out2[5]; + + int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int check2[] = { 1, 2, 3, 4, 5 }; + int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; + + int* result; + + // Same size. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy_n(std::begin(data1), 10, std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::end(out1), result); + bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); + CHECK(is_same); + + // Destination smaller. + std::fill(std::begin(out2), std::end(out2), 0); + result = etl::copy_n(std::begin(data1), 10, std::begin(out2), std::end(out2)); + CHECK_EQUAL(std::end(out2), result); + is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); + CHECK(is_same); + + // Source smaller. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy_n(std::begin(data1), 5, std::begin(out1), std::end(out1)); + CHECK_EQUAL(std::begin(out1) + 5, result); + is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); + CHECK(is_same); + } + //========================================================================= TEST(copy_if) { @@ -172,6 +287,44 @@ namespace CHECK(is_same); } + //========================================================================= + TEST(copy_if_4_parameter) + { + int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int data2[] = { 1, 8, 2, 7, 3 }; + + int out1[4]; + int out2[2]; + int out3[10]; + + int check1[] = { 1, 2, 3, 4 }; + int check2[] = { 1, 2 }; + int check3[] = { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0 }; + + int* result; + + // Exact size. + std::fill(std::begin(out1), std::end(out1), 0); + result = etl::copy_if(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1), std::bind2nd(std::less(), 5)); + CHECK_EQUAL(std::end(out1), result); + bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); + CHECK(is_same); + + // Destination smaller. + std::fill(std::begin(out2), std::end(out2), 0); + result = etl::copy_if(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2), std::bind2nd(std::less(), 5)); + CHECK_EQUAL(std::end(out2), result); + is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); + CHECK(is_same); + + // Destination larger. + std::fill(std::begin(out3), std::end(out3), 0); + result = etl::copy_if(std::begin(data1), std::end(data1), std::begin(out3), std::end(out3), std::bind2nd(std::less(), 5)); + CHECK_EQUAL(std::begin(out3) + 4, result); + is_same = std::equal(std::begin(out3), std::end(out3), std::begin(check3)); + CHECK(is_same); + } + //========================================================================= TEST(any_of) { @@ -318,5 +471,185 @@ namespace int* p = std::find_if_not(std::begin(data1), std::end(data1), std::bind2nd(std::less(), 4)); CHECK_EQUAL(5, *p); } + + //========================================================================= + TEST(for_each_if) + { + int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + + struct Sum + { + Sum() : sum(0) { } + + Sum& operator()(int i) + { + sum += i; + + return *this; + } + + int sum; + } accumulator; + + // For each if everything less than 5. + accumulator = etl::for_each_if(std::begin(data1), + std::end(data1), + accumulator, + std::bind2nd(std::less(), 5)); + + CHECK_EQUAL(10, accumulator.sum); + } + + //========================================================================= + TEST(transform_4_parameter) + { + int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare[] = { 2, 16, 4, 14, 6, 0, 0, 0, 0, 0 }; + + // Double everything and copy to output. + etl::transform(std::begin(input), + std::end(input), + std::begin(output), + std::begin(output) + (etl::size(output) / 2), + std::bind2nd(std::multiplies(), 2)); + + bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + + std::fill(std::begin(output), std::end(output), 0); + + etl::transform(std::begin(input), + std::begin(input) + (etl::size(input) / 2), + std::begin(output), + std::end(output), + std::bind2nd(std::multiplies(), 2)); + + is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + } + + //========================================================================= + TEST(transform_n_random_iterator) + { + int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; + + etl::transform_n(std::begin(input), + 7, + std::begin(output), + std::bind2nd(std::multiplies(), 2)); + + bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + } + + //========================================================================= + TEST(transform_n_non_random_iterator) + { + std::list input = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; + + etl::transform_n(std::begin(input), + 7, + std::begin(output), + std::bind2nd(std::multiplies(), 2)); + + bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + } + + //========================================================================= + TEST(transform_if) + { + int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare[] = { 2, 4, 6, 8, 0, 0, 0, 0, 0, 0 }; + + // Double everything less than 5 and copy to output. + etl::transform_if(std::begin(input), + std::end(input), + std::begin(output), + std::bind2nd(std::multiplies(), 2), + std::bind2nd(std::less(), 5)); + + bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + } + + //========================================================================= + TEST(transform_if_2_input_ranges) + { + int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int input2[] = { 8, 7, 6, 5, 4, 10, 9, 3, 2, 1 }; + int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare[] = { 8, 12, 12, 60, 36, 0, 0, 0, 0, 0 }; + + // Multiply together everything where input1 is less than input2 and copy to output. + etl::transform_if(std::begin(input1), + std::end(input1), + std::begin(input2), + std::begin(output), + std::multiplies(), + std::less()); + + bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); + CHECK(is_same); + } + + //========================================================================= + TEST(partition_transform) + { + int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int output_true[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int output_false[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare_true[] = { 2, 4, 6, 8, 0, 0, 0, 0, 0, 0 }; + int compare_false[] = { -16, -14, -12, -10, -20, -18, 0, 0, 0, 0 }; + + // Multiply everything less than 5 by 2 and copy to output_true. + // Multiply everything not less than 5 by -2 and copy to output_false. + etl::partition_transform(std::begin(input), + std::end(input), + std::begin(output_true), + std::begin(output_false), + std::bind2nd(std::multiplies(), 2), + std::bind2nd(std::multiplies(), -2), + std::bind2nd(std::less(), 5)); + + bool is_same = std::equal(std::begin(output_true), std::end(output_true), std::begin(compare_true)); + CHECK(is_same); + + is_same = std::equal(std::begin(output_false), std::end(output_false), std::begin(compare_false)); + CHECK(is_same); + } + + //========================================================================= + TEST(partition_transform_2_input_ranges) + { + int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; + int input2[] = { 8, 7, 6, 5, 4, 10, 9, 3, 2, 1 }; + int output_true[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int output_false[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int compare_true[] = { 8, 12, 12, 60, 36, 0, 0, 0, 0, 0 }; + int compare_false[] = { 15, 12, 8, 12, 10, 0, 0, 0, 0, 0 }; + + // If input1 < input2 multiply else add. + etl::partition_transform(std::begin(input1), + std::end(input1), + std::begin(input2), + std::begin(output_true), + std::begin(output_false), + std::multiplies(), + std::plus(), + std::less()); + + bool is_same = std::equal(std::begin(output_true), std::end(output_true), std::begin(compare_true)); + CHECK(is_same); + + is_same = std::equal(std::begin(output_false), std::end(output_false), std::begin(compare_false)); + CHECK(is_same); + } }; } diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index ed90a952..f3b28b42 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -36,7 +36,7 @@ SOFTWARE. #include #include -void f(int a) +void f(int) { } diff --git a/test/test_array.cpp b/test/test_array.cpp index 527e8343..69073e35 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -348,6 +348,232 @@ namespace //int i = etl::get<11>(data2); } + //************************************************************************* + TEST(test_assign) + { + int initial[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; + int source[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + int check1[] = { 0, 1, 2, 3, 4, -1, -1, -1, -1, -1 }; + int check2[] = { 0, 1, 2, 3, 4, 99, 99, 99, 99, 99 }; + int check3[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + Data data; + + // Initial data. + data.assign(std::begin(initial), std::end(initial)); + bool isEqual = std::equal(data.begin(), data.end(), std::begin(initial)); + CHECK(isEqual); + + // Assign smaller. + data.assign(std::begin(initial), std::end(initial)); + data.assign(&source[0], &source[5]); + isEqual = std::equal(data.begin(), data.end(), std::begin(check1)); + CHECK(isEqual); + + // Assign smaller + default. + data.assign(std::begin(initial), std::end(initial)); + data.assign(&source[0], &source[5], 99); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2)); + CHECK(isEqual); + + // Assign larger. + data.assign(std::begin(initial), std::end(initial)); + data.assign(&source[0], &source[13]); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3)); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_insert_value) + { + int initial[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int check1[] = { 99, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + int check2[] = { 0, 1, 2, 3, 4, 99, 5, 6, 7, 8 }; + int check3[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 99 }; + + Data data; + Data::iterator result; + + // Insert beginning. + data.assign(std::begin(initial), std::end(initial)); + result = data.insert_at(0, 99); + CHECK_EQUAL(data[0], *result); + bool isEqual = std::equal(data.begin(), data.end(), std::begin(check1)); + CHECK(isEqual); + + // Insert middle. + data.assign(std::begin(initial), std::end(initial)); + result = data.insert_at(5, 99); + CHECK_EQUAL(data[5], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2)); + CHECK(isEqual); + + // Insert end. + data.assign(std::begin(initial), std::end(initial)); + result = data.insert_at(9, 99); + CHECK_EQUAL(data[9], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3)); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_insert_range) + { + int source1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + int source2[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + int check1[] = { 12, 11, 10, 0, 1, 2, 3, 4, 5, 6 }; + int check2[] = { 0, 1, 2, 3, 12, 11, 10, 4, 5, 6 }; + int check3[] = { 0, 1, 2, 3, 4, 5, 6, 12, 11, 10 }; + int check4[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3 }; + int check5[] = { 0, 1, 2, 3, 12, 11, 10, 9, 8, 7, 6 }; + + Data data; + Data::iterator result; + + // Insert smaller, beginning. + data.assign(std::begin(source1), std::end(source1)); + result = data.insert_at(0, &source2[0], &source2[3]); + CHECK_EQUAL(data[0], *result); + bool isEqual = std::equal(data.begin(), data.end(), std::begin(check1)); + CHECK(isEqual); + + // Insert smaller, middle. + data.assign(std::begin(source1), std::end(source1)); + result = data.insert_at(4, &source2[0], &source2[3]); + CHECK_EQUAL(data[4], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2)); + CHECK(isEqual); + + // Insert smaller, end. + data.assign(std::begin(source1), std::end(source1)); + result = data.insert_at(7, &source2[0], &source2[3]); + CHECK_EQUAL(data[7], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3)); + CHECK(isEqual); + + // Insert larger, beginning. + data.assign(std::begin(source1), std::end(source1)); + result = data.insert_at(0, &source2[0], &source2[13]); + CHECK_EQUAL(data[0], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check4)); + CHECK(isEqual); + + // Insert larger, middle. + data.assign(std::begin(source1), std::end(source1)); + result = data.insert_at(4, &source2[0], &source2[13]); + CHECK_EQUAL(data[4], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check5)); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_erase_single) + { + int initial[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int check1a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 }; + int check1b[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 99 }; + int check2a[] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 9 }; + int check2b[] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 99 }; + int check3a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int check3b[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 99 }; + + Data data; + Data::iterator result; + + // Erase beginning. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(0); + CHECK_EQUAL(data[0], *result); + bool isEqual = std::equal(data.begin(), data.end(), std::begin(check1a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(0, 99); + CHECK_EQUAL(data[0], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check1b)); + CHECK(isEqual); + + // Erase middle. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(5); + CHECK_EQUAL(data[5], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(5, 99); + CHECK_EQUAL(data[5], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2b)); + CHECK(isEqual); + + // Erase last. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(9); + CHECK_EQUAL(data[9], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_at(9, 99); + CHECK_EQUAL(data[9], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); + CHECK(isEqual); + } + + //************************************************************************* + TEST(test_erase_range) + { + int initial[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int check1a[] = { 5, 6, 7, 8, 9, 5, 6, 7, 8, 9 }; + int check1b[] = { 5, 6, 7, 8, 9, 99, 99, 99, 99, 99 }; + int check2a[] = { 0, 1, 7, 8, 9, 5, 6, 7, 8, 9 }; + int check2b[] = { 0, 1, 7, 8, 9, 99, 99, 99, 99, 99 }; + int check3a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int check3b[] = { 0, 1, 2, 3, 4, 99, 99, 99, 99, 99 }; + + Data data; + Data::iterator result; + + // Erase beginning. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(0, 5); + CHECK_EQUAL(data[0], *result); + bool isEqual = std::equal(data.begin(), data.end(), std::begin(check1a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(0, 5, 99); + CHECK_EQUAL(data[0], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check1b)); + CHECK(isEqual); + + // Erase middle. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(2, 7); + CHECK_EQUAL(data[2], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(2, 7, 99); + CHECK_EQUAL(data[2], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check2b)); + CHECK(isEqual); + + // Erase last. + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(5, 10); + CHECK_EQUAL(data[5], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3a)); + CHECK(isEqual); + + data.assign(std::begin(initial), std::end(initial)); + result = data.erase_range(5, 10, 99); + CHECK_EQUAL(data[5], *result); + isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); + CHECK(isEqual); + } + //************************************************************************* TEST(test_equal) { diff --git a/test/test_bitset.cpp b/test/test_bitset.cpp index a0ce46a4..6a863299 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset.cpp @@ -432,6 +432,8 @@ namespace bool bc = ~compare[3]; bool bd = ~data[3]; + CHECK_EQUAL(bc, bd); + for (size_t i = 0; i < data.size(); ++i) { CHECK_EQUAL(compare.test(i), data.test(i)); @@ -593,7 +595,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 & 0x23456789); - etl::bitset<60>& rdata = data2 &= data1; + data2 &= data1; CHECK(data2 == data3); } @@ -616,7 +618,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 | 0x23456789); - etl::bitset<60>& rdata = data2 |= data1; + data2 |= data1; CHECK(data2 == data3); } @@ -639,7 +641,7 @@ namespace etl::bitset<60> data2(0x23456789); etl::bitset<60> data3(0x12345678 ^ 0x23456789); - etl::bitset<60>& rdata = data2 ^= data1; + data2 ^= data1; CHECK(data2 == data3); } @@ -723,32 +725,32 @@ namespace etl::bitset<6> data; data.set("000000"); - CHECK_EQUAL(0, data.find_first(false)); + CHECK_EQUAL(0U, data.find_first(false)); CHECK_EQUAL(etl::ibitset::npos, data.find_first(true)); data.set("111111"); CHECK_EQUAL(etl::ibitset::npos, data.find_first(false)); - CHECK_EQUAL(0, data.find_first(true)); + CHECK_EQUAL(0U, data.find_first(true)); data.set("000001"); - CHECK_EQUAL(1, data.find_first(false)); - CHECK_EQUAL(0, data.find_first(true)); + CHECK_EQUAL(1U, data.find_first(false)); + CHECK_EQUAL(0U, data.find_first(true)); data.set("100000"); - CHECK_EQUAL(0, data.find_first(false)); - CHECK_EQUAL(5, data.find_first(true)); + CHECK_EQUAL(0U, data.find_first(false)); + CHECK_EQUAL(5U, data.find_first(true)); data.set("100001"); - CHECK_EQUAL(1, data.find_first(false)); - CHECK_EQUAL(0, data.find_first(true)); + CHECK_EQUAL(1U, data.find_first(false)); + CHECK_EQUAL(0U, data.find_first(true)); data.set("001110"); - CHECK_EQUAL(0, data.find_first(false)); - CHECK_EQUAL(1, data.find_first(true)); + CHECK_EQUAL(0U, data.find_first(false)); + CHECK_EQUAL(1U, data.find_first(true)); data.set("110001"); - CHECK_EQUAL(1, data.find_first(false)); - CHECK_EQUAL(0, data.find_first(true)); + CHECK_EQUAL(1U, data.find_first(false)); + CHECK_EQUAL(0U, data.find_first(true)); } //************************************************************************* @@ -757,24 +759,24 @@ namespace etl::bitset<6> data; data.set("000000"); - CHECK_EQUAL(0, data.find_next(false, 0)); - CHECK_EQUAL(1, data.find_next(false, 1)); + CHECK_EQUAL(0U, data.find_next(false, 0)); + CHECK_EQUAL(1U, data.find_next(false, 1)); CHECK_EQUAL(etl::ibitset::npos, data.find_next(true, 2)); data.set("111111"); - CHECK_EQUAL(0, data.find_next(true, 0)); - CHECK_EQUAL(1, data.find_next(true, 1)); + CHECK_EQUAL(0U, data.find_next(true, 0)); + CHECK_EQUAL(1U, data.find_next(true, 1)); CHECK_EQUAL(etl::ibitset::npos, data.find_next(false, 2)); data.set("001110"); - CHECK_EQUAL(0, data.find_next(false, 0)); - CHECK_EQUAL(1, data.find_next(true, 0)); - CHECK_EQUAL(4, data.find_next(false, 1)); + CHECK_EQUAL(0U, data.find_next(false, 0)); + CHECK_EQUAL(1U, data.find_next(true, 0)); + CHECK_EQUAL(4U, data.find_next(false, 1)); data.set("110001"); - CHECK_EQUAL(0, data.find_next(true, 0)); - CHECK_EQUAL(1, data.find_next(false, 0)); - CHECK_EQUAL(4, data.find_next(true, 1)); + CHECK_EQUAL(0U, data.find_next(true, 0)); + CHECK_EQUAL(1U, data.find_next(false, 0)); + CHECK_EQUAL(4U, data.find_next(true, 1)); } diff --git a/test/test_bloom_filter.cpp b/test/test_bloom_filter.cpp index 46341f12..eed634bb 100644 --- a/test/test_bloom_filter.cpp +++ b/test/test_bloom_filter.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include -#include #include +#include #include "../src/bloom_filter.h" @@ -38,13 +38,15 @@ SOFTWARE. #include "../src/crc16_ccitt.h" #include "../src/crc32.h" +#include "../src/char_traits.h" + struct hash1_t { typedef const char* argument_type; size_t operator ()(argument_type text) const { - return etl::fnv_1a_32(text, text + strlen(text)); + return etl::fnv_1a_32(text, text + etl::char_traits::length(text)); } }; @@ -54,7 +56,7 @@ struct hash2_t size_t operator ()(argument_type text) const { - return etl::crc32(text, text + strlen(text)); + return etl::crc32(text, text + etl::char_traits::length(text)); } }; @@ -64,7 +66,7 @@ struct hash3_t size_t operator ()(argument_type text) const { - return etl::crc16(text, text + strlen(text)) | (etl::crc16_ccitt(text, text + strlen(text)) << 16); + return etl::crc16(text, text + etl::char_traits::length(text)) | (etl::crc16_ccitt(text, text + etl::char_traits::length(text)) << 16); } }; @@ -106,7 +108,7 @@ namespace CHECK(!any_exist); size_t usage = bloom.usage(); - CHECK(usage >= 0); + CHECK(usage > 0); CHECK(usage < 100); size_t count = bloom.count(); @@ -145,7 +147,6 @@ namespace CHECK(!any_exist); size_t usage = bloom.usage(); - CHECK(usage >= 0); CHECK(usage < 100); size_t count = bloom.count(); @@ -184,7 +185,6 @@ namespace CHECK(!any_exist); size_t usage = bloom.usage(); - CHECK(usage >= 0); CHECK(usage < 100); size_t count = bloom.count(); diff --git a/test/test_deque.cpp b/test/test_deque.cpp index e97efee9..d029ed50 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -41,8 +41,8 @@ SOFTWARE. namespace { - SUITE(test_deque) - { + SUITE(test_deque) + { const size_t SIZE = 14; typedef TestDataDC DC; @@ -84,12 +84,12 @@ namespace std::vector initial_data_dc = { DC("0"), DC("1"), DC("2"), DC("3"), DC("4"), DC("5"), DC("6"), DC("7"), DC("8"), DC("9"), DC("10"), DC("11"), DC("12"), DC("13") }; //************************************************************************* - TEST(test_constructor) - { + TEST(test_constructor) + { DataDC data; CHECK_EQUAL(SIZE, data.max_size()); - } + } //************************************************************************* TEST(test_constructor_fill) @@ -118,24 +118,18 @@ namespace } //************************************************************************* - TEST(test_constructor_range_excess) + TEST(test_copy_constructor) { - CHECK_THROW(DataNDC data(initial_data_excess.begin(), initial_data_excess.end()), etl::deque_full); - } - - //************************************************************************* - TEST(test_copy_constructor) - { DataNDC deque1(initial_data.begin(), initial_data.end()); DataNDC deque2(deque1); CHECK_EQUAL(deque1.size(), deque2.size()); CHECK(std::equal(deque1.begin(), deque1.end(), deque2.begin())); - } + } //************************************************************************* - TEST(test_assignment) - { + TEST(test_assignment) + { DataNDC deque1(initial_data.begin(), initial_data.end()); DataNDC deque2; @@ -143,7 +137,7 @@ namespace CHECK_EQUAL(deque1.size(), deque2.size()); CHECK(std::equal(deque1.begin(), deque1.end(), deque2.begin())); - } + } //************************************************************************* TEST(test_assignment_interface) @@ -1477,8 +1471,8 @@ namespace } //************************************************************************* - TEST(test_equality_operator) - { + TEST(test_equality_operator) + { Compare_Data same = { N1, N2, N3, N4, N5, N6 }; Compare_Data different = { N6, N5, N4, N3, N2, N1 }; @@ -1491,7 +1485,7 @@ namespace std::copy(different.begin(), different.end(), deque2.begin()); CHECK(!(deque1 == deque2)); - } + } //************************************************************************* TEST(test_inequality_operator) @@ -1520,5 +1514,5 @@ namespace CHECK(data.rbegin() == data.rend()); CHECK(data.crbegin() == data.crend()); } - }; + }; } diff --git a/test/test_enum_type.cpp b/test/test_enum_type.cpp index c8b84c77..eebd017c 100644 --- a/test/test_enum_type.cpp +++ b/test/test_enum_type.cpp @@ -41,11 +41,11 @@ struct enum_test FOUR }; - DECLARE_ENUM_TYPE(enum_test, int) - ENUM_TYPE(ZERO, "ZERO") - ENUM_TYPE(ONE, "ONE") - ENUM_TYPE(THREE, "THREE") - END_ENUM_TYPE + ETL_DECLARE_ENUM_TYPE(enum_test, int) + ETL_ENUM_TYPE(ZERO, "ZERO") + ETL_ENUM_TYPE(ONE, "ONE") + ETL_ENUM_TYPE(THREE, "THREE") + ETL_END_ENUM_TYPE }; namespace @@ -75,7 +75,7 @@ namespace value = enum_test::THREE; CHECK_EQUAL(std::string("THREE"), std::string(value.c_str())); - // No ENUM_TYPE definition. + // No ETL_ENUM_TYPE definition. value = enum_test::FOUR; CHECK_EQUAL(std::string("?"), std::string(value.c_str())); diff --git a/test/test_exception.cpp b/test/test_exception.cpp index 9d1854cc..c99816b4 100644 --- a/test/test_exception.cpp +++ b/test/test_exception.cpp @@ -40,10 +40,6 @@ namespace { etl::exception e("An exception", "Some file", 123); - std::string what(e.what()); - std::string file(e.file_name()); - int line(e.line_number()); - CHECK_EQUAL(std::string("An exception"), std::string(e.what())); CHECK_EQUAL(std::string("Some file"), std::string(e.file_name())); CHECK_EQUAL(123, e.line_number()); @@ -60,14 +56,10 @@ namespace } catch (etl::exception& c) { - std::string what(c.what()); - std::string file(c.file_name()); - int line(c.line_number()); - CHECK_EQUAL(std::string("An exception"), std::string(c.what())); CHECK_EQUAL(std::string("Some file"), std::string(c.file_name())); CHECK_EQUAL(123, c.line_number()); } } }; -} \ No newline at end of file +} diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index 2c8ab72c..42ddb365 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -36,12 +36,30 @@ SOFTWARE. #include #include +#include + #include "data.h" #include "../src/flat_map.h" namespace { + static const size_t SIZE = 10; + + typedef TestDataDC DC; + typedef TestDataNDC NDC; + + typedef std::pair ElementDC; + typedef std::pair ElementNDC; + + typedef etl::flat_map DataDC; + typedef etl::flat_map DataNDC; + typedef etl::iflat_map IDataDC; + typedef etl::iflat_map IDataNDC; + + typedef std::map Compare_DataDC; + typedef std::map Compare_DataNDC; + //************************************************************************* template bool Check_Equal(T1 begin1, T1 end1, T2 begin2) @@ -60,23 +78,40 @@ namespace return true; } + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + SUITE(test_flat_map) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef std::pair ElementDC; - typedef std::pair ElementNDC; - - typedef etl::flat_map DataDC; - typedef etl::flat_map DataNDC; - typedef etl::iflat_map IDataNDC; - - typedef std::map Compare_DataDC; - typedef std::map Compare_DataNDC; - NDC N0 = NDC("A"); NDC N1 = NDC("B"); NDC N2 = NDC("C"); @@ -98,6 +133,28 @@ namespace NDC N18 = NDC("S"); NDC N19 = NDC("T"); + DC M0 = DC("A"); + DC M1 = DC("B"); + DC M2 = DC("C"); + DC M3 = DC("D"); + DC M4 = DC("E"); + DC M5 = DC("F"); + DC M6 = DC("G"); + DC M7 = DC("H"); + DC M8 = DC("I"); + DC M9 = DC("J"); + DC M10 = DC("K"); + DC M11 = DC("L"); + DC M12 = DC("M"); + DC M13 = DC("N"); + DC M14 = DC("O"); + DC M15 = DC("P"); + DC M16 = DC("Q"); + DC M17 = DC("R"); + DC M18 = DC("S"); + DC M19 = DC("T"); + + std::vector initial_data_dc; std::vector initial_data; std::vector excess_data; std::vector different_data; @@ -144,9 +201,16 @@ namespace ElementNDC(15, N15), ElementNDC(16, N16), ElementNDC(17, N17), ElementNDC(18, N18), ElementNDC(19, N19) }; + ElementDC n4[] = + { + ElementDC(0, M0), ElementDC(1, M1), ElementDC(2, M2), ElementDC(3, M3), ElementDC(4, M4), + ElementDC(5, M5), ElementDC(6, M6), ElementDC(7, M7), ElementDC(8, M8), ElementDC(9, M9) + }; + initial_data.assign(std::begin(n), std::end(n)); excess_data.assign(std::begin(n2), std::end(n2)); different_data.assign(std::begin(n3), std::end(n3)); + initial_data_dc.assign(std::begin(n4), std::end(n4)); } }; @@ -262,9 +326,9 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_index) { - Compare_DataNDC compare_data(initial_data.begin(), initial_data.end()); + Compare_DataDC compare_data(initial_data_dc.begin(), initial_data_dc.end()); - DataNDC data(compare_data.begin(), compare_data.end()); + DataDC data(compare_data.begin(), compare_data.end()); CHECK_EQUAL(compare_data[0], data[0]); CHECK_EQUAL(compare_data[1], data[1]); @@ -281,11 +345,11 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_index_value_changed) { - Compare_DataNDC compare_data; - DataNDC data; + Compare_DataDC compare_data; + DataDC data; - data[0] = N0; - compare_data[0] = N0; + data[0] = M0; + compare_data[0] = M0; bool isEqual = Check_Equal(data.begin(), data.end(), @@ -293,8 +357,8 @@ namespace CHECK(isEqual); - data[0] = N2; - compare_data[0] = N2; + data[0] = M2; + compare_data[0] = M2; isEqual = Check_Equal(data.begin(), data.end(), @@ -370,6 +434,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -378,16 +444,20 @@ namespace Compare_DataNDC compare_data; DataNDC data; - data.insert(DataNDC::value_type(0, N0)); + std::pair result; + + result = data.insert(std::make_pair(0, N0)); compare_data.insert(std::make_pair(0, N0)); bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); - + CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(0, N0)); - data.insert(std::make_pair(2, N2)); + result = data.insert(std::make_pair(2, N2)); compare_data.insert(std::make_pair(2, N2)); isEqual = Check_Equal(data.begin(), @@ -395,8 +465,10 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(2, N2)); - data.insert(std::make_pair(1, N1)); + result = data.insert(std::make_pair(1, N1)); compare_data.insert(std::make_pair(1, N1)); isEqual = Check_Equal(data.begin(), @@ -404,6 +476,10 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(1, N1)); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -412,23 +488,30 @@ namespace Compare_DataNDC compare_data; DataNDC data; - data.insert(DataNDC::value_type(0, N0)); - compare_data.insert(std::make_pair(0, N0)); + std::pair result1; + std::pair result2; + + result1 = data.insert(DataNDC::value_type(0, N0)); + result2 = compare_data.insert(std::make_pair(0, N0)); bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK(result1.second); + CHECK(*result1.first == std::make_pair(0, N0)); - data.insert(std::make_pair(0, N2)); - compare_data.insert(std::make_pair(0, N2)); + result1 = data.insert(std::make_pair(0, N2)); + result2 = compare_data.insert(std::make_pair(0, N2)); isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK(!result1.second); + CHECK(*result1.first != std::make_pair(0, N2)); } //************************************************************************* diff --git a/test/test_flat_multimap.cpp b/test/test_flat_multimap.cpp index 9416de9f..339b80fd 100644 --- a/test/test_flat_multimap.cpp +++ b/test/test_flat_multimap.cpp @@ -42,67 +42,100 @@ SOFTWARE. namespace { - SUITE(test_flat_multimap) + static const size_t SIZE = 10; + + typedef TestDataDC DC; + typedef TestDataNDC NDC; + + typedef std::pair ElementDC; + typedef std::pair ElementNDC; + + typedef etl::flat_multimap DataDC; + typedef etl::flat_multimap DataNDC; + typedef etl::iflat_multimap IDataDC; + typedef etl::iflat_multimap IDataNDC; + + typedef std::multimap Compare_DataDC; + typedef std::multimap Compare_DataNDC; + + NDC N0 = NDC("A"); + NDC N1 = NDC("B"); + NDC N2 = NDC("C"); + NDC N3 = NDC("D"); + NDC N4 = NDC("E"); + NDC N5 = NDC("F"); + NDC N6 = NDC("G"); + NDC N7 = NDC("H"); + NDC N8 = NDC("I"); + NDC N9 = NDC("J"); + NDC N10 = NDC("K"); + NDC N11 = NDC("L"); + NDC N12 = NDC("M"); + NDC N13 = NDC("N"); + NDC N14 = NDC("O"); + NDC N15 = NDC("P"); + NDC N16 = NDC("Q"); + NDC N17 = NDC("R"); + NDC N18 = NDC("S"); + NDC N19 = NDC("T"); + + std::vector initial_data; + std::vector excess_data; + std::vector different_data; + std::vector multi_data; + + //************************************************************************* + template + bool Check_Equal(T1 begin1, T1 end1, T2 begin2) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef std::pair ElementDC; - typedef std::pair ElementNDC; - - typedef etl::flat_multimap DataDC; - typedef etl::flat_multimap DataNDC; - typedef etl::iflat_multimap IDataNDC; - - typedef std::multimap Compare_DataDC; - typedef std::multimap Compare_DataNDC; - - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); - - std::vector initial_data; - std::vector excess_data; - std::vector different_data; - std::vector multi_data; - - //************************************************************************* - template - bool Check_Equal(T1 begin1, T1 end1, T2 begin2) + while (begin1 != end1) { - while (begin1 != end1) + if ((begin1->first != begin2->first) || (begin1->second != begin2->second)) { - if ((begin1->first != begin2->first) || (begin1->second != begin2->second)) - { - return false; - } - - ++begin1; - ++begin2; + return false; } - return true; + ++begin1; + ++begin2; } + return true; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + SUITE(test_flat_multimap) + { //************************************************************************* struct SetupFixture { @@ -127,16 +160,16 @@ namespace ElementNDC(15, N15), ElementNDC(16, N16), ElementNDC(17, N17), ElementNDC(18, N18), ElementNDC(19, N19) }; - ElementNDC n4[] = - { - ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(1, N3), ElementNDC(3, N4), - ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9) - }; + ElementNDC n4[] = + { + ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(1, N3), ElementNDC(3, N4), + ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9) + }; initial_data.assign(std::begin(n), std::end(n)); excess_data.assign(std::begin(n2), std::end(n2)); different_data.assign(std::begin(n3), std::end(n3)); - multi_data.assign(std::begin(n4), std::end(n4)); + multi_data.assign(std::begin(n4), std::end(n4)); } }; @@ -263,6 +296,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -297,6 +332,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -331,6 +368,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -339,6 +378,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(std::make_pair(10, N10)), etl::flat_multimap_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -355,6 +396,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -363,6 +406,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multimap_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -630,39 +675,39 @@ namespace CHECK(initial1 != different); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_multi) - { - Compare_DataNDC compare_data(multi_data.begin(), multi_data.end()); - DataNDC data(multi_data.begin(), multi_data.end()); + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_multi) + { + Compare_DataNDC compare_data(multi_data.begin(), multi_data.end()); + DataNDC data(multi_data.begin(), multi_data.end()); - std::pair compare_range; - std::pair test_range; - - compare_range = compare_data.equal_range(0); - test_range = data.equal_range(0); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + std::pair compare_range; + std::pair test_range; + + compare_range = compare_data.equal_range(0); + test_range = data.equal_range(0); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - compare_range = compare_data.equal_range(1); - test_range = data.equal_range(1); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + compare_range = compare_data.equal_range(1); + test_range = data.equal_range(1); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - compare_range = compare_data.equal_range(2); - test_range = data.equal_range(2); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + compare_range = compare_data.equal_range(2); + test_range = data.equal_range(2); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - compare_range = compare_data.equal_range(3); - test_range = data.equal_range(3); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + compare_range = compare_data.equal_range(3); + test_range = data.equal_range(3); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - compare_range = compare_data.equal_range(4); - test_range = data.equal_range(4); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + compare_range = compare_data.equal_range(4); + test_range = data.equal_range(4); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - compare_range = compare_data.equal_range(5); - test_range = data.equal_range(5); - CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); - } + compare_range = compare_data.equal_range(5); + test_range = data.equal_range(5); + CHECK_EQUAL(std::distance(compare_range.first, compare_range.second), std::distance(test_range.first, test_range.second)); + } //************************************************************************* TEST_FIXTURE(SetupFixture, test_count) diff --git a/test/test_flat_multiset.cpp b/test/test_flat_multiset.cpp index 7d54bc6c..0e870cd0 100644 --- a/test/test_flat_multiset.cpp +++ b/test/test_flat_multiset.cpp @@ -42,49 +42,81 @@ SOFTWARE. namespace { + static const size_t SIZE = 10; + + typedef TestDataDC DC; + typedef TestDataNDC NDC; + + typedef etl::flat_multiset DataDC; + typedef etl::flat_multiset DataNDC; + typedef etl::iflat_multiset IDataNDC; + + typedef std::multiset Compare_DataDC; + typedef std::multiset Compare_DataNDC; + + NDC NX = NDC("@"); + NDC NY = NDC("["); + + NDC N0 = NDC("A"); + NDC N1 = NDC("B"); + NDC N2 = NDC("C"); + NDC N3 = NDC("D"); + NDC N4 = NDC("E"); + NDC N5 = NDC("F"); + NDC N6 = NDC("G"); + NDC N7 = NDC("H"); + NDC N8 = NDC("I"); + NDC N9 = NDC("J"); + NDC N10 = NDC("K"); + NDC N11 = NDC("L"); + NDC N12 = NDC("M"); + NDC N13 = NDC("N"); + NDC N14 = NDC("O"); + NDC N15 = NDC("P"); + NDC N16 = NDC("Q"); + NDC N17 = NDC("R"); + NDC N18 = NDC("S"); + NDC N19 = NDC("T"); + + std::vector initial_data; + std::vector excess_data; + std::vector different_data; + std::vector multi_data; + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->value; + + return os; + } + SUITE(test_flat_multiset) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef etl::flat_multiset DataDC; - typedef etl::flat_multiset DataNDC; - typedef etl::iflat_multiset IDataNDC; - - typedef std::multiset Compare_DataDC; - typedef std::multiset Compare_DataNDC; - - NDC NX = NDC("@"); - NDC NY = NDC("["); - - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); - - std::vector initial_data; - std::vector excess_data; - std::vector different_data; - std::vector multi_data; - //************************************************************************* struct SetupFixture { @@ -240,6 +272,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -274,6 +308,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -308,6 +344,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -316,6 +354,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(N10), etl::flat_multiset_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -332,6 +372,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -340,6 +382,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multiset_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* diff --git a/test/test_flat_set.cpp b/test/test_flat_set.cpp index cab386c8..c770a1fa 100644 --- a/test/test_flat_set.cpp +++ b/test/test_flat_set.cpp @@ -40,50 +40,82 @@ SOFTWARE. #include "../src/flat_set.h" +static const size_t SIZE = 10; + +typedef TestDataDC DC; +typedef TestDataNDC NDC; + +typedef etl::flat_set DataDC; +typedef etl::flat_set DataNDC; +typedef etl::iflat_set IDataNDC; + +typedef std::set Compare_DataDC; +typedef std::set Compare_DataNDC; + +NDC NX = NDC("@"); +NDC NY = NDC("["); + +NDC N0 = NDC("A"); +NDC N1 = NDC("B"); +NDC N2 = NDC("C"); +NDC N3 = NDC("D"); +NDC N4 = NDC("E"); +NDC N5 = NDC("F"); +NDC N6 = NDC("G"); +NDC N7 = NDC("H"); +NDC N8 = NDC("I"); +NDC N9 = NDC("J"); +NDC N10 = NDC("K"); +NDC N11 = NDC("L"); +NDC N12 = NDC("M"); +NDC N13 = NDC("N"); +NDC N14 = NDC("O"); +NDC N15 = NDC("P"); +NDC N16 = NDC("Q"); +NDC N17 = NDC("R"); +NDC N18 = NDC("S"); +NDC N19 = NDC("T"); + +std::vector initial_data; +std::vector excess_data; +std::vector different_data; + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) +{ + os << itr->value; + + return os; +} + namespace { SUITE(test_flat_set) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef etl::flat_set DataDC; - typedef etl::flat_set DataNDC; - typedef etl::iflat_set IDataNDC; - - typedef std::set Compare_DataDC; - typedef std::set Compare_DataNDC; - - NDC NX = NDC("@"); - NDC NY = NDC("["); - - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); - - std::vector initial_data; - std::vector excess_data; - std::vector different_data; - //************************************************************************* struct SetupFixture { @@ -233,6 +265,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -245,8 +279,8 @@ namespace compare_data.insert(N0); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); @@ -254,19 +288,23 @@ namespace compare_data.insert(N2); isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(N1); compare_data.insert(N1); + std::vector test(data.begin(), data.end()); + isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -295,6 +333,8 @@ namespace compare_data.insert(N2); CHECK_EQUAL(compare_data.size(), data.size()); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -303,6 +343,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(N10), etl::flat_set_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -315,10 +357,12 @@ namespace compare_data.insert(initial_data.begin(), initial_data.end()); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -327,6 +371,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_set_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -344,8 +390,8 @@ namespace CHECK_EQUAL(count_compare, count); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -366,8 +412,8 @@ namespace data.erase(i_data); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -394,8 +440,8 @@ namespace data.erase(i_data, i_data_end); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } diff --git a/test/test_fnv_1.cpp b/test/test_fnv_1.cpp index 33b6ed67..8f8d4ccf 100644 --- a/test/test_fnv_1.cpp +++ b/test/test_fnv_1.cpp @@ -46,7 +46,7 @@ namespace uint32_t hash = etl::fnv_1_32(data.begin(), data.end()); - CHECK_EQUAL(0x24148816, hash); + CHECK_EQUAL(0x24148816U, hash); } //************************************************************************* @@ -63,7 +63,7 @@ namespace uint32_t hash = fnv_1_32_calculator.value(); - CHECK_EQUAL(0x24148816, hash); + CHECK_EQUAL(0x24148816U, hash); } //************************************************************************* @@ -77,7 +77,7 @@ namespace uint32_t hash = fnv_1_32_calculator.value(); - CHECK_EQUAL(0x24148816, hash); + CHECK_EQUAL(0x24148816U, hash); } //************************************************************************* @@ -102,7 +102,7 @@ namespace uint32_t hash = etl::fnv_1a_32(data.begin(), data.end()); - CHECK_EQUAL(0xBB86B11C, hash); + CHECK_EQUAL(0xBB86B11CU, hash); } //************************************************************************* @@ -119,7 +119,7 @@ namespace uint32_t hash = fnv_1a_32_calculator.value(); - CHECK_EQUAL(0xBB86B11C, hash); + CHECK_EQUAL(0xBB86B11CU, hash); } //************************************************************************* @@ -133,7 +133,7 @@ namespace uint32_t hash = fnv_1a_32_calculator.value(); - CHECK_EQUAL(0xBB86B11C, hash); + CHECK_EQUAL(0xBB86B11CU, hash); } //************************************************************************* @@ -158,7 +158,7 @@ namespace uint64_t hash = etl::fnv_1_64(data.begin(), data.end()); - CHECK_EQUAL(0xA72FFC362BF916D6, hash); + CHECK_EQUAL(0xA72FFC362BF916D6U, hash); } //************************************************************************* @@ -175,7 +175,7 @@ namespace uint64_t hash = fnv_1_64_calculator; - CHECK_EQUAL(0xA72FFC362BF916D6, hash); + CHECK_EQUAL(0xA72FFC362BF916D6U, hash); } //************************************************************************* @@ -189,7 +189,7 @@ namespace uint64_t hash = fnv_1_64_calculator.value(); - CHECK_EQUAL(0xA72FFC362BF916D6, hash); + CHECK_EQUAL(0xA72FFC362BF916D6U, hash); } //************************************************************************* @@ -214,7 +214,7 @@ namespace uint64_t hash = etl::fnv_1a_64(data.begin(), data.end()); - CHECK_EQUAL(0x06D5573923C6CDFC, hash); + CHECK_EQUAL(0x06D5573923C6CDFCU, hash); } //************************************************************************* @@ -231,7 +231,7 @@ namespace uint64_t hash = fnv_1a_64_calculator; - CHECK_EQUAL(0x06D5573923C6CDFC, hash); + CHECK_EQUAL(0x06D5573923C6CDFCU, hash); } //************************************************************************* @@ -245,7 +245,7 @@ namespace uint64_t hash = fnv_1a_64_calculator.value(); - CHECK_EQUAL(0x06D5573923C6CDFC, hash); + CHECK_EQUAL(0x06D5573923C6CDFCU, hash); } //************************************************************************* diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 45d35805..e5944874 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -52,6 +52,7 @@ namespace typedef etl::forward_list DataNDC; typedef etl::iforward_list IDataNDC; + typedef std::forward_list CompareDataDC; typedef std::forward_list CompareDataNDC; typedef std::vector InitialDataNDC; @@ -77,7 +78,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_default_constructor) { - DataNDC data; + DataDC data; CHECK(data.empty()); CHECK_EQUAL(data.max_size(), SIZE); @@ -160,16 +161,17 @@ namespace { const size_t INITIAL_SIZE = 4; const size_t NEW_SIZE = 8; - const ItemNDC VALUE("1"); + const ItemDC VALUE("1"); - DataNDC data(INITIAL_SIZE, VALUE); + DataDC data(INITIAL_SIZE, VALUE); data.resize(NEW_SIZE); - CompareDataNDC compare_data(INITIAL_SIZE, VALUE); + CompareDataDC compare_data(INITIAL_SIZE, VALUE); compare_data.resize(NEW_SIZE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -186,8 +188,9 @@ namespace CompareDataNDC compare_data(INITIAL_SIZE, VALUE); compare_data.resize(NEW_SIZE, VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -205,16 +208,17 @@ namespace { const size_t INITIAL_SIZE = 4; const size_t NEW_SIZE = 2; - const ItemNDC VALUE("1"); + const ItemDC VALUE("1"); - DataNDC data(INITIAL_SIZE, VALUE); + DataDC data(INITIAL_SIZE, VALUE); data.resize(NEW_SIZE); - CompareDataNDC compare_data(INITIAL_SIZE, VALUE); + CompareDataDC compare_data(INITIAL_SIZE, VALUE); compare_data.resize(NEW_SIZE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -231,8 +235,9 @@ namespace CompareDataNDC compare_data(INITIAL_SIZE, VALUE); compare_data.resize(NEW_SIZE, VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -255,8 +260,9 @@ namespace data.assign(compare_data.begin(), compare_data.end()); data.assign(compare_data.begin(), compare_data.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -273,8 +279,9 @@ namespace data.assign(INITIAL_SIZE, VALUE); data.assign(INITIAL_SIZE, VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -309,8 +316,9 @@ namespace data.insert_after(i_data, INSERT_VALUE); compare_data.insert_after(i_compare_data, INSERT_VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); offset = 0; @@ -324,8 +332,9 @@ namespace data.insert_after(i_data, INSERT_VALUE); compare_data.insert_after(i_compare_data, INSERT_VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -350,8 +359,9 @@ namespace data.insert_after(i_data, 2, INSERT_VALUE); compare_data.insert_after(i_compare_data, 2, INSERT_VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); offset = 0; @@ -365,8 +375,9 @@ namespace data.insert_after(i_data, 2, INSERT_VALUE); compare_data.insert_after(i_compare_data, 2, INSERT_VALUE); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -382,8 +393,9 @@ namespace compare_data.insert_after(compare_data.before_begin(), test2.begin(), test2.end()); data.insert_after(data.before_begin(), test2.begin(), test2.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); compare_data.assign(test1.begin(), test1.end()); @@ -398,8 +410,9 @@ namespace compare_data.insert_after(icd, test2.begin(), test2.end()); data.insert_after(id, test2.begin(), test2.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -423,41 +436,42 @@ namespace CHECK_NO_THROW(data.push_front(ItemNDC("5"))); CHECK_NO_THROW(data.push_front(ItemNDC("6"))); - CHECK_EQUAL(6, data.size()); + CHECK_EQUAL(6U, data.size()); CHECK_EQUAL(6, std::distance(data.begin(), data.end())); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_null) { - CompareDataNDC compare_data; - DataNDC data; + CompareDataDC compare_data; + DataDC data; - compare_data.push_front(ItemNDC("1")); - compare_data.push_front(ItemNDC("2")); - compare_data.push_front(ItemNDC("3")); - compare_data.push_front(ItemNDC("4")); - compare_data.push_front(ItemNDC("5")); - compare_data.push_front(ItemNDC("6")); + compare_data.push_front(ItemDC("1")); + compare_data.push_front(ItemDC("2")); + compare_data.push_front(ItemDC("3")); + compare_data.push_front(ItemDC("4")); + compare_data.push_front(ItemDC("5")); + compare_data.push_front(ItemDC("6")); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("1"); + data.front() = ItemDC("1"); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("2"); + data.front() = ItemDC("2"); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("3"); + data.front() = ItemDC("3"); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("4"); + data.front() = ItemDC("4"); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("5"); + data.front() = ItemDC("5"); CHECK_NO_THROW(data.push_front()); - data.front() = ItemNDC("6"); + data.front() = ItemDC("6"); - CHECK_EQUAL(6, data.size()); + CHECK_EQUAL(6U, data.size()); CHECK_EQUAL(6, std::distance(data.begin(), data.end())); are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -552,16 +566,18 @@ namespace i_compare_data = compare_data.erase_after(i_compare_data); i_data = data.erase_after(i_data); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); CHECK(*i_compare_data == *i_data); i_compare_data = compare_data.erase_after(compare_data.begin()); i_data = data.erase_after(data.begin()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); are_equal = *i_data == *i_compare_data; @@ -576,6 +592,8 @@ namespace //std::advance(i_data, data.size() - 1); i_data = data.erase_after(i_data); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -607,6 +625,8 @@ namespace CHECK_EQUAL(*i_compare_result, *i_result); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -629,6 +649,8 @@ namespace CHECK(i_result == data.end()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -664,7 +686,6 @@ namespace CHECK_EQUAL(data.size(), other_data.size()); are_equal = std::equal(data.begin(), data.end(), other_data.begin()); - CHECK(are_equal); } @@ -680,7 +701,6 @@ namespace idata2 = idata1; bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); - CHECK(isEqual); } @@ -696,7 +716,6 @@ namespace CHECK_EQUAL(data.size(), other_data.size()); are_equal = std::equal(data.begin(), data.end(), other_data.begin()); - CHECK(are_equal); } @@ -709,8 +728,9 @@ namespace compare_data.unique(); data.unique(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -723,8 +743,9 @@ namespace compare_data.unique(); data.unique(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -737,8 +758,9 @@ namespace compare_data.remove(ItemNDC("7")); data.remove(ItemNDC("7")); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -751,8 +773,9 @@ namespace compare_data.remove_if(std::bind2nd(std::equal_to(), ItemNDC("7"))); data.remove_if(std::bind2nd(std::equal_to(), ItemNDC("7"))); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -765,8 +788,12 @@ namespace compare_data.reverse(); data.reverse(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + CHECK_EQUAL(data.size(), std::distance(data.begin(), data.end())); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -780,7 +807,6 @@ namespace data.reverse(); are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); - CHECK(are_equal); } @@ -793,8 +819,9 @@ namespace compare_data.sort(); data.sort(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -807,8 +834,9 @@ namespace compare_data.sort(); data.sort(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -837,8 +865,9 @@ namespace compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before); data.move_after(i_from_before, i_to_before); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); // Move to the end. @@ -857,8 +886,9 @@ namespace compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before); data.move_after(i_from_before, i_to_before); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); // Move to nearby. @@ -877,8 +907,9 @@ namespace compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before); data.move_after(i_from_before, i_to_before); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); // Move to same. @@ -897,8 +928,9 @@ namespace compare_data.splice_after(i_compare_to_before, compare_data, i_compare_from_before); data.move_after(i_from_before, i_to_before); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -935,8 +967,9 @@ namespace compare_data.splice_after(i_compare_to_before, compare_data, i_compare_first_before, i_compare_last); data.move_after(i_first_before, i_last, i_to_before); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); // Move to the end. diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 53e50d70..d8e42e6b 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -43,10 +43,10 @@ namespace TEST(test_hash_bool) { size_t hash = etl::hash()(false); - CHECK_EQUAL(0, hash); + CHECK_EQUAL(0U, hash); hash = etl::hash()(true); - CHECK_EQUAL(1, hash); + CHECK_EQUAL(1U, hash); } //************************************************************************* @@ -54,7 +54,7 @@ namespace { size_t hash = etl::hash()((char)(0x5A)); - CHECK_EQUAL(0x5A, hash); + CHECK_EQUAL(0x5AU, hash); } //************************************************************************* @@ -62,7 +62,7 @@ namespace { size_t hash = etl::hash()((signed char)(0x5A)); - CHECK_EQUAL(0x5A, hash); + CHECK_EQUAL(0x5AU, hash); } //************************************************************************* @@ -70,7 +70,7 @@ namespace { size_t hash = etl::hash()((unsigned char)(0x5A)); - CHECK_EQUAL(0x5A, hash); + CHECK_EQUAL(0x5AU, hash); } //************************************************************************* @@ -78,7 +78,7 @@ namespace { size_t hash = etl::hash()((short)(0x5AA5)); - CHECK_EQUAL(0x5AA5, hash); + CHECK_EQUAL(0x5AA5U, hash); } //************************************************************************* @@ -86,7 +86,7 @@ namespace { size_t hash = etl::hash()((unsigned short)(0x5AA5)); - CHECK_EQUAL(0x5AA5, hash); + CHECK_EQUAL(0x5AA5U, hash); } //************************************************************************* @@ -94,7 +94,7 @@ namespace { size_t hash = etl::hash()((int)(0x5AA555AA)); - CHECK_EQUAL(0x5AA555AA, hash); + CHECK_EQUAL(0x5AA555AAU, hash); } //************************************************************************* @@ -102,7 +102,7 @@ namespace { size_t hash = etl::hash()((unsigned int)(0x5AA555AA)); - CHECK_EQUAL(0x5AA555AA, hash); + CHECK_EQUAL(0x5AA555AAU, hash); } //************************************************************************* @@ -110,7 +110,7 @@ namespace { size_t hash = etl::hash()((long)(0x5AA555AA)); - CHECK_EQUAL(0x5AA555AA, hash); + CHECK_EQUAL(0x5AA555AAU, hash); } //************************************************************************* @@ -118,7 +118,7 @@ namespace { size_t hash = etl::hash()((unsigned long)(0x5AA555AA)); - CHECK_EQUAL(0x5AA555AA, hash); + CHECK_EQUAL(0x5AA555AAU, hash); } //************************************************************************* @@ -127,9 +127,9 @@ namespace size_t hash = etl::hash()((long long)(0x5AA555AA3CC333CC)); if (sizeof(size_t) == sizeof(long long)) - CHECK_EQUAL(0x5AA555AA3CC333CC, hash); + CHECK_EQUAL(0x5AA555AA3CC333CCU, hash); else - CHECK_EQUAL(0xEC6A8D69, hash); + CHECK_EQUAL(0xEC6A8D69U, hash); } //************************************************************************* @@ -138,9 +138,9 @@ namespace size_t hash = etl::hash()((unsigned long long)(0x5AA555AA3CC333CC)); if (sizeof(size_t) == sizeof(unsigned long long)) - CHECK_EQUAL(0x5AA555AA3CC333CC, hash); + CHECK_EQUAL(0x5AA555AA3CC333CCU, hash); else - CHECK_EQUAL(0xEC6A8D69, hash); + CHECK_EQUAL(0xEC6A8D69U, hash); } //************************************************************************* @@ -148,7 +148,7 @@ namespace { size_t hash = etl::hash()((float)(1.2345)); - CHECK_EQUAL(0X3F9E0419, hash); + CHECK_EQUAL(0X3F9E0419U, hash); } //************************************************************************* @@ -157,9 +157,9 @@ namespace size_t hash = etl::hash()((double)(1.2345)); if (sizeof(size_t) == sizeof(double)) - CHECK_EQUAL(0X3FF3C083126E978D, hash); + CHECK_EQUAL(0X3FF3C083126E978DU, hash); else - CHECK_EQUAL(0x86FBF224, hash); + CHECK_EQUAL(0x86FBF224U, hash); } //************************************************************************* diff --git a/test/test_instance_count.cpp b/test/test_instance_count.cpp index 885963bc..5be67615 100644 --- a/test/test_instance_count.cpp +++ b/test/test_instance_count.cpp @@ -47,25 +47,25 @@ namespace struct Test2 : public etl::instance_count {}; - CHECK_EQUAL(0, Test1::get_instance_count()); - CHECK_EQUAL(0, Test2::get_instance_count()); + CHECK_EQUAL(0U, Test1::get_instance_count()); + CHECK_EQUAL(0U, Test2::get_instance_count()); - //Test1 test1a; - //CHECK_EQUAL(1, Test1::get_instance_count()); - //CHECK_EQUAL(0, Test2::get_instance_count()); + Test1 test1a; + CHECK_EQUAL(1U, Test1::get_instance_count()); + CHECK_EQUAL(0U, Test2::get_instance_count()); - //Test1 test1b; - //Test2 test2a; - //CHECK_EQUAL(2, Test1::get_instance_count()); - //CHECK_EQUAL(1, Test2::get_instance_count()); + Test1 test1b; + Test2 test2a; + CHECK_EQUAL(2U, Test1::get_instance_count()); + CHECK_EQUAL(1U, Test2::get_instance_count()); - //Test2* ptest2b = new Test2; - //CHECK_EQUAL(2, Test1::get_instance_count()); - //CHECK_EQUAL(2, Test2::get_instance_count()); + Test2* ptest2b = new Test2; + CHECK_EQUAL(2U, Test1::get_instance_count()); + CHECK_EQUAL(2U, Test2::get_instance_count()); - //delete ptest2b; - //CHECK_EQUAL(2, Test1::get_instance_count()); - //CHECK_EQUAL(1, Test2::get_instance_count()); + delete ptest2b; + CHECK_EQUAL(2U, Test1::get_instance_count()); + CHECK_EQUAL(1U, Test2::get_instance_count()); } }; -} \ No newline at end of file +} diff --git a/test/test_intrusive_forward_list.cpp b/test/test_intrusive_forward_list.cpp index aaf9179f..af5f9bc0 100644 --- a/test/test_intrusive_forward_list.cpp +++ b/test/test_intrusive_forward_list.cpp @@ -45,8 +45,8 @@ typedef TestDataNDC ItemNDC; namespace { - typedef etl::forward_link<0, etl::link_option::AUTO> FirstLink; - typedef etl::forward_link<1> SecondLink; + typedef etl::forward_link<0> FirstLink; + typedef etl::bidirectional_link<1> SecondLink; //*************************************************************************** class ItemDCNode : public FirstLink, public SecondLink @@ -259,12 +259,6 @@ namespace ////************************************************************************* TEST_FIXTURE(SetupFixture, test_two_lists_different) { - std::list compare0; - std::list compare1; - - DataNDC0 data0; - DataNDC1 data1; - ItemNDCNode node0("0"); ItemNDCNode node1("1"); ItemNDCNode node2("2"); @@ -274,43 +268,51 @@ namespace ItemNDCNode node6("6"); ItemNDCNode node7("7"); - compare0.push_front(node0); - compare0.push_front(node1); - compare0.push_front(node2); - compare0.push_front(node4); - compare0.push_front(node6); - compare0.push_front(node7); - - data0.push_front(node0); - data0.push_front(node1); - data0.push_front(node2); - data0.push_front(node4); - data0.push_front(node6); - data0.push_front(node7); + { + std::list compare0; + std::list compare1; - are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); - CHECK(are_equal); - CHECK_EQUAL(6, data0.size()); - CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + DataNDC0 data0; + DataNDC1 data1; - compare1.push_front(node0); - compare1.push_front(node1); - compare1.push_front(node3); - compare1.push_front(node4); - compare1.push_front(node5); - compare1.push_front(node7); + compare0.push_front(node0); + compare0.push_front(node1); + compare0.push_front(node2); + compare0.push_front(node4); + compare0.push_front(node6); + compare0.push_front(node7); - data1.push_front(node0); - data1.push_front(node1); - data1.push_front(node3); - data1.push_front(node4); - data1.push_front(node5); - data1.push_front(node7); + compare1.push_front(node0); + compare1.push_front(node1); + compare1.push_front(node3); + compare1.push_front(node4); + compare1.push_front(node5); + compare1.push_front(node7); - are_equal = std::equal(data1.begin(), data1.end(), compare1.begin()); - CHECK(are_equal); - CHECK_EQUAL(6, data1.size()); - CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); + data0.push_front(node0); + data0.push_front(node1); + data0.push_front(node2); + data0.push_front(node4); + data0.push_front(node6); + data0.push_front(node7); + + are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); + CHECK(are_equal); + CHECK_EQUAL(6U, data0.size()); + CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + + data1.push_front(node0); + data1.push_front(node1); + data1.push_front(node3); + data1.push_front(node4); + data1.push_front(node5); + data1.push_front(node7); + + are_equal = std::equal(data1.begin(), data1.end(), compare1.begin()); + CHECK(are_equal); + CHECK_EQUAL(6U, data1.size()); + CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); + } } //************************************************************************* @@ -336,13 +338,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); offset = 0; @@ -352,22 +354,18 @@ namespace i_compare_data = compare_data.begin(); std::advance(i_compare_data, offset); - std::forward_list temp(data0.begin(), data0.end()); - data0.insert_after(i_data, INSERT_VALUE2); compare_data.insert_after(i_compare_data, INSERT_VALUE2); - temp.assign(data0.begin(), data0.end()); - are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -389,7 +387,7 @@ namespace are_equal = std::equal(data1.begin(), data1.end(), test1.begin()); CHECK(are_equal); CHECK_EQUAL(test1.size(), data1.size()); - CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(test1.size(), size_t(std::distance(data1.begin(), data1.end()))); compare.assign(test1.begin(), test1.end()); data0.assign(test1.begin(), test1.end()); @@ -411,15 +409,12 @@ namespace are_equal = std::equal(data1.begin(), data1.end(), test1.begin()); CHECK(are_equal); CHECK_EQUAL(test1.size(), data1.size()); - CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(test1.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front) { - std::list compare_data; - DataNDC0 data0; - ItemNDCNode node1("1"); ItemNDCNode node2("2"); ItemNDCNode node3("3"); @@ -427,32 +422,34 @@ namespace ItemNDCNode node5("5"); ItemNDCNode node6("6"); - compare_data.push_front(node1); - compare_data.push_front(node2); - compare_data.push_front(node3); - compare_data.push_front(node4); - compare_data.push_front(node5); - compare_data.push_front(node6); + { + std::list compare_data; + DataNDC0 data0; - CHECK_NO_THROW(data0.push_front(node1)); - CHECK_NO_THROW(data0.push_front(node2)); - CHECK_NO_THROW(data0.push_front(node3)); - CHECK_NO_THROW(data0.push_front(node4)); - CHECK_NO_THROW(data0.push_front(node5)); - CHECK_NO_THROW(data0.push_front(node6)); + compare_data.push_front(node1); + compare_data.push_front(node2); + compare_data.push_front(node3); + compare_data.push_front(node4); + compare_data.push_front(node5); + compare_data.push_front(node6); - are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); - CHECK(are_equal); - CHECK_EQUAL(6, data0.size()); - CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + CHECK_NO_THROW(data0.push_front(node1)); + CHECK_NO_THROW(data0.push_front(node2)); + CHECK_NO_THROW(data0.push_front(node3)); + CHECK_NO_THROW(data0.push_front(node4)); + CHECK_NO_THROW(data0.push_front(node5)); + CHECK_NO_THROW(data0.push_front(node6)); + + are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); + CHECK(are_equal); + CHECK_EQUAL(6U, data0.size()); + CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + } } //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_pop_front) { - DataNDC0 data0; - DataNDC1 data1; - ItemNDCNode node1("1"); ItemNDCNode node2("2"); ItemNDCNode node3("3"); @@ -460,43 +457,48 @@ namespace ItemNDCNode node5("5"); ItemNDCNode node6("6"); - data0.push_front(node1); - data0.push_front(node2); - data0.push_front(node3); - data0.push_front(node4); - data0.push_front(node5); - data0.push_front(node6); + { + DataNDC0 data0; + DataNDC1 data1; - data1.push_front(node1); - data1.push_front(node2); - data1.push_front(node3); - data1.push_front(node4); - data1.push_front(node5); - data1.push_front(node6); + data0.push_front(node1); + data0.push_front(node2); + data0.push_front(node3); + data0.push_front(node4); + data0.push_front(node5); + data0.push_front(node6); - CHECK_EQUAL(6, data0.size()); - CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); - CHECK(!data0.empty()); + data1.push_front(node1); + data1.push_front(node2); + data1.push_front(node3); + data1.push_front(node4); + data1.push_front(node5); + data1.push_front(node6); - data0.pop_front(); - data0.pop_front(); - data0.pop_front(); - data0.pop_front(); - data0.pop_front(); + CHECK_EQUAL(6U, data0.size()); + CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); + CHECK(!data0.empty()); - CHECK_EQUAL(1, data0.size()); - CHECK_EQUAL(1, std::distance(data0.begin(), data0.end())); - CHECK(!data0.empty()); + data0.pop_front(); + data0.pop_front(); + data0.pop_front(); + data0.pop_front(); + data0.pop_front(); - data0.pop_front(); + CHECK_EQUAL(1U, data0.size()); + CHECK_EQUAL(1, std::distance(data0.begin(), data0.end())); + CHECK(!data0.empty()); - CHECK_EQUAL(0, data0.size()); - CHECK_EQUAL(0, std::distance(data0.begin(), data0.end())); - CHECK(data0.empty()); + data0.pop_front(); - CHECK_EQUAL(6, data1.size()); - CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); - CHECK(!data1.empty()); + CHECK_EQUAL(0U, data0.size()); + CHECK_EQUAL(0, std::distance(data0.begin(), data0.end())); + CHECK(data0.empty()); + + CHECK_EQUAL(6U, data1.size()); + CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); + CHECK(!data1.empty()); + } } //************************************************************************* @@ -526,13 +528,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); are_equal = *i_data == *i_compare_data; CHECK(are_equal); @@ -547,13 +549,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); are_equal = *i_data == *i_compare_data; CHECK(are_equal); @@ -586,13 +588,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -616,13 +618,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -655,13 +657,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), unique_data.begin()); CHECK(are_equal); CHECK_EQUAL(unique_data.size(), data0.size()); - CHECK_EQUAL(unique_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(unique_data.size(), size_t(std::distance(data0.begin(), data0.end()))); // data1 should not have changed. are_equal = std::equal(data1.begin(), data1.end(), non_unique_data.begin()); CHECK(are_equal); CHECK_EQUAL(non_unique_data.size(), data1.size()); - CHECK_EQUAL(non_unique_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(non_unique_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -677,13 +679,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -699,13 +701,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare_data.begin(), compare_data.end())), data0.size()); CHECK_EQUAL(std::distance(compare_data.begin(), compare_data.end()), std::distance(data0.begin(), data0.end())); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -716,6 +718,9 @@ namespace data0.reverse(); // Just reverse one of them. + CHECK_EQUAL(data1.size(), data0.size()); + CHECK_EQUAL(data0.size(), std::distance(data0.begin(), data0.end())); + are_equal = std::equal(data0.begin(), data0.end(), sorted_data.rbegin()); CHECK(are_equal); @@ -776,8 +781,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare1.begin(), compare1.end())), data1.size()); } //************************************************************************* @@ -790,18 +795,14 @@ namespace DataNDC0::iterator idata_destination = data0.begin(); std::advance(idata_destination, 3); - std::forward_list compare0(data0.begin(), data0.end()); - - std::forward_list::iterator icompare_destination = compare0.begin(); - std::advance(icompare_destination, 3); + std::forward_list compare0(sorted_data2.begin(), sorted_data2.end()); data0.splice_after(idata_destination, data0); - compare0.splice_after(icompare_destination, compare0); are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); } //************************************************************************* @@ -839,8 +840,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare1.begin(), compare1.end())), data1.size()); } //************************************************************************* @@ -859,7 +860,7 @@ namespace DataNDC0::iterator idata_end = data0.begin(); std::advance(idata_end, 7); - std::forward_list compare0(data0.begin(), data0.end()); + std::forward_list compare0(sorted_data2.begin(), sorted_data2.end()); std::forward_list::iterator icompare_destination = compare0.begin(); std::advance(icompare_destination, 2); @@ -872,11 +873,11 @@ namespace data0.splice_after(idata_destination, data0, idata_begin, idata_end); compare0.splice_after(icompare_destination, compare0, icompare_begin, icompare_end); - + are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); } //************************************************************************* @@ -896,8 +897,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare1.begin(), compare1.end())), data1.size()); } //************************************************************************* @@ -917,8 +918,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare2.begin(), compare2.end()), data2.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare2.begin(), compare2.end())), data2.size()); } //************************************************************************* @@ -938,8 +939,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare3.begin(), compare3.end()), data3.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare3.begin(), compare3.end())), data3.size()); } //************************************************************************* @@ -959,8 +960,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare4.begin(), compare4.end()), data4.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare4.begin(), compare4.end())), data4.size()); } //************************************************************************* @@ -986,8 +987,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(std::distance(compare0.begin(), compare0.end()), data0.size()); - CHECK_EQUAL(std::distance(compare1.begin(), compare1.end()), data1.size()); + CHECK_EQUAL(size_t(std::distance(compare0.begin(), compare0.end())), data0.size()); + CHECK_EQUAL(size_t(std::distance(compare1.begin(), compare1.end())), data1.size()); } }; } diff --git a/test/test_intrusive_links.cpp b/test/test_intrusive_links.cpp index adc54cec..299df532 100644 --- a/test/test_intrusive_links.cpp +++ b/test/test_intrusive_links.cpp @@ -38,11 +38,10 @@ namespace //******************************************************* // Forward //******************************************************* - typedef etl::forward_link<0> FirstFLink; - typedef etl::forward_link<1> SecondFLink; - typedef etl::forward_link<2, etl::link_option::AUTO> ThirdFLinkAuto; + typedef etl::forward_link<0> FLink0; + typedef etl::forward_link<1> FLink1; - struct FData : public FirstFLink, public SecondFLink, public ThirdFLinkAuto + struct FData : public FLink0, public FLink1 { FData(int value) : value(value) @@ -55,12 +54,10 @@ namespace //******************************************************* // Bidirectional //******************************************************* - typedef etl::bidirectional_link<0, etl::link_option::AUTO> FirstBLinkAuto; - typedef etl::bidirectional_link<0, etl::link_option::CHECKED> FirstBLinkChecked; - typedef etl::bidirectional_link<0> FirstBLink; - typedef etl::bidirectional_link<1> SecondBLink; + typedef etl::bidirectional_link<0> BLink0; + typedef etl::bidirectional_link<1> BLink1; - struct BData : public FirstBLink, public SecondBLink + struct BData : public BLink0, public BLink1 { BData(int value) : value(value) @@ -70,34 +67,14 @@ namespace int value; }; - struct BDataAuto : public FirstBLinkAuto, public SecondBLink - { - BDataAuto(int value) - : value(value) - { - } - - int value; - }; - - struct BDataChecked : public FirstBLinkChecked - { - BDataChecked(int value) - : value(value) - { - } - - int value; - }; - //******************************************************* // Tree //******************************************************* - typedef etl::tree_link<0> FirstTLink; - typedef etl::tree_link<1> SecondTLink; - typedef etl::tree_link<2> ThirdTLink; + typedef etl::tree_link<0> TLink0; + typedef etl::tree_link<1> TLink1; + typedef etl::tree_link<2> TLink2; - struct TData : public FirstTLink, public SecondTLink + struct TData : public TLink0, public TLink1 { TData(int value) : value(value) @@ -110,7 +87,7 @@ namespace //******************************************************* // Mixed //******************************************************* - struct MData : public FirstFLink, public SecondBLink, public ThirdTLink + struct MData : public FLink0, public BLink1, public TLink2 { MData(int value) : value(value) @@ -121,7 +98,7 @@ namespace }; SUITE(test_forward_list) - { + { //************************************************************************* TEST(test_link_forward_link) { @@ -130,54 +107,54 @@ namespace FData data2(2); FData data3(3); - data0.FirstFLink::clear(); - etl::link(data0, data1); - CHECK(data0.FirstFLink::etl_next == &data1); + data0.FLink0::clear(); + etl::link(data0, data1); + CHECK(data0.FLink0::etl_next == &data1); - data0.FirstFLink::clear(); - etl::link(&data0, data1); - CHECK(data0.FirstFLink::etl_next == &data1); + data0.FLink0::clear(); + etl::link(&data0, data1); + CHECK(data0.FLink0::etl_next == &data1); - data0.FirstFLink::clear(); - etl::link(data0, &data1); - CHECK(data0.FirstFLink::etl_next == &data1); + data0.FLink0::clear(); + etl::link(data0, &data1); + CHECK(data0.FLink0::etl_next == &data1); - data0.FirstFLink::clear(); - etl::link(&data0, &data1); - CHECK(data0.FirstFLink::etl_next == &data1); + data0.FLink0::clear(); + etl::link(&data0, &data1); + CHECK(data0.FLink0::etl_next == &data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - CHECK(data1.FirstFLink::etl_next == &data2); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data1.FLink0::etl_next == &data2); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondFLink::etl_next == &data2); - CHECK(data2.SecondFLink::etl_next == &data1); - CHECK(data1.SecondFLink::etl_next == &data0); - CHECK(data0.SecondFLink::etl_next == nullptr); + CHECK(data3.FLink1::etl_next == &data2); + CHECK(data2.FLink1::etl_next == &data1); + CHECK(data1.FLink1::etl_next == &data0); + CHECK(data0.FLink1::etl_next == nullptr); FData* pdata; - pdata = static_cast(data0.FirstFLink::etl_next); + pdata = static_cast(data0.FLink0::etl_next); CHECK_EQUAL(1, pdata->value); - pdata = static_cast(pdata->FirstFLink::etl_next); + pdata = static_cast(pdata->FLink0::etl_next); CHECK_EQUAL(2, pdata->value); - pdata = static_cast(pdata->FirstFLink::etl_next); + pdata = static_cast(pdata->FLink0::etl_next); CHECK_EQUAL(3, pdata->value); - pdata = static_cast(data3.SecondFLink::etl_next); + pdata = static_cast(data3.FLink1::etl_next); CHECK_EQUAL(2, pdata->value); - pdata = static_cast(pdata->SecondFLink::etl_next); + pdata = static_cast(pdata->FLink1::etl_next); CHECK_EQUAL(1, pdata->value); - pdata = static_cast(pdata->SecondFLink::etl_next); + pdata = static_cast(pdata->FLink1::etl_next); CHECK_EQUAL(0, pdata->value); } @@ -189,35 +166,35 @@ namespace FData data2(2); FData data3(3); - data0.FirstFLink::clear(); - etl::link_splice(data0, data1); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == nullptr); + data0.FLink0::clear(); + etl::link_splice(data0, data1); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == nullptr); - data0.FirstFLink::clear(); - etl::link_splice(data0, &data1); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == nullptr); + data0.FLink0::clear(); + etl::link_splice(data0, &data1); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == nullptr); - data0.FirstFLink::clear(); - etl::link_splice(&data0, data1); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == nullptr); + data0.FLink0::clear(); + etl::link_splice(&data0, data1); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == nullptr); - data0.FirstFLink::clear(); - etl::link_splice(&data0, &data1); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == nullptr); + data0.FLink0::clear(); + etl::link_splice(&data0, &data1); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == nullptr); - data0.FirstFLink::clear(); - etl::link_splice(data0, data3); - etl::link_splice(data0, data1); - etl::link_splice(data1, data2); + data0.FLink0::clear(); + etl::link_splice(data0, data3); + etl::link_splice(data0, data1); + etl::link_splice(data1, data2); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data2); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data2); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == nullptr); } //************************************************************************* @@ -233,65 +210,65 @@ namespace FData data7(7); // First range. - data0.FirstFLink::clear(); - etl::link_splice(data0, data1); - etl::link_splice(data1, data6); - etl::link_splice(data6, data7); + data0.FLink0::clear(); + etl::link_splice(data0, data1); + etl::link_splice(data1, data6); + etl::link_splice(data6, data7); // Second range. - data2.FirstFLink::clear(); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.FLink0::clear(); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(data1, data2, data5); + etl::link_splice(data1, data2, data5); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data2); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == &data4); - CHECK(data4.FirstFLink::etl_next == &data5); - CHECK(data5.FirstFLink::etl_next == &data6); - CHECK(data6.FirstFLink::etl_next == &data7); - CHECK(data7.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data2); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == &data4); + CHECK(data4.FLink0::etl_next == &data5); + CHECK(data5.FLink0::etl_next == &data6); + CHECK(data6.FLink0::etl_next == &data7); + CHECK(data7.FLink0::etl_next == nullptr); // Do it again with a pointer. // First range. - data0.FirstFLink::clear(); - etl::link_splice(data0, data1); - etl::link_splice(data1, data6); - etl::link_splice(data6, data7); + data0.FLink0::clear(); + etl::link_splice(data0, data1); + etl::link_splice(data1, data6); + etl::link_splice(data6, data7); // Second range. - data2.FirstFLink::clear(); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.FLink0::clear(); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(&data1, data2, data5); + etl::link_splice(&data1, data2, data5); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data2); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == &data4); - CHECK(data4.FirstFLink::etl_next == &data5); - CHECK(data5.FirstFLink::etl_next == &data6); - CHECK(data6.FirstFLink::etl_next == &data7); - CHECK(data7.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data2); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == &data4); + CHECK(data4.FLink0::etl_next == &data5); + CHECK(data5.FLink0::etl_next == &data6); + CHECK(data6.FLink0::etl_next == &data7); + CHECK(data7.FLink0::etl_next == nullptr); // Do it again with a nullptr pointer. // Second range. - data2.FirstFLink::clear(); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.FLink0::clear(); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(nullptr, data2, data5); + etl::link_splice(nullptr, data2, data5); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == &data4); - CHECK(data4.FirstFLink::etl_next == &data5); - CHECK(data5.FirstFLink::etl_next == nullptr); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == &data4); + CHECK(data4.FLink0::etl_next == &data5); + CHECK(data5.FLink0::etl_next == nullptr); } @@ -303,63 +280,51 @@ namespace FData data2(2); FData data3(3); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(data0, data1); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - etl::unlink_after(data1); - data2.FirstFLink::clear(); + etl::unlink_after(data1); + data2.FLink0::clear(); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data3); - CHECK(data2.FirstFLink::etl_next == nullptr); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data3); + CHECK(data2.FLink0::etl_next == nullptr); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondFLink::etl_next == &data2); - CHECK(data2.SecondFLink::etl_next == &data1); - CHECK(data1.SecondFLink::etl_next == &data0); - CHECK(data0.SecondFLink::etl_next == nullptr); + CHECK(data3.FLink1::etl_next == &data2); + CHECK(data2.FLink1::etl_next == &data1); + CHECK(data1.FLink1::etl_next == &data0); + CHECK(data0.FLink1::etl_next == nullptr); - etl::unlink_after(data2); - data1.SecondFLink::clear(); + etl::unlink_after(data2); + data1.FLink1::clear(); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondFLink::etl_next == &data2); - CHECK(data2.SecondFLink::etl_next == &data0); - CHECK(data1.SecondFLink::etl_next == nullptr); - CHECK(data0.SecondFLink::etl_next == nullptr); + CHECK(data3.FLink1::etl_next == &data2); + CHECK(data2.FLink1::etl_next == &data0); + CHECK(data1.FLink1::etl_next == nullptr); + CHECK(data0.FLink1::etl_next == nullptr); - etl::unlink_after(data3); - etl::unlink_after(data0); + etl::unlink_after(data3); + etl::unlink_after(data0); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondFLink::etl_next == &data2); - CHECK(data2.SecondFLink::etl_next == &data0); - CHECK(data0.SecondFLink::etl_next == nullptr); - - // Check auto link. - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); - - etl::unlink_after(data1); - - CHECK(data0.ThirdFLinkAuto::etl_next == &data1); - CHECK(data1.ThirdFLinkAuto::etl_next == &data3); - CHECK(data3.ThirdFLinkAuto::etl_next == nullptr); + CHECK(data3.FLink1::etl_next == &data2); + CHECK(data2.FLink1::etl_next == &data0); + CHECK(data0.FLink1::etl_next == nullptr); } //************************************************************************* @@ -370,29 +335,29 @@ namespace FData data2(2); FData data3(3); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(data0, data1); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - etl::unlink_after(data0, data2); - data1.FirstFLink::clear(); - data2.FirstFLink::clear(); + etl::unlink_after(data0, data2); + data1.FLink0::clear(); + data2.FLink0::clear(); - CHECK(data0.FirstFLink::etl_next == &data3); - CHECK(data1.FirstFLink::etl_next == nullptr); - CHECK(data2.FirstFLink::etl_next == nullptr); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data3); + CHECK(data1.FLink0::etl_next == nullptr); + CHECK(data2.FLink0::etl_next == nullptr); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondFLink::etl_next == &data2); - CHECK(data2.SecondFLink::etl_next == &data1); - CHECK(data1.SecondFLink::etl_next == &data0); - CHECK(data0.SecondFLink::etl_next == nullptr); + CHECK(data3.FLink1::etl_next == &data2); + CHECK(data2.FLink1::etl_next == &data1); + CHECK(data1.FLink1::etl_next == &data0); + CHECK(data0.FLink1::etl_next == nullptr); } //************************************************************************* @@ -400,134 +365,131 @@ namespace { FData data0(0); - etl::link(data0, data0); + etl::link(data0, data0); - CHECK(data0.FirstFLink::etl_next == &data0); + CHECK(data0.FLink0::etl_next == &data0); - etl::unlink_after(data0); + etl::unlink_after(data0); - CHECK(data0.FirstFLink::etl_next == &data0); + CHECK(data0.FLink0::etl_next == &data0); } //************************************************************************* TEST(test_link_bidirectional_link) { - // FirstBLinkAuto is auto-unlink, SecondBLink is not. + BData data0(0); + BData data1(1); + BData data2(2); + BData data3(3); - BDataAuto* data0 = new BDataAuto(0); - BDataAuto* data1 = new BDataAuto(1); - BDataAuto* data2 = new BDataAuto(2); - BDataAuto* data3 = new BDataAuto(3); + etl::link(nullptr, data0); - etl::link(nullptr, data0); + data1.BLink0::clear(); + etl::link(data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); - data1->FirstBLinkAuto::clear(); - etl::link(*data0, *data1); - CHECK(data0->FirstBLinkAuto::etl_next == data1); - CHECK(data1->FirstBLinkAuto::etl_previous == data0); - - data1->FirstBLinkAuto::clear(); - etl::link(*data0, data1); - CHECK(data0->FirstBLinkAuto::etl_next == data1); - CHECK(data1->FirstBLinkAuto::etl_previous == data0); + data1.BLink0::clear(); + etl::link(data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); - data1->FirstBLinkAuto::clear(); - etl::link(data0, *data1); - CHECK(data0->FirstBLinkAuto::etl_next == data1); - CHECK(data1->FirstBLinkAuto::etl_previous == data0); + data1.BLink0::clear(); + etl::link(data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); - data1->FirstBLinkAuto::clear(); - etl::link(data0, data1); - CHECK(data0->FirstBLinkAuto::etl_next == data1); - CHECK(data1->FirstBLinkAuto::etl_previous == data0); + data1.BLink0::clear(); + etl::link(data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - CHECK(data0->FirstBLinkAuto::etl_previous == nullptr); - CHECK(data1->FirstBLinkAuto::etl_previous == data0); - CHECK(data1->FirstBLinkAuto::etl_next == data2); - CHECK(data2->FirstBLinkAuto::etl_previous == data1); - CHECK(data2->FirstBLinkAuto::etl_next == data3); - CHECK(data3->FirstBLinkAuto::etl_previous == data2); - CHECK(data3->FirstBLinkAuto::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data1); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); - etl::link(nullptr, data3); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(nullptr, data3); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - CHECK(data3->SecondBLink::etl_previous == nullptr); - CHECK(data3->SecondBLink::etl_next == data2); - CHECK(data2->SecondBLink::etl_previous == data3); - CHECK(data2->SecondBLink::etl_next == data1); - CHECK(data1->SecondBLink::etl_previous == data2); - CHECK(data1->SecondBLink::etl_next == data0); - CHECK(data0->SecondBLink::etl_previous == data1); - CHECK(data0->SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next == &data1); + CHECK(data1.BLink1::etl_previous == &data2); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); - BDataAuto* pdataauto; BData* pdata; - pdataauto = static_cast(data0->FirstBLinkAuto::etl_next); - CHECK_EQUAL(1, pdataauto->value); - pdataauto = static_cast(pdataauto->FirstBLinkAuto::etl_next); - CHECK_EQUAL(2, pdataauto->value); - pdataauto = static_cast(pdataauto->FirstBLinkAuto::etl_next); - CHECK_EQUAL(3, pdataauto->value); - - pdataauto = static_cast(data3->FirstBLinkAuto::etl_previous); - CHECK_EQUAL(2, pdataauto->value); - pdataauto = static_cast(pdataauto->FirstBLinkAuto::etl_previous); - CHECK_EQUAL(1, pdataauto->value); - pdataauto = static_cast(pdataauto->FirstBLinkAuto::etl_previous); - CHECK_EQUAL(0, pdataauto->value); - - pdata = static_cast(data3->SecondBLink::etl_next); - CHECK_EQUAL(2, pdata->value); - pdata = static_cast(pdata->SecondBLink::etl_next); + pdata = static_cast(data0.BLink0::etl_next); CHECK_EQUAL(1, pdata->value); - pdata = static_cast(pdata->SecondBLink::etl_next); - CHECK_EQUAL(0, pdata->value); - - pdata = static_cast(data0->SecondBLink::etl_previous); - CHECK_EQUAL(1, pdata->value); - pdata = static_cast(pdata->SecondBLink::etl_previous); + pdata = static_cast(pdata->BLink0::etl_next); CHECK_EQUAL(2, pdata->value); - pdata = static_cast(pdata->SecondBLink::etl_previous); + pdata = static_cast(pdata->BLink0::etl_next); CHECK_EQUAL(3, pdata->value); - delete data1; - CHECK(data0->FirstBLinkAuto::etl_next == data2); - CHECK(data2->FirstBLinkAuto::etl_previous == data0); + pdata = static_cast(data3.BLink0::etl_previous); + CHECK_EQUAL(2, pdata->value); + pdata = static_cast(pdata->BLink0::etl_previous); + CHECK_EQUAL(1, pdata->value); + pdata = static_cast(pdata->BLink0::etl_previous); + CHECK_EQUAL(0, pdata->value); - CHECK(data3->SecondBLink::etl_previous == nullptr); - CHECK(data3->SecondBLink::etl_next == data2); - CHECK(data2->SecondBLink::etl_previous == data3); - CHECK(data2->SecondBLink::etl_next != nullptr); - CHECK(data0->SecondBLink::etl_previous != nullptr); - CHECK(data0->SecondBLink::etl_next == nullptr); + pdata = static_cast(data3.BLink1::etl_next); + CHECK_EQUAL(2, pdata->value); + pdata = static_cast(pdata->BLink1::etl_next); + CHECK_EQUAL(1, pdata->value); + pdata = static_cast(pdata->BLink1::etl_next); + CHECK_EQUAL(0, pdata->value); - delete data0; - CHECK(data2->FirstBLinkAuto::etl_next == data3); - CHECK(data2->FirstBLinkAuto::etl_previous == nullptr); - CHECK(data3->FirstBLinkAuto::etl_previous == data2); - - CHECK(data3->SecondBLink::etl_previous == nullptr); - CHECK(data3->SecondBLink::etl_next == data2); - CHECK(data2->SecondBLink::etl_previous == data3); - CHECK(data2->SecondBLink::etl_next != nullptr); + pdata = static_cast(data0.BLink1::etl_previous); + CHECK_EQUAL(1, pdata->value); + pdata = static_cast(pdata->BLink1::etl_previous); + CHECK_EQUAL(2, pdata->value); + pdata = static_cast(pdata->BLink1::etl_previous); + CHECK_EQUAL(3, pdata->value); - delete data3; - CHECK(data2->FirstBLinkAuto::etl_next == nullptr); - CHECK(data2->FirstBLinkAuto::etl_previous == nullptr); + data1.BLink0::unlink(); + CHECK(data0.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data0); - CHECK(data2->SecondBLink::etl_next != nullptr); - CHECK(data2->SecondBLink::etl_previous != nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next != nullptr); + CHECK(data0.BLink1::etl_previous != nullptr); + CHECK(data0.BLink1::etl_next == nullptr); - delete data2; + data0.BLink0::unlink(); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data3.BLink0::etl_previous == &data2); + + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next != nullptr); + + data3.BLink0::unlink(); + CHECK(data2.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == nullptr); + + CHECK(data2.BLink1::etl_next != nullptr); + CHECK(data2.BLink1::etl_previous != nullptr); + + data2.BLink0::unlink(); } //************************************************************************* @@ -538,52 +500,52 @@ namespace BData data2(2); BData data3(3); - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); - etl::link_splice(data0, data1); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == nullptr); + etl::link_splice(data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == nullptr); - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); - etl::link_splice(data0, &data1); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == nullptr); + etl::link_splice(data0, &data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == nullptr); - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); - etl::link_splice(&data0, data1); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == nullptr); + etl::link_splice(&data0, data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == nullptr); - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); - etl::link_splice(&data0, &data1); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == nullptr); + etl::link_splice(&data0, &data1); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == nullptr); - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); - etl::link_splice(data0, data3); - etl::link_splice(data0, data1); - etl::link_splice(data1, data2); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); + etl::link_splice(data0, data3); + etl::link_splice(data0, data1); + etl::link_splice(data1, data2); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == &data2); - CHECK(data2.FirstBLink::etl_previous == &data1); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data1); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); } //************************************************************************* @@ -599,110 +561,90 @@ namespace BData data7(7); // Build the first range. - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); - etl::link_splice(data0, data1); - etl::link_splice(data1, data6); - etl::link_splice(data6, data7); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); + etl::link_splice(data0, data1); + etl::link_splice(data1, data6); + etl::link_splice(data6, data7); // Build the second range. - data2.FirstBLink::clear(); - etl::link_splice(nullptr, data2); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.BLink0::clear(); + etl::link_splice(nullptr, data2); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(data1, data2, data5); - - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == &data2); - CHECK(data2.FirstBLink::etl_previous == &data1); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == &data4); - CHECK(data4.FirstBLink::etl_previous == &data3); - CHECK(data4.FirstBLink::etl_next == &data5); - CHECK(data5.FirstBLink::etl_previous == &data4); - CHECK(data5.FirstBLink::etl_next == &data6); - CHECK(data6.FirstBLink::etl_previous == &data5); - CHECK(data6.FirstBLink::etl_next == &data7); - CHECK(data7.FirstBLink::etl_previous == &data6); - CHECK(data7.FirstBLink::etl_next == nullptr); + etl::link_splice(data1, data2, data5); + + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data1); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == &data4); + CHECK(data4.BLink0::etl_previous == &data3); + CHECK(data4.BLink0::etl_next == &data5); + CHECK(data5.BLink0::etl_previous == &data4); + CHECK(data5.BLink0::etl_next == &data6); + CHECK(data6.BLink0::etl_previous == &data5); + CHECK(data6.BLink0::etl_next == &data7); + CHECK(data7.BLink0::etl_previous == &data6); + CHECK(data7.BLink0::etl_next == nullptr); // Do it again with a pointer parameter. // Build the first range. - data0.FirstBLink::clear(); - etl::link_splice(nullptr, data0); - etl::link_splice(data0, data1); - etl::link_splice(data1, data6); - etl::link_splice(data6, data7); + data0.BLink0::clear(); + etl::link_splice(nullptr, data0); + etl::link_splice(data0, data1); + etl::link_splice(data1, data6); + etl::link_splice(data6, data7); // Build the second range. - data2.FirstBLink::clear(); - etl::link_splice(nullptr, data2); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.BLink0::clear(); + etl::link_splice(nullptr, data2); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(&data1, data2, data5); + etl::link_splice(&data1, data2, data5); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data1); - CHECK(data1.FirstBLink::etl_previous == &data0); - CHECK(data1.FirstBLink::etl_next == &data2); - CHECK(data2.FirstBLink::etl_previous == &data1); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == &data4); - CHECK(data4.FirstBLink::etl_previous == &data3); - CHECK(data4.FirstBLink::etl_next == &data5); - CHECK(data5.FirstBLink::etl_previous == &data4); - CHECK(data5.FirstBLink::etl_next == &data6); - CHECK(data6.FirstBLink::etl_previous == &data5); - CHECK(data6.FirstBLink::etl_next == &data7); - CHECK(data7.FirstBLink::etl_previous == &data6); - CHECK(data7.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data1); + CHECK(data1.BLink0::etl_previous == &data0); + CHECK(data1.BLink0::etl_next == &data2); + CHECK(data2.BLink0::etl_previous == &data1); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == &data4); + CHECK(data4.BLink0::etl_previous == &data3); + CHECK(data4.BLink0::etl_next == &data5); + CHECK(data5.BLink0::etl_previous == &data4); + CHECK(data5.BLink0::etl_next == &data6); + CHECK(data6.BLink0::etl_previous == &data5); + CHECK(data6.BLink0::etl_next == &data7); + CHECK(data7.BLink0::etl_previous == &data6); + CHECK(data7.BLink0::etl_next == nullptr); // Do it again with a nullptr parameter. // Build the range. - data2.FirstBLink::clear(); - etl::link_splice(nullptr, data2); - etl::link_splice(data2, data3); - etl::link_splice(data3, data4); - etl::link_splice(data4, data5); + data2.BLink0::clear(); + etl::link_splice(nullptr, data2); + etl::link_splice(data2, data3); + etl::link_splice(data3, data4); + etl::link_splice(data4, data5); - etl::link_splice(nullptr, data2, data5); + etl::link_splice(nullptr, data2, data5); - CHECK(data2.FirstBLink::etl_previous == nullptr); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == &data4); - CHECK(data4.FirstBLink::etl_previous == &data3); - CHECK(data4.FirstBLink::etl_next == &data5); - CHECK(data5.FirstBLink::etl_previous == &data4); - CHECK(data5.FirstBLink::etl_next == nullptr); - } - - //************************************************************************* - TEST(test_link_bidirectional_link_checked) - { - // FirstBLinkAuto is auto-unlink - - BDataChecked* data0 = new BDataChecked(0); - BDataChecked* data1 = new BDataChecked(1); - BDataChecked* data2 = new BDataChecked(2); - BDataChecked* data3 = new BDataChecked(3); - - etl::link(nullptr, data0); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); - - data2->FirstBLinkChecked::clear(); - CHECK_NO_THROW(delete data2); + CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == &data4); + CHECK(data4.BLink0::etl_previous == &data3); + CHECK(data4.BLink0::etl_next == &data5); + CHECK(data5.BLink0::etl_previous == &data4); + CHECK(data5.BLink0::etl_next == nullptr); } //************************************************************************* @@ -713,101 +655,101 @@ namespace BData data2(2); BData data3(3); - etl::link(nullptr, data0); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(nullptr, data0); + etl::link(data0, data1); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - etl::link(nullptr, data3); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(nullptr, data3); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - etl::unlink(data1); - data1.FirstBLink::clear(); + etl::unlink(data1); + data1.BLink0::clear(); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data2); - CHECK(data1.FirstBLink::etl_previous == nullptr); - CHECK(data1.FirstBLink::etl_next == nullptr); - CHECK(data2.FirstBLink::etl_previous == &data0); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data2); + CHECK(data1.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == &data0); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == &data2); - CHECK(data2.SecondBLink::etl_previous == &data3); - CHECK(data2.SecondBLink::etl_next == &data1); - CHECK(data1.SecondBLink::etl_previous == &data2); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next == &data1); + CHECK(data1.BLink1::etl_previous == &data2); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); - etl::unlink(data2); - data2.SecondBLink::clear(); + etl::unlink(data2); + data2.BLink1::clear(); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data2); - CHECK(data1.FirstBLink::etl_previous == nullptr); - CHECK(data1.FirstBLink::etl_next == nullptr); - CHECK(data2.FirstBLink::etl_previous == &data0); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data2); + CHECK(data1.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == &data0); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == &data1); - CHECK(data2.SecondBLink::etl_previous == nullptr); - CHECK(data2.SecondBLink::etl_next == nullptr); - CHECK(data1.SecondBLink::etl_previous == &data3); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data1); + CHECK(data2.BLink1::etl_previous == nullptr); + CHECK(data2.BLink1::etl_next == nullptr); + CHECK(data1.BLink1::etl_previous == &data3); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); - etl::unlink(data0); - data0.FirstBLink::clear(); + etl::unlink(data0); + data0.BLink0::clear(); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == nullptr); - CHECK(data1.FirstBLink::etl_previous == nullptr); - CHECK(data1.FirstBLink::etl_next == nullptr); - CHECK(data2.FirstBLink::etl_previous == nullptr); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == nullptr); + CHECK(data1.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == &data1); - CHECK(data2.SecondBLink::etl_previous == nullptr); - CHECK(data2.SecondBLink::etl_next == nullptr); - CHECK(data1.SecondBLink::etl_previous == &data3); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data1); + CHECK(data2.BLink1::etl_previous == nullptr); + CHECK(data2.BLink1::etl_next == nullptr); + CHECK(data1.BLink1::etl_previous == &data3); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); - etl::unlink(data3); - data3.SecondBLink::clear(); + etl::unlink(data3); + data3.BLink1::clear(); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == nullptr); - CHECK(data1.FirstBLink::etl_previous == nullptr); - CHECK(data1.FirstBLink::etl_next == nullptr); - CHECK(data2.FirstBLink::etl_previous == nullptr); - CHECK(data2.FirstBLink::etl_next == &data3); - CHECK(data3.FirstBLink::etl_previous == &data2); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == nullptr); + CHECK(data1.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data2.BLink0::etl_next == &data3); + CHECK(data3.BLink0::etl_previous == &data2); + CHECK(data3.BLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == nullptr); - CHECK(data2.SecondBLink::etl_previous == nullptr); - CHECK(data2.SecondBLink::etl_next == nullptr); - CHECK(data1.SecondBLink::etl_previous == nullptr); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == nullptr); + CHECK(data2.BLink1::etl_previous == nullptr); + CHECK(data2.BLink1::etl_next == nullptr); + CHECK(data1.BLink1::etl_previous == nullptr); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); } //************************************************************************* @@ -818,55 +760,55 @@ namespace BData data2(2); BData data3(3); - etl::link(nullptr, data0); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + etl::link(nullptr, data0); + etl::link(data0, data1); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); - etl::link(nullptr, data3); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(nullptr, data3); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); - etl::unlink(data1, data2); - data1.FirstBLink::clear(); - data2.FirstBLink::clear(); + etl::unlink(data1, data2); + data1.BLink0::clear(); + data2.BLink0::clear(); - CHECK(data0.FirstBLink::etl_previous == nullptr); - CHECK(data0.FirstBLink::etl_next == &data3); - CHECK(data1.FirstBLink::etl_previous == nullptr); - CHECK(data1.FirstBLink::etl_next == nullptr); - CHECK(data2.FirstBLink::etl_previous == nullptr); - CHECK(data2.FirstBLink::etl_next == nullptr); - CHECK(data3.FirstBLink::etl_previous == &data0); - CHECK(data3.FirstBLink::etl_next == nullptr); + CHECK(data0.BLink0::etl_previous == nullptr); + CHECK(data0.BLink0::etl_next == &data3); + CHECK(data1.BLink0::etl_previous == nullptr); + CHECK(data1.BLink0::etl_next == nullptr); + CHECK(data2.BLink0::etl_previous == nullptr); + CHECK(data2.BLink0::etl_next == nullptr); + CHECK(data3.BLink0::etl_previous == &data0); + CHECK(data3.BLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == &data2); - CHECK(data2.SecondBLink::etl_previous == &data3); - CHECK(data2.SecondBLink::etl_next == &data1); - CHECK(data1.SecondBLink::etl_previous == &data2); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next == &data1); + CHECK(data1.BLink1::etl_previous == &data2); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); } - + //************************************************************************* TEST(test_self_link_bidirectional_link) { BData data0(0); - etl::link(data0, data0); + etl::link(data0, data0); - CHECK(data0.FirstBLink::etl_previous == &data0); - CHECK(data0.FirstBLink::etl_next == &data0); + CHECK(data0.BLink0::etl_previous == &data0); + CHECK(data0.BLink0::etl_next == &data0); - etl::unlink(data0); + etl::unlink(data0); - CHECK(data0.FirstBLink::etl_previous == &data0); - CHECK(data0.FirstBLink::etl_next == &data0); + CHECK(data0.BLink0::etl_previous == &data0); + CHECK(data0.BLink0::etl_next == &data0); } //************************************************************************* @@ -881,114 +823,114 @@ namespace TData data6(6); // First link - data0.FirstTLink::clear(); - etl::link_left(data0, data1); - etl::link_right(data0, data2); - CHECK(data0.FirstTLink::etl_left == &data1); - CHECK(data0.FirstTLink::etl_right == &data2); - CHECK(data1.FirstTLink::etl_parent == &data0); - CHECK(data2.FirstTLink::etl_parent == &data0); + data0.TLink0::clear(); + etl::link_left(data0, data1); + etl::link_right(data0, data2); + CHECK(data0.TLink0::etl_left == &data1); + CHECK(data0.TLink0::etl_right == &data2); + CHECK(data1.TLink0::etl_parent == &data0); + CHECK(data2.TLink0::etl_parent == &data0); - data0.FirstTLink::clear(); - etl::link_left(&data0, data1); - etl::link_right(&data0, data2); - CHECK(data0.FirstTLink::etl_left == &data1); - CHECK(data0.FirstTLink::etl_right == &data2); - CHECK(data1.FirstTLink::etl_parent == &data0); - CHECK(data2.FirstTLink::etl_parent == &data0); + data0.TLink0::clear(); + etl::link_left(&data0, data1); + etl::link_right(&data0, data2); + CHECK(data0.TLink0::etl_left == &data1); + CHECK(data0.TLink0::etl_right == &data2); + CHECK(data1.TLink0::etl_parent == &data0); + CHECK(data2.TLink0::etl_parent == &data0); - data0.FirstTLink::clear(); - etl::link_left(data0, &data1); - etl::link_right(data0, &data2); - CHECK(data0.FirstTLink::etl_left == &data1); - CHECK(data0.FirstTLink::etl_right == &data2); - CHECK(data1.FirstTLink::etl_parent == &data0); - CHECK(data2.FirstTLink::etl_parent == &data0); + data0.TLink0::clear(); + etl::link_left(data0, &data1); + etl::link_right(data0, &data2); + CHECK(data0.TLink0::etl_left == &data1); + CHECK(data0.TLink0::etl_right == &data2); + CHECK(data1.TLink0::etl_parent == &data0); + CHECK(data2.TLink0::etl_parent == &data0); - data0.FirstTLink::clear(); - etl::link_left(&data0, &data1); - etl::link_right(&data0, &data2); + data0.TLink0::clear(); + etl::link_left(&data0, &data1); + etl::link_right(&data0, &data2); - etl::link_left(data1, data3); - etl::link_right(data1, data4); - etl::link_left(data3, nullptr); - etl::link_right(data3, nullptr); - etl::link_left(data4, nullptr); - etl::link_right(data4, nullptr); + etl::link_left(data1, data3); + etl::link_right(data1, data4); + etl::link_left(data3, nullptr); + etl::link_right(data3, nullptr); + etl::link_left(data4, nullptr); + etl::link_right(data4, nullptr); - etl::link_left(data2, data5); - etl::link_right(data2, data6); - etl::link_left(data5, nullptr); - etl::link_right(data5, nullptr); - etl::link_left(data6, nullptr); - etl::link_right(data6, nullptr); + etl::link_left(data2, data5); + etl::link_right(data2, data6); + etl::link_left(data5, nullptr); + etl::link_right(data5, nullptr); + etl::link_left(data6, nullptr); + etl::link_right(data6, nullptr); // Second link - data0.SecondTLink::clear(); - etl::link_left(&data6, &data4); - etl::link_right(&data6, &data5); + data0.TLink1::clear(); + etl::link_left(&data6, &data4); + etl::link_right(&data6, &data5); - etl::link_left(data4, data0); - etl::link_right(data4, data1); - etl::link_left(data0, nullptr); - etl::link_right(data0, nullptr); - etl::link_left(data1, nullptr); - etl::link_right(data1, nullptr); + etl::link_left(data4, data0); + etl::link_right(data4, data1); + etl::link_left(data0, nullptr); + etl::link_right(data0, nullptr); + etl::link_left(data1, nullptr); + etl::link_right(data1, nullptr); - etl::link_left(data5, data2); - etl::link_right(data5, data3); - etl::link_left(data2, nullptr); - etl::link_right(data2, nullptr); - etl::link_left(data3, nullptr); - etl::link_right(data3, nullptr); + etl::link_left(data5, data2); + etl::link_right(data5, data3); + etl::link_left(data2, nullptr); + etl::link_right(data2, nullptr); + etl::link_left(data3, nullptr); + etl::link_right(data3, nullptr); // Check first - CHECK(data0.FirstTLink::etl_left == &data1); - CHECK(data0.FirstTLink::etl_right == &data2); - CHECK(data1.FirstTLink::etl_parent == &data0); - CHECK(data2.FirstTLink::etl_parent == &data0); + CHECK(data0.TLink0::etl_left == &data1); + CHECK(data0.TLink0::etl_right == &data2); + CHECK(data1.TLink0::etl_parent == &data0); + CHECK(data2.TLink0::etl_parent == &data0); - CHECK(data1.FirstTLink::etl_left == &data3); - CHECK(data1.FirstTLink::etl_right == &data4); - CHECK(data3.FirstTLink::etl_parent == &data1); - CHECK(data3.FirstTLink::etl_left == nullptr); - CHECK(data3.FirstTLink::etl_right == nullptr); - CHECK(data4.FirstTLink::etl_parent == &data1); - CHECK(data4.FirstTLink::etl_left == nullptr); - CHECK(data4.FirstTLink::etl_right == nullptr); + CHECK(data1.TLink0::etl_left == &data3); + CHECK(data1.TLink0::etl_right == &data4); + CHECK(data3.TLink0::etl_parent == &data1); + CHECK(data3.TLink0::etl_left == nullptr); + CHECK(data3.TLink0::etl_right == nullptr); + CHECK(data4.TLink0::etl_parent == &data1); + CHECK(data4.TLink0::etl_left == nullptr); + CHECK(data4.TLink0::etl_right == nullptr); - CHECK(data2.FirstTLink::etl_left == &data5); - CHECK(data2.FirstTLink::etl_right == &data6); - CHECK(data5.FirstTLink::etl_parent == &data2); - CHECK(data5.FirstTLink::etl_left == nullptr); - CHECK(data5.FirstTLink::etl_right == nullptr); - CHECK(data6.FirstTLink::etl_parent == &data2); - CHECK(data6.FirstTLink::etl_left == nullptr); - CHECK(data6.FirstTLink::etl_right == nullptr); + CHECK(data2.TLink0::etl_left == &data5); + CHECK(data2.TLink0::etl_right == &data6); + CHECK(data5.TLink0::etl_parent == &data2); + CHECK(data5.TLink0::etl_left == nullptr); + CHECK(data5.TLink0::etl_right == nullptr); + CHECK(data6.TLink0::etl_parent == &data2); + CHECK(data6.TLink0::etl_left == nullptr); + CHECK(data6.TLink0::etl_right == nullptr); // Check second - CHECK(data6.SecondTLink::etl_left == &data4); - CHECK(data6.SecondTLink::etl_right == &data5); - CHECK(data4.SecondTLink::etl_parent == &data6); - CHECK(data5.SecondTLink::etl_parent == &data6); - - CHECK(data4.SecondTLink::etl_left == &data0); - CHECK(data4.SecondTLink::etl_right == &data1); - CHECK(data0.SecondTLink::etl_parent == &data4); - CHECK(data0.SecondTLink::etl_left == nullptr); - CHECK(data0.SecondTLink::etl_right == nullptr); - CHECK(data1.SecondTLink::etl_parent == &data4); - CHECK(data1.SecondTLink::etl_left == nullptr); - CHECK(data1.SecondTLink::etl_right == nullptr); + CHECK(data6.TLink1::etl_left == &data4); + CHECK(data6.TLink1::etl_right == &data5); + CHECK(data4.TLink1::etl_parent == &data6); + CHECK(data5.TLink1::etl_parent == &data6); - CHECK(data5.SecondTLink::etl_left == &data2); - CHECK(data5.SecondTLink::etl_right == &data3); - CHECK(data2.SecondTLink::etl_parent == &data5); - CHECK(data2.SecondTLink::etl_left == nullptr); - CHECK(data2.SecondTLink::etl_right == nullptr); - CHECK(data3.SecondTLink::etl_parent == &data5); - CHECK(data3.SecondTLink::etl_left == nullptr); - CHECK(data3.SecondTLink::etl_right == nullptr); + CHECK(data4.TLink1::etl_left == &data0); + CHECK(data4.TLink1::etl_right == &data1); + CHECK(data0.TLink1::etl_parent == &data4); + CHECK(data0.TLink1::etl_left == nullptr); + CHECK(data0.TLink1::etl_right == nullptr); + CHECK(data1.TLink1::etl_parent == &data4); + CHECK(data1.TLink1::etl_left == nullptr); + CHECK(data1.TLink1::etl_right == nullptr); + + CHECK(data5.TLink1::etl_left == &data2); + CHECK(data5.TLink1::etl_right == &data3); + CHECK(data2.TLink1::etl_parent == &data5); + CHECK(data2.TLink1::etl_left == nullptr); + CHECK(data2.TLink1::etl_right == nullptr); + CHECK(data3.TLink1::etl_parent == &data5); + CHECK(data3.TLink1::etl_left == nullptr); + CHECK(data3.TLink1::etl_right == nullptr); } //************************************************************************* @@ -996,51 +938,51 @@ namespace { // Forward link FData fdata(0); - - fdata.FirstFLink::clear(); - fdata.SecondFLink::clear(); - CHECK(!fdata.FirstFLink::is_linked()); - CHECK(!fdata.SecondFLink::is_linked()); - etl::link(fdata, fdata); - CHECK(fdata.FirstFLink::is_linked()); - CHECK(!fdata.SecondFLink::is_linked()); + fdata.FLink0::clear(); + fdata.FLink1::clear(); + CHECK(!fdata.FLink0::is_linked()); + CHECK(!fdata.FLink1::is_linked()); - etl::link(fdata, fdata); - CHECK(fdata.FirstFLink::is_linked()); - CHECK(fdata.SecondFLink::is_linked()); + etl::link(fdata, fdata); + CHECK(fdata.FLink0::is_linked()); + CHECK(!fdata.FLink1::is_linked()); + + etl::link(fdata, fdata); + CHECK(fdata.FLink0::is_linked()); + CHECK(fdata.FLink1::is_linked()); // Bidirectional link BData bdata(0); - bdata.FirstBLink::clear(); - bdata.SecondBLink::clear(); - CHECK(!bdata.FirstBLink::is_linked()); - CHECK(!bdata.SecondBLink::is_linked()); + bdata.BLink0::clear(); + bdata.BLink1::clear(); + CHECK(!bdata.BLink0::is_linked()); + CHECK(!bdata.BLink1::is_linked()); - etl::link(bdata, bdata); - CHECK(bdata.FirstBLink::is_linked()); - CHECK(!bdata.SecondBLink::is_linked()); + etl::link(bdata, bdata); + CHECK(bdata.BLink0::is_linked()); + CHECK(!bdata.BLink1::is_linked()); - etl::link(bdata, bdata); - CHECK(bdata.FirstBLink::is_linked()); - CHECK(bdata.SecondBLink::is_linked()); + etl::link(bdata, bdata); + CHECK(bdata.BLink0::is_linked()); + CHECK(bdata.BLink1::is_linked()); // Tree link TData tdata(0); - tdata.FirstTLink::clear(); - tdata.SecondTLink::clear(); - CHECK(!tdata.FirstTLink::is_linked()); - CHECK(!tdata.SecondTLink::is_linked()); + tdata.TLink0::clear(); + tdata.TLink1::clear(); + CHECK(!tdata.TLink0::is_linked()); + CHECK(!tdata.TLink1::is_linked()); - etl::link_left(tdata, tdata); - CHECK(tdata.FirstTLink::is_linked()); - CHECK(!tdata.SecondTLink::is_linked()); + etl::link_left(tdata, tdata); + CHECK(tdata.TLink0::is_linked()); + CHECK(!tdata.TLink1::is_linked()); - etl::link_right(tdata, tdata); - CHECK(tdata.FirstTLink::is_linked()); - CHECK(tdata.SecondTLink::is_linked()); + etl::link_right(tdata, tdata); + CHECK(tdata.TLink0::is_linked()); + CHECK(tdata.TLink1::is_linked()); } //************************************************************************* @@ -1055,72 +997,198 @@ namespace MData data6(6); // Forward - data0.FirstFLink::clear(); - etl::link(data0, data1); - etl::link(data1, data2); - etl::link(data2, data3); - etl::link(data3, nullptr); + data0.FLink0::clear(); + etl::link(data0, data1); + etl::link(data1, data2); + etl::link(data2, data3); + etl::link(data3, nullptr); // Bidirectional - etl::link(nullptr, data3); - etl::link(data3, data2); - etl::link(data2, data1); - etl::link(data1, data0); - etl::link(data0, nullptr); + etl::link(nullptr, data3); + etl::link(data3, data2); + etl::link(data2, data1); + etl::link(data1, data0); + etl::link(data0, nullptr); // Tree - data0.ThirdTLink::clear(); - etl::link_left(data0, data1); - etl::link_right(data0, data2); - etl::link_left(data1, data3); - etl::link_right(data1, data4); - etl::link_left(data3, nullptr); - etl::link_right(data3, nullptr); - etl::link_left(data4, nullptr); - etl::link_right(data4, nullptr); - etl::link_left(data2, data5); - etl::link_right(data2, data6); - etl::link_left(data5, nullptr); - etl::link_right(data5, nullptr); - etl::link_left(data6, nullptr); - etl::link_right(data6, nullptr); + data0.TLink2::clear(); + etl::link_left(data0, data1); + etl::link_right(data0, data2); + etl::link_left(data1, data3); + etl::link_right(data1, data4); + etl::link_left(data3, nullptr); + etl::link_right(data3, nullptr); + etl::link_left(data4, nullptr); + etl::link_right(data4, nullptr); + etl::link_left(data2, data5); + etl::link_right(data2, data6); + etl::link_left(data5, nullptr); + etl::link_right(data5, nullptr); + etl::link_left(data6, nullptr); + etl::link_right(data6, nullptr); - CHECK(data0.FirstFLink::etl_next == &data1); - CHECK(data1.FirstFLink::etl_next == &data2); - CHECK(data2.FirstFLink::etl_next == &data3); - CHECK(data3.FirstFLink::etl_next == nullptr); + CHECK(data0.FLink0::etl_next == &data1); + CHECK(data1.FLink0::etl_next == &data2); + CHECK(data2.FLink0::etl_next == &data3); + CHECK(data3.FLink0::etl_next == nullptr); - CHECK(data3.SecondBLink::etl_previous == nullptr); - CHECK(data3.SecondBLink::etl_next == &data2); - CHECK(data2.SecondBLink::etl_previous == &data3); - CHECK(data2.SecondBLink::etl_next == &data1); - CHECK(data1.SecondBLink::etl_previous == &data2); - CHECK(data1.SecondBLink::etl_next == &data0); - CHECK(data0.SecondBLink::etl_previous == &data1); - CHECK(data0.SecondBLink::etl_next == nullptr); + CHECK(data3.BLink1::etl_previous == nullptr); + CHECK(data3.BLink1::etl_next == &data2); + CHECK(data2.BLink1::etl_previous == &data3); + CHECK(data2.BLink1::etl_next == &data1); + CHECK(data1.BLink1::etl_previous == &data2); + CHECK(data1.BLink1::etl_next == &data0); + CHECK(data0.BLink1::etl_previous == &data1); + CHECK(data0.BLink1::etl_next == nullptr); - CHECK(data0.ThirdTLink::etl_left == &data1); - CHECK(data0.ThirdTLink::etl_right == &data2); - CHECK(data1.ThirdTLink::etl_parent == &data0); - CHECK(data2.ThirdTLink::etl_parent == &data0); + CHECK(data0.TLink2::etl_left == &data1); + CHECK(data0.TLink2::etl_right == &data2); + CHECK(data1.TLink2::etl_parent == &data0); + CHECK(data2.TLink2::etl_parent == &data0); - CHECK(data1.ThirdTLink::etl_left == &data3); - CHECK(data1.ThirdTLink::etl_right == &data4); - CHECK(data3.ThirdTLink::etl_parent == &data1); - CHECK(data3.ThirdTLink::etl_left == nullptr); - CHECK(data3.ThirdTLink::etl_right == nullptr); - CHECK(data4.ThirdTLink::etl_parent == &data1); - CHECK(data4.ThirdTLink::etl_left == nullptr); - CHECK(data4.ThirdTLink::etl_right == nullptr); + CHECK(data1.TLink2::etl_left == &data3); + CHECK(data1.TLink2::etl_right == &data4); + CHECK(data3.TLink2::etl_parent == &data1); + CHECK(data3.TLink2::etl_left == nullptr); + CHECK(data3.TLink2::etl_right == nullptr); + CHECK(data4.TLink2::etl_parent == &data1); + CHECK(data4.TLink2::etl_left == nullptr); + CHECK(data4.TLink2::etl_right == nullptr); - CHECK(data2.ThirdTLink::etl_left == &data5); - CHECK(data2.ThirdTLink::etl_right == &data6); - CHECK(data5.ThirdTLink::etl_parent == &data2); - CHECK(data5.ThirdTLink::etl_left == nullptr); - CHECK(data5.ThirdTLink::etl_right == nullptr); - CHECK(data6.ThirdTLink::etl_parent == &data2); - CHECK(data6.ThirdTLink::etl_left == nullptr); - CHECK(data6.ThirdTLink::etl_right == nullptr); + CHECK(data2.TLink2::etl_left == &data5); + CHECK(data2.TLink2::etl_right == &data6); + CHECK(data5.TLink2::etl_parent == &data2); + CHECK(data5.TLink2::etl_left == nullptr); + CHECK(data5.TLink2::etl_right == nullptr); + CHECK(data6.TLink2::etl_parent == &data2); + CHECK(data6.TLink2::etl_left == nullptr); + CHECK(data6.TLink2::etl_right == nullptr); + } + + //************************************************************************* + TEST(test_tree_link_rotate_left) + { + TLink0 r; + TLink0 a; + TLink0 b; + TLink0 c; + TLink0 d; + TLink0 e; + + r.clear(); + c.clear(); + d.clear(); + e.clear(); + etl::link_left(r, b); + etl::link_right(b, a); + etl::link_left(b, d); + etl::link_right(a, c); + etl::link_left(a, e); + + etl::link_rotate_left(b, a); + + CHECK(a.etl_parent == &r); + CHECK(b.etl_parent == &a); + CHECK(e.etl_parent == &b); + CHECK(d.etl_parent == &b); + CHECK(c.etl_parent == &a); + CHECK(a.etl_left == &b); + CHECK(a.etl_right == &c); + CHECK(b.etl_left == &d); + CHECK(b.etl_right == &e); + } + + //************************************************************************* + TEST(test_tree_link_rotate_left_nullptr) + { + TLink0 r; + TLink0 a; + TLink0 b; + TLink0 c; + TLink0 d; + + r.clear(); + a.clear(); + c.clear(); + d.clear(); + etl::link_left(r, b); + etl::link_right(b, a); + etl::link_left(b, d); + etl::link_right(a, c); + + etl::link_rotate_left(b, a); + + CHECK(a.etl_parent == &r); + CHECK(b.etl_parent == &a); + CHECK(d.etl_parent == &b); + CHECK(c.etl_parent == &a); + CHECK(a.etl_left == &b); + CHECK(a.etl_right == &c); + CHECK(b.etl_left == &d); + CHECK(b.etl_right == nullptr); + } + + //************************************************************************* + TEST(test_tree_link_rotate_right) + { + TLink0 r; + TLink0 a; + TLink0 b; + TLink0 c; + TLink0 d; + TLink0 e; + + r.clear(); + c.clear(); + d.clear(); + e.clear(); + etl::link_left(r, a); + etl::link_left(a, b); + etl::link_left(b, d); + etl::link_right(a, c); + etl::link_right(b, e); + + etl::link_rotate_right(a, b); + + CHECK(b.etl_parent == &r); + CHECK(d.etl_parent == &b); + CHECK(a.etl_parent == &b); + CHECK(e.etl_parent == &a); + CHECK(c.etl_parent == &a); + CHECK(b.etl_left == &d); + CHECK(b.etl_right == &a); + CHECK(a.etl_left == &e); + CHECK(a.etl_right == &c); + } + + //************************************************************************* + TEST(test_tree_link_rotate_right_nullptr) + { + TLink0 r; + TLink0 a; + TLink0 b; + TLink0 c; + TLink0 d; + + r.clear(); + b.clear(); + c.clear(); + d.clear(); + etl::link_left(r, a); + etl::link_left(a, b); + etl::link_left(b, d); + etl::link_right(a, c); + + etl::link_rotate_right(a, b); + + CHECK(b.etl_parent == &r); + CHECK(d.etl_parent == &b); + CHECK(a.etl_parent == &b); + CHECK(c.etl_parent == &a); + CHECK(b.etl_left == &d); + CHECK(b.etl_right == &a); + CHECK(a.etl_left == nullptr); + CHECK(a.etl_right == &c); } }; } diff --git a/test/test_intrusive_list.cpp b/test/test_intrusive_list.cpp index d7c16ff8..34e01071 100644 --- a/test/test_intrusive_list.cpp +++ b/test/test_intrusive_list.cpp @@ -84,25 +84,25 @@ namespace }; //*************************************************************************** - bool operator ==(const ItemDCNode& lhs, const ItemDCNode& rhs) - { - return lhs.data == rhs.data; - } +// bool operator ==(const ItemDCNode& lhs, const ItemDCNode& rhs) +// { +// return lhs.data == rhs.data; +// } bool operator ==(const ItemNDCNode& lhs, const ItemNDCNode& rhs) { return lhs.data == rhs.data; } - bool operator !=(const ItemDCNode& lhs, const ItemDCNode& rhs) - { - return lhs.data != rhs.data; - } +// bool operator !=(const ItemDCNode& lhs, const ItemDCNode& rhs) +// { +// return lhs.data != rhs.data; +// } - bool operator !=(const ItemNDCNode& lhs, const ItemNDCNode& rhs) - { - return lhs.data != rhs.data; - } +// bool operator !=(const ItemNDCNode& lhs, const ItemNDCNode& rhs) +// { +// return lhs.data != rhs.data; +// } std::ostream& operator << (std::ostream& os, const ItemNDCNode& node) { @@ -136,10 +136,10 @@ namespace typedef std::vector InitialDataNDC; } -namespace -{ +namespace +{ SUITE(test_intrusive_list) - { + { InitialDataNDC unsorted_data; InitialDataNDC sorted_data; InitialDataNDC sorted_data2; @@ -151,7 +151,7 @@ namespace InitialDataNDC merge_data2; InitialDataNDC merge_data3; InitialDataNDC merge_data4; - + //************************************************************************* struct SetupFixture { @@ -200,11 +200,11 @@ namespace DataNDC0 data0; CHECK(data0.begin() == data0.end()); - + DataNDC0::const_iterator begin = data0.begin(); DataNDC0::const_iterator end = data0.end(); CHECK(begin == end); - + CHECK(data0.cbegin() == data0.cend()); } @@ -224,7 +224,7 @@ namespace TEST_FIXTURE(SetupFixture, test_const_iterator) { bool are_equal; - + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); are_equal = std::equal(data0.cbegin(), data0.cend(), sorted_data.begin()); @@ -282,7 +282,7 @@ namespace std::list compare0; std::list compare1; - + DataNDC0 data0; DataNDC1 data1; @@ -301,7 +301,7 @@ namespace compare0.push_front(node4); compare0.push_front(node6); compare0.push_front(node7); - + data0.push_front(node0); data0.push_front(node1); data0.push_front(node2); @@ -311,7 +311,7 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(6, data0.size()); + CHECK_EQUAL(6U, data0.size()); CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); compare1.push_front(node0); @@ -330,7 +330,7 @@ namespace are_equal = std::equal(data1.begin(), data1.end(), compare1.begin()); CHECK(are_equal); - CHECK_EQUAL(6, data1.size()); + CHECK_EQUAL(6U, data1.size()); CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); } @@ -360,12 +360,12 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); offset = 0; @@ -385,12 +385,12 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -414,7 +414,7 @@ namespace are_equal = std::equal(data1.begin(), data1.end(), test1.begin()); CHECK(are_equal); CHECK_EQUAL(test1.size(), data1.size()); - CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(test1.size(), size_t(std::distance(data1.begin(), data1.end()))); compare.assign(test1.begin(), test1.end()); data0.assign(test1.begin(), test1.end()); @@ -437,7 +437,7 @@ namespace are_equal = std::equal(data1.begin(), data1.end(), test1.begin()); CHECK(are_equal); CHECK_EQUAL(test1.size(), data1.size()); - CHECK_EQUAL(test1.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(test1.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -471,7 +471,7 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); - CHECK_EQUAL(6, data0.size()); + CHECK_EQUAL(6U, data0.size()); CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); } @@ -502,7 +502,7 @@ namespace data1.push_front(node5); data1.push_front(node6); - CHECK_EQUAL(6, data0.size()); + CHECK_EQUAL(6U, data0.size()); CHECK_EQUAL(6, std::distance(data0.begin(), data0.end())); CHECK(!data0.empty()); @@ -512,17 +512,17 @@ namespace data0.pop_front(); data0.pop_front(); - CHECK_EQUAL(1, data0.size()); + CHECK_EQUAL(1U, data0.size()); CHECK_EQUAL(1, std::distance(data0.begin(), data0.end())); CHECK(!data0.empty()); data0.pop_front(); - CHECK_EQUAL(0, data0.size()); + CHECK_EQUAL(0U, data0.size()); CHECK_EQUAL(0, std::distance(data0.begin(), data0.end())); CHECK(data0.empty()); - CHECK_EQUAL(6, data1.size()); + CHECK_EQUAL(6U, data1.size()); CHECK_EQUAL(6, std::distance(data1.begin(), data1.end())); CHECK(!data1.empty()); } @@ -557,12 +557,12 @@ namespace CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); are_equal = *i_data == *i_compare_data; CHECK(are_equal); @@ -578,12 +578,12 @@ namespace CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); are_equal = *i_data == *i_compare_data; CHECK(are_equal); @@ -619,12 +619,12 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -651,12 +651,12 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare_data.begin()); CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -691,13 +691,13 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), unique_data.begin()); CHECK(are_equal); CHECK_EQUAL(unique_data.size(), data0.size()); - CHECK_EQUAL(unique_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(unique_data.size(), size_t(std::distance(data0.begin(), data0.end()))); // data1 should not have changed. are_equal = std::equal(data1.begin(), data1.end(), non_unique_data.begin()); CHECK(are_equal); CHECK_EQUAL(non_unique_data.size(), data1.size()); - CHECK_EQUAL(non_unique_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(non_unique_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -717,12 +717,12 @@ namespace CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -742,12 +742,12 @@ namespace CHECK(are_equal); CHECK_EQUAL(compare_data.size(), data0.size()); - CHECK_EQUAL(compare_data.size(), std::distance(data0.begin(), data0.end())); + CHECK_EQUAL(compare_data.size(), size_t(std::distance(data0.begin(), data0.end()))); are_equal = std::equal(data1.begin(), data1.end(), sorted_data.begin()); CHECK(are_equal); CHECK_EQUAL(sorted_data.size(), data1.size()); - CHECK_EQUAL(sorted_data.size(), std::distance(data1.begin(), data1.end())); + CHECK_EQUAL(sorted_data.size(), size_t(std::distance(data1.begin(), data1.end()))); } //************************************************************************* @@ -760,6 +760,9 @@ namespace data0.reverse(); // Just reverse one of them. + CHECK_EQUAL(data1.size(), data0.size()); + CHECK_EQUAL(data0.size(), std::distance(data0.begin(), data0.end())); + are_equal = std::equal(data0.begin(), data0.end(), sorted_data.rbegin()); CHECK(are_equal); @@ -899,13 +902,9 @@ namespace DataNDC0::iterator idata_destination = data0.begin(); std::advance(idata_destination, 3); - std::list compare0(data0.begin(), data0.end()); - - std::list::iterator icompare_destination = compare0.begin(); - std::advance(icompare_destination, 3); + std::list compare0(sorted_data2.begin(), sorted_data2.end()); data0.splice(idata_destination, data0); - compare0.splice(icompare_destination, compare0); are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); diff --git a/test/test_intrusive_queue.cpp b/test/test_intrusive_queue.cpp new file mode 100644 index 00000000..a0f660e2 --- /dev/null +++ b/test/test_intrusive_queue.cpp @@ -0,0 +1,259 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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. +******************************************************************************/ + +#include + +#include "../src/intrusive_queue.h" +#include "../src/intrusive_links.h" + +#include + +namespace +{ + typedef etl::forward_link<0> link0; + typedef etl::bidirectional_link<1> link1; + + struct Data : public link0, public link1 + { + Data(int i) + : i(i) + { + + } + + int i; + }; + + bool operator ==(const Data& lhs, const Data& rhs) + { + return lhs.i == rhs.i; + } + + std::ostream& operator << (std::ostream& os, const Data& data) + { + os << data.i; + return os; + } + + std::vector data = + { + Data(1), Data(2), Data(3), Data(4), Data(5), Data(6), Data(7), Data(8) + }; + + SUITE(test_intrusive_queue) + { + //************************************************************************* + TEST(test_constructor) + { + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + CHECK(queueD.empty()); + CHECK(queueC.empty()); + + CHECK_EQUAL(0U, queueD.size()); + CHECK_EQUAL(0U, queueC.size()); + } + + //************************************************************************* + TEST(test_empty) + { + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + Data data1(1); + Data data2(2); + + CHECK(queueD.empty()); + CHECK(queueC.empty()); + + queueD.push(data1); + queueC.push(data2); + + CHECK(!queueD.empty()); + CHECK(!queueC.empty()); + } + + //************************************************************************* + TEST(test_size) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + queueD.push(data1); + queueD.push(data2); + queueD.push(data3); + + queueC.push(data1); + queueC.push(data2); + + CHECK_EQUAL(3U, queueD.size()); + CHECK_EQUAL(2U, queueC.size()); + } + + //************************************************************************* + TEST(test_clear) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + queueD.push(data1); + queueD.push(data2); + queueD.push(data3); + + queueC.push(data1); + queueC.push(data2); + + queueD.clear(); + queueC.clear(); + + CHECK(queueD.empty()); + CHECK(queueC.empty()); + } + + //************************************************************************* + TEST(test_push) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + queueD.push(data1); + CHECK_EQUAL(queueD.front(), data1); + CHECK_EQUAL(queueD.back(), data1); + + queueD.push(data2); + CHECK_EQUAL(queueD.front(), data1); + CHECK_EQUAL(queueD.back(), data2); + + queueD.push(data3); + CHECK_EQUAL(queueD.front(), data1); + CHECK_EQUAL(queueD.back(), data3); + + queueC.push(data1); + CHECK_EQUAL(queueC.front(), data1); + CHECK_EQUAL(queueC.back(), data1); + + queueC.push(data2); + CHECK_EQUAL(queueC.front(), data1); + CHECK_EQUAL(queueC.back(), data2); + } + + + //************************************************************************* + TEST(test_pop) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; + + queueD.push(data1); + queueD.push(data2); + queueD.push(data3); + + queueC.push(data1); + queueC.push(data2); + + CHECK_EQUAL(queueD.front(), data1); + CHECK_EQUAL(queueD.back(), data3); + queueD.pop(); + CHECK_EQUAL(queueD.front(), data2); + CHECK_EQUAL(queueD.back(), data3); + queueD.pop(); + CHECK_EQUAL(queueD.front(), data3); + CHECK_EQUAL(queueD.back(), data3); + queueD.pop(); + CHECK(queueD.empty()); + + CHECK_EQUAL(queueC.front(), data1); + CHECK_EQUAL(queueC.back(), data2); + queueC.pop(); + CHECK_EQUAL(queueC.front(), data2); + CHECK_EQUAL(queueC.back(), data2); + queueC.pop(); + CHECK(queueC.empty()); + } + + //************************************************************************* + TEST(test_front_const) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + const etl::intrusive_queue& queueDR = queueD; + + queueD.push(data1); + queueD.push(data2); + queueD.push(data3); + + CHECK_EQUAL(queueD.front(), queueDR.front()); + queueD.pop(); + CHECK_EQUAL(queueD.front(), queueDR.front()); + queueD.pop(); + CHECK_EQUAL(queueD.front(), queueDR.front()); + } + + //************************************************************************* + TEST(test_back_const) + { + + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queueD; + const etl::intrusive_queue& queueDR = queueD; + + queueD.push(data1); + queueD.push(data2); + queueD.push(data3); + + CHECK_EQUAL(queueD.back(), queueDR.back()); + queueD.pop(); + CHECK_EQUAL(queueD.back(), queueDR.back()); + queueD.pop(); + CHECK_EQUAL(queueD.back(), queueDR.back()); + } + }; +} diff --git a/test/test_intrusive_stack.cpp b/test/test_intrusive_stack.cpp new file mode 100644 index 00000000..da4da4ba --- /dev/null +++ b/test/test_intrusive_stack.cpp @@ -0,0 +1,226 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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. +******************************************************************************/ + +#include + +#include "../src/intrusive_stack.h" +#include "../src/intrusive_links.h" + +#include + +namespace +{ + typedef etl::forward_link<0> link0; + typedef etl::bidirectional_link<1> link1; + + struct Data : public link0, public link1 + { + Data(int i) + : i(i) + { + + } + + int i; + }; + + bool operator ==(const Data& lhs, const Data& rhs) + { + return lhs.i == rhs.i; + } + + std::ostream& operator << (std::ostream& os, const Data& data) + { + os << data.i; + return os; + } + + std::vector data = + { + Data(1), Data(2), Data(3), Data(4), Data(5), Data(6), Data(7), Data(8) + }; + + SUITE(test_intrusive_stack) + { + //************************************************************************* + TEST(test_constructor) + { + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + CHECK(stackD.empty()); + CHECK(stackC.empty()); + + CHECK_EQUAL(0U, stackD.size()); + CHECK_EQUAL(0U, stackC.size()); + } + + //************************************************************************* + TEST(test_empty) + { + Data data1(1); + Data data2(2); + + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + CHECK(stackD.empty()); + CHECK(stackC.empty()); + + stackD.push(data1); + stackC.push(data2); + + CHECK(!stackD.empty()); + CHECK(!stackC.empty()); + } + + //************************************************************************* + TEST(test_size) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + stackD.push(data1); + stackD.push(data2); + stackD.push(data3); + + stackC.push(data1); + stackC.push(data2); + + CHECK_EQUAL(3U, stackD.size()); + CHECK_EQUAL(2U, stackC.size()); + } + + //************************************************************************* + TEST(test_clear) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + stackD.push(data1); + stackD.push(data2); + stackD.push(data3); + + stackC.push(data1); + stackC.push(data2); + + stackD.clear(); + stackC.clear(); + + CHECK(stackD.empty()); + CHECK(stackC.empty()); + } + + //************************************************************************* + TEST(test_push) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + stackD.push(data1); + CHECK_EQUAL(stackD.top(), data1); + + stackD.push(data2); + CHECK_EQUAL(stackD.top(), data2); + + stackD.push(data3); + CHECK_EQUAL(stackD.top(), data3); + + stackC.push(data1); + CHECK_EQUAL(stackC.top(), data1); + + stackC.push(data2); + CHECK_EQUAL(stackC.top(), data2); + } + + //************************************************************************* + TEST(test_pop) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_stack stackD; + etl::intrusive_stack stackC; + + stackD.push(data1); + stackD.push(data2); + stackD.push(data3); + + stackC.push(data1); + stackC.push(data2); + + CHECK_EQUAL(stackD.top(), data3); + stackD.pop(); + CHECK_EQUAL(stackD.top(), data2); + stackD.pop(); + CHECK_EQUAL(stackD.top(), data1); + stackD.pop(); + CHECK(stackD.empty()); + + CHECK_EQUAL(stackC.top(), data2); + stackC.pop(); + CHECK_EQUAL(stackC.top(), data1); + stackC.pop(); + CHECK(stackC.empty()); + } + + //************************************************************************* + TEST(test_top_const) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_stack stackD; + const etl::intrusive_stack& stackDR = stackD; + + stackD.push(data1); + stackD.push(data2); + stackD.push(data3); + + CHECK_EQUAL(stackD.top(), stackDR.top()); + stackD.pop(); + CHECK_EQUAL(stackD.top(), stackDR.top()); + stackD.pop(); + CHECK_EQUAL(stackD.top(), stackDR.top()); + } + }; +} diff --git a/test/test_io_port.cpp b/test/test_io_port.cpp index 62487683..656ce1a3 100644 --- a/test/test_io_port.cpp +++ b/test/test_io_port.cpp @@ -32,7 +32,12 @@ SOFTWARE. #include -#pragma warning(disable:4101) // Unused variable. +#if defined(ETL_COMPILER_GCC) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-variable" +#else + #pragma warning(disable:4101) // Unused variable. +#endif template struct serial_port @@ -113,3 +118,7 @@ namespace } }; } + +#if defined(ETL_COMPILER_GCC) + #pragma GCC diagnostic pop +#endif diff --git a/test/test_iterator.cpp b/test/test_iterator.cpp new file mode 100644 index 00000000..f77c6b71 --- /dev/null +++ b/test/test_iterator.cpp @@ -0,0 +1,172 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +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. +******************************************************************************/ + +#include + +#include "../src/iterator.h" + +#include + +struct input : public std::iterator +{ + +}; + +struct output : public std::iterator +{ + +}; + +struct forward : public std::iterator +{ + +}; + +struct bidirectional : public std::iterator +{ + +}; + +struct random : public std::iterator +{ + +}; + +typedef int* pointer; +typedef const int* const_pointer; + +namespace +{ + SUITE(test_iterator) + { + TEST(test_input) + { + CHECK(etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(!etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(!etl::is_output_iterator_concept::value); + CHECK(!etl::is_forward_iterator_concept::value); + CHECK(!etl::is_bidirectional_iterator_concept::value); + CHECK(!etl::is_random_iterator_concept::value); + } + + TEST(test_output) + { + CHECK(!etl::is_input_iterator::value); + CHECK(etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(!etl::is_random_iterator::value); + + CHECK(!etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(!etl::is_forward_iterator_concept::value); + CHECK(!etl::is_bidirectional_iterator_concept::value); + CHECK(!etl::is_random_iterator_concept::value); + } + + TEST(test_forward) + { + CHECK(!etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(!etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(etl::is_forward_iterator_concept::value); + CHECK(!etl::is_bidirectional_iterator_concept::value); + CHECK(!etl::is_random_iterator_concept::value); + } + + TEST(test_bidirectional) + { + CHECK(!etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(etl::is_bidirectional_iterator::value); + CHECK(!etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(etl::is_forward_iterator_concept::value); + CHECK(etl::is_bidirectional_iterator_concept::value); + CHECK(!etl::is_random_iterator_concept::value); + } + + TEST(test_random) + { + CHECK(!etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(etl::is_forward_iterator_concept::value); + CHECK(etl::is_bidirectional_iterator_concept::value); + CHECK(etl::is_random_iterator_concept::value); + } + + TEST(test_pointer) + { + CHECK(!etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(etl::is_forward_iterator_concept::value); + CHECK(etl::is_bidirectional_iterator_concept::value); + CHECK(etl::is_random_iterator_concept::value); + } + + TEST(test_const_pointer) + { + CHECK(!etl::is_input_iterator::value); + CHECK(!etl::is_output_iterator::value); + CHECK(!etl::is_forward_iterator::value); + CHECK(!etl::is_bidirectional_iterator::value); + CHECK(etl::is_random_iterator::value); + + CHECK(etl::is_input_iterator_concept::value); + CHECK(etl::is_output_iterator_concept::value); + CHECK(etl::is_forward_iterator_concept::value); + CHECK(etl::is_bidirectional_iterator_concept::value); + CHECK(etl::is_random_iterator_concept::value); + } + }; +} diff --git a/test/test_jenkins.cpp b/test/test_jenkins.cpp index 3bef5bf2..9f609f73 100644 --- a/test/test_jenkins.cpp +++ b/test/test_jenkins.cpp @@ -28,8 +28,6 @@ SOFTWARE. #include -#include "murmurhash3.h" // The 'C' reference implementation. - #include #include #include @@ -39,7 +37,7 @@ SOFTWARE. #include "../src/endian.h" template -uint32_t jenkins32(TIterator begin, TIterator end) +uint32_t jenkins(TIterator begin, TIterator end) { uint32_t hash = 0; @@ -57,177 +55,91 @@ uint32_t jenkins32(TIterator begin, TIterator end) return hash; } -template -uint64_t jenkins64(TIterator begin, TIterator end) -{ - uint64_t hash = 0; - - while (begin != end) - { - hash += *begin++; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash; -} - namespace -{ +{ SUITE(test_jenkins) { //************************************************************************* - TEST(test_jenkins_32_constructor) + TEST(test_jenkins_constructor) { std::string data("123456789"); - uint32_t hash = etl::jenkins(data.begin(), data.end()); - uint32_t compare = jenkins32(data.begin(), data.end()); + uint32_t hash = etl::jenkins(data.begin(), data.end()); + uint32_t compare = jenkins(data.begin(), data.end()); CHECK_EQUAL(compare, hash); } //************************************************************************* - TEST(test_jenkins_32_add_values) + TEST(test_jenkins_add_values) { std::string data("123456789"); - etl::jenkins jenkins_32_calculator; + etl::jenkins jenkins_calculator; for (size_t i = 0; i < data.size(); ++i) { - jenkins_32_calculator.add(data[i]); + jenkins_calculator.add(data[i]); } - uint32_t hash = jenkins_32_calculator; - uint32_t compare = jenkins32(data.begin(), data.end()); + uint32_t hash = jenkins_calculator; + uint32_t compare = jenkins(data.begin(), data.end()); CHECK_EQUAL(compare, hash); } //************************************************************************* - TEST(test_jenkins_32_add_range) + TEST(test_jenkins_add_range) { std::string data("123456789"); - etl::jenkins jenkins_32_calculator; + etl::jenkins jenkins_calculator; - jenkins_32_calculator.add(data.begin(), data.end()); + jenkins_calculator.add(data.begin(), data.end()); - uint32_t hash = jenkins_32_calculator.value(); + uint32_t hash = jenkins_calculator.value(); - uint32_t compare = jenkins32(data.begin(), data.end()); + uint32_t compare = jenkins(data.begin(), data.end()); CHECK_EQUAL(compare, hash); } //************************************************************************* - TEST(test_jenkins_32_add_range_endian) + TEST(test_jenkins_add_range_endian) { std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; std::vector data2 = { 0x04030201, 0x08070605 }; std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - uint32_t hash1 = etl::jenkins(data1.begin(), data1.end()); - uint32_t hash2 = etl::jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); - uint32_t hash3 = etl::jenkins(data3.rbegin(), data3.rend()); + uint32_t hash1 = etl::jenkins(data1.begin(), data1.end()); + uint32_t hash2 = etl::jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); + uint32_t hash3 = etl::jenkins(data3.rbegin(), data3.rend()); CHECK_EQUAL(hash1, hash2); CHECK_EQUAL(hash1, hash3); - uint64_t compare1 = jenkins32(data1.begin(), data1.end()); + uint64_t compare1 = jenkins(data1.begin(), data1.end()); CHECK_EQUAL(compare1, hash1); - uint64_t compare2 = jenkins32((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); + uint64_t compare2 = jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); CHECK_EQUAL(compare2, hash2); - uint64_t compare3 = jenkins32(data3.rbegin(), data3.rend()); - CHECK_EQUAL(compare2, hash3); + uint64_t compare3 = jenkins(data3.rbegin(), data3.rend()); + CHECK_EQUAL(compare3, hash3); } //************************************************************************* - TEST(test_jenkins_32_finalised_exception) + TEST(test_jenkins_finalised_exception) { std::string data("123456789"); - etl::jenkins j32; + etl::jenkins j32; j32.add(data.begin(), data.end()); - uint32_t hash = j32; + + j32.value(); CHECK_THROW(j32.add(0), etl::hash_finalised); } - - //************************************************************************* - TEST(test_jenkins_64_constructor) - { - std::string data("123456789"); - - uint64_t hash = etl::jenkins(data.begin(), data.end()); - uint64_t compare = jenkins64(data.begin(), data.end()); - - CHECK_EQUAL(compare, hash); - } - - //************************************************************************* - TEST(test_jenkins_64_add_values) - { - std::string data("123456789"); - - etl::jenkins jenkins_64_calculator; - - for (size_t i = 0; i < data.size(); ++i) - { - jenkins_64_calculator.add(data[i]); - } - - uint64_t hash = jenkins_64_calculator; - uint64_t compare = jenkins64(data.begin(), data.end()); - - CHECK_EQUAL(compare, hash); - } - - //************************************************************************* - TEST(test_jenkins_64_add_range) - { - std::string data("123456789"); - - etl::jenkins jenkins_64_calculator; - - jenkins_64_calculator.add(data.begin(), data.end()); - - uint64_t hash = jenkins_64_calculator.value(); - - uint64_t compare = jenkins64(data.begin(), data.end()); - - CHECK_EQUAL(compare, hash); - } - - //************************************************************************* - TEST(test_jenkins_64_add_range_endian) - { - std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; - std::vector data2 = { 0x04030201, 0x08070605 }; - std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - - uint64_t hash1 = etl::jenkins(data1.begin(), data1.end()); - uint64_t hash2 = etl::jenkins((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); - uint64_t hash3 = etl::jenkins(data3.rbegin(), data3.rend()); - CHECK_EQUAL(hash1, hash2); - CHECK_EQUAL(hash1, hash3); - - uint64_t compare1 = jenkins64(data1.begin(), data1.end()); - CHECK_EQUAL(compare1, hash1); - - uint64_t compare2 = jenkins64((uint8_t*)&data2[0], (uint8_t*)&data2[0] + (data2.size() * sizeof(uint32_t))); - CHECK_EQUAL(compare2, hash2); - - uint64_t compare3 = jenkins64(data3.rbegin(), data3.rend()); - CHECK_EQUAL(compare2, hash3); - } }; } diff --git a/test/test_list.cpp b/test/test_list.cpp index 217e5ddc..cc80886a 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -235,6 +235,8 @@ namespace CompareData compare_data(INITIAL_SIZE, VALUE); compare_data.resize(NEW_SIZE, VALUE); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -270,7 +272,7 @@ namespace DataNDC data(sorted_data.begin(), sorted_data.end()); data.clear(); - CHECK_EQUAL(data.size(), 0); + CHECK_EQUAL(0U, data.size()); } //************************************************************************* @@ -385,8 +387,9 @@ namespace compare_data.insert(compare_data.begin(), test2.begin(), test2.end()); data.insert(data.begin(), test2.begin(), test2.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); compare_data.assign(test1.begin(), test1.end()); @@ -395,8 +398,9 @@ namespace compare_data.insert(compare_data.end(), test2.begin(), test2.end()); data.insert(data.end(), test2.begin(), test2.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); compare_data.assign(test1.begin(), test1.end()); @@ -411,8 +415,9 @@ namespace compare_data.insert(icd, test2.begin(), test2.end()); data.insert(id, test2.begin(), test2.end()); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -436,8 +441,9 @@ namespace CHECK_NO_THROW(data.push_front(ItemNDC("5"))); CHECK_NO_THROW(data.push_front(ItemNDC("6"))); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -536,8 +542,9 @@ namespace CHECK_NO_THROW(data.push_back(ItemNDC("5"))); CHECK_NO_THROW(data.push_back(ItemNDC("6"))); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -572,8 +579,9 @@ namespace data.pop_back(); data.pop_back(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -608,6 +616,8 @@ namespace i_compare_data = compare_data.erase(i_compare_data); i_data = data.erase(i_data); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -616,6 +626,8 @@ namespace i_compare_data = compare_data.erase(compare_data.begin()); i_data = data.erase(data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -632,6 +644,8 @@ namespace std::advance(i_data, data.size() - 1); i_data = data.erase(i_data); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -661,8 +675,9 @@ namespace data.erase(i_data_1, i_data_2); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -678,7 +693,7 @@ namespace // Check that it is still in a valid state. data.push_back(ItemNDC("1")); CHECK(!data.empty()); - CHECK_EQUAL(1, data.size()); + CHECK_EQUAL(1U, data.size()); } //************************************************************************* @@ -764,7 +779,6 @@ namespace CHECK_EQUAL(data.size(), other_data.size()); are_equal = std::equal(data.begin(), data.end(), other_data.begin()); - CHECK(are_equal); } @@ -777,8 +791,9 @@ namespace compare_data.unique(); data.unique(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -791,8 +806,9 @@ namespace compare_data.unique(); data.unique(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -805,8 +821,9 @@ namespace compare_data.remove(ItemNDC("7")); data.remove(ItemNDC("7")); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -819,8 +836,9 @@ namespace compare_data.remove_if(std::bind2nd(std::equal_to(), ItemNDC("7"))); data.remove_if(std::bind2nd(std::equal_to(), ItemNDC("7"))); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -833,6 +851,9 @@ namespace compare_data.reverse(); data.reverse(); + CHECK_EQUAL(compare_data.size(), data.size()); + CHECK_EQUAL(data.size(), std::distance(data.begin(), data.end())); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -847,8 +868,9 @@ namespace compare_data.sort(); data.sort(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -861,8 +883,9 @@ namespace compare_data.sort(); data.sort(); - are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -889,6 +912,8 @@ namespace to = data.begin(); data.splice(to, data, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -903,6 +928,8 @@ namespace to = data.end(); data.splice(to, data, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -919,6 +946,8 @@ namespace std::advance(to, 6); data.splice(to, data, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -935,6 +964,8 @@ namespace std::advance(to, 4); data.splice(to, data, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); } @@ -965,9 +996,13 @@ namespace to = data.begin(); data.splice(to, data2, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -988,9 +1023,13 @@ namespace to = data.end(); data.splice(to, data2, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1013,9 +1052,13 @@ namespace std::advance(to, 6); data.splice(to, data2, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1038,9 +1081,13 @@ namespace std::advance(to, 4); data.splice(to, data2, from); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); } @@ -1074,6 +1121,8 @@ namespace to = data.begin(); data.splice(to, data, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -1092,6 +1141,8 @@ namespace to = data.end(); data.splice(to, data, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -1112,6 +1163,8 @@ namespace std::advance(to, 7); data.splice(to, data, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); @@ -1125,6 +1178,9 @@ namespace DataNDC data2(data); data.splice(to, data, begin, end); + + CHECK_EQUAL(data.size(), data2.size()); + are_equal = std::equal(data.begin(), data.end(), data2.begin()); CHECK(are_equal); @@ -1170,9 +1226,13 @@ namespace to = data.begin(); data.splice(to, data2, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1197,9 +1257,13 @@ namespace to = data.end(); data.splice(to, data2, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1226,9 +1290,13 @@ namespace std::advance(to, 7); data.splice(to, data2, begin, end); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); } @@ -1252,9 +1320,13 @@ namespace to = data.begin(); data.splice(to, data2); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1271,9 +1343,13 @@ namespace to = data.end(); data.splice(to, data2); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); @@ -1292,9 +1368,13 @@ namespace std::advance(to, 7); data.splice(to, data2); + CHECK_EQUAL(compare_data.size(), data.size()); + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(are_equal); + CHECK_EQUAL(compare_data2.size(), data2.size()); + are_equal = std::equal(data2.begin(), data2.end(), compare_data2.begin()); CHECK(are_equal); } @@ -1316,8 +1396,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(data0.size(), compare0.size()); - CHECK_EQUAL(data1.size(), compare1.size()); + CHECK_EQUAL(compare0.size(), data0.size()); + CHECK_EQUAL(compare1.size(), data1.size()); } //************************************************************************* @@ -1337,8 +1417,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(data0.size(), compare0.size()); - CHECK_EQUAL(data2.size(), compare2.size()); + CHECK_EQUAL(compare0.size(), data0.size()); + CHECK_EQUAL(compare2.size(), data2.size()); } //************************************************************************* @@ -1358,8 +1438,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(data0.size(), compare0.size()); - CHECK_EQUAL(data3.size(), compare3.size()); + CHECK_EQUAL(compare0.size(), data0.size()); + CHECK_EQUAL(compare3.size(), data3.size()); } //************************************************************************* @@ -1379,8 +1459,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(data0.size(), compare0.size()); - CHECK_EQUAL(data4.size(), compare4.size()); + CHECK_EQUAL(compare0.size(), data0.size()); + CHECK_EQUAL(compare4.size(), data4.size()); } //************************************************************************* @@ -1394,6 +1474,8 @@ namespace data0.reverse(); data1.reverse(); + + CompareData compare0(merge_data0.begin(), merge_data0.end()); CompareData compare1(merge_data1.begin(), merge_data1.end()); @@ -1406,8 +1488,8 @@ namespace are_equal = std::equal(data0.begin(), data0.end(), compare0.begin()); CHECK(are_equal); - CHECK_EQUAL(data0.size(), compare0.size()); - CHECK_EQUAL(data1.size(), compare1.size()); + CHECK_EQUAL(compare0.size(), data0.size()); + CHECK_EQUAL(compare1.size(), data1.size()); } //************************************************************************* diff --git a/test/test_map.cpp b/test/test_map.cpp index b88ce7f8..534c7416 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -190,6 +190,8 @@ namespace Data data(compare_data.begin(), compare_data.end()); + size_t d = std::distance(data.begin(), data.end()); + CHECK(data.size() == SIZE); CHECK(!data.empty()); } diff --git a/test/test_maths.cpp b/test/test_maths.cpp index 2a4ac523..47f98fc3 100644 --- a/test/test_maths.cpp +++ b/test/test_maths.cpp @@ -281,71 +281,71 @@ namespace //************************************************************************* TEST(test_fibbonacci) { - CHECK_EQUAL(0, (size_t)etl::fibonacci<0>::value); - CHECK_EQUAL(1, (size_t)etl::fibonacci<1>::value); - CHECK_EQUAL(1, (size_t)etl::fibonacci<2>::value); - CHECK_EQUAL(2, (size_t)etl::fibonacci<3>::value); - CHECK_EQUAL(3, (size_t)etl::fibonacci<4>::value); - CHECK_EQUAL(5, (size_t)etl::fibonacci<5>::value); - CHECK_EQUAL(8, (size_t)etl::fibonacci<6>::value); - CHECK_EQUAL(13, (size_t)etl::fibonacci<7>::value); - CHECK_EQUAL(21, (size_t)etl::fibonacci<8>::value); - CHECK_EQUAL(34, (size_t)etl::fibonacci<9>::value); - CHECK_EQUAL(55, (size_t)etl::fibonacci<10>::value); - CHECK_EQUAL(89, (size_t)etl::fibonacci<11>::value); - CHECK_EQUAL(144, (size_t)etl::fibonacci<12>::value); - CHECK_EQUAL(233, (size_t)etl::fibonacci<13>::value); - CHECK_EQUAL(377, (size_t)etl::fibonacci<14>::value); - CHECK_EQUAL(610, (size_t)etl::fibonacci<15>::value); - CHECK_EQUAL(987, (size_t)etl::fibonacci<16>::value); - CHECK_EQUAL(1597, (size_t)etl::fibonacci<17>::value); - CHECK_EQUAL(2584, (size_t)etl::fibonacci<18>::value); - CHECK_EQUAL(4181, (size_t)etl::fibonacci<19>::value); - CHECK_EQUAL(6765, (size_t)etl::fibonacci<20>::value); - CHECK_EQUAL(10946, (size_t)etl::fibonacci<21>::value); - CHECK_EQUAL(17711, (size_t)etl::fibonacci<22>::value); - CHECK_EQUAL(28657, (size_t)etl::fibonacci<23>::value); - CHECK_EQUAL(46368, (size_t)etl::fibonacci<24>::value); - CHECK_EQUAL(75025, (size_t)etl::fibonacci<25>::value); - CHECK_EQUAL(121393, (size_t)etl::fibonacci<26>::value); - CHECK_EQUAL(196418, (size_t)etl::fibonacci<27>::value); - CHECK_EQUAL(317811, (size_t)etl::fibonacci<28>::value); - CHECK_EQUAL(514229, (size_t)etl::fibonacci<29>::value); - CHECK_EQUAL(832040, (size_t)etl::fibonacci<30>::value); - CHECK_EQUAL(1346269, (size_t)etl::fibonacci<31>::value); - CHECK_EQUAL(2178309, (size_t)etl::fibonacci<32>::value); - CHECK_EQUAL(3524578, (size_t)etl::fibonacci<33>::value); - CHECK_EQUAL(5702887, (size_t)etl::fibonacci<34>::value); - CHECK_EQUAL(9227465, (size_t)etl::fibonacci<35>::value); - CHECK_EQUAL(14930352, (size_t)etl::fibonacci<36>::value); - CHECK_EQUAL(24157817, (size_t)etl::fibonacci<37>::value); - CHECK_EQUAL(39088169, (size_t)etl::fibonacci<38>::value); - CHECK_EQUAL(63245986, (size_t)etl::fibonacci<39>::value); - CHECK_EQUAL(102334155, (size_t)etl::fibonacci<40>::value); - CHECK_EQUAL(165580141, (size_t)etl::fibonacci<41>::value); - CHECK_EQUAL(267914296, (size_t)etl::fibonacci<42>::value); - CHECK_EQUAL(433494437, (size_t)etl::fibonacci<43>::value); - CHECK_EQUAL(701408733, (size_t)etl::fibonacci<44>::value); - CHECK_EQUAL(1134903170, (size_t)etl::fibonacci<45>::value); - CHECK_EQUAL(1836311903, (size_t)etl::fibonacci<46>::value); + CHECK_EQUAL(0U, (size_t)etl::fibonacci<0>::value); + CHECK_EQUAL(1U, (size_t)etl::fibonacci<1>::value); + CHECK_EQUAL(1U, (size_t)etl::fibonacci<2>::value); + CHECK_EQUAL(2U, (size_t)etl::fibonacci<3>::value); + CHECK_EQUAL(3U, (size_t)etl::fibonacci<4>::value); + CHECK_EQUAL(5U, (size_t)etl::fibonacci<5>::value); + CHECK_EQUAL(8U, (size_t)etl::fibonacci<6>::value); + CHECK_EQUAL(13U, (size_t)etl::fibonacci<7>::value); + CHECK_EQUAL(21U, (size_t)etl::fibonacci<8>::value); + CHECK_EQUAL(34U, (size_t)etl::fibonacci<9>::value); + CHECK_EQUAL(55U, (size_t)etl::fibonacci<10>::value); + CHECK_EQUAL(89U, (size_t)etl::fibonacci<11>::value); + CHECK_EQUAL(144U, (size_t)etl::fibonacci<12>::value); + CHECK_EQUAL(233U, (size_t)etl::fibonacci<13>::value); + CHECK_EQUAL(377U, (size_t)etl::fibonacci<14>::value); + CHECK_EQUAL(610U, (size_t)etl::fibonacci<15>::value); + CHECK_EQUAL(987U, (size_t)etl::fibonacci<16>::value); + CHECK_EQUAL(1597U, (size_t)etl::fibonacci<17>::value); + CHECK_EQUAL(2584U, (size_t)etl::fibonacci<18>::value); + CHECK_EQUAL(4181U, (size_t)etl::fibonacci<19>::value); + CHECK_EQUAL(6765U, (size_t)etl::fibonacci<20>::value); + CHECK_EQUAL(10946U, (size_t)etl::fibonacci<21>::value); + CHECK_EQUAL(17711U, (size_t)etl::fibonacci<22>::value); + CHECK_EQUAL(28657U, (size_t)etl::fibonacci<23>::value); + CHECK_EQUAL(46368U, (size_t)etl::fibonacci<24>::value); + CHECK_EQUAL(75025U, (size_t)etl::fibonacci<25>::value); + CHECK_EQUAL(121393U, (size_t)etl::fibonacci<26>::value); + CHECK_EQUAL(196418U, (size_t)etl::fibonacci<27>::value); + CHECK_EQUAL(317811U, (size_t)etl::fibonacci<28>::value); + CHECK_EQUAL(514229U, (size_t)etl::fibonacci<29>::value); + CHECK_EQUAL(832040U, (size_t)etl::fibonacci<30>::value); + CHECK_EQUAL(1346269U, (size_t)etl::fibonacci<31>::value); + CHECK_EQUAL(2178309U, (size_t)etl::fibonacci<32>::value); + CHECK_EQUAL(3524578U, (size_t)etl::fibonacci<33>::value); + CHECK_EQUAL(5702887U, (size_t)etl::fibonacci<34>::value); + CHECK_EQUAL(9227465U, (size_t)etl::fibonacci<35>::value); + CHECK_EQUAL(14930352U, (size_t)etl::fibonacci<36>::value); + CHECK_EQUAL(24157817U, (size_t)etl::fibonacci<37>::value); + CHECK_EQUAL(39088169U, (size_t)etl::fibonacci<38>::value); + CHECK_EQUAL(63245986U, (size_t)etl::fibonacci<39>::value); + CHECK_EQUAL(102334155U, (size_t)etl::fibonacci<40>::value); + CHECK_EQUAL(165580141U, (size_t)etl::fibonacci<41>::value); + CHECK_EQUAL(267914296U, (size_t)etl::fibonacci<42>::value); + CHECK_EQUAL(433494437U, (size_t)etl::fibonacci<43>::value); + CHECK_EQUAL(701408733U, (size_t)etl::fibonacci<44>::value); + CHECK_EQUAL(1134903170U, (size_t)etl::fibonacci<45>::value); + CHECK_EQUAL(1836311903U, (size_t)etl::fibonacci<46>::value); CHECK_EQUAL(2971215073U, (size_t)etl::fibonacci<47>::value); } TEST(test_factorial) { - CHECK_EQUAL(1, (size_t)etl::factorial<0>::value); - CHECK_EQUAL(1, (size_t)etl::factorial<1>::value); - CHECK_EQUAL(2, (size_t)etl::factorial<2>::value); - CHECK_EQUAL(6, (size_t)etl::factorial<3>::value); - CHECK_EQUAL(24, (size_t)etl::factorial<4>::value); - CHECK_EQUAL(120, (size_t)etl::factorial<5>::value); - CHECK_EQUAL(720, (size_t)etl::factorial<6>::value); - CHECK_EQUAL(5040, (size_t)etl::factorial<7>::value); - CHECK_EQUAL(40320, (size_t)etl::factorial<8>::value); - CHECK_EQUAL(362880, (size_t)etl::factorial<9>::value); - CHECK_EQUAL(3628800, (size_t)etl::factorial<10>::value); - CHECK_EQUAL(39916800, (size_t)etl::factorial<11>::value); - CHECK_EQUAL(479001600, (size_t)etl::factorial<12>::value); + CHECK_EQUAL(1U, (size_t)etl::factorial<0>::value); + CHECK_EQUAL(1U, (size_t)etl::factorial<1>::value); + CHECK_EQUAL(2U, (size_t)etl::factorial<2>::value); + CHECK_EQUAL(6U, (size_t)etl::factorial<3>::value); + CHECK_EQUAL(24U, (size_t)etl::factorial<4>::value); + CHECK_EQUAL(120U, (size_t)etl::factorial<5>::value); + CHECK_EQUAL(720U, (size_t)etl::factorial<6>::value); + CHECK_EQUAL(5040U, (size_t)etl::factorial<7>::value); + CHECK_EQUAL(40320U, (size_t)etl::factorial<8>::value); + CHECK_EQUAL(362880U, (size_t)etl::factorial<9>::value); + CHECK_EQUAL(3628800U, (size_t)etl::factorial<10>::value); + CHECK_EQUAL(39916800U, (size_t)etl::factorial<11>::value); + CHECK_EQUAL(479001600U, (size_t)etl::factorial<12>::value); } }; } diff --git a/test/test_memory.cpp b/test/test_memory.cpp new file mode 100644 index 00000000..6cc2ee0d --- /dev/null +++ b/test/test_memory.cpp @@ -0,0 +1,449 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 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. +******************************************************************************/ + +#include + +#include "../src/memory.h" +#include "../src/debug_count.h" + +#include +#include +#include +#include +#include + +#include + +namespace +{ + typedef std::string non_trivial_t; + typedef uint32_t trivial_t; + + const size_t SIZE = 10; + + std::array test_data_non_trivial = + { + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten" + }; + + std::array test_data_trivial = + { + 0x11223344, 0x22334455, 0x33445566, 0x44556677, 0x55667788, + 0x66778899, 0x778899AA, 0x8899AABB, 0x99AABBCC, 0xAABBCCDD + }; + + non_trivial_t test_item_non_trivial("eleven"); + non_trivial_t test_item_non_trivial_null(""); + trivial_t test_item_trivial(0xBBCCDDEE); + + char buffer_non_trivial[sizeof(non_trivial_t) * SIZE]; + char buffer_trivial[sizeof(trivial_t) * SIZE]; + + non_trivial_t* output_non_trivial = reinterpret_cast(buffer_non_trivial); + trivial_t* output_trivial = reinterpret_cast(buffer_trivial); + + struct overloaded + { + overloaded* operator&() + { + return nullptr; + } + }; +} + +namespace +{ + SUITE(test_memory) + { + //************************************************************************* + TEST(test_addressof) + { + int i; + CHECK(&i == etl::addressof(i)); + + overloaded ol; + CHECK(&ol != etl::addressof(ol)); + CHECK(reinterpret_cast(&reinterpret_cast(ol)) == etl::addressof(ol)); + } + + //************************************************************************* + TEST(test_create_destroy_trivial) + { + char n[sizeof(trivial_t)]; + trivial_t* pn = reinterpret_cast(n); + + // Non count. + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_default_at(pn); + CHECK_EQUAL(0xFFFFFFFF, *pn); + etl::destroy_at(pn); + CHECK_EQUAL(0xFFFFFFFF, *pn); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_value_at(pn); + CHECK_EQUAL(0x0000000, *pn); + etl::destroy_at(pn); + CHECK_EQUAL(0x0000000, *pn); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_copy_at(pn, test_item_trivial); + CHECK_EQUAL(test_item_trivial, *pn); + etl::destroy_at(pn); + CHECK_EQUAL(test_item_trivial, *pn); + + // Count. + size_t count = 0; + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_default_at(pn, count); + CHECK_EQUAL(0xFFFFFFFF, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(0xFFFFFFFF, *pn); + CHECK_EQUAL(0, count); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_value_at(pn, count); + CHECK_EQUAL(0x0000000, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(0x0000000, *pn); + CHECK_EQUAL(0, count); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_copy_at(pn, test_item_trivial, count); + CHECK_EQUAL(test_item_trivial, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(test_item_trivial, *pn); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_create_destroy_non_trivial) + { + char n[sizeof(non_trivial_t)]; + non_trivial_t* pn = reinterpret_cast(n); + + // Non count. + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_default_at(pn); + CHECK_EQUAL(test_item_non_trivial_null, *pn); + etl::destroy_at(pn); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_value_at(pn); + CHECK_EQUAL(test_item_non_trivial_null, *pn); + etl::destroy_at(pn); + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_copy_at(pn, test_item_non_trivial); + CHECK_EQUAL(test_item_non_trivial, *pn); + etl::destroy_at(pn); + + // Count. + size_t count = 0; + + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_default_at(pn, count); + CHECK_EQUAL(test_item_non_trivial_null, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(0, count); + + count = 0; + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_value_at(pn, count); + CHECK_EQUAL(test_item_non_trivial_null, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(0, count); + + count = 0; + std::fill(std::begin(n), std::end(n), 0xFF); + etl::create_copy_at(pn, test_item_non_trivial, count); + CHECK_EQUAL(test_item_non_trivial, *pn); + CHECK_EQUAL(1, count); + etl::destroy_at(pn, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_fill_n_trivial) + { + // Also tests uninitialized_fill. + + // Non count. + trivial_t* p = reinterpret_cast(buffer_trivial); + + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0); + etl::uninitialized_fill_n(p, SIZE, test_item_trivial); + + trivial_t* result; + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == test_item_trivial; }); + + CHECK(result == output_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0); + etl::uninitialized_fill_n(p, SIZE, test_item_trivial, count); + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == test_item_trivial; }); + + CHECK(result == output_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_fill_n_non_trivial) + { + // Also tests uninitialized_fill. + + // Non count. + non_trivial_t* p = reinterpret_cast(buffer_non_trivial); + + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0); + etl::uninitialized_fill_n(p, SIZE, test_item_non_trivial); + + non_trivial_t* result; + + result = std::find_if_not(output_non_trivial, output_non_trivial + SIZE, [](const non_trivial_t& i) { return i == test_item_non_trivial; }); + + CHECK(result == output_non_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0); + etl::uninitialized_fill_n(p, SIZE, test_item_non_trivial, count); + + result = std::find_if_not(output_non_trivial, + output_non_trivial + SIZE, + [](non_trivial_t i) { return i == test_item_non_trivial; }); + + CHECK(result == output_non_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_copy_n_trivial) + { + // Also tests uninitialized_copy. + + bool is_equal; + + // Non count. + trivial_t* p = reinterpret_cast(buffer_trivial); + + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0); + etl::uninitialized_copy_n(test_data_trivial.begin(), SIZE, p); + + is_equal = std::equal(output_trivial, output_trivial + SIZE, test_data_trivial.begin()); + CHECK(is_equal); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0); + etl::uninitialized_copy_n(test_data_trivial.begin(), SIZE, p, count); + + is_equal = std::equal(output_trivial, output_trivial + SIZE, test_data_trivial.begin()); + CHECK(is_equal); + CHECK_EQUAL(SIZE, count); + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_copy_n_non_trivial) + { + // Also tests uninitialized_copy. + + bool is_equal; + + // Non count. + non_trivial_t* p = reinterpret_cast(buffer_non_trivial); + + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0); + etl::uninitialized_copy_n(test_data_non_trivial.begin(), SIZE, p); + + is_equal = std::equal(output_non_trivial, output_non_trivial + SIZE, test_data_non_trivial.begin()); + CHECK(is_equal); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0); + etl::uninitialized_copy_n(test_data_non_trivial.begin(), SIZE, p, count); + + is_equal = std::equal(output_non_trivial, output_non_trivial + SIZE, test_data_non_trivial.begin()); + CHECK(is_equal); + CHECK_EQUAL(SIZE, count); + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_default_construct_n_trivial) + { + // Also tests uninitialized_default_construct. + + // Non count. + trivial_t* p = reinterpret_cast(buffer_trivial); + + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0xFF); + etl::uninitialized_default_construct_n(p, SIZE); + + trivial_t* result; + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == 0xFFFFFFFF; }); + + CHECK(result == output_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0xFF); + etl::uninitialized_default_construct_n(p, SIZE, count); + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == 0xFFFFFFFF; }); + + CHECK(result == output_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_default_construct_n_non_trivial) + { + // Also tests uninitialized_default_construct. + + // Non count. + non_trivial_t* p = reinterpret_cast(buffer_non_trivial); + + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0xFF); + etl::uninitialized_default_construct_n(p, SIZE); + + non_trivial_t* result; + + result = std::find_if_not(output_non_trivial, output_non_trivial + SIZE, [](non_trivial_t i) { return i == test_item_non_trivial_null; }); + + CHECK(result == output_non_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0xFF); + etl::uninitialized_default_construct_n(p, SIZE, count); + + result = std::find_if_not(output_non_trivial, output_non_trivial + SIZE, [](non_trivial_t i) { return i == test_item_non_trivial_null; }); + + CHECK(result == output_non_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_value_construct_n_trivial) + { + // Also tests uninitialized_default_construct. + + // Non count. + trivial_t* p = reinterpret_cast(buffer_trivial); + + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0xFF); + etl::uninitialized_value_construct_n(p, SIZE); + + trivial_t* result; + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == trivial_t(); }); + + CHECK(result == output_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_trivial), std::end(buffer_trivial), 0xFF); + etl::uninitialized_value_construct_n(p, SIZE, count); + + result = std::find_if_not(output_trivial, output_trivial + SIZE, [](trivial_t i) { return i == trivial_t(); }); + + CHECK(result == output_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_uninitialized_value_construct_n_non_trivial) + { + // Also tests uninitialized_default_construct. + + // Non count. + non_trivial_t* p = reinterpret_cast(buffer_non_trivial); + + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0xFF); + etl::uninitialized_value_construct_n(p, SIZE); + + non_trivial_t* result; + + result = std::find_if_not(output_non_trivial, output_non_trivial + SIZE, [](non_trivial_t i) { return i == non_trivial_t(); }); + + CHECK(result == output_non_trivial + SIZE); + etl::destroy(p, p + SIZE); + + // Count. + size_t count = 0; + std::fill(std::begin(buffer_non_trivial), std::end(buffer_non_trivial), 0xFF); + etl::uninitialized_value_construct_n(p, SIZE, count); + + result = std::find_if_not(output_non_trivial, output_non_trivial + SIZE, [](non_trivial_t i) { return i == non_trivial_t(); }); + + CHECK(result == output_non_trivial + SIZE); + CHECK_EQUAL(SIZE, count); + + etl::destroy(p, p + SIZE, count); + CHECK_EQUAL(0, count); + } + }; +} diff --git a/test/test_observer.cpp b/test/test_observer.cpp index a59e2a56..1c6853ad 100644 --- a/test/test_observer.cpp +++ b/test/test_observer.cpp @@ -125,7 +125,7 @@ public: //******************************************* // Notification1 is passed by value. //******************************************* - void notification(Notification1 data1) + void notification(Notification1 /*data1*/) { ++data1_count; } @@ -133,7 +133,7 @@ public: //******************************************* // Notification2 is passed by reference. //******************************************* - void notification(Notification2& data2) + void notification(Notification2& /*data2*/) { ++data2_count; } @@ -141,7 +141,7 @@ public: //******************************************* // Notification3 is passed by const reference. //******************************************* - void notification(const Notification3& data3) + void notification(const Notification3& /*data3*/) { ++data3_count; } @@ -170,7 +170,7 @@ public: //******************************************* // Notification1 is passed by value. //******************************************* - void notification(Notification1 data1) + void notification(Notification1 /*data1*/) { ++data1_count; } @@ -178,7 +178,7 @@ public: //******************************************* // Notification2 is passed by reference. //******************************************* - void notification(Notification2& data2) + void notification(Notification2& /*data2*/) { ++data2_count; } @@ -186,7 +186,7 @@ public: //******************************************* // Notification3 is passed by const reference. //******************************************* - void notification(const Notification3& data3) + void notification(const Notification3& /*data3*/) { ++data3_count; } diff --git a/test/test_optional.cpp b/test/test_optional.cpp index 222698c5..47b821e2 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -184,7 +184,7 @@ namespace CHECK(bool(container)); container.value().resize(5, Data("1")); - CHECK_EQUAL(5, container.value().size()); + CHECK_EQUAL(5U, container.value().size()); CHECK_EQUAL(Data("1"), container.value()[0]); CHECK_EQUAL(Data("1"), container.value()[1]); diff --git a/test/test_pool.cpp b/test/test_pool.cpp index afbbbff2..fbe53642 100644 --- a/test/test_pool.cpp +++ b/test/test_pool.cpp @@ -36,6 +36,11 @@ SOFTWARE. #include "../src/pool.h" +#if defined(ETL_COMPILER_GCC) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif + typedef TestDataDC Test_Data; typedef TestDataNDC Test_Data2; @@ -48,15 +53,15 @@ namespace { etl::pool pool; - Test_Data* p1; - Test_Data* p2; - Test_Data* p3; - Test_Data* p4; + Test_Data* p1 = nullptr; + Test_Data* p2 = nullptr; + Test_Data* p3 = nullptr; + Test_Data* p4 = nullptr; - CHECK_NO_THROW(p1 = pool.allocate()); - CHECK_NO_THROW(p2 = pool.allocate()); - CHECK_NO_THROW(p3 = pool.allocate()); - CHECK_NO_THROW(p4 = pool.allocate()); + CHECK_NO_THROW(p1 = pool.allocate()); + CHECK_NO_THROW(p2 = pool.allocate()); + CHECK_NO_THROW(p3 = pool.allocate()); + CHECK_NO_THROW(p4 = pool.allocate()); CHECK(p1 != p2); CHECK(p1 != p3); @@ -65,7 +70,7 @@ namespace CHECK(p2 != p4); CHECK(p3 != p4); - CHECK_THROW(pool.allocate(), etl::pool_no_allocation); + CHECK_THROW(pool.allocate(), etl::pool_no_allocation); } //************************************************************************* @@ -73,21 +78,21 @@ namespace { etl::pool pool; - Test_Data* p1 = pool.allocate(); - Test_Data* p2 = pool.allocate(); - Test_Data* p3 = pool.allocate(); - Test_Data* p4 = pool.allocate(); + Test_Data* p1 = pool.allocate(); + Test_Data* p2 = pool.allocate(); + Test_Data* p3 = pool.allocate(); + Test_Data* p4 = pool.allocate(); CHECK_NO_THROW(pool.release(p2)); - CHECK_NO_THROW(pool.release(*p3)); + CHECK_NO_THROW(pool.release(p3)); CHECK_NO_THROW(pool.release(p1)); - CHECK_NO_THROW(pool.release(*p4)); + CHECK_NO_THROW(pool.release(p4)); CHECK_EQUAL(4U, pool.available()); Test_Data not_in_pool; - CHECK_THROW(pool.release(not_in_pool), etl::pool_object_not_in_pool); + CHECK_THROW(pool.release(¬_in_pool), etl::pool_object_not_in_pool); } //************************************************************************* @@ -95,10 +100,10 @@ namespace { etl::pool pool; - Test_Data* p1 = pool.allocate(); - Test_Data* p2 = pool.allocate(); - Test_Data* p3 = pool.allocate(); - Test_Data* p4 = pool.allocate(); + Test_Data* p1 = pool.allocate(); + Test_Data* p2 = pool.allocate(); + Test_Data* p3 = pool.allocate(); + Test_Data* p4 = pool.allocate(); // Allocated p1, p2, p3, p4 @@ -111,8 +116,8 @@ namespace CHECK_EQUAL(2U, pool.available()); - Test_Data* p5 = pool.allocate(); - Test_Data* p6 = pool.allocate(); + Test_Data* p5 = pool.allocate(); + Test_Data* p6 = pool.allocate(); // Allocated p1, p4, p5, p6 @@ -130,7 +135,7 @@ namespace CHECK_EQUAL(1U, pool.available()); - Test_Data* p7 = pool.allocate(); + Test_Data* p7 = pool.allocate(); // Allocated p1, p4, p6, p7 @@ -145,20 +150,20 @@ namespace TEST(test_available) { etl::pool pool; - CHECK_EQUAL(4, pool.available()); + CHECK_EQUAL(4U, pool.available()); Test_Data* p; - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(3U, pool.available()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(2U, pool.available()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(1U, pool.available()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(0U, pool.available()); } @@ -167,7 +172,7 @@ namespace { etl::pool pool; - CHECK(pool.max_size() == 4U); + CHECK(pool.max_items() == 4U); } //************************************************************************* @@ -178,16 +183,16 @@ namespace Test_Data* p; - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(1U, pool.size()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(2U, pool.size()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(3U, pool.size()); - p = pool.allocate(); + p = pool.allocate(); CHECK_EQUAL(4U, pool.size()); } @@ -200,19 +205,19 @@ namespace Test_Data* p; - p = pool.allocate(); + p = pool.allocate(); CHECK(!pool.empty()); CHECK(!pool.full()); - p = pool.allocate(); + p = pool.allocate(); CHECK(!pool.empty()); CHECK(!pool.full()); - p = pool.allocate(); + p = pool.allocate(); CHECK(!pool.empty()); CHECK(!pool.full()); - p = pool.allocate(); + p = pool.allocate(); CHECK(!pool.empty()); CHECK(pool.full()); } @@ -223,165 +228,169 @@ namespace etl::pool pool; Test_Data not_in_pool; - Test_Data* p1 = pool.allocate(); + Test_Data* p1 = pool.allocate(); CHECK(pool.is_in_pool(p1)); - CHECK(!pool.is_in_pool(not_in_pool)); + CHECK(!pool.is_in_pool(¬_in_pool)); } //************************************************************************* TEST(test_begin_empty) { - etl::pool pool; + //etl::pool pool; - etl::pool::iterator it = pool.begin(); - CHECK(it == pool.end()); + //etl::pool::iterator it = pool.begin(); + //CHECK(it == pool.end()); - etl::pool::const_iterator cit = pool.begin(); - CHECK(cit == pool.end()); + //etl::pool::const_iterator cit = pool.begin(); + //CHECK(cit == pool.end()); - cit = pool.cbegin(); - CHECK(cit == pool.end()); + //cit = pool.cbegin(); + //CHECK(cit == pool.end()); } //************************************************************************* TEST(test_iterator) { - etl::pool pool; + //etl::pool pool; - std::set compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") }; - std::set test; - std::vector objects; + //std::set compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") }; + //std::set test; + //std::vector objects; - // Build the set of objects. - objects.push_back(pool.allocate(Test_Data2("9"))); - objects.push_back(pool.allocate(Test_Data2("7"))); - objects.push_back(pool.allocate(Test_Data2("8"))); - objects.push_back(pool.allocate(Test_Data2("6"))); - objects.push_back(pool.allocate(Test_Data2("5"))); - objects.push_back(pool.allocate(Test_Data2("3"))); - objects.push_back(pool.allocate(Test_Data2("4"))); - objects.push_back(pool.allocate(Test_Data2("2"))); - objects.push_back(pool.allocate(Test_Data2("0"))); - objects.push_back(pool.allocate(Test_Data2("1"))); + //// Build the set of objects. + //objects.push_back(pool.allocate(Test_Data2("9"))); + //objects.push_back(pool.allocate(Test_Data2("7"))); + //objects.push_back(pool.allocate(Test_Data2("8"))); + //objects.push_back(pool.allocate(Test_Data2("6"))); + //objects.push_back(pool.allocate(Test_Data2("5"))); + //objects.push_back(pool.allocate(Test_Data2("3"))); + //objects.push_back(pool.allocate(Test_Data2("4"))); + //objects.push_back(pool.allocate(Test_Data2("2"))); + //objects.push_back(pool.allocate(Test_Data2("0"))); + //objects.push_back(pool.allocate(Test_Data2("1"))); - // Release "1", "3", "5", "7", "9". - pool.release(objects[0]); - pool.release(objects[1]); - pool.release(objects[4]); - pool.release(objects[5]); - pool.release(objects[9]); + //// Release "1", "3", "5", "7", "9". + //pool.release(objects[0]); + //pool.release(objects[1]); + //pool.release(objects[4]); + //pool.release(objects[5]); + //pool.release(objects[9]); - // Fill the test set with what we get from the iterator. - etl::pool::iterator i_pool = pool.begin(); + //// Fill the test set with what we get from the iterator. + //etl::pool::iterator i_pool = pool.begin(); - while (i_pool != pool.end()) - { - test.insert(*i_pool); - ++i_pool; - } + //while (i_pool != pool.end()) + //{ + // test.insert(*i_pool); + // ++i_pool; + //} - // Compare the results. - std::set::iterator i_compare = compare.begin(); - std::set::iterator i_test = test.begin(); + //// Compare the results. + //std::set::iterator i_compare = compare.begin(); + //std::set::iterator i_test = test.begin(); - CHECK_EQUAL(compare.size(), test.size()); + //CHECK_EQUAL(compare.size(), test.size()); - while ((i_compare != compare.end()) && (i_test != test.end())) - { - CHECK_EQUAL(*i_compare++, *i_test++); - } + //while ((i_compare != compare.end()) && (i_test != test.end())) + //{ + // CHECK_EQUAL(*i_compare++, *i_test++); + //} } //************************************************************************* TEST(test_const_iterator) { - etl::pool pool; + //etl::pool pool; - std::set compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") }; - std::set test; - std::vector objects; + //std::set compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") }; + //std::set test; + //std::vector objects; - // Build the set of objects. - objects.push_back(pool.allocate(Test_Data2("9"))); - objects.push_back(pool.allocate(Test_Data2("7"))); - objects.push_back(pool.allocate(Test_Data2("8"))); - objects.push_back(pool.allocate(Test_Data2("6"))); - objects.push_back(pool.allocate(Test_Data2("5"))); - objects.push_back(pool.allocate(Test_Data2("3"))); - objects.push_back(pool.allocate(Test_Data2("4"))); - objects.push_back(pool.allocate(Test_Data2("2"))); - objects.push_back(pool.allocate(Test_Data2("0"))); - objects.push_back(pool.allocate(Test_Data2("1"))); + //// Build the set of objects. + //objects.push_back(pool.allocate(Test_Data2("9"))); + //objects.push_back(pool.allocate(Test_Data2("7"))); + //objects.push_back(pool.allocate(Test_Data2("8"))); + //objects.push_back(pool.allocate(Test_Data2("6"))); + //objects.push_back(pool.allocate(Test_Data2("5"))); + //objects.push_back(pool.allocate(Test_Data2("3"))); + //objects.push_back(pool.allocate(Test_Data2("4"))); + //objects.push_back(pool.allocate(Test_Data2("2"))); + //objects.push_back(pool.allocate(Test_Data2("0"))); + //objects.push_back(pool.allocate(Test_Data2("1"))); - // Release "1", "3", "5", "7", "9". - pool.release(objects[0]); - pool.release(objects[1]); - pool.release(objects[4]); - pool.release(objects[5]); - pool.release(objects[9]); + //// Release "1", "3", "5", "7", "9". + //pool.release(objects[0]); + //pool.release(objects[1]); + //pool.release(objects[4]); + //pool.release(objects[5]); + //pool.release(objects[9]); - // Fill the test set with what we get from the iterator. - etl::pool::const_iterator i_pool = pool.begin(); + //// Fill the test set with what we get from the iterator. + //etl::pool::const_iterator i_pool = pool.begin(); - while (i_pool != pool.end()) - { - test.insert(*i_pool); - ++i_pool; - } + //while (i_pool != pool.end()) + //{ + // test.insert(*i_pool); + // ++i_pool; + //} - // Compare the results. - std::set::const_iterator i_compare = compare.begin(); - std::set::const_iterator i_test = test.begin(); + //// Compare the results. + //std::set::const_iterator i_compare = compare.begin(); + //std::set::const_iterator i_test = test.begin(); - CHECK_EQUAL(compare.size(), test.size()); + //CHECK_EQUAL(compare.size(), test.size()); - while ((i_compare != compare.end()) && (i_test != test.end())) - { - CHECK_EQUAL(*i_compare++, *i_test++); - } + //while ((i_compare != compare.end()) && (i_test != test.end())) + //{ + // CHECK_EQUAL(*i_compare++, *i_test++); + //} } //************************************************************************* TEST(test_get_iterator) { - typedef etl::pool Pool; + //typedef etl::pool Pool; - Pool pool; - Test_Data not_in_pool; + //Pool pool; + //Test_Data not_in_pool; - Test_Data* p1 = pool.allocate(); - Test_Data* p2 = pool.allocate(); + //Test_Data* p1 = pool.allocate(); + //Test_Data* p2 = pool.allocate(); - Pool::iterator i_data = pool.get_iterator(*p1); - Pool::iterator i_data2 = pool.get_iterator(*p2); - Pool::iterator i_ndata = pool.get_iterator(not_in_pool); + //Pool::iterator i_data = pool.get_iterator(*p1); + //Pool::iterator i_data2 = pool.get_iterator(*p2); + //Pool::iterator i_ndata = pool.get_iterator(not_in_pool); - CHECK(p1 == &*i_data); - CHECK(p2 != &*i_data); - CHECK(p2 == &*i_data2); - CHECK(pool.end() == i_ndata); + //CHECK(p1 == &*i_data); + //CHECK(p2 != &*i_data); + //CHECK(p2 == &*i_data2); + //CHECK(pool.end() == i_ndata); } //************************************************************************* TEST(test_get_iterator_const) { - typedef etl::pool Pool; + //typedef etl::pool Pool; - Pool pool; - const Test_Data not_in_pool; + //Pool pool; + //const Test_Data not_in_pool; - const Test_Data* p1 = pool.allocate(); - const Test_Data* p2 = pool.allocate(); + //const Test_Data* p1 = pool.allocate(); + //const Test_Data* p2 = pool.allocate(); - Pool::const_iterator i_data = pool.get_iterator(*p1); - Pool::const_iterator i_data2 = pool.get_iterator(*p2); - Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool); + //Pool::const_iterator i_data = pool.get_iterator(*p1); + //Pool::const_iterator i_data2 = pool.get_iterator(*p2); + //Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool); - CHECK(p1 == &*i_data); - CHECK(p2 != &*i_data); - CHECK(p2 == &*i_data2); - CHECK(pool.end() == i_ndata); + //CHECK(p1 == &*i_data); + //CHECK(p2 != &*i_data); + //CHECK(p2 == &*i_data2); + //CHECK(pool.end() == i_ndata); } }; } + +#if defined(ETL_COMPILER_GCC) + #pragma GCC diagnostic pop +#endif diff --git a/test/test_priority_queue.cpp b/test/test_priority_queue.cpp index f38dffa0..f6ca449f 100644 --- a/test/test_priority_queue.cpp +++ b/test/test_priority_queue.cpp @@ -97,7 +97,7 @@ namespace priority_queue.push(2); priority_queue.push(3); - CHECK_EQUAL(3, priority_queue.size()); + CHECK_EQUAL(3U, priority_queue.size()); } //************************************************************************* @@ -108,7 +108,7 @@ namespace priority_queue.push(1); priority_queue.push(2); priority_queue.clear(); - CHECK_EQUAL(0, priority_queue.size()); + CHECK_EQUAL(0U, priority_queue.size()); } //************************************************************************* @@ -294,10 +294,6 @@ namespace priority_queue.pop(); compare_priority_queue.pop(); CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); - - // Go one beyond (which we handle without throwing) - priority_queue.pop(); - CHECK_EQUAL(compare_priority_queue.size(), priority_queue.size()); } //************************************************************************* diff --git a/test/test_random.cpp b/test/test_random.cpp new file mode 100644 index 00000000..704477fa --- /dev/null +++ b/test/test_random.cpp @@ -0,0 +1,79 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2016 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. +******************************************************************************/ + +#include + +#include + +#include "../src/random.h" + +#include +#include +#include + +namespace +{ + SUITE(test_random) + { + //========================================================================= + TEST(test_sequence) + { + std::vector out1(32768); + etl::random_xorshift r; + + struct generator + { + generator(etl::random& r_) + : r(r_) + { + } + + uint32_t operator()() + { + return r(); + } + + etl::random& r; + }; + + std::generate(out1.begin(), out1.end(), generator(r)); + + std::ofstream file("random.csv"); + + if (!file.fail()) + { + for (size_t i = 0; i < out1.size(); i += 2) + { + file << (out1[i] >> 16) << "," << (out1[i + 1] >> 16) << "\n"; + } + } + + file.close(); + } + }; +} diff --git a/test/test_smallest.cpp b/test/test_smallest.cpp index 26beb42c..232119b3 100644 --- a/test/test_smallest.cpp +++ b/test/test_smallest.cpp @@ -79,44 +79,167 @@ namespace } //************************************************************************* - TEST(test_smallest_size_for_bits) + TEST(test_smallest_uint_for_bits) { bool type; - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; CHECK(type); - type = std::is_same::type>::value; + type = std::is_same::type>::value; + CHECK(type); + } + + //************************************************************************* + TEST(test_smallest_int_for_bits) + { + bool type; + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + } + + //************************************************************************* + TEST(test_smallest_uint_for_value) + { + bool type; + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + } + + //************************************************************************* + TEST(test_smallest_int_for_value) + { + bool type; + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; + CHECK(type); + + type = std::is_same::type>::value; CHECK(type); } }; diff --git a/test/test_string_char.cpp b/test/test_string_char.cpp index 265ace9b..712a9efc 100644 --- a/test/test_string_char.cpp +++ b/test/test_string_char.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "../src/string.h" +#include "../src/cstring.h" #undef min @@ -635,20 +635,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_pop_back_excess) - { - Text text; - - text.resize(2); - - text.pop_back(); - text.pop_back(); - - text.pop_back(); - CHECK(text.empty()); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_position_value) { @@ -983,8 +969,8 @@ namespace Text append(insert_text.c_str()); // Whole string. - compare_text.append(insert_text, 0); - text.append(append, 0); + compare_text.append(insert_text, 0, std::string::npos); + text.append(append, 0, Text::npos); bool is_equal = Equal(compare_text, text); CHECK(is_equal); @@ -2081,7 +2067,7 @@ namespace CHECK_EQUAL(position1, position2); position2 = haystack.find(needle, position2 + 1); - CHECK_EQUAL(etl::istring::npos, position2); + CHECK_EQUAL(etl::string<50>::npos, position2); etl::string<50> pin(STR("pin")); position2 = haystack.find(pin); diff --git a/test/test_string_u16.cpp b/test/test_string_u16.cpp index 89c56788..0fc03b28 100644 --- a/test/test_string_u16.cpp +++ b/test/test_string_u16.cpp @@ -635,20 +635,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_pop_back_excess) - { - Text text; - - text.resize(2); - - text.pop_back(); - text.pop_back(); - - text.pop_back(); - CHECK(text.empty()); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_position_value) { @@ -983,8 +969,8 @@ namespace Text append(insert_text.c_str()); // Whole string. - compare_text.append(insert_text, 0); - text.append(append, 0); + compare_text.append(insert_text, 0, std::u16string::npos); + text.append(append, 0, etl::iu16string::npos); bool is_equal = Equal(compare_text, text); CHECK(is_equal); diff --git a/test/test_string_u32.cpp b/test/test_string_u32.cpp index cd8e87e9..366ee2aa 100644 --- a/test/test_string_u32.cpp +++ b/test/test_string_u32.cpp @@ -635,20 +635,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_pop_back_excess) - { - Text text; - - text.resize(2); - - text.pop_back(); - text.pop_back(); - - text.pop_back(); - CHECK(text.empty()); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_position_value) { @@ -983,8 +969,8 @@ namespace Text append(insert_text.c_str()); // Whole string. - compare_text.append(insert_text, 0); - text.append(append, 0); + compare_text.append(insert_text, 0, std::u32string::npos); + text.append(append, 0, etl::iu32string::npos); bool is_equal = Equal(compare_text, text); CHECK(is_equal); diff --git a/test/test_string_wchar_t.cpp b/test/test_string_wchar_t.cpp index 2b968918..e60ab97b 100644 --- a/test/test_string_wchar_t.cpp +++ b/test/test_string_wchar_t.cpp @@ -635,20 +635,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_pop_back_excess) - { - Text text; - - text.resize(2); - - text.pop_back(); - text.pop_back(); - - text.pop_back(); - CHECK(text.empty()); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_position_value) { @@ -983,8 +969,8 @@ namespace Text append(insert_text.c_str()); // Whole string. - compare_text.append(insert_text, 0); - text.append(append, 0); + compare_text.append(insert_text, 0, std::wstring::npos); + text.append(append, 0, etl::iwstring::npos); bool is_equal = Equal(compare_text, text); CHECK(is_equal); diff --git a/test/test_type_def.cpp b/test/test_type_def.cpp index c921293a..86e0933b 100644 --- a/test/test_type_def.cpp +++ b/test/test_type_def.cpp @@ -45,8 +45,8 @@ namespace type1_t t1 = type1_t(1); type2_t t2 = type2_t(1); - uint32_t i1 = t1; - uint32_t i2 = t2; + uint32_t i1 = t1.get(); + uint32_t i2 = t2.get(); CHECK_EQUAL(i1, i2); } @@ -63,8 +63,8 @@ namespace type1_t t1 = type1_t(1); type2_t t2 = type2_t(1); - uint32_t i1 = t1; - uint32_t i2 = t2; + uint32_t i1 = t1.get(); + uint32_t i2 = t2.get(); CHECK_EQUAL(i1, i2); } @@ -93,30 +93,30 @@ namespace uint32_t i = 0x5A3D; type_t t(0x5A3D); - CHECK_EQUAL(++i, ++t); - CHECK_EQUAL(i++, t++); - CHECK_EQUAL(--i, --t); - CHECK_EQUAL(i--, t--); - CHECK_EQUAL(i += 2, t += 2); - CHECK_EQUAL(i += 2, t += type_t(2)); - CHECK_EQUAL(i -= 2, t -= 2); - CHECK_EQUAL(i -= 2, t -= type_t(2)); - CHECK_EQUAL(i *= 2, t *= 2); - CHECK_EQUAL(i *= 2, t *= type_t(2)); - CHECK_EQUAL(i /= 2, t /= 2); - CHECK_EQUAL(i /= 2, t /= type_t(2)); - CHECK_EQUAL(i &= 0xFF00, t &= 0xFF00); - CHECK_EQUAL(i &= 0xFF00, t &= type_t(0xFF00)); - CHECK_EQUAL(i |= 0x003D, t |= 0x003D); - CHECK_EQUAL(i |= 0x003D, t |= type_t(0x003D)); - CHECK_EQUAL(i ^= 0xAA55, t ^= 0xAA55); - CHECK_EQUAL(i ^= 0xAA55, t ^= type_t(0xAA55)); - CHECK_EQUAL(i <<= 2, t <<= 2); - CHECK_EQUAL(i >>= 2, t >>= 2); - CHECK_EQUAL(i %= 23, t %= 23); + CHECK_EQUAL(++i, uint32_t(++t)); + CHECK_EQUAL(i++, uint32_t(t++)); + CHECK_EQUAL(--i, uint32_t(--t)); + CHECK_EQUAL(i--, uint32_t(t--)); + CHECK_EQUAL(i += 2, uint32_t(t += 2)); + CHECK_EQUAL(i += 2, uint32_t(t += type_t(2))); + CHECK_EQUAL(i -= 2, uint32_t(t -= 2)); + CHECK_EQUAL(i -= 2, uint32_t(t -= type_t(2))); + CHECK_EQUAL(i *= 2, uint32_t(t *= 2)); + CHECK_EQUAL(i *= 2, uint32_t(t *= type_t(2))); + CHECK_EQUAL(i /= 2, uint32_t(t /= 2)); + CHECK_EQUAL(i /= 2, uint32_t(t /= type_t(2))); + CHECK_EQUAL(i &= 0xFF00, uint32_t(t &= 0xFF00)); + CHECK_EQUAL(i &= 0xFF00, uint32_t(t &= type_t(0xFF00))); + CHECK_EQUAL(i |= 0x003D, uint32_t(t |= 0x003D)); + CHECK_EQUAL(i |= 0x003D, uint32_t(t |= type_t(0x003D))); + CHECK_EQUAL(i ^= 0xAA55, uint32_t(t ^= 0xAA55)); + CHECK_EQUAL(i ^= 0xAA55, uint32_t(t ^= type_t(0xAA55))); + CHECK_EQUAL(i <<= 2, uint32_t(t <<= 2)); + CHECK_EQUAL(i >>= 2, uint32_t(t >>= 2)); + CHECK_EQUAL(i %= 23, uint32_t(t %= 23)); t = type_t(0x1234); - CHECK_EQUAL(0x1234, t); + CHECK_EQUAL(0x1234U, uint32_t(t)); } //========================================================================= diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index 207fc468..db654ad6 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -425,7 +425,7 @@ namespace CHECK((std::is_same::type, std::make_signed::type>::value)); CHECK((std::is_same::type, std::make_signed::type>::value)); CHECK((std::is_same::type, std::make_signed::type>::value)); - CHECK((std::is_same::type, std::make_signed::type>::value)); + CHECK(std::is_signed::type>::value && (sizeof(wchar_t) == sizeof(etl::make_signed::type))); CHECK((std::is_same::type, std::make_signed::type>::value)); CHECK((std::is_same::type, std::make_signed::type>::value)); CHECK((std::is_same::type, std::make_signed::type>::value)); @@ -450,7 +450,7 @@ namespace CHECK((std::is_same::type, std::make_unsigned::type>::value)); CHECK((std::is_same::type, std::make_unsigned::type>::value)); CHECK((std::is_same::type, std::make_unsigned::type>::value)); - CHECK((std::is_same::type, std::make_unsigned::type>::value)); + CHECK(std::is_unsigned::type>::value && (sizeof(wchar_t) == sizeof(etl::make_unsigned::type))); CHECK((std::is_same::type, std::make_unsigned::type>::value)); CHECK((std::is_same::type, std::make_unsigned::type>::value)); CHECK((std::is_same::type, std::make_unsigned::type>::value)); diff --git a/test/test_unordered_map.cpp b/test/test_unordered_map.cpp index 3d19f4f5..7c713b93 100644 --- a/test/test_unordered_map.cpp +++ b/test/test_unordered_map.cpp @@ -80,9 +80,9 @@ namespace typedef std::pair ElementDC; typedef std::pair ElementNDC; - typedef etl::unordered_map DataDC; - typedef etl::unordered_map DataNDC; - typedef etl::iunordered_map IDataNDC; + typedef etl::unordered_map DataDC; + typedef etl::unordered_map DataNDC; + typedef etl::iunordered_map IDataNDC; NDC N0 = NDC("A"); NDC N1 = NDC("B"); @@ -105,6 +105,27 @@ namespace NDC N18 = NDC("S"); NDC N19 = NDC("T"); + DC M0 = DC("A"); + DC M1 = DC("B"); + DC M2 = DC("C"); + DC M3 = DC("D"); + DC M4 = DC("E"); + DC M5 = DC("F"); + DC M6 = DC("G"); + DC M7 = DC("H"); + DC M8 = DC("I"); + DC M9 = DC("J"); + DC M10 = DC("K"); + DC M11 = DC("L"); + DC M12 = DC("M"); + DC M13 = DC("N"); + DC M14 = DC("O"); + DC M15 = DC("P"); + DC M16 = DC("Q"); + DC M17 = DC("R"); + DC M18 = DC("S"); + DC M19 = DC("T"); + const char* K0 = "FF"; // 0 const char* K1 = "FG"; // 1 const char* K2 = "FH"; // 2 @@ -128,6 +149,8 @@ namespace std::string K[] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19 }; + std::vector initial_data_dc; + std::vector initial_data; std::vector excess_data; std::vector different_data; @@ -174,9 +197,16 @@ namespace ElementNDC(K15, N15), ElementNDC(K16, N16), ElementNDC(K17, N17), ElementNDC(K18, N18), ElementNDC(K19, N19) }; + ElementDC n4[] = + { + ElementDC(K0, M0), ElementDC(K1, M1), ElementDC(K2, M2), ElementDC(K3, M3), ElementDC(K4, M4), + ElementDC(K5, M5), ElementDC(K6, M6), ElementDC(K7, M7), ElementDC(K8, M8), ElementDC(K9, M9) + }; + initial_data.assign(std::begin(n), std::end(n)); excess_data.assign(std::begin(n2), std::end(n2)); different_data.assign(std::begin(n3), std::end(n3)); + initial_data_dc.assign(std::begin(n4), std::end(n4)); } }; @@ -194,7 +224,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_constructor_range) { - DataNDC data(initial_data.begin(), initial_data.end()); + DataDC data(initial_data_dc.begin(), initial_data_dc.end()); CHECK(data.size() == SIZE); CHECK(!data.empty()); @@ -266,46 +296,46 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_index_read) { - DataNDC data(initial_data.begin(), initial_data.end()); + DataDC data(initial_data_dc.begin(), initial_data_dc.end()); - CHECK_EQUAL(N0, data[K0]); - CHECK_EQUAL(N1, data[K1]); - CHECK_EQUAL(N2, data[K2]); - CHECK_EQUAL(N3, data[K3]); - CHECK_EQUAL(N4, data[K4]); - CHECK_EQUAL(N5, data[K5]); - CHECK_EQUAL(N6, data[K6]); - CHECK_EQUAL(N7, data[K7]); - CHECK_EQUAL(N8, data[K8]); - CHECK_EQUAL(N9, data[K9]); + CHECK_EQUAL(M0, data[K0]); + CHECK_EQUAL(M1, data[K1]); + CHECK_EQUAL(M2, data[K2]); + CHECK_EQUAL(M3, data[K3]); + CHECK_EQUAL(M4, data[K4]); + CHECK_EQUAL(M5, data[K5]); + CHECK_EQUAL(M6, data[K6]); + CHECK_EQUAL(M7, data[K7]); + CHECK_EQUAL(M8, data[K8]); + CHECK_EQUAL(M9, data[K9]); } //************************************************************************* TEST_FIXTURE(SetupFixture, test_index_write) { - DataNDC data(initial_data.begin(), initial_data.end()); + DataDC data(initial_data_dc.begin(), initial_data_dc.end()); - data[K0] = N9; - data[K1] = N8; - data[K2] = N7; - data[K3] = N6; - data[K4] = N5; - data[K5] = N4; - data[K6] = N3; - data[K7] = N2; - data[K8] = N1; - data[K9] = N0; + data[K0] = M9; + data[K1] = M8; + data[K2] = M7; + data[K3] = M6; + data[K4] = M5; + data[K5] = M4; + data[K6] = M3; + data[K7] = M2; + data[K8] = M1; + data[K9] = M0; - CHECK_EQUAL(N9, data[K0]); - CHECK_EQUAL(N8, data[K1]); - CHECK_EQUAL(N7, data[K2]); - CHECK_EQUAL(N6, data[K3]); - CHECK_EQUAL(N5, data[K4]); - CHECK_EQUAL(N4, data[K5]); - CHECK_EQUAL(N3, data[K6]); - CHECK_EQUAL(N2, data[K7]); - CHECK_EQUAL(N1, data[K8]); - CHECK_EQUAL(N0, data[K9]); + CHECK_EQUAL(M9, data[K0]); + CHECK_EQUAL(M8, data[K1]); + CHECK_EQUAL(M7, data[K2]); + CHECK_EQUAL(M6, data[K3]); + CHECK_EQUAL(M5, data[K4]); + CHECK_EQUAL(M4, data[K5]); + CHECK_EQUAL(M3, data[K6]); + CHECK_EQUAL(M2, data[K7]); + CHECK_EQUAL(M1, data[K8]); + CHECK_EQUAL(M0, data[K9]); } //************************************************************************* @@ -431,10 +461,14 @@ namespace size_t count = data.erase(K5); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); DataNDC::iterator idata = data.find(K5); CHECK(idata == data.end()); + + // Test that erase really does erase from the pool. + CHECK(!data.full()); + CHECK(!data.empty()); } //************************************************************************* @@ -458,20 +492,29 @@ namespace { DataNDC data(initial_data.begin(), initial_data.end()); - DataNDC::iterator idata = data.find(K5); - DataNDC::iterator idata_end = data.find(K8); + DataNDC::iterator idata = data.begin(); + std::advance(idata, 2); - idata = data.erase(idata, idata_end); // Erase K5, K6, K7 - CHECK(idata == data.find(K8)); + DataNDC::iterator idata_end = data.begin(); + std::advance(idata_end, 5); + + data.erase(idata, idata_end); + + CHECK_EQUAL(initial_data.size() - 3, data.size()); + CHECK(!data.full()); + CHECK(!data.empty()); + + idata = data.find(K8); + CHECK(idata != data.end()); idata = data.find(K0); CHECK(idata != data.end()); idata = data.find(K1); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(K2); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(K3); CHECK(idata != data.end()); @@ -480,13 +523,13 @@ namespace CHECK(idata != data.end()); idata = data.find(K5); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(K6); CHECK(idata == data.end()); idata = data.find(K7); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(K8); CHECK(idata != data.end()); @@ -511,10 +554,10 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); size_t count = data.count(K5); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); count = data.count(K12); - CHECK_EQUAL(0, count); + CHECK_EQUAL(0U, count); } //************************************************************************* @@ -622,13 +665,18 @@ namespace CHECK_CLOSE(0.0, data.load_factor(), 0.01); // Half the buckets used. - data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 2)); - CHECK_CLOSE(0.5, data.load_factor(), 0.01); + data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 4)); + CHECK_CLOSE(0.4, data.load_factor(), 0.01); // All of the buckets used. - data.clear(); data.assign(initial_data.begin(), initial_data.end()); - CHECK_CLOSE(1.0, data.load_factor(), 0.01); + CHECK_CLOSE(2.0, data.load_factor(), 0.01); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_release) + { + } }; } diff --git a/test/test_unordered_multimap.cpp b/test/test_unordered_multimap.cpp index d5ca8aa6..57f8fb22 100644 --- a/test/test_unordered_multimap.cpp +++ b/test/test_unordered_multimap.cpp @@ -80,9 +80,9 @@ namespace typedef std::pair ElementDC; typedef std::pair ElementNDC; - typedef etl::unordered_multimap DataDC; - typedef etl::unordered_multimap DataNDC; - typedef etl::iunordered_multimap IDataNDC; + typedef etl::unordered_multimap DataDC; + typedef etl::unordered_multimap DataNDC; + typedef etl::iunordered_multimap IDataNDC; NDC N0 = NDC("A"); NDC N1 = NDC("B"); @@ -369,14 +369,14 @@ namespace size_t count = data.erase(K10); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); DataNDC::iterator idata = data.find(K10); CHECK(idata == data.end()); count = data.erase(K11); - CHECK_EQUAL(3, count); + CHECK_EQUAL(3U, count); idata = data.find(K11); CHECK(idata == data.end()); @@ -396,6 +396,10 @@ namespace CHECK(idata == data.end()); CHECK(inext == iafter); + + // Test that erase really does erase from the pool. + CHECK(!data.full()); + CHECK(!data.empty()); } //************************************************************************* @@ -403,20 +407,29 @@ namespace { DataNDC data(initial_data.begin(), initial_data.end()); - DataNDC::iterator idata = data.find(K5); - DataNDC::iterator idata_end = data.find(K8); + DataNDC::iterator idata = data.begin(); + std::advance(idata, 2); - idata = data.erase(idata, idata_end); // Erase K5, K6, K7 - CHECK(idata == data.find(K8)); + DataNDC::iterator idata_end = data.begin(); + std::advance(idata_end, 5); + + data.erase(idata, idata_end); + + CHECK_EQUAL(initial_data.size() - 3, data.size()); + CHECK(!data.full()); + CHECK(!data.empty()); + + idata = data.find(K8); + CHECK(idata != data.end()); idata = data.find(K0); CHECK(idata != data.end()); idata = data.find(K1); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(K2); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(K3); CHECK(idata != data.end()); @@ -425,13 +438,13 @@ namespace CHECK(idata != data.end()); idata = data.find(K5); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(K6); CHECK(idata == data.end()); idata = data.find(K7); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(K8); CHECK(idata != data.end()); @@ -456,13 +469,13 @@ namespace DataNDC data(equal_data.begin(), equal_data.end()); size_t count = data.count(K10); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); count = data.count(K11); - CHECK_EQUAL(3, count); + CHECK_EQUAL(3U, count); count = data.count(K1); - CHECK_EQUAL(0, count); + CHECK_EQUAL(0U, count); } //************************************************************************* @@ -580,13 +593,13 @@ namespace CHECK_CLOSE(0.0, data.load_factor(), 0.01); // Half the buckets used. - data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 2)); - CHECK_CLOSE(0.5, data.load_factor(), 0.01); + data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 4)); + CHECK_CLOSE(0.4, data.load_factor(), 0.01); // All of the buckets used. data.clear(); data.assign(initial_data.begin(), initial_data.end()); - CHECK_CLOSE(1.0, data.load_factor(), 0.01); + CHECK_CLOSE(2.0, data.load_factor(), 0.01); } }; } diff --git a/test/test_unordered_multiset.cpp b/test/test_unordered_multiset.cpp index 0edf7a86..f7c62051 100644 --- a/test/test_unordered_multiset.cpp +++ b/test/test_unordered_multiset.cpp @@ -59,8 +59,8 @@ namespace } }; - typedef etl::unordered_multiset DataDC; - typedef etl::unordered_multiset DataNDC; + typedef etl::unordered_multiset DataDC; + typedef etl::unordered_multiset DataNDC; typedef etl::iunordered_multiset IDataNDC; NDC N0 = NDC("FF"); @@ -294,14 +294,14 @@ namespace size_t count = data.erase(N0); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); DataNDC::iterator idata = data.find(N0); CHECK(idata == data.end()); count = data.erase(N1); - CHECK_EQUAL(3, count); + CHECK_EQUAL(3U, count); idata = data.find(N1); CHECK(idata == data.end()); @@ -321,6 +321,10 @@ namespace CHECK(idata == data.end()); CHECK(inext == iafter); + + // Test that erase really does erase from the pool. + CHECK(!data.full()); + CHECK(!data.empty()); } //************************************************************************* @@ -328,26 +332,29 @@ namespace { DataNDC data(initial_data.begin(), initial_data.end()); - DataNDC::iterator idata = data.find(N5); - DataNDC::iterator idata_end = data.find(N8); + DataNDC::iterator idata = data.begin(); + std::advance(idata, 2); - std::vector test; + DataNDC::iterator idata_end = data.begin(); + std::advance(idata_end, 5); - test.assign(data.begin(), data.end()); + data.erase(idata, idata_end); - idata = data.erase(idata, idata_end); // Erase N5, N6, N7 - CHECK(idata == data.find(N8)); + CHECK_EQUAL(initial_data.size() - 3, data.size()); + CHECK(!data.full()); + CHECK(!data.empty()); - test.assign(data.begin(), data.end()); + idata = data.find(N8); + CHECK(idata != data.end()); idata = data.find(N0); CHECK(idata != data.end()); idata = data.find(N1); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(N2); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(N3); CHECK(idata != data.end()); @@ -356,13 +363,13 @@ namespace CHECK(idata != data.end()); idata = data.find(N5); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(N6); CHECK(idata == data.end()); idata = data.find(N7); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(N8); CHECK(idata != data.end()); @@ -386,13 +393,13 @@ namespace DataNDC data(equal_data.begin(), equal_data.end()); size_t count = data.count(N0); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); count = data.count(N1); - CHECK_EQUAL(3, count); + CHECK_EQUAL(3U, count); count = data.count(N10); - CHECK_EQUAL(0, count); + CHECK_EQUAL(0U, count); } //************************************************************************* @@ -510,13 +517,13 @@ namespace CHECK_CLOSE(0.0, data.load_factor(), 0.01); // Half the buckets used. - data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 2)); - CHECK_CLOSE(0.5, data.load_factor(), 0.01); + data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 4)); + CHECK_CLOSE(0.4, data.load_factor(), 0.01); // All of the buckets used. data.clear(); data.assign(initial_data.begin(), initial_data.end()); - CHECK_CLOSE(1.0, data.load_factor(), 0.01); + CHECK_CLOSE(2.0, data.load_factor(), 0.01); } }; } diff --git a/test/test_unordered_set.cpp b/test/test_unordered_set.cpp index 1436c177..44af7202 100644 --- a/test/test_unordered_set.cpp +++ b/test/test_unordered_set.cpp @@ -58,9 +58,9 @@ namespace } }; - typedef etl::unordered_set DataDC; - typedef etl::unordered_set DataNDC; - typedef etl::iunordered_set IDataNDC; + typedef etl::unordered_set DataDC; + typedef etl::unordered_set DataNDC; + typedef etl::iunordered_set IDataNDC; NDC N0 = NDC("FF"); NDC N1 = NDC("FG"); @@ -281,7 +281,7 @@ namespace size_t count = data.erase(N5); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); DataNDC::iterator idata = data.find(N5); CHECK(idata == data.end()); @@ -301,6 +301,10 @@ namespace CHECK(idata == data.end()); CHECK(inext == iafter); + + // Test that erase really does erase from the pool. + CHECK(!data.full()); + CHECK(!data.empty()); } //************************************************************************* @@ -308,26 +312,29 @@ namespace { DataNDC data(initial_data.begin(), initial_data.end()); - DataNDC::iterator idata = data.find(N5); - DataNDC::iterator idata_end = data.find(N8); + DataNDC::iterator idata = data.begin(); + std::advance(idata, 2); - std::vector test; + DataNDC::iterator idata_end = data.begin(); + std::advance(idata_end, 5); - test.assign(data.begin(), data.end()); + data.erase(idata, idata_end); - idata = data.erase(idata, idata_end); // Erase N5, N6, N7 - CHECK(idata == data.find(N8)); + CHECK_EQUAL(initial_data.size() - 3, data.size()); + CHECK(!data.full()); + CHECK(!data.empty()); - test.assign(data.begin(), data.end()); + idata = data.find(N8); + CHECK(idata != data.end()); idata = data.find(N0); CHECK(idata != data.end()); idata = data.find(N1); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(N2); - CHECK(idata != data.end()); + CHECK(idata == data.end()); idata = data.find(N3); CHECK(idata != data.end()); @@ -336,13 +343,13 @@ namespace CHECK(idata != data.end()); idata = data.find(N5); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(N6); CHECK(idata == data.end()); idata = data.find(N7); - CHECK(idata == data.end()); + CHECK(idata != data.end()); idata = data.find(N8); CHECK(idata != data.end()); @@ -366,10 +373,10 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); size_t count = data.count(N5); - CHECK_EQUAL(1, count); + CHECK_EQUAL(1U, count); count = data.count(N12); - CHECK_EQUAL(0, count); + CHECK_EQUAL(0U, count); } //************************************************************************* @@ -425,13 +432,13 @@ namespace CHECK_CLOSE(0.0, data.load_factor(), 0.01); // Half the buckets used. - data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 2)); - CHECK_CLOSE(0.5, data.load_factor(), 0.01); + data.assign(initial_data.begin(), initial_data.begin() + (initial_data.size() / 4)); + CHECK_CLOSE(0.4, data.load_factor(), 0.01); // All of the buckets used. data.clear(); data.assign(initial_data.begin(), initial_data.end()); - CHECK_CLOSE(1.0, data.load_factor(), 0.01); + CHECK_CLOSE(2.0, data.load_factor(), 0.01); } }; } diff --git a/test/test_utility.cpp b/test/test_utility.cpp new file mode 100644 index 00000000..046b12dd --- /dev/null +++ b/test/test_utility.cpp @@ -0,0 +1,99 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +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. +******************************************************************************/ + +#include + +#include "../src/utility.h" + +namespace +{ + bool nonConstCalled; + bool constCalled; + + void TestText(std::string&) + { + nonConstCalled = true; + } + + void TestText(const std::string&) + { + constCalled = true; + } +} + +namespace +{ + SUITE(test_utility) + { + //========================================================================= + TEST(test_exchange) + { + int a = 1; + int b = 2; + int c = etl::exchange(a, b); // c = a, a = b + + CHECK_EQUAL(2, a); + CHECK_EQUAL(2, b); + CHECK_EQUAL(1, c); + } + + //========================================================================= + TEST(test_exchange_const) + { + int a = 1; + const int b = 2; + int c = etl::exchange(a, b); // c = a, a = b + + CHECK_EQUAL(2, a); + CHECK_EQUAL(2, b); + CHECK_EQUAL(1, c); + } + + //========================================================================= + TEST(test_as_const) + { + std::string text = "Hello World!"; + + nonConstCalled = false; + constCalled = false; + + TestText(text); + + CHECK(nonConstCalled); + CHECK(!constCalled); + + nonConstCalled = false; + constCalled = false; + + TestText(etl::as_const(text)); + + CHECK(!nonConstCalled); + CHECK(constCalled); + } + }; +} diff --git a/test/test_variant.cpp b/test/test_variant.cpp index 12967dc7..8583c239 100644 --- a/test/test_variant.cpp +++ b/test/test_variant.cpp @@ -192,6 +192,22 @@ namespace CHECK(variant_2.is_valid()); } + //************************************************************************* + TEST(test_assign_from_variant2) + { + std::string text("Some Text"); + int integer(99); + test_variant_3a variant_1; + test_variant_3a variant_2; + + variant_1 = text; + variant_2 = integer; + variant_2 = variant_1; + + CHECK_EQUAL(text, variant_2.get()); + CHECK(variant_2.is_valid()); + } + //************************************************************************* TEST(test_assignment_incorrect_type_exception) { diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 82f04346..2785bb6b 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -244,6 +244,8 @@ namespace std::array compare_data; compare_data.fill(INITIAL_VALUE); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(is_equal); @@ -432,6 +434,8 @@ namespace data.assign(compare_data.begin(), compare_data.end()); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -450,6 +454,8 @@ namespace Data data; data.assign(INITIAL_SIZE, INITIAL_VALUE); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -487,6 +493,8 @@ namespace data.push_back(i); } + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -505,6 +513,8 @@ namespace data.push_back(); data[0] = 1; + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -537,6 +547,8 @@ namespace data.pop_back(); data.pop_back(); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -623,6 +635,8 @@ namespace data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE); compare_data.insert(compare_data.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -668,11 +682,15 @@ namespace Compare_Data compare_data; Data data; + data.resize(SIZE, -1); + data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); compare_data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); data.insert(data.begin() + offset, insert_data.begin(), insert_data.end()); compare_data.insert(compare_data.begin() + offset, insert_data.begin(), insert_data.end()); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -717,6 +735,8 @@ namespace data.erase(data.begin() + 2); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -734,6 +754,8 @@ namespace data.erase(data.begin() + 2, data.begin() + 4); + CHECK_EQUAL(compare_data.size(), data.size()); + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); @@ -933,17 +955,5 @@ namespace const Data initial2(initial_data.begin(), initial_data.end()); CHECK((initial >= initial2) == (initial_data >= initial_data)); } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_allocated_size) - { - const size_t INITIAL_SIZE = 5; - - Data data(INITIAL_SIZE); - - size_t expected_size = (SIZE * sizeof(int)) + (2 * sizeof(size_t)) + sizeof(int*); - - CHECK_EQUAL(expected_size, sizeof(Data)); - } }; } diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp new file mode 100644 index 00000000..843c2e82 --- /dev/null +++ b/test/test_vector_non_trivial.cpp @@ -0,0 +1,960 @@ +///****************************************************************************** +//The MIT License(MIT) +// +//Embedded Template Library. +//https://github.com/ETLCPP/etl +//http://www.etlcpp.com +// +//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. +//******************************************************************************/ + +#include + +#include +#include +#include + +#include "../src/vector.h" +#include "data.h" + +namespace +{ + SUITE(test_vector_non_trivial) + { + static const size_t SIZE = 10; + + typedef TestDataNDC NDC; + typedef TestDataDC DC; + + typedef etl::vector DataNDC; + typedef etl::ivector IDataNDC; + typedef std::vector CompareDataNDC; + + typedef etl::vector DataDC; + typedef etl::ivector IDataDC; + typedef std::vector CompareDataDC; + + CompareDataNDC initial_data; + CompareDataNDC less_data; + CompareDataNDC greater_data; + CompareDataNDC shorter_data; + CompareDataNDC different_data; + CompareDataNDC insert_data; + + //************************************************************************* + struct SetupFixture + { + SetupFixture() + { + NDC n[] = { NDC("0"), NDC("1"), NDC("2"), NDC("3"), NDC("4"), NDC("5"), NDC("6"), NDC("7"), NDC("8"), NDC("9") }; + NDC n_insert[] = { NDC("11"), NDC("12"), NDC("13") }; + NDC n_less[] = { NDC("0"), NDC("1"), NDC("2"), NDC("3"), NDC("3"), NDC("5"), NDC("6"), NDC("7"), NDC("8"), NDC("9") }; + NDC n_greater[] = { NDC("0"), NDC("1"), NDC("2"), NDC("4"), NDC("4"), NDC("5"), NDC("6"), NDC("7"), NDC("8"), NDC("9") }; + + initial_data.assign(std::begin(n), std::end(n)); + insert_data.assign(std::begin(n_insert), std::end(n_insert)); + less_data.assign(std::begin(n_less), std::end(n_less)); + greater_data.assign(std::begin(n_greater), std::end(n_greater)); + shorter_data.assign(std::begin(n_greater), std::end(n_greater) - 1); + different_data.assign(initial_data.rbegin(), initial_data.rend()); + } + }; + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_default_constructor) + { + DataDC data; + + CHECK_EQUAL(data.size(), size_t(0)); + CHECK(data.empty()); + CHECK_EQUAL(data.capacity(), SIZE); + CHECK_EQUAL(data.max_size(), SIZE); + } + + //************************************************************************* + TEST(test_iterator_comparison_empty) + { + DataDC data; + + CHECK(data.begin() == data.end()); + CHECK(data.cbegin() == data.cend()); + CHECK(data.rbegin() == data.rend()); + CHECK(data.crbegin() == data.crend()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size) + { + const size_t INITIAL_SIZE = 5; + DataDC data(INITIAL_SIZE); + + CHECK(data.size() == INITIAL_SIZE); + CHECK(!data.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_value) + { + const size_t INITIAL_SIZE = 5; + const NDC INITIAL_VALUE("1"); + + std::vector compare_data(INITIAL_SIZE, INITIAL_VALUE); + DataNDC data(size_t(5), NDC("1")); + + CHECK(data.size() == INITIAL_SIZE); + CHECK(!data.empty()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_size_excess) + { + CHECK_THROW(DataDC data(SIZE + 1), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_range) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + CHECK(data.size() == SIZE); + CHECK(!data.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_copy_constructor) + { + DataNDC data(initial_data.begin(), initial_data.end()); + DataNDC data2(data); + CHECK(data2 == data); + + data2[2] = NDC("X"); + CHECK(data2 != data); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment) + { + DataNDC data(initial_data.begin(), initial_data.end()); + DataNDC other_data; + + other_data = data; + + bool is_equal = std::equal(data.begin(), + data.end(), + other_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assignment_iterface) + { + DataNDC data1(initial_data.begin(), initial_data.end()); + DataNDC data2; + + IDataNDC& idata1 = data1; + IDataNDC& idata2 = data2; + + idata2 = idata1; + + bool is_equal = std::equal(data1.begin(), + data1.end(), + data2.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_self_assignment) + { + DataNDC data(initial_data.begin(), initial_data.end()); + DataNDC other_data(data); + + other_data = other_data; + + bool is_equal = std::equal(data.begin(), + data.end(), + other_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_begin) + { + DataDC data(10); + const DataDC constData(10); + + CHECK_EQUAL(&data[0], data.begin()); + CHECK_EQUAL(&constData[0], constData.begin()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_end) + { + DataDC data(10); + const DataDC constData(10); + + CHECK_EQUAL(&data[10], data.end()); + CHECK_EQUAL(&constData[10], constData.end()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + + DataDC data(INITIAL_SIZE); + data.resize(NEW_SIZE); + + CHECK_EQUAL(data.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_up_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 8; + const NDC INITIAL_VALUE("1"); + + DataNDC data(INITIAL_SIZE, INITIAL_VALUE); + data.resize(NEW_SIZE, INITIAL_VALUE); + + std::vector compare_data(NEW_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_excess) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = SIZE + 1; + + DataDC data(INITIAL_SIZE); + + CHECK_THROW(data.resize(NEW_SIZE), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + + DataDC data(INITIAL_SIZE); + data.resize(NEW_SIZE); + + CHECK_EQUAL(data.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_resize_down_value) + { + const size_t INITIAL_SIZE = 5; + const size_t NEW_SIZE = 2; + const NDC INITIAL_VALUE("1"); + + DataNDC data(INITIAL_SIZE, INITIAL_VALUE); + data.resize(NEW_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(data.size(), NEW_SIZE); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_empty) + { + DataDC data; + data.resize(data.max_size()); + + CHECK(data.full()); + CHECK(!data.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_full) + { + DataNDC data; + + CHECK(!data.full()); + CHECK(data.empty()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + for (size_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data[i], compare_data[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index_const) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + const DataNDC data(compare_data.begin(), compare_data.end()); + + for (size_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data[i], compare_data[i]); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + for (size_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.at(i), compare_data.at(i)); + } + + CHECK_THROW(data.at(data.size()), etl::vector_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_at_const) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + const DataNDC data(initial_data.begin(), initial_data.end()); + + for (size_t i = 0; i < data.size(); ++i) + { + CHECK_EQUAL(data.at(i), compare_data.at(i)); + } + + CHECK_THROW(data.at(data.size()), etl::vector_out_of_bounds); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK(data.front() == compare_data.front()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_front_const) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + const DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK(data.front() == compare_data.front()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK(data.back() == compare_data.back()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_back_const) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + const DataNDC data(initial_data.begin(), initial_data.end()); + + CHECK(data.back() == compare_data.back()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.data(), + data.data() + data.size(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_data_const) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + const DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.data(), + data.data() + data.size(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_range) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data; + + data.assign(compare_data.begin(), compare_data.end()); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value) + { + const size_t INITIAL_SIZE = 5; + const NDC INITIAL_VALUE("1"); + std::vector compare_data(INITIAL_SIZE, INITIAL_VALUE); + + DataNDC data; + data.assign(INITIAL_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_assign_size_value_excess) + { + const size_t INITIAL_SIZE = SIZE; + const size_t EXCESS_SIZE = SIZE + 1; + const NDC INITIAL_VALUE("1"); + std::vector compare_data(INITIAL_SIZE, INITIAL_VALUE); + + DataNDC data; + + CHECK_THROW(data.assign(EXCESS_SIZE, INITIAL_VALUE), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back) + { + CompareDataNDC compare_data; + DataNDC data; + + for (size_t i = 0; i < SIZE; ++i) + { + std::string value(" "); + value[0] = char('A' + i); + compare_data.push_back(value); + data.push_back(NDC(value)); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_null) + { + CompareDataDC compare_data; + DataDC data; + + compare_data.push_back(DC("1")); + + data.push_back(); + data[0] = DC("1"); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_push_back_excess) + { + DataNDC data; + + for (size_t i = 0; i < SIZE; ++i) + { + std::string value(" "); + value[0] = char('A' + i); + data.push_back(NDC(value)); + } + + CHECK_THROW(data.push_back(NDC("Z")), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + compare_data.pop_back(); + compare_data.pop_back(); + + data.pop_back(); + data.pop_back(); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_pop_back_exception) + { + DataDC data; + + data.resize(2); + + data.pop_back(); + data.pop_back(); + + CHECK_THROW(data.pop_back(), etl::vector_empty); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value) + { + const size_t INITIAL_SIZE = 5; + const NDC INITIAL_VALUE("1"); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + CompareDataNDC compare_data; + DataNDC data; + + data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + compare_data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + + data.insert(data.begin() + offset, INITIAL_VALUE); + compare_data.insert(compare_data.begin() + offset, INITIAL_VALUE); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_value_excess) + { + const size_t INITIAL_SIZE = SIZE; + const NDC INITIAL_VALUE("1"); + const NDC UNINITIALISED_VALUE("Z"); + + DataNDC data(INITIAL_SIZE, INITIAL_VALUE); + + size_t offset = 2; + + CHECK_THROW(data.insert(data.begin() + offset, INITIAL_VALUE), etl::vector_full); + + offset = 0; + + CHECK_THROW(data.insert(data.begin() + offset, INITIAL_VALUE), etl::vector_full); + + offset = data.size(); + + CHECK_THROW(data.insert(data.begin() + offset, INITIAL_VALUE), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value) + { + const size_t INITIAL_SIZE = 5; + const size_t INSERT_SIZE = 3; + const NDC INITIAL_VALUE("1"); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + CompareDataNDC compare_data; + DataNDC data; + + data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + compare_data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + compare_data.insert(compare_data.begin() + offset, INSERT_SIZE, INITIAL_VALUE); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_n_value_excess) + { + const size_t INITIAL_SIZE = SIZE; + const size_t INSERT_SIZE = 4; + const NDC INITIAL_VALUE("1"); + + DataNDC data(INITIAL_SIZE, INITIAL_VALUE); + + size_t offset = 0; + + CHECK_THROW(data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE), etl::vector_full); + + offset = 2; + + CHECK_THROW(data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE), etl::vector_full); + + offset = 4; + + CHECK_THROW(data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE), etl::vector_full); + + offset = data.size(); + + CHECK_THROW(data.insert(data.begin() + offset, INSERT_SIZE, INITIAL_VALUE), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range) + { + const size_t INITIAL_SIZE = 5; + const NDC INITIAL_VALUE("1"); + + for (size_t offset = 0; offset <= INITIAL_SIZE; ++offset) + { + CompareDataNDC compare_data; + DataNDC data; + + data.resize(SIZE, NDC("Z")); + + data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + compare_data.assign(initial_data.begin(), initial_data.begin() + INITIAL_SIZE); + data.insert(data.begin() + offset, insert_data.begin(), insert_data.end()); + compare_data.insert(compare_data.begin() + offset, insert_data.begin(), insert_data.end()); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_excess) + { + const size_t INITIAL_SIZE = 5; + const NDC INITIAL_VALUE("1"); + + DataNDC data(INITIAL_SIZE, INITIAL_VALUE); + + size_t offset = 0; + + CHECK_THROW(data.insert(data.begin() + offset, initial_data.begin(), initial_data.end()), etl::vector_full); + + offset = 2; + + CHECK_THROW(data.insert(data.begin() + offset, initial_data.begin(), initial_data.end()), etl::vector_full); + + offset = 4; + + CHECK_THROW(data.insert(data.begin() + offset, initial_data.begin(), initial_data.end()), etl::vector_full); + + offset = data.size(); + + CHECK_THROW(data.insert(data.begin() + offset, initial_data.begin(), initial_data.end()), etl::vector_full); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_single) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + compare_data.erase(compare_data.begin() + 2); + + data.erase(data.begin() + 2); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_erase_range) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + DataNDC data(initial_data.begin(), initial_data.end()); + + compare_data.erase(compare_data.begin() + 2, compare_data.begin() + 4); + + data.erase(data.begin() + 2, data.begin() + 4); + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_clear) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + data.clear(); + + CHECK_EQUAL(data.size(), size_t(0)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_iterator) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_iterator) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.cbegin(), + data.cend(), + compare_data.cbegin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_reverse_iterator) + { + CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.rbegin(), + data.rend(), + compare_data.rbegin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_reverse_iterator) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + const DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.crbegin(), + data.crend(), + compare_data.crbegin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_reverse_iterator2) + { + const CompareDataNDC compare_data(initial_data.begin(), initial_data.end()); + + const DataNDC data(compare_data.begin(), compare_data.end()); + + bool is_equal = std::equal(data.rbegin(), + data.rend(), + compare_data.rbegin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_equal) + { + const DataNDC initial1(initial_data.begin(), initial_data.end()); + const DataNDC initial2(initial_data.begin(), initial_data.end()); + + CHECK(initial1 == initial2); + + const DataNDC different(different_data.begin(), different_data.end()); + + CHECK(!(initial1 == different)); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK(!(shorter == initial1)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_not_equal) + { + const DataNDC initial1(initial_data.begin(), initial_data.end()); + const DataNDC initial2(initial_data.begin(), initial_data.end()); + + CHECK(!(initial1 != initial2)); + + const DataNDC different(different_data.begin(), different_data.end()); + + CHECK(initial1 != different); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK(shorter != initial1); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than) + { + const DataNDC less(less_data.begin(), less_data.end()); + const DataNDC initial(initial_data.begin(), initial_data.end()); + + CHECK((less < initial) == (less_data < initial_data)); + + const DataNDC greater(greater_data.begin(), greater_data.end()); + + CHECK((greater < initial) == (greater_data < initial_data)); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK((shorter < initial) == (shorter_data < initial_data)); + CHECK((initial < shorter) == (initial_data < shorter_data)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_less_than_or_equal) + { + const DataNDC less(less_data.begin(), less_data.end()); + const DataNDC initial(initial_data.begin(), initial_data.end()); + + CHECK((less <= initial) == (less_data <= initial_data)); + + const DataNDC greater(greater_data.begin(), greater_data.end()); + + CHECK((greater <= initial) == (greater_data <= initial_data)); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK((shorter <= initial) == (shorter_data <= initial_data)); + CHECK((initial <= shorter) == (initial_data <= shorter_data)); + + const DataNDC initial2(initial_data.begin(), initial_data.end()); + CHECK((initial <= initial2) == (initial_data <= initial_data)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than) + { + const DataNDC less(less_data.begin(), less_data.end()); + const DataNDC initial(initial_data.begin(), initial_data.end()); + + CHECK((less > initial) == (less_data > initial_data)); + + const DataNDC greater(greater_data.begin(), greater_data.end()); + + CHECK((greater > initial) == (greater_data > initial_data)); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK((shorter > initial) == (shorter_data > initial_data)); + CHECK((initial > shorter) == (initial_data > shorter_data)); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_greater_than_or_equal) + { + const DataNDC less(less_data.begin(), less_data.end()); + const DataNDC initial(initial_data.begin(), initial_data.end()); + + CHECK((less >= initial) == (less_data >= initial_data)); + + const DataNDC greater(greater_data.begin(), greater_data.end()); + + CHECK((greater >= initial) == (greater_data >= initial_data)); + + const DataNDC shorter(shorter_data.begin(), shorter_data.end()); + + CHECK((shorter >= initial) == (shorter_data >= initial_data)); + CHECK((initial >= shorter) == (initial_data > shorter_data)); + + const DataNDC initial2(initial_data.begin(), initial_data.end()); + CHECK((initial >= initial2) == (initial_data >= initial_data)); + } + }; +} diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index 2c337e60..1eb13af3 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -933,17 +933,5 @@ namespace const Data initial2(initial_data.begin(), initial_data.end()); CHECK((initial >= initial2) == (initial_data >= initial_data)); } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_allocated_size) - { - const size_t INITIAL_SIZE = 5; - - Data data(INITIAL_SIZE); - - size_t expected_size = (SIZE * sizeof(int)) + (2 * sizeof(size_t)) + sizeof(int*); - - CHECK_EQUAL(expected_size, sizeof(Data)); - } }; } diff --git a/test/vs2015/etl.vcxproj b/test/vs2015/etl.vcxproj index 793faf35..f2e8c9b6 100644 --- a/test/vs2015/etl.vcxproj +++ b/test/vs2015/etl.vcxproj @@ -19,6 +19,7 @@ Win32Proj unittest etl + 10.0.10586.0 @@ -63,6 +64,7 @@ false + true @@ -111,8 +113,9 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_THROW_EXCEPTIONS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_THROW_EXCEPTIONS;ETL_VERBOSE_ERRORS;ETL_CHECK_PUSH_POP;%(PreprocessorDefinitions) ../../../unittest-cpp + false Console @@ -169,8 +172,10 @@ + + @@ -208,6 +213,8 @@ + + @@ -217,8 +224,10 @@ + + @@ -231,6 +240,7 @@ true + @@ -265,12 +275,12 @@ + - @@ -278,8 +288,11 @@ + + + @@ -316,6 +329,7 @@ + @@ -343,8 +357,12 @@ - - + + true + + + true + false false @@ -356,10 +374,23 @@ - - - + + false + + + false + + + false + + + false + + + false + + @@ -367,8 +398,12 @@ false false - + + true + false + + @@ -382,7 +417,12 @@ - + + true + + + true + @@ -395,8 +435,10 @@ + + diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index 715746e3..cdf1831e 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -498,9 +498,6 @@ ETL\Containers - - ETL\Containers - ETL\Containers @@ -519,6 +516,39 @@ ETL\Utilities + + ETL\Containers + + + ETL\Utilities + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Utilities + + + ETL\Utilities + + + ETL\Utilities + + + ETL\Utilities + + + ETL\Utilities + @@ -620,9 +650,6 @@ Source Files - - Source Files - Source Files @@ -701,15 +728,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -806,6 +824,42 @@ ETL\Private + + Source Files + + + Source Files + + + Source Files + + + ETL\Utilities + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files +