Skip to content

Fix MemoryPreferences::GetMultipleValue - #2077

Open
cho-m wants to merge 1 commit into
OpenLightingProject:masterfrom
cho-m:GetMultipleValue-fix
Open

cho-m wants to merge 1 commit into
OpenLightingProject:masterfrom
cho-m:GetMultipleValue-fix

Conversation

@cho-m

@cho-m cho-m commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

There is no guarantee on ordering of std::multimap::find https://en.cppreference.com/cpp/container/multimap/find:

If there are several elements with the requested key in the container,
any of them may be returned.

In recent LLVM / Apple Clang, the PreferencesTest fails as LLVM changed their implementation so the assumption of exact returned element is no longer true:

Instead, switch to an interface that provides ordering guarantee.

There is no guarantee on ordering of std::multimap::find
https://en.cppreference.com/cpp/container/multimap/find:
> If there are several elements with the requested key in the container,
> any of them may be returned.
@peternewman

Copy link
Copy Markdown
Member

Hi @cho-m ,

Thanks for this. Hopefully it won't make a difference, but please can you also try for you with the additional tests in #2080 .

@peternewman peternewman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit worried about ordering requirements for lower_bound, but it seems like that doesn't apply to multimap just other containers. Should we also check for upper_bound to be more efficient (potentially).

If it's insertion order, then:

a=1
b=0
a=5
c=42
d=11

We could avoid inspecting c or d presumably if we stop at the upper_bound of a?

It would definitely be good to add a slightly more complex test to cover that if so.

@peternewman peternewman mentioned this pull request Oct 13, 2026
5 of 26 tasks
Comment on lines +349 to 351
for (iter = m_pref_map.lower_bound(key);
iter != m_pref_map.end() && iter->first == key; ++iter) {
values.push_back(iter->second);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (iter = m_pref_map.lower_bound(key);
iter != m_pref_map.end() && iter->first == key; ++iter) {
values.push_back(iter->second);
const std::pair<PreferencesMap::const_iterator, PreferencesMap::const_iterator> range = m_pref_map.equal_range(key);
for (iter = range.first; iter != range.second; ++iter) {
values.push_back(iter->second);

@aroffringa

Copy link
Copy Markdown
Contributor

We could avoid inspecting c or d presumably if we stop at the upper_bound of a?

This is what equal_range() is for, which finds lower and upper bounds at once ; I've added a suggestion how to change that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants