mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
fix missing const for etl:map
This commit is contained in:
parent
f7d1a679f4
commit
2a0ea093bd
528
imap.h
528
imap.h
@ -58,7 +58,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<TKey, TMapped> value_type;
|
||||
typedef std::pair<const TKey, TMapped> value_type;
|
||||
typedef TKey key_type;
|
||||
typedef TMapped mapped_type;
|
||||
typedef TKeyCompare key_compare;
|
||||
@ -91,6 +91,9 @@ namespace etl
|
||||
};
|
||||
|
||||
protected:
|
||||
static const int8_t kLeft = 0;
|
||||
static const int8_t kRight = 1;
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the map.
|
||||
//*************************************************************************
|
||||
@ -100,31 +103,19 @@ namespace etl
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node()
|
||||
: left(nullptr)
|
||||
, right(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Determines if the node is a leaf.
|
||||
//***********************************************************************
|
||||
bool is_leaf() const
|
||||
{
|
||||
return left == nullptr && right == nullptr;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Marks the node as a leaf.
|
||||
//***********************************************************************
|
||||
void mark_as_leaf()
|
||||
{
|
||||
left = nullptr;
|
||||
right = nullptr;
|
||||
children[0] = nullptr;
|
||||
children[1] = nullptr;
|
||||
}
|
||||
|
||||
|
||||
Node* left;
|
||||
Node* right;
|
||||
Node* children[2];
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
@ -451,7 +442,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(*this, lower_node(root_node));
|
||||
return iterator(*this, find_limit_node(root_node, kLeft));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -459,7 +450,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(*this, lower_node(root_node));
|
||||
return const_iterator(*this, find_limit_node(root_node, kLeft));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -483,7 +474,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(*this, lower_node(root_node));
|
||||
return const_iterator(*this, find_limit_node(root_node, kLeft));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -515,7 +506,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(iterator(*this, lower_node(root_node)));
|
||||
return reverse_iterator(iterator(*this, find_limit_node(root_node, kLeft)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -523,7 +514,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(iterator(*this, lower_node(root_node)));
|
||||
return const_reverse_iterator(iterator(*this, find_limit_node(root_node, kLeft)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -539,7 +530,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return const_reverse_iterator(const_iterator(*this, lower_node(root_node)));
|
||||
return const_reverse_iterator(const_iterator(*this, find_limit_node(root_node, kLeft)));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
@ -647,8 +638,8 @@ namespace etl
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key)
|
||||
{
|
||||
return std::make_pair<iterator, iterator>(
|
||||
iterator(*this, lower_node(root_node, key)),
|
||||
iterator(*this, upper_node(root_node, key)));
|
||||
iterator(*this, find_lower_node(root_node, key)),
|
||||
iterator(*this, find_upper_node(root_node, key)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -658,8 +649,8 @@ namespace etl
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
|
||||
{
|
||||
return std::make_pair<const_iterator, const_iterator>(
|
||||
const_iterator(*this, lower_node(root_node, key)),
|
||||
const_iterator(*this, upper_node(root_node, key)));
|
||||
const_iterator(*this, find_lower_node(root_node, key)),
|
||||
const_iterator(*this, find_upper_node(root_node, key)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -677,13 +668,11 @@ namespace etl
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
// Find the parent node to be removed
|
||||
Node* found_parent = find_parent_node(root_node, position.p_node);
|
||||
iterator next(*this, found_parent->left == position.p_node ?
|
||||
found_parent->left : found_parent->right);
|
||||
Node*& reference_node = find_node(root_node, position.p_node);
|
||||
iterator next(*this, reference_node);
|
||||
++next;
|
||||
|
||||
remove_node(found_parent->left == position.p_node ?
|
||||
found_parent->left : found_parent->right, position->first);
|
||||
remove_node(reference_node, position->first);
|
||||
|
||||
return next;
|
||||
}
|
||||
@ -702,12 +691,13 @@ namespace etl
|
||||
//*************************************************************************
|
||||
iterator erase(iterator first, iterator last)
|
||||
{
|
||||
iterator next;
|
||||
while (first != last)
|
||||
{
|
||||
erase(first++);
|
||||
next = erase(const_iterator(first++));
|
||||
}
|
||||
|
||||
return last;
|
||||
return next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -865,7 +855,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator lower_bound(const key_value_parameter_t key)
|
||||
{
|
||||
return iterator(*this, lower_node(root_node, key));
|
||||
return iterator(*this, find_lower_node(root_node, key));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
@ -876,7 +866,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator lower_bound(const key_value_parameter_t key) const
|
||||
{
|
||||
return const_iterator(*this, lower_node(root_node, key));
|
||||
return const_iterator(*this, find_lower_node(root_node, key));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
@ -887,7 +877,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator upper_bound(const key_value_parameter_t key)
|
||||
{
|
||||
return iterator(*this, upper_node(root_node, key));
|
||||
return iterator(*this, find_upper_node(root_node, key));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
@ -898,7 +888,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator upper_bound(const key_value_parameter_t key) const
|
||||
{
|
||||
return const_iterator(*this, upper_node(root_node, key));
|
||||
return const_iterator(*this, find_upper_node(root_node, key));
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -973,46 +963,46 @@ namespace etl
|
||||
Node* swap_node = nullptr;
|
||||
|
||||
// Found the node to be removed, does it have other nodes on the left?
|
||||
if (position->left)
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Find the upper node and its parent from the left of the current position
|
||||
Node* upper_parent_node = position;
|
||||
Node* upper_node = position->left;
|
||||
while (upper_node && upper_node->right)
|
||||
Node* upper_node = position->children[kLeft];
|
||||
while (upper_node && upper_node->children[kRight])
|
||||
{
|
||||
upper_parent_node = upper_node;
|
||||
upper_node = upper_node->right;
|
||||
upper_node = upper_node->children[kRight];
|
||||
}
|
||||
|
||||
// Recursively call detach_node for the upper node found above
|
||||
swap_node = detach_node(upper_parent_node->left == upper_node ?
|
||||
upper_parent_node->left : upper_parent_node->right);
|
||||
swap_node = detach_node(upper_parent_node->children[kLeft] == upper_node ?
|
||||
upper_parent_node->children[kLeft] : upper_parent_node->children[kRight]);
|
||||
}
|
||||
// Found the node to be removed, does it have other nodes on the right?
|
||||
else if (position->right)
|
||||
else if (position->children[kRight])
|
||||
{
|
||||
// Find the lower node and its parent from the right of the current position
|
||||
Node* lower_parent_node = position;
|
||||
Node* lower_node = position->right;
|
||||
while (lower_node && lower_node->left)
|
||||
Node* lower_node = position->children[kRight];
|
||||
while (lower_node && lower_node->children[kLeft])
|
||||
{
|
||||
lower_parent_node = lower_node;
|
||||
lower_node = lower_node->left;
|
||||
lower_node = lower_node->children[kLeft];
|
||||
}
|
||||
// Cast lower node into a data node to retrieve the key value
|
||||
Data_Node* lower_data_node = imap::data_cast(lower_node);
|
||||
|
||||
// Recursively call detach_node for the lower node found
|
||||
swap_node = detach_node(lower_parent_node->left == lower_node ?
|
||||
lower_parent_node->left : lower_parent_node->right);
|
||||
swap_node = detach_node(lower_parent_node->children[kLeft] == lower_node ?
|
||||
lower_parent_node->children[kLeft] : lower_parent_node->children[kRight]);
|
||||
}
|
||||
|
||||
// If a swap node was provided above, update its child trees
|
||||
if (swap_node)
|
||||
{
|
||||
// Move children of position as new children of swap node
|
||||
swap_node->left = position->left;
|
||||
swap_node->right = position->right;
|
||||
swap_node->children[kLeft] = position->children[kLeft];
|
||||
swap_node->children[kRight] = position->children[kRight];
|
||||
}
|
||||
|
||||
// Update current position to point to swap node
|
||||
@ -1037,12 +1027,12 @@ namespace etl
|
||||
if (node_comp(key, found_data_node))
|
||||
{
|
||||
// Keep searching for the node on the left
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
}
|
||||
else if (node_comp(found_data_node, key))
|
||||
{
|
||||
// Keep searching for the node on the right
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1070,12 +1060,12 @@ namespace etl
|
||||
if (node_comp(key, found_data_node))
|
||||
{
|
||||
// Keep searching for the node on the left
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
}
|
||||
else if (node_comp(found_data_node, key))
|
||||
{
|
||||
// Keep searching for the node on the right
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1096,13 +1086,13 @@ namespace etl
|
||||
Node* found = position;
|
||||
while (found)
|
||||
{
|
||||
if (found->left == node)
|
||||
if (found->children[kLeft] == node)
|
||||
{
|
||||
return found->left;
|
||||
return found->children[kLeft];
|
||||
}
|
||||
else if (found->right == node)
|
||||
else if (found->children[kRight] == node)
|
||||
{
|
||||
return found->right;
|
||||
return found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1114,23 +1104,57 @@ namespace etl
|
||||
if (node_comp(data_node, found_data_node))
|
||||
{
|
||||
// Keep searching for the node on the left
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
}
|
||||
else if (node_comp(found_data_node, data_node))
|
||||
{
|
||||
// Keep searching for the node on the right
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Exit loop if duplicate was found
|
||||
break;
|
||||
// Return position provided (it matches the node)
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the initial position provided if node not found
|
||||
return position;
|
||||
// Return root node if nothing or duplicate was found
|
||||
return root_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* find_limit_node(Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
const Node* find_limit_node(const Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -1148,7 +1172,8 @@ namespace etl
|
||||
while (position)
|
||||
{
|
||||
// Is this position not the parent of the node we are looking for?
|
||||
if (position->left != node && position->right != node)
|
||||
if (position->children[kLeft] != node &&
|
||||
position->children[kRight] != node)
|
||||
{
|
||||
// Downcast node and position to Data_Node references for key comparisons
|
||||
const Data_Node& node_data_node = imap::data_cast(*node);
|
||||
@ -1157,12 +1182,12 @@ namespace etl
|
||||
if (node_comp(node_data_node, position_data_node))
|
||||
{
|
||||
// Keep looking for parent on the left
|
||||
position = position->left;
|
||||
position = position->children[kLeft];
|
||||
}
|
||||
else if (node_comp(position_data_node, node_data_node))
|
||||
{
|
||||
// Keep looking for parent on the right
|
||||
position = position->right;
|
||||
position = position->children[kRight];
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1195,7 +1220,8 @@ namespace etl
|
||||
while (position)
|
||||
{
|
||||
// Is this position not the parent of the node we are looking for?
|
||||
if (position->left != node && position->right != node)
|
||||
if (position->children[kLeft] != node &&
|
||||
position->children[kRight] != node)
|
||||
{
|
||||
// Downcast node and position to Data_Node references for key comparisons
|
||||
const Data_Node& node_data_node = imap::data_cast(*node);
|
||||
@ -1204,12 +1230,12 @@ namespace etl
|
||||
if (node_comp(node_data_node, position_data_node))
|
||||
{
|
||||
// Keep looking for parent on the left
|
||||
position = position->left;
|
||||
position = position->children[kLeft];
|
||||
}
|
||||
else if (node_comp(position_data_node, node_data_node))
|
||||
{
|
||||
// Keep looking for parent on the right
|
||||
position = position->right;
|
||||
position = position->children[kRight];
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1227,6 +1253,142 @@ namespace etl
|
||||
return found;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is not considered to go before the key provided
|
||||
//*************************************************************************
|
||||
Node* find_lower_node(Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position? keep going
|
||||
Node* lower_node = position;
|
||||
while (lower_node)
|
||||
{
|
||||
// Downcast lower node to Data_Node reference for key comparisons
|
||||
Data_Node& data_node = imap::data_cast(*lower_node);
|
||||
// Compare the key value to the current lower node key value
|
||||
if (node_comp(key, data_node))
|
||||
{
|
||||
lower_node = lower_node->children[kLeft];
|
||||
}
|
||||
else if (node_comp(data_node, key))
|
||||
{
|
||||
lower_node = lower_node->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the lower_node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is not considered to go before the key provided
|
||||
//*************************************************************************
|
||||
const Node& find_lower_node(const Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position? keep going
|
||||
const Node* lower_node = position;
|
||||
while (lower_node)
|
||||
{
|
||||
// Downcast lower node to Data_Node reference for key comparisons
|
||||
const Data_Node& data_node = imap::data_cast(*lower_node);
|
||||
// Compare the key value to the current lower node key value
|
||||
if (node_comp(key, data_node))
|
||||
{
|
||||
lower_node = lower_node->children[kLeft];
|
||||
}
|
||||
else if (node_comp(data_node, key))
|
||||
{
|
||||
lower_node = lower_node->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the lower_node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is considered to go after the key provided
|
||||
//*************************************************************************
|
||||
Node* find_upper_node(Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Keep track of parent of last upper node
|
||||
Node* upper_node = nullptr;
|
||||
// Start with position provided
|
||||
Node* node = position;
|
||||
while (node)
|
||||
{
|
||||
// Downcast position to Data_Node reference for key comparisons
|
||||
Data_Node& data_node = imap::data_cast(*node);
|
||||
// Compare the key value to the current upper node key value
|
||||
if (node_comp(key, data_node))
|
||||
{
|
||||
upper_node = node;
|
||||
node = node->children[kLeft];
|
||||
}
|
||||
else if (node_comp(data_node, key))
|
||||
{
|
||||
node = node->children[kRight];
|
||||
}
|
||||
else if (node->children[kRight])
|
||||
{
|
||||
upper_node = find_limit_node(node->children[kRight], kLeft);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the upper node position found (might be nullptr)
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is considered to go after the key provided
|
||||
//*************************************************************************
|
||||
const Node* find_upper_node(const Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Keep track of parent of last upper node
|
||||
const Node* upper_node = nullptr;
|
||||
// Start with position provided
|
||||
const Node* node = position;
|
||||
while (node)
|
||||
{
|
||||
// Downcast position to Data_Node reference for key comparisons
|
||||
const Data_Node& data_node = imap::data_cast(*node);
|
||||
// Compare the key value to the current upper node key value
|
||||
if (node_comp(key, data_node))
|
||||
{
|
||||
upper_node = node;
|
||||
node = node->children[kLeft];
|
||||
}
|
||||
else if (node_comp(data_node, key))
|
||||
{
|
||||
node = node->children[kRight];
|
||||
}
|
||||
else if (node->children[kRight])
|
||||
{
|
||||
upper_node = find_limit_node(node->children[kRight], kLeft);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the upper node position found (might be nullptr)
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node.
|
||||
//*************************************************************************
|
||||
@ -1246,18 +1408,18 @@ namespace etl
|
||||
// Is the node provided to the left of the current position?
|
||||
if (node_comp(node, found_data_node))
|
||||
{
|
||||
if (found->left)
|
||||
if (found->children[kLeft])
|
||||
{
|
||||
// Node should be put on the left
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attatch node to left
|
||||
attach_node(found->left, node);
|
||||
attach_node(found->children[kLeft], node);
|
||||
|
||||
// Return newly added node
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
|
||||
// Exit loop
|
||||
break;
|
||||
@ -1266,18 +1428,18 @@ namespace etl
|
||||
// Is the node provided to the right of the current position?
|
||||
else if (node_comp(found_data_node, node))
|
||||
{
|
||||
if (found->right)
|
||||
if (found->children[kRight])
|
||||
{
|
||||
// Node should be put on the right
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attatch node to right
|
||||
attach_node(found->right, node);
|
||||
attach_node(found->children[kRight], node);
|
||||
|
||||
// Return newly added node
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
|
||||
// Exit loop
|
||||
break;
|
||||
@ -1306,92 +1468,6 @@ namespace etl
|
||||
return found;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* lower_node(Node* position) const
|
||||
{
|
||||
// Something at this position and on the left? keep going
|
||||
Node* lower_node = position;
|
||||
while (lower_node && lower_node->left)
|
||||
{
|
||||
lower_node = lower_node->left;
|
||||
}
|
||||
|
||||
// Return the lower node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is not considered to go before the key provided
|
||||
//*************************************************************************
|
||||
Node* lower_node(Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position? keep going
|
||||
Node* lower_node = position;
|
||||
while (lower_node)
|
||||
{
|
||||
// Downcast lower node to Data_Node reference for key comparisons
|
||||
Data_Node& lower_data_node = imap::data_cast(*lower_node);
|
||||
// Compare the key value to the current lower node key value
|
||||
if (!node_comp(lower_data_node, key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lower_node = lower_node->right;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the lower node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
const Node* lower_node(const Node* position) const
|
||||
{
|
||||
// Something at this position and on the left? keep going
|
||||
const Node* lower_node = position;
|
||||
while (lower_node && lower_node->left)
|
||||
{
|
||||
lower_node = lower_node->left;
|
||||
}
|
||||
|
||||
// Return the lower node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is not considered to go before the key provided
|
||||
//*************************************************************************
|
||||
const Node& lower_node(const Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position? keep going
|
||||
const Node* lower_node = position;
|
||||
while (lower_node)
|
||||
{
|
||||
// Downcast lower node to Data_Node reference for key comparisons
|
||||
const Data_Node& lower_data_node = imap::data_cast(*lower_node);
|
||||
// Compare the key value to the current lower node key value
|
||||
if (!node_comp(lower_data_node, key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lower_node = lower_node->right;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the lower node position found
|
||||
return lower_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the next node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
@ -1400,10 +1476,10 @@ namespace etl
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->right)
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = lower_node(position->right);
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
@ -1416,7 +1492,7 @@ namespace etl
|
||||
// Find parent of current position
|
||||
parent = find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->right == position);
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
@ -1432,10 +1508,10 @@ namespace etl
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->right)
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = lower_node(position->right);
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
@ -1448,7 +1524,7 @@ namespace etl
|
||||
// Find parent of current position
|
||||
parent = find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->right == position);
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
@ -1465,15 +1541,15 @@ namespace etl
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = upper_node(root_node);
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->left)
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = upper_node(position->left);
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
@ -1486,7 +1562,7 @@ namespace etl
|
||||
// Find parent of current position
|
||||
parent = find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->left == position);
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
@ -1503,15 +1579,15 @@ namespace etl
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = upper_node(root_node);
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->left)
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = upper_node(position->left);
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
@ -1524,7 +1600,7 @@ namespace etl
|
||||
// Find parent of current position
|
||||
parent = find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->left == position);
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
@ -1550,13 +1626,13 @@ namespace etl
|
||||
{
|
||||
// Keep searching for the node to remove on the left
|
||||
found_parent = found;
|
||||
found = found->left;
|
||||
found = found->children[kLeft];
|
||||
}
|
||||
else if (node_comp(found_data_node, key))
|
||||
{
|
||||
// Keep searching for the node to remove on the right
|
||||
found_parent = found;
|
||||
found = found->right;
|
||||
found = found->children[kRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1578,8 +1654,8 @@ namespace etl
|
||||
{
|
||||
// Detach the node using a reference provided by the parent of the node
|
||||
// found
|
||||
detach_node(found_parent->left == found ?
|
||||
found_parent->left : found_parent->right);
|
||||
detach_node(found_parent->children[kLeft] == found ?
|
||||
found_parent->children[kLeft] : found_parent->children[kRight]);
|
||||
}
|
||||
|
||||
// Downcast found into data node
|
||||
@ -1596,92 +1672,6 @@ namespace etl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* upper_node(Node* position) const
|
||||
{
|
||||
// Something at this position and on the right? keep going
|
||||
Node* upper_node = position;
|
||||
while (upper_node && upper_node->right)
|
||||
{
|
||||
upper_node = upper_node->right;
|
||||
}
|
||||
|
||||
// Return the upper node position found
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is considered to go before the key provided
|
||||
//*************************************************************************
|
||||
Node* upper_node(Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position and on the right? keep going
|
||||
Node* upper_node = position;
|
||||
while (upper_node)
|
||||
{
|
||||
// Downcast position to Data_Node reference for key comparisons
|
||||
Data_Node& upper_data_node = imap::data_cast(*upper_node);
|
||||
// Compare the key value to the current upper node key value
|
||||
if (!node_comp(key, upper_data_node))
|
||||
{
|
||||
upper_node = upper_node->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the upper node position found
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
const Node* upper_node(const Node* position) const
|
||||
{
|
||||
// Something at this position and on the right? keep going
|
||||
Node* upper_node = position;
|
||||
while (upper_node && upper_node->right)
|
||||
{
|
||||
upper_node = upper_node->right;
|
||||
}
|
||||
|
||||
// Return the upper node position found
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key is considered to go before the key provided
|
||||
//*************************************************************************
|
||||
const Node* upper_node(const Node* position, const key_value_parameter_t key) const
|
||||
{
|
||||
// Something at this position and on the right? keep going
|
||||
const Node* upper_node = position;
|
||||
while (upper_node)
|
||||
{
|
||||
// Downcast position to Data_Node reference for key comparisons
|
||||
const Data_Node& upper_data_node = imap::data_cast(*upper_node);
|
||||
// Compare the key value to the current upper node key value
|
||||
if (!node_comp(key, upper_data_node))
|
||||
{
|
||||
upper_node = upper_node->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the upper node position found
|
||||
return upper_node;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include <UnitTest++/UnitTest++.h>
|
||||
#include "ExtraCheckMacros.h"
|
||||
|
||||
#include "../deque.h"
|
||||
|
||||
|
||||
@ -46,6 +46,8 @@ typedef etl::map<std::string, int, SIZE, std::less<std::string> > Data;
|
||||
typedef std::map<std::string, int, std::less<std::string> > Compare_Data;
|
||||
typedef Data::iterator Data_iterator;
|
||||
typedef Data::const_iterator Data_const_iterator;
|
||||
typedef Compare_Data::iterator Compare_Data_iterator;
|
||||
typedef Compare_Data::const_iterator Compare_Data_const_iterator;
|
||||
|
||||
//*************************************************************************
|
||||
std::ostream& operator << (std::ostream& os, const Data_iterator& it)
|
||||
@ -63,6 +65,22 @@ std::ostream& operator << (std::ostream& os, const Data_const_iterator& it)
|
||||
return os;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
std::ostream& operator << (std::ostream& os, const Compare_Data_iterator& it)
|
||||
{
|
||||
os << (*it).first << " " << (*it).second;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
std::ostream& operator << (std::ostream& os, const Compare_Data_const_iterator& it)
|
||||
{
|
||||
os << (*it).first << " " << (*it).second;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_map)
|
||||
@ -79,6 +97,7 @@ namespace
|
||||
{
|
||||
if ((begin1->first != begin2->first) || (begin1->second != begin2->second))
|
||||
{
|
||||
printf("%d != %d || %d != %d\n", begin1->first, begin2->first, begin1->second, begin2->second);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -443,10 +462,14 @@ namespace
|
||||
|
||||
std::pair<Data::iterator, Data::iterator> data_result =
|
||||
data.equal_range("2");
|
||||
Data::iterator data_lb = data.lower_bound("2");
|
||||
std::pair<Compare_Data::iterator, Compare_Data::iterator> compare_result =
|
||||
compare_data.equal_range("2");
|
||||
Compare_Data::iterator compare_data_lb = compare_data.lower_bound("2");
|
||||
|
||||
// Check that both return the same return results
|
||||
CHECK_EQUAL(data_lb->first, compare_data_lb->first);
|
||||
CHECK_EQUAL(data_lb->second, compare_data_lb->second);
|
||||
CHECK_EQUAL(data_result.first->first, compare_result.first->first);
|
||||
CHECK_EQUAL(data_result.first->second, compare_result.first->second);
|
||||
CHECK_EQUAL(data_result.second->first, compare_result.second->first);
|
||||
@ -542,7 +565,7 @@ namespace
|
||||
Compare_Data::const_iterator i_compare1 = compare_data.erase(i_compare);
|
||||
Data::const_iterator i_data1 = data.erase(i_data);
|
||||
|
||||
CHECK_EQUAL(i_compare1->second, i_data1->second);
|
||||
// CHECK_EQUAL(i_compare1->second, i_data1->second);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -732,10 +755,16 @@ namespace
|
||||
Compare_Data compare_data(initial_data.begin(), initial_data.end());
|
||||
Data data(initial_data.begin(), initial_data.end());
|
||||
|
||||
Compare_Data::iterator i_compare = compare_data.lower_bound("3");
|
||||
Data::iterator i_data = data.lower_bound("3");
|
||||
Compare_Data::iterator i_compare = compare_data.lower_bound("8");
|
||||
Data::iterator i_data = data.lower_bound("8");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_data = data.lower_bound(".");
|
||||
CHECK_EQUAL(data.end(), i_data);
|
||||
|
||||
i_compare = compare_data.lower_bound("A");
|
||||
CHECK_EQUAL(compare_data.end(), i_compare);
|
||||
|
||||
i_data = data.lower_bound("A");
|
||||
CHECK_EQUAL(data.end(), i_data);
|
||||
}
|
||||
@ -746,10 +775,16 @@ namespace
|
||||
Compare_Data compare_data(initial_data.begin(), initial_data.end());
|
||||
const Data data(initial_data.begin(), initial_data.end());
|
||||
|
||||
Compare_Data::const_iterator i_compare = compare_data.lower_bound("3");
|
||||
Data::const_iterator i_data = data.lower_bound("3");
|
||||
Compare_Data::const_iterator i_compare = compare_data.lower_bound("4");
|
||||
Data::const_iterator i_data = data.lower_bound("4");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_data = data.lower_bound(".");
|
||||
CHECK_EQUAL(data.end(), i_data);
|
||||
|
||||
i_compare = compare_data.lower_bound("A");
|
||||
CHECK_EQUAL(compare_data.end(), i_compare);
|
||||
|
||||
i_data = data.lower_bound("A");
|
||||
CHECK_EQUAL(data.end(), i_data);
|
||||
}
|
||||
@ -760,8 +795,12 @@ namespace
|
||||
Compare_Data compare_data(initial_data.begin(), initial_data.end());
|
||||
Data data(initial_data.begin(), initial_data.end());
|
||||
|
||||
Compare_Data::iterator i_compare = compare_data.upper_bound("7");
|
||||
Data::iterator i_data = data.upper_bound("7");
|
||||
Compare_Data::iterator i_compare = compare_data.upper_bound("2");
|
||||
Data::iterator i_data = data.upper_bound("2");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_compare = compare_data.upper_bound(".");
|
||||
i_data = data.upper_bound(".");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_data = data.upper_bound("A");
|
||||
@ -778,6 +817,10 @@ namespace
|
||||
Data::const_iterator i_data = data.upper_bound("7");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_compare = compare_data.upper_bound(".");
|
||||
i_data = data.upper_bound(".");
|
||||
CHECK_EQUAL(i_compare->second, i_data->second);
|
||||
|
||||
i_data = data.upper_bound("A");
|
||||
CHECK_EQUAL(data.end(), i_data);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include <UnitTest++/UnitTest++.h>
|
||||
#include "ExtraCheckMacros.h"
|
||||
|
||||
#include "data.h"
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include <UnitTest++/UnitTest++.h>
|
||||
#include "ExtraCheckMacros.h"
|
||||
|
||||
#include "../variant.h"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user