-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[libc++] Make <map>
std::map
constexpr as part of P3372R3
#134330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc++] Make <map>
std::map
constexpr as part of P3372R3
#134330
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
46d0bb9
to
9ea718f
Compare
…__value_type<int, int>')
At this point, I have fixed all the trivially fixable issues as far as I can tell, but naturally trying to fix the lifetime issue I saw when trying to fix it in: (need explicit constructors for And that has resulted in a im-perfect forwarding (I think) I did find this commit that mentions that the code is UB (slightly less than previously), so maybe |
This is clearly UB in the core language. Per current rules we can't assign the IIUC we need to perform different operations (e.g. reconstructing the node) in constant evaluation. |
Update: Need to wait for #134819 to be merged before this PR can proceed. That PR should get rid of some more UB, and later I should be able to:
From Discord by philnik777 |
…660-P3372-constexpr-map
…P3372-constexpr-map
This reverts commit 9f931f5. # Conflicts: # libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
…P3372-constexpr-map
5c409c9
to
57183b4
Compare
Please also make your email public. It is a requirement for contributing to libc++/llvm. |
I have disabled that checkbox. ![]() but I believe the bot comment hasn't been updated since the first commit |
libcxx/test/std/containers/associative/map/map.access/at.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/docs/ReleaseNotes/22.rst
Outdated
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__) | ||
- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__) | ||
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__) | ||
- P3372R3: ``constexpr map`` (`Github <https://llvm.org/PR134330>`__) (The paper is partially implemented. ``constexpr map`` is implemented in this release) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to add this release note for a partially implemented paper. You can update the status page though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at this PR for a reference:
https://github.com/llvm/llvm-project/pull/137453/files
So Cxx2cPapers.csv already has an entry for it:
"`P3372R3 <https://wg21.link/P3372R3>`__","constexpr containers and adaptors","2025-02 (Hagenberg)","|In Progress|","","`#127876 <https://github.com/llvm/llvm-project/issues/127876>`__","" |
and I originally added it here using this as a reference:
- P3372R3: ``constexpr`` containers and adaptors (`Github <https://github.com/llvm/llvm-project/issues/127876>`__) (``forward_list``, ``list``, ``priority_queue``, ``flat_map``, and ``flat_set`` are implemented) |
So perhaps should I just remove this line for this review?
removed in 483a33b
libcxx/include/__tree
Outdated
// within __insert_unique_from_orphaned_node, the code will fail to compile where the value is not | ||
// copy_constructible for runtime execution as well; unless we use `if constexpr`. Given the copy-constructible | ||
// code path will be a performance regression, we want to restrict it to only execute during constant evaluation | ||
//, we need to delay the template instantiation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//, we need to delay the template instantiation | |
//, we need to delay the template instantiation. |
Nit. Please do this everywhere too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few . and capitalized first letters of sentences. Rewrote some parts.
let me know if this is better!
libcxx/include/__tree
Outdated
// we use copy, and not "move" as the constraint | ||
// because we can NOT move from `const key_type`, which is how `value_type` is defined | ||
// atleast for map | ||
// typedef pair<const key_type, mapped_type> value_type; | ||
// so we must copy it | ||
|
||
// const_cast is not allowed at constexpr time. | ||
// we get around this by deleting __lhs and creating a new node in-place | ||
// to avoid const_cast __lhs.first | ||
|
||
// We create a sfinae wrapper method here, because if the body of the true_type overload for | ||
// __assign_value__sfinae() gets template instantiated within __assign_value, the code will fail to compile where | ||
// the value is not copy_constructible for runtime execution as well; unless we use `if constexpr`. Given the | ||
// copy-constructible code path will be a performance regression, we want to restrict it to only execute during | ||
// constant evaluation | ||
//, we need to delay the template instantiation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit formatted oddly, could you please update it and add punctuation, e.g (not complete).
// we use copy, and not "move" as the constraint | |
// because we can NOT move from `const key_type`, which is how `value_type` is defined | |
// atleast for map | |
// typedef pair<const key_type, mapped_type> value_type; | |
// so we must copy it | |
// const_cast is not allowed at constexpr time. | |
// we get around this by deleting __lhs and creating a new node in-place | |
// to avoid const_cast __lhs.first | |
// We create a sfinae wrapper method here, because if the body of the true_type overload for | |
// __assign_value__sfinae() gets template instantiated within __assign_value, the code will fail to compile where | |
// the value is not copy_constructible for runtime execution as well; unless we use `if constexpr`. Given the | |
// copy-constructible code path will be a performance regression, we want to restrict it to only execute during | |
// constant evaluation | |
//, we need to delay the template instantiation | |
// We use copy, and not "move" as the constraint because we can NOT move from `const key_type`, which is how `value_type` is defined | |
// atleast for map | |
// typedef pair<const key_type, mapped_type> value_type; | |
// so we must copy it | |
// const_cast is not allowed at constexpr time. | |
// we get around this by deleting __lhs and creating a new node in-place | |
// to avoid const_cast __lhs.first | |
// We create a sfinae wrapper method here, because if the body of the true_type overload for | |
// __assign_value__sfinae() gets template instantiated within __assign_value, the code will fail to compile where | |
// the value is not copy_constructible for runtime execution as well; unless we use `if constexpr`. Given the | |
// copy-constructible code path will be a performance regression, we want to restrict it to only execute during | |
// constant evaluation, we need to delay the template instantiation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few . and capitalized first letters of sentences. Rewrote some parts.
let me know if this is better!
libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/include/map
Outdated
constexpr iterator emplace_hint(const_iterator position, Args&&... args); // constexpr since C++26 | ||
constexpr pair<iterator, bool> insert(const value_type& v); // constexpr since C++26 | ||
constexpr pair<iterator, bool> insert( value_type&& v); // C++17, constexpr | ||
since C++26 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constexpr iterator emplace_hint(const_iterator position, Args&&... args); // constexpr since C++26 | |
constexpr pair<iterator, bool> insert(const value_type& v); // constexpr since C++26 | |
constexpr pair<iterator, bool> insert( value_type&& v); // C++17, constexpr | |
since C++26 | |
constexpr iterator emplace_hint(const_iterator position, Args&&... args); // constexpr since C++26 | |
constexpr pair<iterator, bool> insert(const value_type& v); // constexpr since C++26 | |
constexpr pair<iterator, bool> insert( value_type&& v); // C++17, constexpr since C++26 |
Can you align these comments a bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in
66b4d6f
Aligned it to each "stanza" / section, let me know if this looks good
libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
Show resolved
Hide resolved
missing double //
8658eee
to
66b4d6f
Compare
Fixes #128660
Depends on:
libcxx/include/__memory/pointer_traits.h
#157304std::__tree_node
construction #153908Summary:
Apply
_LIBCPP_CONSTEXPR_SINCE_CXX26
tomap
,__tree
,node-handle
,__libcpp_erase_if
,__lazy_synth_three_way_comparator
,__lazy_compare_result
,libcxx/include/__utility/try_key_extraction.h
Skip test
erase_if.pass.cpp
for GCC during constant evaluation. AFAICT this appears to be a g++ bug, as the test passes with clangDisable test for
node-handle::key()
during constant evaluation (CWG2514). It is annotated with a// FIXME
map.modifiers/try.emplace.pass.cpp
: Start using the previously unusedmv3
. (Should this be a separate patch?)Has a TODO for
multimap
and ohtersa.
libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
b.
libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
a.
libcxx/test/std/containers/container.node/node_handle.pass.cpp
Fix typo in-> [NFC][libc++] Fix typo inlibcxx/include/__memory/pointer_traits.h
libcxx/include/__memory/pointer_traits.h
#157304pair<const MoveOnly, ...>
a.
move_assign.pass.cpp
b.
move_alloc.pass.cpp
c. Fails to compile if
static_assert(test());
is called in the test filed. Has a
// FIXME
with commented codeChangeThis became -> [libc++] Remove UB from__tree_node
to construct it's__node_value_type
during construction to avoid the:note: member call on object outside its lifetime is not allowed in a constant expression
issue.std::__tree_node
construction #153908