I have asked this question again (updated) at the suggestion of one of the StackOverflow members (see comment to this question: Traversing a bidirectional iterator back to the first element).
I have these aliases:
using SuggestedPublishersSet = std::set<CString>;
using SuggestedPublishersSetIter = SuggestedPublishersSet::iterator;
using SuggestedPublishersMap = std::map<long, SuggestedPublishersSet>;
using SuggestedPublishersMapIter = SuggestedPublishersMap::iterator;
And my class has these data members:
SuggestedPublishersMap m_mapSuggestedPublishers;
SuggestedPublishersMapIter m_mapSuggestedPublishersIter;
SuggestedPublishersSetIter m_setSuggestedPublishersIter;
My class is for a dialog and it has a button handler to let the user iterate forward sequentially through the container.
- In the first instance it builds the container and selects the first name.
- Then each time they click the button it moves forward by one name.
- When it reaches the end it resets back to the first name again in a continuous cycle.
void CDemoPickerDlg::OnBnClickedButtonSuggest()
{
if (m_mapSuggestedPublishers.empty())
{
// Build the map first - snipped
// Begin iterators and select first suggested name
m_mapSuggestedPublishersIter = m_mapSuggestedPublishers.begin();
m_setSuggestedPublishersIter = m_mapSuggestedPublishersIter->second.begin();
}
else
{
// Find the next suggested name (if any)
while (m_mapSuggestedPublishersIter != m_mapSuggestedPublishers.end())
{
// Did we reach the last name in the current "set"?
if (m_setSuggestedPublishersIter == m_mapSuggestedPublishersIter->second.end())
{
// Yes, so we need to move to the next date and begin a new iterator
m_mapSuggestedPublishersIter++;
// Have we reached the end?
if (m_mapSuggestedPublishersIter == m_mapSuggestedPublishers.end())
{
// Reset iterators and select first suggested name
m_mapSuggestedPublishersIter = m_mapSuggestedPublishers.begin();
m_setSuggestedPublishersIter = m_mapSuggestedPublishersIter->second.begin();
}
else
{
// Start with first name of this next date
m_setSuggestedPublishersIter = m_mapSuggestedPublishersIter->second.begin();
}
break;
}
else
{
// Move to next name
m_setSuggestedPublishersIter++;
// Have we reached the last name?
if (m_setSuggestedPublishersIter == m_mapSuggestedPublishersIter->second.end())
{
// Yes, so we need to move to the next date and begin a new iterator
m_mapSuggestedPublishersIter++;
// Have we reached the end?
if (m_mapSuggestedPublishersIter == m_mapSuggestedPublishers.end())
{
// Reset iterators and select first suggested name
m_mapSuggestedPublishersIter = m_mapSuggestedPublishers.begin();
m_setSuggestedPublishersIter = m_mapSuggestedPublishersIter->second.begin();
}
else
{
// Start with first name of this next date
m_setSuggestedPublishersIter = m_mapSuggestedPublishersIter->second.begin();
}
}
break;
}
}
}
// Get the next publisher to use
const auto& strNextPublisher = m_setSuggestedPublishersIter->GetString();
// Iterate grid to find this publisher - snipped
}
This code supports forward iteration. Next I want to allow the user to click the button and iterate backwards through the container (do the same in reverse). Eg. we detect if CTRL is pressed when they click the button (I know how deleted the key press) then it should work backwards.