diff --git a/ibitset.h b/ibitset.h index 7d9112a6..1aed3d92 100644 --- a/ibitset.h +++ b/ibitset.h @@ -33,6 +33,7 @@ SOFTWARE. #include #include +#include #include "exception.h" #include "integral_limits.h" diff --git a/ideque.h b/ideque.h index aafd32b9..ce29cf59 100644 --- a/ideque.h +++ b/ideque.h @@ -890,7 +890,6 @@ namespace etl // Are we closer to the front? if (distance(_begin, insert_position) < difference_type(current_size / 2)) { - size_t insert_index = std::distance(begin(), position); size_t n_insert = n; size_t n_move = std::distance(begin(), position); size_t n_create_copy = std::min(n_insert, n_move); @@ -922,7 +921,6 @@ namespace etl } else { - size_t insert_index = std::distance(begin(), position); size_t n_insert = n; size_t n_move = std::distance(position, end()); size_t n_create_copy = std::min(n_insert, n_move); diff --git a/iforward_list.h b/iforward_list.h index 8915bdad..cf00fbf2 100644 --- a/iforward_list.h +++ b/iforward_list.h @@ -573,6 +573,68 @@ namespace etl } } + //************************************************************************* + /// Erases the value at the specified position. + //************************************************************************* + void move_after(const_iterator from_before, const_iterator to_before) + { + if (from_before == to_before) // Can't more 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* p_from = p_from_before->next; + + // Disconnect from the list. + join(p_from_before, p_from->next); + + // Attach it to the new position. + join(p_from, p_to_before->next); + join(p_to_before, p_from); + } + + //************************************************************************* + /// Moves a range from one position to another within the list. + /// Moves a range at position 'first_before'/'last' to the position before 'to_before'. + //************************************************************************* + void move_after(const_iterator first_before, const_iterator last, const_iterator to_before) + { + if ((first_before == to_before) || (last == to_before)) + { + return; // Can't more to before yourself! + } + +#ifdef _DEBUG + // Check that we are not doing an illegal move! + for (const_iterator item = first_before; item != last; ++item) + { + ETL_ASSERT(item != to_before, ETL_ERROR(forward_list_iterator)); + } +#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; + + // Find the last node that will be moved. + while (p_final->next != p_last) + { + p_final = p_final->next; + } + + // Disconnect from the list. + join(p_first_before, p_final->next); + + // Attach it to the new position. + join(p_final, p_to_before->next); + join(p_to_before, p_first); + } + //************************************************************************* /// Removes all but the first element from every consecutive group of equal /// elements in the container. diff --git a/ilist.h b/ilist.h index f24783f5..160eb3d8 100644 --- a/ilist.h +++ b/ilist.h @@ -762,6 +762,60 @@ namespace etl } } + //************************************************************************* + /// Moves an element from one position to another within the list. + /// Moves the element at position 'from' to the position before 'to'. + //************************************************************************* + void move(const_iterator from, const_iterator to) + { + if (from == to) + { + return; // Can't more to before yourself! + } + + Node& from_node = const_cast(*from.p_node); // We're not changing the value, just it's position. + Node& to_node = const_cast(*to.p_node); // We're not changing the value, just it's position. + + // Disconnect the node from the list. + join(*from_node.previous, *from_node.next); + + // Attach it to the new position. + join(*to_node.previous, from_node); + join(from_node, to_node); + } + + //************************************************************************* + /// Moves a range from one position to another within the list. + /// Moves a range at position 'first'/'last' to the position before 'to'. + //************************************************************************* + void move(const_iterator first, const_iterator last, const_iterator to) + { + if ((first == to) || (last == to)) + { + return; // Can't more to before yourself! + } + +#ifdef _DEBUG + // Check that we are not doing an illegal move! + for (const_iterator item = first; item != last; ++item) + { + ETL_ASSERT(item != to, ETL_ERROR(list_iterator)); + } +#endif + + Node& first_node = const_cast(*first.p_node); // We're not changing the value, just it's position. + Node& last_node = const_cast(*last.p_node); // We're not changing the value, just it's position. + Node& to_node = const_cast(*to.p_node); // We're not changing the value, just it's position. + Node& final_node = *last_node.previous; + + // Disconnect the range from the list. + join(*first_node.previous, last_node); + + // Attach it to the new position. + join(*to_node.previous, first_node); + join(final_node, to_node); + } + //************************************************************************* /// Sort using in-place merge sort algorithm. /// Uses 'less-than operator as the predicate. diff --git a/intrusive_forward_list.h b/intrusive_forward_list.h index 9e3b4546..75f1a000 100644 --- a/intrusive_forward_list.h +++ b/intrusive_forward_list.h @@ -42,7 +42,7 @@ SOFTWARE. #include "nullptr.h" #include "type_traits.h" -#include "intrusive_forward_list_node.h" +#include "intrusive_forward_list_link.h" namespace etl { @@ -105,22 +105,23 @@ namespace etl //*************************************************************************** /// An intrusive forward list. ///\ingroup intrusive_forward_list + ///\note TLink must be a base of TValue. //*************************************************************************** - template + template > class intrusive_forward_list { public: // Node typedef. - typedef __private_intrusive_forward_list__::intrusive_forward_list_node_base node_t; + typedef TLink link_type; // STL style typedefs. - typedef TValue value_type; - typedef TValue* pointer; - typedef const TValue* const_pointer; - typedef TValue& reference; - typedef const TValue& const_reference; - typedef size_t size_type; + 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; public: @@ -134,75 +135,74 @@ namespace etl friend class intrusive_forward_list; iterator() - : p_node(nullptr), - index(0) + : p_value(nullptr) { } - iterator(node_t& node, size_t index) - : p_node(&node), - index(index) + iterator(value_type& value) + : p_value(&value) { } iterator(const iterator& other) - : p_node(other.p_node), - index(other.index) + : p_value(other.p_value) { } iterator& operator ++() { - p_node = p_node->get_next(index); + // Read the appropriate 'ifll_next'. + p_value = static_cast(p_value->link_type::ifll_next); return *this; } iterator operator ++(int) { iterator temp(*this); - p_node = p_node->get_next(index); + // Read the appropriate 'ifll_next'. + p_value = static_cast(p_value->link_type::ifll_next); return temp; } iterator operator =(const iterator& other) { - p_node = other.p_node; + p_value = other.p_value; return *this; } reference operator *() { - return static_cast(*p_node); + return *p_value; } const_reference operator *() const { - return static_cast(*p_node); + return *p_value; } pointer operator &() { - return static_cast(p_node); + return p_value; } const_pointer operator &() const { - return static_cast(p_node); + return p_value; } pointer operator ->() { - return static_cast(p_node); + return p_value; } const_pointer operator ->() const { - return static_cast(p_node); + return p_value; } friend bool operator == (const iterator& lhs, const iterator& rhs) { - return lhs.p_node == rhs.p_node; + return lhs.p_value == rhs.p_value; } friend bool operator != (const iterator& lhs, const iterator& rhs) @@ -212,8 +212,7 @@ namespace etl private: - node_t* p_node; - size_t index; + value_type* p_value; }; //************************************************************************* @@ -226,72 +225,64 @@ namespace etl friend class intrusive_forward_list; const_iterator() - : p_node(nullptr), - index(0) + : p_value(nullptr) { } - const_iterator(node_t& node, size_t index) - : p_node(&node), - index(index) + const_iterator(const value_type& value) + : p_value(&value) { } - const_iterator(const node_t& node, size_t index) - : p_node(&node), - index(index) - { - } - - const_iterator(const typename intrusive_forward_list::iterator& other) - : p_node(other.p_node), - index(other.index) + const_iterator(const typename intrusive_forward_list::iterator& other) + : p_value(other.p_value) { } const_iterator(const const_iterator& other) - : p_node(other.p_node), - index(other.index) + : p_value(other.p_value) { } const_iterator& operator ++() { - p_node = p_node->get_next(index); + // Read the appropriate 'ifll_next'. + p_value = static_cast(p_value->link_type::ifll_next); return *this; } const_iterator operator ++(int) { const_iterator temp(*this); - p_node = p_node->get_next(index); + // Read the appropriate 'ifll_next'. + p_value = static_cast(p_value->link_type::ifll_next); return temp; } const_iterator operator =(const const_iterator& other) { - p_node = other.p_node; + p_value = other.p_value; return *this; } const_reference operator *() const { - return static_cast(*p_node); + return *p_value; } const_pointer operator &() const { - return static_cast(p_node); + return p_value; } const_pointer operator ->() const { - return static_cast(p_node); + return p_value; } friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) { - return lhs.p_node == rhs.p_node; + return lhs.p_value == rhs.p_value; } friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) @@ -301,8 +292,7 @@ namespace etl private: - const node_t* p_node; - size_t index; + const value_type* p_value; }; typedef typename std::iterator_traits::difference_type difference_type; @@ -310,8 +300,7 @@ namespace etl //************************************************************************* /// Constructor. //************************************************************************* - intrusive_forward_list(size_t index) - : index(index) + intrusive_forward_list() { initialise(); } @@ -320,8 +309,7 @@ namespace etl /// Constructor from range //************************************************************************* template - intrusive_forward_list(size_t index, TIterator first, TIterator last) - : index(index) + intrusive_forward_list(TIterator first, TIterator last) { assign(first, last); } @@ -331,7 +319,7 @@ namespace etl //************************************************************************* iterator begin() { - return iterator(get_head(), index); + return iterator(static_cast(get_head())); } //************************************************************************* @@ -339,7 +327,7 @@ namespace etl //************************************************************************* const_iterator begin() const { - return const_iterator(get_head(), index); + return const_iterator(static_cast(get_head())); } //************************************************************************* @@ -347,7 +335,7 @@ namespace etl //************************************************************************* iterator before_begin() { - return iterator(start_node, index); + return iterator(static_cast(start_link)); } //************************************************************************* @@ -355,7 +343,7 @@ namespace etl //************************************************************************* const_iterator before_begin() const { - return const_iterator(start_node, index); + return const_iterator(static_cast(start_link)); } //************************************************************************* @@ -363,7 +351,7 @@ namespace etl //************************************************************************* const_iterator cbegin() const { - return const_iterator(get_head(), index); + return const_iterator(static_cast(get_head())); } //************************************************************************* @@ -403,7 +391,7 @@ namespace etl //************************************************************************* reference front() { - return static_cast(get_head()); + return static_cast(get_head()); } //************************************************************************* @@ -411,7 +399,7 @@ namespace etl //************************************************************************* const_reference front() const { - return get_head(); + return static_cast(get_head());; } //************************************************************************* @@ -428,15 +416,15 @@ namespace etl initialise(); - node_t* p_last_node = &start_node; + link_type* p_last_link = &start_link; // Add all of the elements. while (first != last) { - node_t& node = *first++; - join(p_last_node, &node); - join(&node, nullptr); - p_last_node = &node; + link_type& link = *first++; + join(p_last_link, &link); + join(&link, nullptr); + p_last_link = &link; ++current_size; } } @@ -444,9 +432,9 @@ namespace etl //************************************************************************* /// Pushes a value to the front of the intrusive_forward_list. //************************************************************************* - void push_front(node_t& value) + void push_front(link_type& value) { - insert_node_after(start_node, value); + insert_link_after(start_link, value); } //************************************************************************* @@ -457,7 +445,7 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!empty(), ETL_ERROR(intrusive_forward_list_empty)); #endif - remove_node_after(start_node); + remove_link_after(start_link); } //************************************************************************* @@ -470,29 +458,29 @@ namespace etl return; } - node_t* first = nullptr; // To keep first node - node_t* second = start_node.get_next(index); // To keep second node - node_t* track = start_node.get_next(index); // Track the list + link_type* first = nullptr; // To keep first link + link_type* second = start_link.ifll_next; // To keep second link + link_type* track = start_link.ifll_next; // Track the list while (track != NULL) { - track = track->get_next(index); // Track point to next node; - second->set_next(index, first); // Second node point to first - first = second; // Move first node to next - second = track; // Move second node to next + track = track->ifll_next; // Track point to next link; + second->ifll_next = first; // Second link point to first + first = second; // Move first link to next + second = track; // Move second link to next } - join(&start_node, first); + join(&start_link, first); } //************************************************************************* /// Inserts a value to the intrusive_forward_list after the specified position. //************************************************************************* - iterator insert_after(iterator position, node_t& value) + iterator insert_after(iterator position, value_type& value) { - insert_node_after(*position.p_node, value); + insert_link_after(*position.p_value, value); - return iterator(value, index); + return iterator(value); } //************************************************************************* @@ -503,8 +491,8 @@ namespace etl { while (first != last) { - // Set up the next free node. - insert_node_after(*position.p_node, *first++); + // Set up the next free link. + insert_link_after(*position.p_value, *first++); ++position; } } @@ -518,7 +506,7 @@ namespace etl ++next; ++next; - remove_node_after(*position.p_node); + remove_link_after(*position.p_value); return next; } @@ -528,9 +516,9 @@ namespace etl //************************************************************************* iterator erase_after(iterator first, iterator last) { - node_t* p_first = first.p_node; - node_t* p_last = last.p_node; - node_t* p_next = p_first->get_next(index); + link_type* p_first = first.p_value; + link_type* p_last = last.p_value; + link_type* p_next = p_first->ifll_next; // Join the ends. join(p_first, p_last); @@ -543,8 +531,8 @@ namespace etl // One less. --current_size; - p_next = p_first->get_next(index); // Remember the next node. - p_first = p_next; // Move to the next node. + p_next = p_first->ifll_next; // Remember the next link. + p_first = p_next; // Move to the next link. } if (p_next == nullptr) @@ -553,7 +541,7 @@ namespace etl } else { - return iterator(*p_last, index); + return iterator(*static_cast(p_last)); } } @@ -569,15 +557,15 @@ namespace etl return; } - node_t* last = &get_head(); - node_t* current = last->get_next(index); + link_type* last = &get_head(); + link_type* current = last->ifll_next; while (current != nullptr) { // Is this value the same as the last? - if (isEqual(static_cast(*current), static_cast(*last))) + if (isEqual(*static_cast(current), *static_cast(last))) { - remove_node_after(*last); + remove_link_after(*last); } else { @@ -585,7 +573,7 @@ namespace etl last = current; } - current = last->get_next(index); + current = last->ifll_next; } } @@ -594,7 +582,7 @@ namespace etl //************************************************************************* void sort() { - sort(std::less()); + sort(std::less()); } //************************************************************************* @@ -607,7 +595,7 @@ namespace etl { iterator i_left; iterator i_right; - iterator i_node; + iterator i_link; iterator i_head; iterator i_tail; int list_size = 1; @@ -653,50 +641,50 @@ namespace etl // Now we have two lists. Merge them. while (left_size > 0 || (right_size > 0 && i_right != end())) { - // Decide whether the next node of merge comes from left or right. + // Decide whether the next link of merge comes from left or right. if (left_size == 0) { - // Left is empty. The node must come from right. - i_node = 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 node must come from left. - i_node = 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 node of left is lower or same. The node must come from left. - i_node = 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 node of right is lower. The node must come from right. - i_node = 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 node to the merged head. + // Add the next link to the merged head. if (i_head == before_begin()) { - join(i_head.p_node, i_node.p_node); - i_head = i_node; - i_tail = i_node; + join(i_head.p_value, i_link.p_value); + i_head = i_link; + i_tail = i_link; } else { - join(i_tail.p_node, i_node.p_node); - i_tail = i_node; + join(i_tail.p_value, i_link.p_value); + i_tail = i_link; } - i_tail.p_node->set_next(index, nullptr); + i_tail.p_value->link_type::ifll_next = nullptr; } // Now left has stepped `list_size' places along, and right has too. @@ -717,14 +705,14 @@ namespace etl //************************************************************************* // Removes the values specified. //************************************************************************* - void remove(node_t& value) + void remove(const_reference value) { iterator i_item = begin(); iterator i_last_item = before_begin(); while (i_item != end()) { - if (static_cast(*i_item) == static_cast(value)) + if (*i_item == value) { i_item = erase_after(i_last_item); } @@ -777,16 +765,16 @@ namespace etl private: - node_t start_node; ///< The node that acts as the intrusive_forward_list start. - size_t current_size; ///< The number of elements in the list. - size_t index; ///< The index level of the node that this list operates on. + link_type start_link; ///< The link that acts as the intrusive_forward_list start. + size_t current_size; ///< The number of elements in the list. + size_t index; ///< The index level of the link that this list operates on. //************************************************************************* - /// Join two nodes. + /// Join two links. //************************************************************************* - void join(node_t* left, node_t* right) + void join(link_type* left, link_type* right) { - left->set_next(index, right); + left->ifll_next = right; } //************************************************************************* @@ -798,46 +786,46 @@ namespace etl } //************************************************************************* - /// Insert a node. + /// Insert a link. //************************************************************************* - void insert_node_after(node_t& position, node_t& node) + void insert_link_after(link_type& position, link_type& link) { // Connect to the intrusive_forward_list. - join(&node, position.get_next(index)); - join(&position, &node); + join(&link, position.ifll_next); + join(&position, &link); ++current_size; } //************************************************************************* - /// Remove a node. + /// Remove a link. //************************************************************************* - void remove_node_after(node_t& node) + void remove_link_after(link_type& link) { - // The node to erase. - node_t* p_node = node.get_next(index); + // The link to erase. + link_type* p_link = link.ifll_next; - if (p_node != nullptr) + if (p_link != nullptr) { - // Disconnect the node from the intrusive_forward_list. - join(&node, p_node->get_next(index)); + // Disconnect the link from the intrusive_forward_list. + join(&link, p_link->ifll_next); --current_size; } } //************************************************************************* - /// Get the head node. + /// Get the head link. //************************************************************************* - node_t& get_head() + link_type& get_head() { - return *start_node.get_next(index); + return *start_link.ifll_next; } //************************************************************************* - /// Get the head node. + /// Get the head link. //************************************************************************* - const node_t& get_head() const + const link_type& get_head() const { - return *start_node.get_next(index); + return *start_link.ifll_next; } //************************************************************************* @@ -845,7 +833,7 @@ namespace etl //************************************************************************* void initialise() { - start_node.set_next(index, nullptr); + start_link.ifll_next = nullptr; current_size = 0; } diff --git a/intrusive_forward_list_link.h b/intrusive_forward_list_link.h new file mode 100644 index 00000000..8d020450 --- /dev/null +++ b/intrusive_forward_list_link.h @@ -0,0 +1,49 @@ +///\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_INTRUSIVE_FORWARD_LIST_LINK__ +#define __ETL_INTRUSIVE_FORWARD_LIST_LINK__ + +#include "error_handler.h" +#include "array.h" + +namespace etl +{ + //*************************************************************************** + /// The link element in the intrusive_forward_list. + //*************************************************************************** + template + struct intrusive_forward_list_link + { + intrusive_forward_list_link* ifll_next; + }; +} + +#endif diff --git a/intrusive_forward_list_node.h b/intrusive_forward_list_node.h index 7c44c1a8..1d8d8ae7 100644 --- a/intrusive_forward_list_node.h +++ b/intrusive_forward_list_node.h @@ -36,58 +36,13 @@ SOFTWARE. namespace etl { - namespace __private_intrusive_forward_list__ - { - //*************************************************************************** - /// The node element in the intrusive_forward_list. - //*************************************************************************** - class intrusive_forward_list_node_base - { - public: - - virtual intrusive_forward_list_node_base* get_next(size_t index) const - { - return base_next; - } - - virtual void set_next(size_t index, intrusive_forward_list_node_base* pnext) - { - base_next = pnext; - } - - private: - - intrusive_forward_list_node_base* base_next; - }; - } - //*************************************************************************** /// The node element in the intrusive_forward_list. //*************************************************************************** - template - struct intrusive_forward_list_node : public __private_intrusive_forward_list__::intrusive_forward_list_node_base + template + struct intrusive_forward_list_node { - public: - - __private_intrusive_forward_list__::intrusive_forward_list_node_base* get_next(size_t index) const - { -#ifdef _DEBUG - ETL_ASSERT(index < SIZE, ETL_ERROR(intrusive_forward_list_index_exception)); -#endif - return next[index]; - } - - void set_next(size_t index, __private_intrusive_forward_list__::intrusive_forward_list_node_base* pnext) - { -#ifdef _DEBUG - ETL_ASSERT(index < SIZE, ETL_ERROR(intrusive_forward_list_index_exception)); -#endif - next[index] = pnext; - } - - private: - - etl::array<__private_intrusive_forward_list__::intrusive_forward_list_node_base*, SIZE> next; + intrusive_list_tag* ifln_next; }; } diff --git a/iunordered_map.h b/iunordered_map.h index a81828c8..4c94baa7 100644 --- a/iunordered_map.h +++ b/iunordered_map.h @@ -113,7 +113,7 @@ namespace etl /// Can be used as a reference type for all unordered_map containing a specific type. ///\ingroup unordered_map //*************************************************************************** - template , typename TKeyEqual = std::equal_to > + template , typename TKeyEqual = std::equal_to > class iunordered_map { public: @@ -130,7 +130,7 @@ namespace etl typedef const value_type* const_pointer; typedef size_t size_type; - + typedef typename parameter_type::type key_value_parameter_t; // The nodes that store the elements. @@ -151,7 +151,7 @@ namespace etl typedef etl::ivector bucket_list_t; typedef typename bucket_list_t::iterator bucket_list_iterator; - + public: // Local iterators iterate over one bucket. @@ -586,7 +586,7 @@ namespace etl //********************************************************************* size_type bucket(key_value_parameter_t key) const { - return hash_function(key) % pbuckets->size(); + return key_hash_function(key) % pbuckets->size(); } //********************************************************************* @@ -647,7 +647,9 @@ namespace etl } // Doesn't exist, so add a new one. - ibucket->insert_after(ibucket->before_begin(), node_t(value_type(key, T()))); + // Get a new node. + node_t& node = *pnodepool->allocate(node_t(value_type(key, T()))); + ibucket->insert_after(ibucket->before_begin(), node); return ibucket->begin().ref_cast().key_value_pair.second; } @@ -747,9 +749,9 @@ namespace etl } //********************************************************************* - // Inserts a value to the unordered_map. - // If asserts or exceptions are enabled, emits unordered_map_full if the unordered_map is already full. - //\param value The value to insert. + /// Inserts a value to the unordered_map. + /// If asserts or exceptions are enabled, emits unordered_map_full if the unordered_map is already full. + ///\param value The value to insert. //********************************************************************* std::pair insert(const value_type& key_value_pair) { @@ -1084,6 +1086,33 @@ namespace etl return pnodepool->available(); } + //************************************************************************* + /// Returns the load factor = size / bucket_count. + ///\return The load factor = size / bucket_count. + //************************************************************************* + float load_factor() const + { + return static_cast(size()) / static_cast(bucket_count()); + } + + //************************************************************************* + /// Returns the function that hashes the keys. + ///\return The function that hashes the keys.. + //************************************************************************* + hasher hash_function() const + { + return key_hash_function; + } + + //************************************************************************* + /// Returns the function that compares the keys. + ///\return The function that compares the keys.. + //************************************************************************* + key_equal key_eq() const + { + return key_equal_function; + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -1146,7 +1175,7 @@ namespace etl last = ibucket; } } - + // Disable copy construction. iunordered_map(const iunordered_map&); @@ -1161,7 +1190,7 @@ namespace etl bucket_list_iterator last; /// The function that creates the hashes. - hasher hash_function; + hasher key_hash_function; /// The function that compares the keys for equality. key_equal key_equal_function; diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index 3d47bf30..f22f7e44 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -127,6 +127,8 @@ + + @@ -162,6 +164,7 @@ + @@ -175,6 +178,7 @@ + @@ -217,6 +221,7 @@ + @@ -262,6 +267,7 @@ + diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 81dbdb02..f577a5cf 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -677,8 +677,6 @@ namespace compare_data.insert(compare_data.begin() + offset, insert_size, N14); data.insert(data.begin() + offset, insert_size, N14); - bool equal = std::equal(compare_data.begin(), compare_data.end(), data.begin()); - CHECK_EQUAL(compare_data.size(), data.size()); CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin())); } @@ -1482,7 +1480,7 @@ namespace TEST(test_iterator_comparison_empty) { DataNDC data; - + CHECK(data.begin() == data.end()); CHECK(data.cbegin() == data.cend()); CHECK(data.rbegin() == data.rend()); diff --git a/test/test_error_handler.cpp b/test/test_error_handler.cpp index f75a51f0..de3521a6 100644 --- a/test/test_error_handler.cpp +++ b/test/test_error_handler.cpp @@ -61,7 +61,7 @@ void receive_error(const etl::exception& e) std::ostringstream oss; oss << "Error '" << e.what() << "' in " << e.file_name() << " at line " << e.line_number() << "\n"; -#if defined(PLATFORM_WINDOWS) +#if defined(PLATFORM_WINDOWS) && defined(COMPILER_MICROSOFT) std::string stext = oss.str(); WCHAR text[200]; @@ -86,7 +86,7 @@ public: std::ostringstream oss; oss << "Error '" << e.what() << "' in " << e.file_name() << " at line " << e.line_number() << "\n"; -#if defined(PLATFORM_WINDOWS) +#if defined(PLATFORM_WINDOWS) && defined(COMPILER_MICROSOFT) std::string stext = oss.str(); WCHAR text[200]; diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 1f54828c..12d31974 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -601,5 +601,183 @@ namespace CHECK(are_equal); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_move) + { + CompareDataNDC compare_data(sorted_data.begin(), sorted_data.end()); + DataNDC data(sorted_data.begin(), sorted_data.end()); + + DataNDC::const_iterator i_from_before; + DataNDC::const_iterator i_to_before; + CompareDataNDC::const_iterator i_compare_from_before; + CompareDataNDC::const_iterator i_compare_to_before; + + // Move to the beginning. + i_from_before = data.begin(); + std::advance(i_from_before, 5); + + i_to_before = data.before_begin(); + + i_compare_from_before = compare_data.begin(); + std::advance(i_compare_from_before, 5); + + i_compare_to_before = compare_data.before_begin(); + + 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(are_equal); + + // Move to the end. + i_from_before = data.begin(); + std::advance(i_from_before, 5); + + i_to_before = data.begin(); + std::advance(i_to_before, 9); + + i_compare_from_before = compare_data.begin(); + std::advance(i_compare_from_before, 5); + + i_compare_to_before = compare_data.begin(); + std::advance(i_compare_to_before, 9); + + 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(are_equal); + + // Move to nearby. + i_from_before = data.begin(); + std::advance(i_from_before, 3); + + i_to_before = data.begin(); + std::advance(i_to_before, 7); + + i_compare_from_before = compare_data.begin(); + std::advance(i_compare_from_before, 3); + + i_compare_to_before = compare_data.begin(); + std::advance(i_compare_to_before, 7); + + 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(are_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_move_range) + { + CompareDataNDC compare_data(sorted_data.begin(), sorted_data.end()); + DataNDC data(sorted_data.begin(), sorted_data.end()); + + DataNDC::const_iterator i_first_before; + DataNDC::const_iterator i_last; + DataNDC::const_iterator i_to_before; + CompareDataNDC::const_iterator i_compare_first_before; + CompareDataNDC::const_iterator i_compare_last; + CompareDataNDC::const_iterator i_compare_to_before; + + // Move to the beginning. + i_first_before = data.begin(); + std::advance(i_first_before, 4); + + i_last = i_first_before; + std::advance(i_last, 4); + + i_to_before = data.before_begin(); + + i_compare_first_before = compare_data.begin(); + std::advance(i_compare_first_before, 4); + + i_compare_last = i_compare_first_before; + std::advance(i_compare_last, 4); + + i_compare_to_before = compare_data.before_begin(); + + 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(are_equal); + + // Move to the end. + i_first_before = data.begin(); + std::advance(i_first_before, 4); + + i_last = i_first_before; + std::advance(i_last, 4); + + i_to_before = data.begin(); + std::advance(i_to_before, 9); + + i_compare_first_before = compare_data.begin(); + std::advance(i_compare_first_before, 4); + + i_compare_last = i_compare_first_before; + std::advance(i_compare_last, 4); + + i_compare_to_before = compare_data.begin(); + std::advance(i_compare_to_before, 9); + + 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); + + //DataNDC::const_iterator id = data.begin(); + //CompareDataNDC::const_iterator ic = compare_data.begin(); + + //ItemNDC d; + //ItemNDC c; + + //while (ic != compare_data.end()) + //{ + // d = *id++; + // c = *ic++; + //} + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + + // Move to nearby. + i_first_before = data.begin(); + std::advance(i_first_before, 4); + + i_last = i_first_before; + std::advance(i_last, 4); + + i_to_before = data.begin(); + std::advance(i_to_before, 2); + + i_compare_first_before = compare_data.begin(); + std::advance(i_compare_first_before, 4); + + i_compare_last = i_compare_first_before; + std::advance(i_compare_last, 4); + + i_compare_to_before = compare_data.begin(); + std::advance(i_compare_to_before, 2); + + 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()); + + // Move to illegal place. + i_first_before = data.begin(); + std::advance(i_first_before, 2); + i_last = i_first_before; + std::advance(i_last, 3); + i_to_before = i_first_before; + std::advance(i_to_before, 2); + + CHECK_THROW(data.move_after(i_first_before, i_last, i_to_before), etl::forward_list_iterator); + } }; } diff --git a/test/test_intrusive_forward_list.cpp b/test/test_intrusive_forward_list.cpp index 82ec2a6a..68518ffb 100644 --- a/test/test_intrusive_forward_list.cpp +++ b/test/test_intrusive_forward_list.cpp @@ -42,9 +42,14 @@ SOFTWARE. typedef TestDataDC ItemDC; typedef TestDataNDC ItemNDC; + namespace { - class ItemDCNode : public etl::intrusive_forward_list_node<2> + typedef etl::intrusive_forward_list_link<0> FirstLink; + typedef etl::intrusive_forward_list_link<1> SecondLink; + + //*************************************************************************** + class ItemDCNode : public FirstLink, public SecondLink { public: @@ -56,9 +61,8 @@ namespace ItemDC data; }; - const size_t INDEXES = 2; - - class ItemNDCNode : public etl::intrusive_forward_list_node + //*************************************************************************** + class ItemNDCNode : public FirstLink, public SecondLink { public: @@ -75,6 +79,7 @@ namespace ItemNDC data; }; + //*************************************************************************** bool operator ==(const ItemDCNode& lhs, const ItemDCNode& rhs) { return lhs.data == rhs.data; @@ -85,12 +90,23 @@ namespace 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; + } + std::ostream& operator << (std::ostream& os, const ItemNDCNode& node) { os << node.data; return os; } + //*************************************************************************** struct CompareItemNDCNode { bool operator ()(const ItemNDCNode& lhs, const ItemNDCNode& rhs) const @@ -106,17 +122,39 @@ namespace return lhs.data == rhs.data; } }; + + //*************************************************************************** + typedef etl::intrusive_forward_list DataDC0; + typedef etl::intrusive_forward_list DataDC1; + typedef etl::intrusive_forward_list DataNDC0; + typedef etl::intrusive_forward_list DataNDC1; + + typedef std::vector InitialDataNDC; + + template + bool Equal(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2) + { + while (begin1 != end1) + { + if (*begin1 != *begin2) + { + return false; + } + + ++begin1; + ++begin2; + } + + return true; + } } namespace { SUITE(test_forward_list) { - typedef etl::intrusive_forward_list DataDC; - typedef etl::intrusive_forward_list DataNDC; - - typedef std::vector InitialDataNDC; - InitialDataNDC unsorted_data; InitialDataNDC sorted_data; InitialDataNDC non_unique_data; @@ -141,8 +179,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_default_constructor) { - DataNDC data0(0); - DataNDC data1(1); + DataNDC0 data0; + DataNDC1 data1; CHECK(data0.empty()); CHECK(data1.empty()); @@ -151,7 +189,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_constructor_range) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); CHECK(!data0.empty()); CHECK_EQUAL(sorted_data.size(), data0.size()); @@ -160,7 +198,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_iterator) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin()); @@ -170,7 +208,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_const_iterator) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); are_equal = std::equal(data0.cbegin(), data0.cend(), sorted_data.begin()); @@ -180,7 +218,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_clear) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); data0.clear(); CHECK(data0.empty()); @@ -189,7 +227,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range) { - DataNDC data0(0); + DataNDC0 data0; // Do it twice. We should only get one copy. data0.assign(sorted_data.begin(), sorted_data.end()); @@ -203,8 +241,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range_two_lists_same) { - DataNDC data0(0); - DataNDC data1(1); + DataNDC0 data0; + DataNDC0 data1; data0.assign(sorted_data.begin(), sorted_data.end()); data1.assign(sorted_data.begin(), sorted_data.end()); @@ -216,14 +254,14 @@ namespace CHECK(are_equal); } - //************************************************************************* + ////************************************************************************* TEST_FIXTURE(SetupFixture, test_two_lists_different) { std::list compare0; std::list compare1; - DataNDC data0(0); - DataNDC data1(1); + DataNDC0 data0; + DataNDC1 data1; ItemNDCNode node0("0"); ItemNDCNode node1("1"); @@ -280,12 +318,12 @@ namespace ItemNDCNode INSERT_VALUE2 = ItemNDCNode("2"); std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); size_t offset = 2; - DataNDC::iterator i_data = data0.begin(); + DataNDC0::iterator i_data = data0.begin(); std::advance(i_data, offset); std::vector::iterator i_compare_data = compare_data.begin(); @@ -338,8 +376,8 @@ namespace std::vector compare(test2); compare.insert(compare.end(), test1.begin(), test1.end()); - DataNDC data0(0, test1.begin(), test1.end()); - DataNDC data1(1, test1.begin(), test1.end()); + DataNDC0 data0(test1.begin(), test1.end()); + DataNDC1 data1(test1.begin(), test1.end()); data0.insert_after(data0.before_begin(), test2.begin(), test2.end()); @@ -355,7 +393,7 @@ namespace data0.assign(test1.begin(), test1.end()); std::vector::iterator icd = compare.begin(); - DataNDC::iterator id = data0.begin(); + DataNDC0::iterator id = data0.begin(); std::advance(icd, 4); std::advance(id, 3); @@ -378,7 +416,7 @@ namespace TEST_FIXTURE(SetupFixture, test_push_front) { std::list compare_data; - DataNDC data0(0); + DataNDC0 data0; ItemNDCNode node1("1"); ItemNDCNode node2("2"); @@ -410,8 +448,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_pop_front) { - DataNDC data0(0); - DataNDC data1(1); + DataNDC0 data0; + DataNDC1 data1; ItemNDCNode node1("1"); ItemNDCNode node2("2"); @@ -463,10 +501,10 @@ namespace TEST_FIXTURE(SetupFixture, test_erase_after_single) { std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); - DataNDC::iterator i_data = data0.begin(); + DataNDC0::iterator i_data = data0.begin(); std::advance(i_data, 2); std::vector::iterator i_compare_data = compare_data.begin(); @@ -523,13 +561,13 @@ namespace TEST_FIXTURE(SetupFixture, test_erase_after_range) { std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); - DataNDC::iterator i_data_1 = data0.begin(); + DataNDC0::iterator i_data_1 = data0.begin(); std::advance(i_data_1, 2); - DataNDC::iterator i_data_2 = data0.begin(); + DataNDC0::iterator i_data_2 = data0.begin(); std::advance(i_data_2, 4); std::vector::iterator i_compare_data_1 = compare_data.begin(); @@ -540,7 +578,7 @@ namespace std::vector::iterator i_compare_result = compare_data.erase(i_compare_data_1, i_compare_data_2); - DataNDC::iterator i_result = data0.erase_after(i_data_1, i_data_2); + DataNDC0::iterator i_result = data0.erase_after(i_data_1, i_data_2); CHECK_EQUAL(*i_compare_result, *i_result); @@ -559,10 +597,10 @@ namespace TEST_FIXTURE(SetupFixture, test_erase_after_range_end) { std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); - DataNDC::iterator i_data = data0.begin(); + DataNDC0::iterator i_data = data0.begin(); std::advance(i_data, 4); std::vector::iterator i_compare_data = compare_data.begin(); @@ -570,7 +608,7 @@ namespace std::vector::iterator i_compare_result = compare_data.erase(i_compare_data, compare_data.end()); - DataNDC::iterator i_result = data0.erase_after(i_data, data0.end()); + DataNDC0::iterator i_result = data0.erase_after(i_data, data0.end()); CHECK(i_result == data0.end()); @@ -588,7 +626,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_erase_after_all) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); data0.erase_after(data0.before_begin(), data0.end()); @@ -598,7 +636,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_front) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); CHECK_EQUAL(sorted_data.front(), data0.front()); } @@ -606,8 +644,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_unique) { - DataNDC data0(0, non_unique_data.begin(), non_unique_data.end()); - DataNDC data1(1, non_unique_data.begin(), non_unique_data.end()); + DataNDC0 data0(non_unique_data.begin(), non_unique_data.end()); + DataNDC1 data1(non_unique_data.begin(), non_unique_data.end()); data0.unique(EqualItemNDCNode()); @@ -628,8 +666,8 @@ namespace TEST_FIXTURE(SetupFixture, test_remove) { std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); std::vector::iterator i_item = std::find(compare_data.begin(), compare_data.end(), ItemNDCNode("7")); compare_data.erase(i_item); @@ -651,8 +689,8 @@ namespace TEST_FIXTURE(SetupFixture, test_remove_if) { std::vector compare_data(sorted_data.begin(), sorted_data.end()); - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); std::vector::iterator i_item = std::find(compare_data.begin(), compare_data.end(), ItemNDCNode("7")); compare_data.erase(i_item); @@ -673,8 +711,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_reverse) { - DataNDC data0(0, sorted_data.begin(), sorted_data.end()); - DataNDC data1(1, sorted_data.begin(), sorted_data.end()); + DataNDC0 data0(sorted_data.begin(), sorted_data.end()); + DataNDC1 data1(sorted_data.begin(), sorted_data.end()); data0.reverse(); // Just reverse one of them. @@ -688,8 +726,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_sort) { - DataNDC data0(0, unsorted_data.begin(), unsorted_data.end()); - DataNDC data1(1, unsorted_data.begin(), unsorted_data.end()); + DataNDC0 data0(unsorted_data.begin(), unsorted_data.end()); + DataNDC1 data1(unsorted_data.begin(), unsorted_data.end()); data0.sort(); // Just sort one of them. @@ -703,8 +741,8 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_sort_compare) { - DataNDC data0(0, unsorted_data.begin(), unsorted_data.end()); - DataNDC data1(1, unsorted_data.begin(), unsorted_data.end()); + DataNDC0 data0(unsorted_data.begin(), unsorted_data.end()); + DataNDC1 data1(unsorted_data.begin(), unsorted_data.end()); data0.sort(CompareItemNDCNode()); // Just sort one of them. diff --git a/test/test_list.cpp b/test/test_list.cpp index b1614386..d3825c82 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -38,8 +38,8 @@ SOFTWARE. #include #include -namespace -{ +namespace +{ SUITE(test_list) { typedef TestDataDC ItemDC; @@ -136,6 +136,7 @@ namespace TEST_FIXTURE(SetupFixture, test_copy_constructor) { CompareData compare_data(sorted_data.begin(), sorted_data.end()); + DataNDC data(sorted_data.begin(), sorted_data.end()); DataNDC other_data(data); @@ -427,7 +428,7 @@ namespace //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_excess) - { + { DataNDC data; CHECK_NO_THROW(data.push_front(ItemNDC("1"))); @@ -454,7 +455,7 @@ namespace CHECK_NO_THROW(data.push_front(ItemNDC("1"))); data.pop_front(); } - + CHECK(data.empty()); } @@ -482,7 +483,7 @@ namespace CHECK_NO_THROW(data.push_front(ItemNDC("1"))); data.pop_front(); } - + CHECK(data.empty()); } @@ -496,7 +497,7 @@ namespace CHECK_NO_THROW(data.push_front(ItemNDC("1"))); data.pop_back(); } - + CHECK(data.empty()); } @@ -524,7 +525,7 @@ namespace CHECK(are_equal); } - + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_excess) { @@ -805,5 +806,159 @@ namespace CHECK(are_equal); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_move) + { + CompareData compare_data(unsorted_data.begin(), unsorted_data.end()); + DataNDC data(unsorted_data.begin(), unsorted_data.end()); + + CompareData::iterator compare_from; + CompareData::iterator compare_to; + + DataNDC::const_iterator from; + DataNDC::const_iterator to; + + // Move to the beginning. + compare_from = compare_data.begin(); + std::advance(compare_from, 4); + compare_to = compare_data.begin(); + compare_data.splice(compare_to, compare_data, compare_from); + + from = data.begin(); + std::advance(from, 4); + to = data.begin(); + data.move(from, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move to the end. + compare_from = compare_data.begin(); + std::advance(compare_from, 4); + compare_to = compare_data.end(); + compare_data.splice(compare_to, compare_data, compare_from); + + from = data.begin(); + std::advance(from, 4); + to = data.end(); + data.move(from, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move nearby. + compare_from = compare_data.begin(); + std::advance(compare_from, 4); + compare_to = compare_data.begin(); + std::advance(compare_to, 6); + compare_data.splice(compare_to, compare_data, compare_from); + + from = data.begin(); + std::advance(from, 4); + to = data.begin(); + std::advance(to, 6); + data.move(from, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move to same place. + compare_from = compare_data.begin(); + std::advance(compare_from, 4); + compare_to = compare_data.begin(); + std::advance(compare_to, 4); + compare_data.splice(compare_to, compare_data, compare_from); + + from = data.begin(); + std::advance(from, 4); + to = data.begin(); + std::advance(to, 4); + data.move(from, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_move_range) + { + CompareData compare_data(unsorted_data.begin(), unsorted_data.end()); + DataNDC data(unsorted_data.begin(), unsorted_data.end()); + + CompareData::iterator compare_begin; + CompareData::iterator compare_end; + CompareData::iterator compare_to; + + DataNDC::const_iterator begin; + DataNDC::const_iterator end; + DataNDC::const_iterator to; + + // Move to the beginning. + compare_begin = compare_data.begin(); + std::advance(compare_begin, 3); + compare_end = compare_begin; + std::advance(compare_end, 3); + compare_to = compare_data.begin(); + compare_data.splice(compare_to, compare_data, compare_begin, compare_end); + + begin = data.begin(); + std::advance(begin, 3); + end = begin; + std::advance(end, 3); + to = data.begin(); + data.move(begin, end, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move to the end. + compare_begin = compare_data.begin(); + std::advance(compare_begin, 3); + compare_end = compare_begin; + std::advance(compare_end, 3); + compare_to = compare_data.end(); + compare_data.splice(compare_to, compare_data, compare_begin, compare_end); + + begin = data.begin(); + std::advance(begin, 3); + end = begin; + std::advance(end, 3); + to = data.end(); + data.move(begin, end, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move nearby. + compare_begin = compare_data.begin(); + std::advance(compare_begin, 2); + compare_end = compare_begin; + std::advance(compare_end, 3); + compare_to = compare_data.begin(); + std::advance(compare_to, 7); + compare_data.splice(compare_to, compare_data, compare_begin, compare_end); + + begin = data.begin(); + std::advance(begin, 2); + end = begin; + std::advance(end, 3); + to = data.begin(); + std::advance(to, 7); + data.move(begin, end, to); + + are_equal = std::equal(data.begin(), data.end(), compare_data.begin()); + CHECK(are_equal); + + // Move to illegal place. + begin = data.begin(); + std::advance(begin, 2); + end = begin; + std::advance(end, 3); + to = data.begin(); + std::advance(to, 4); + + CHECK_THROW(data.move(begin, end, to), etl::list_iterator); + } }; } diff --git a/test/test_pool.cpp b/test/test_pool.cpp index 42638eb3..f2ae63d6 100644 --- a/test/test_pool.cpp +++ b/test/test_pool.cpp @@ -109,14 +109,14 @@ namespace // Allocated p1, p4 - CHECK_EQUAL(2, pool.available()); + CHECK_EQUAL(2U, pool.available()); Test_Data* p5 = pool.allocate(); Test_Data* p6 = pool.allocate(); // Allocated p1, p4, p5, p6 - CHECK_EQUAL(0, pool.available()); + CHECK_EQUAL(0U, pool.available()); CHECK(p5 != p1); CHECK(p5 != p4); @@ -128,7 +128,7 @@ namespace // Allocated p1, p4, p6 - CHECK_EQUAL(1, pool.available()); + CHECK_EQUAL(1U, pool.available()); Test_Data* p7 = pool.allocate(); @@ -150,16 +150,16 @@ namespace Test_Data* p; p = pool.allocate(); - CHECK_EQUAL(3, pool.available()); + CHECK_EQUAL(3U, pool.available()); p = pool.allocate(); - CHECK_EQUAL(2, pool.available()); + CHECK_EQUAL(2U, pool.available()); p = pool.allocate(); - CHECK_EQUAL(1, pool.available()); + CHECK_EQUAL(1U, pool.available()); p = pool.allocate(); - CHECK_EQUAL(0, pool.available()); + CHECK_EQUAL(0U, pool.available()); } //************************************************************************* @@ -167,28 +167,28 @@ namespace { etl::pool pool; - CHECK(pool.max_size() == 4); + CHECK(pool.max_size() == 4U); } //************************************************************************* TEST(test_size) { etl::pool pool; - CHECK_EQUAL(0, pool.size()); + CHECK_EQUAL(0U, pool.size()); Test_Data* p; p = pool.allocate(); - CHECK_EQUAL(1, pool.size()); + CHECK_EQUAL(1U, pool.size()); p = pool.allocate(); - CHECK_EQUAL(2, pool.size()); + CHECK_EQUAL(2U, pool.size()); p = pool.allocate(); - CHECK_EQUAL(3, pool.size()); + CHECK_EQUAL(3U, pool.size()); p = pool.allocate(); - CHECK_EQUAL(4, pool.size()); + CHECK_EQUAL(4U, pool.size()); } //************************************************************************* diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 00bf0a4d..896668db 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -199,10 +199,10 @@ namespace etl::queue queue; queue.push() = 1; - CHECK_EQUAL(1, queue.size()); + CHECK_EQUAL(1U, queue.size()); queue.push() = 2; - CHECK_EQUAL(2, queue.size()); + CHECK_EQUAL(2U, queue.size()); CHECK_EQUAL(1, queue.front()); @@ -297,7 +297,7 @@ namespace queue.push(1); queue.push(2); queue.pop(); - CHECK_EQUAL(1, queue.size()); + CHECK_EQUAL(1U, queue.size()); } //************************************************************************* diff --git a/test/test_unordered_map.cpp b/test/test_unordered_map.cpp index eec97746..f6246a4b 100644 --- a/test/test_unordered_map.cpp +++ b/test/test_unordered_map.cpp @@ -125,7 +125,7 @@ namespace const char* K17 = "FW"; // 7 const char* K18 = "FX"; // 8 const char* K19 = "FY"; // 9 - + 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; @@ -361,14 +361,14 @@ namespace TEST_FIXTURE(SetupFixture, test_insert_value) { DataNDC data; - + data.insert(DataNDC::value_type(K0, N0)); // Inserted data.insert(DataNDC::value_type(K2, N2)); // Inserted data.insert(DataNDC::value_type(K1, N1)); // Inserted data.insert(DataNDC::value_type(K11, N1)); // Duplicate hash. Inserted data.insert(DataNDC::value_type(K1, N3)); // Duplicate key. Not inserted - CHECK_EQUAL(4, data.size()); + CHECK_EQUAL(4U, data.size()); DataNDC::iterator idata; @@ -376,7 +376,7 @@ namespace CHECK(idata != data.end()); CHECK(idata->first == K0); CHECK(idata->second == N0); - + idata = data.find(K1); CHECK(idata != data.end()); CHECK(idata->first == K1); @@ -541,5 +541,41 @@ namespace CHECK(initial1 != different); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_hash_function) + { + DataNDC data; + DataNDC::hasher hash_function = data.hash_function(); + + CHECK_EQUAL(simple_hash()(std::string("ABCDEF")), hash_function(std::string("ABCDEF"))); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_key_eq_function) + { + DataNDC data; + DataNDC::key_equal key_eq = data.key_eq(); + + CHECK(key_eq(std::string("ABCDEF"), std::string("ABCDEF"))); + CHECK(!key_eq(std::string("ABCDEF"), std::string("ABCDEG"))); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_load_factor) + { + // Empty. + DataNDC data; + 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); + + // All of the buckets used. + data.clear(); + data.assign(initial_data.begin(), initial_data.end()); + CHECK_CLOSE(1.0, data.load_factor(), 0.01); + } }; } diff --git a/test/vs2015/etl.sln b/test/vs2015/etl.sln index 45f74e08..476a5ddc 100644 --- a/test/vs2015/etl.sln +++ b/test/vs2015/etl.sln @@ -7,13 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "etl", "etl.vcxproj", "{C21D EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug No Uint Tests|Win32 = Debug No Unit Tests|Win32 Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug No Unit Tests|Win32.ActiveCfg = Debug No Unit Tests|Win32 - {C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug No Unit Tests|Win32.Build.0 = Debug No Unit Tests|Win32 {C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.ActiveCfg = Debug|Win32 {C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Debug|Win32.Build.0 = Debug|Win32 {C21DF78C-D8E0-46AB-9D6F-D38A3C1CB0FB}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/test/vs2015/etl.vcxproj b/test/vs2015/etl.vcxproj index 40063922..f798f135 100644 --- a/test/vs2015/etl.vcxproj +++ b/test/vs2015/etl.vcxproj @@ -190,6 +190,7 @@ + @@ -222,7 +223,9 @@ - + + true + diff --git a/test/vs2015/etl.vcxproj.filters b/test/vs2015/etl.vcxproj.filters index 6dd59bb2..bb93b7ec 100644 --- a/test/vs2015/etl.vcxproj.filters +++ b/test/vs2015/etl.vcxproj.filters @@ -360,30 +360,12 @@ ETL\Containers - - ETL\Maths - - - ETL\Maths - - - ETL\Maths - ETL\Maths - - ETL\Maths - - - ETL\Maths - ETL\Maths - - ETL\Maths - Source Files @@ -468,6 +450,27 @@ ETL\Utilities + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers + + + ETL\Containers +