-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[libc++][ranges] LWG4016: container-insertable checks do not match what container-inserter does #113103
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
[libc++][ranges] LWG4016: container-insertable checks do not match what container-inserter does #113103
Changes from 2 commits
97d7316
482b830
a80c61c
fd03741
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,15 +10,13 @@ | |
| #ifndef _LIBCPP___RANGES_TO_H | ||
| #define _LIBCPP___RANGES_TO_H | ||
|
|
||
| #include <__algorithm/ranges_copy.h> | ||
| #include <__algorithm/ranges_for_each.h> | ||
| #include <__concepts/constructible.h> | ||
| #include <__concepts/convertible_to.h> | ||
| #include <__concepts/derived_from.h> | ||
| #include <__concepts/same_as.h> | ||
| #include <__config> | ||
| #include <__functional/bind_back.h> | ||
| #include <__iterator/back_insert_iterator.h> | ||
| #include <__iterator/insert_iterator.h> | ||
| #include <__iterator/iterator_traits.h> | ||
| #include <__ranges/access.h> | ||
| #include <__ranges/concepts.h> | ||
|
|
@@ -54,19 +52,26 @@ constexpr bool __reservable_container = | |
| }; | ||
|
|
||
| template <class _Container, class _Ref> | ||
| constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) { | ||
| constexpr bool __container_appendable = requires(_Container& __c, _Ref&& __ref) { | ||
| requires( | ||
| requires { __c.emplace_back(std::forward<_Ref>(__ref)); } || | ||
| requires { __c.push_back(std::forward<_Ref>(__ref)); } || | ||
| requires { __c.emplace(__c.end(), std::forward<_Ref>(__ref)); } || | ||
| requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); }); | ||
| }; | ||
|
|
||
| template <class _Ref, class _Container> | ||
| _LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) { | ||
| if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) { | ||
| return std::back_inserter(__c); | ||
| } else { | ||
| return std::inserter(__c, __c.end()); | ||
| } | ||
| template <class _Container> | ||
| _LIBCPP_HIDE_FROM_ABI constexpr auto __container_append(_Container& __c) { | ||
| return [&__c]<class _Ref>(_Ref&& __ref) { | ||
| if constexpr (requires { __c.emplace_back(declval<_Ref>()); }) | ||
| __c.emplace_back(std::forward<_Ref>(__ref)); | ||
| else if constexpr (requires { __c.push_back(declval<_Ref>()); }) | ||
| __c.push_back(std::forward<_Ref>(__ref)); | ||
| else if constexpr (requires { __c.emplace(__c.end(), declval<_Ref>()); }) | ||
| __c.emplace(__c.end(), std::forward<_Ref>(__ref)); | ||
| else if constexpr (requires { __c.insert(__c.end(), declval<_Ref>()); }) | ||
|
||
| __c.insert(__c.end(), std::forward<_Ref>(__ref)); | ||
| }; | ||
| } | ||
|
|
||
| // Note: making this a concept allows short-circuiting the second condition. | ||
|
|
@@ -113,13 +118,13 @@ template <class _Container, input_range _Range, class... _Args> | |
|
|
||
| // Case 4 -- default-construct (or construct from the extra arguments) and insert, reserving the size if possible. | ||
| else if constexpr (constructible_from<_Container, _Args...> && | ||
| __container_insertable<_Container, range_reference_t<_Range>>) { | ||
| __container_appendable<_Container, range_reference_t<_Range>>) { | ||
| _Container __result(std::forward<_Args>(__args)...); | ||
| if constexpr (sized_range<_Range> && __reservable_container<_Container>) { | ||
| __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range))); | ||
| } | ||
|
|
||
| ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result)); | ||
| ranges::for_each(__range, ranges::__container_append(__result)); | ||
|
|
||
| return __result; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.