mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Fix for unordered_multimap, unordered_set and unordered_multiset insert and erase bug.
This commit is contained in:
parent
15d49227c1
commit
25ecc38700
@ -681,10 +681,9 @@ namespace etl
|
||||
|
||||
// Just add the pointer to the bucket;
|
||||
bucket.insert_after(bucket.before_begin(), node);
|
||||
adjust_first_last_markers_after_insert(pbucket);
|
||||
|
||||
result = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
|
||||
|
||||
adjust_first_last_markers(pbucket);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -711,6 +710,7 @@ namespace etl
|
||||
|
||||
// Add the node to the end of the bucket;
|
||||
bucket.insert_after(inode_previous, node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
++inode_previous;
|
||||
|
||||
result = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
|
||||
@ -768,6 +768,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key_value_pair.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
++n;
|
||||
icurrent = iprevious;
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
@ -806,6 +807,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key_value_pair.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
return inext;
|
||||
@ -841,6 +843,7 @@ namespace etl
|
||||
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key_value_pair.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(pbucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
icurrent = inext;
|
||||
@ -1157,16 +1160,69 @@ namespace etl
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the new entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers(bucket_t* pbucket)
|
||||
void adjust_first_last_markers_after_insert(bucket_t* pbucket)
|
||||
{
|
||||
if (pbucket < first)
|
||||
if (size() == 1)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket < first)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the erased entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
first = pbuckets;
|
||||
last = pbuckets;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket == first)
|
||||
{
|
||||
// We erased the first so, we need to search again from where we erased.
|
||||
while (first->empty())
|
||||
{
|
||||
++first;
|
||||
}
|
||||
}
|
||||
else if (pbucket == last)
|
||||
{
|
||||
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
|
||||
bucket_t* pbucket = first;
|
||||
bucket_t* pend = last;
|
||||
|
||||
last = first;
|
||||
|
||||
while (pbucket != pend)
|
||||
{
|
||||
if (!pbucket->empty())
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
|
||||
++pbucket;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable copy construction.
|
||||
|
||||
@ -674,11 +674,10 @@ namespace etl
|
||||
|
||||
// Just add the pointer to the bucket;
|
||||
bucket.insert_after(bucket.before_begin(), node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
|
||||
result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
|
||||
result.second = true;
|
||||
|
||||
adjust_first_last_markers(pbucket);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -705,6 +704,7 @@ namespace etl
|
||||
|
||||
// Add the node to the end of the bucket;
|
||||
bucket.insert_after(inode_previous, node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
++inode_previous;
|
||||
|
||||
result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
|
||||
@ -763,6 +763,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
++n;
|
||||
icurrent = iprevious;
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
@ -801,6 +802,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
return inext;
|
||||
@ -836,6 +838,7 @@ namespace etl
|
||||
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(pbucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
icurrent = inext;
|
||||
@ -1152,16 +1155,69 @@ namespace etl
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the new entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers(bucket_t* pbucket)
|
||||
void adjust_first_last_markers_after_insert(bucket_t* pbucket)
|
||||
{
|
||||
if (pbucket < first)
|
||||
if (size() == 1)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket < first)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the erased entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
first = pbuckets;
|
||||
last = pbuckets;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket == first)
|
||||
{
|
||||
// We erased the first so, we need to search again from where we erased.
|
||||
while (first->empty())
|
||||
{
|
||||
++first;
|
||||
}
|
||||
}
|
||||
else if (pbucket == last)
|
||||
{
|
||||
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
|
||||
bucket_t* pbucket = first;
|
||||
bucket_t* pend = last;
|
||||
|
||||
last = first;
|
||||
|
||||
while (pbucket != pend)
|
||||
{
|
||||
if (!pbucket->empty())
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
|
||||
++pbucket;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable copy construction.
|
||||
|
||||
@ -675,11 +675,10 @@ namespace etl
|
||||
|
||||
// Just add the pointer to the bucket;
|
||||
bucket.insert_after(bucket.before_begin(), node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
|
||||
result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
|
||||
result.second = true;
|
||||
|
||||
adjust_first_last_markers(pbucket);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -709,6 +708,7 @@ namespace etl
|
||||
|
||||
// Add the node to the end of the bucket;
|
||||
bucket.insert_after(inode_previous, node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
++inode_previous;
|
||||
|
||||
result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
|
||||
@ -774,6 +774,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
n = 1;
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
}
|
||||
@ -804,6 +805,7 @@ namespace etl
|
||||
bucket.erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(&bucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
return inext;
|
||||
@ -839,6 +841,7 @@ namespace etl
|
||||
local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket.
|
||||
icurrent->key.~value_type(); // Destroy the value.
|
||||
pnodepool->release(&*icurrent); // Release it back to the pool.
|
||||
adjust_first_last_markers_after_erase(pbucket);
|
||||
ETL_DECREMENT_DEBUG_COUNT
|
||||
|
||||
icurrent = inext;
|
||||
@ -1129,16 +1132,69 @@ namespace etl
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the new entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers(bucket_t* pbucket)
|
||||
void adjust_first_last_markers_after_insert(bucket_t* pbucket)
|
||||
{
|
||||
if (pbucket < first)
|
||||
if (size() == 1)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket < first)
|
||||
{
|
||||
first = pbucket;
|
||||
}
|
||||
else if (pbucket > last)
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Adjust the first and last markers according to the erased entry.
|
||||
//*********************************************************************
|
||||
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
first = pbuckets;
|
||||
last = pbuckets;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbucket == first)
|
||||
{
|
||||
// We erased the first so, we need to search again from where we erased.
|
||||
while (first->empty())
|
||||
{
|
||||
++first;
|
||||
}
|
||||
}
|
||||
else if (pbucket == last)
|
||||
{
|
||||
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
|
||||
bucket_t* pbucket = first;
|
||||
bucket_t* pend = last;
|
||||
|
||||
last = first;
|
||||
|
||||
while (pbucket != pend)
|
||||
{
|
||||
if (!pbucket->empty())
|
||||
{
|
||||
last = pbucket;
|
||||
}
|
||||
|
||||
++pbucket;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable copy construction.
|
||||
|
||||
1
test/vs2017/.vs/etl/v15/.gitignore
vendored
Normal file
1
test/vs2017/.vs/etl/v15/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.VC.opendb
|
||||
Loading…
x
Reference in New Issue
Block a user