|
10 | 10 | #ifndef _LIBCPP___RANGES_TO_H |
11 | 11 | #define _LIBCPP___RANGES_TO_H |
12 | 12 |
|
| 13 | +#include <__algorithm/ranges_for_each.h> |
13 | 14 | #include <__concepts/constructible.h> |
14 | 15 | #include <__concepts/convertible_to.h> |
15 | 16 | #include <__concepts/derived_from.h> |
@@ -70,6 +71,22 @@ concept __constructible_from_iter_pair = |
70 | 71 | derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> && |
71 | 72 | constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>; |
72 | 73 |
|
| 74 | +template <class _Container> |
| 75 | +constexpr auto __container_append(_Container& __c) { |
| 76 | + return [&__c]<class _Ref>(_Ref&& __ref) { |
| 77 | + if constexpr (requires { __c.emplace_back(std::declval<_Ref>()); }) |
| 78 | + __c.emplace_back(std::forward<_Ref>(__ref)); |
| 79 | + else if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) |
| 80 | + __c.push_back(std::forward<_Ref>(__ref)); |
| 81 | + else if constexpr (requires { __c.emplace(__c.end(), std::declval<_Ref>()); }) |
| 82 | + __c.emplace(__c.end(), std::forward<_Ref>(__ref)); |
| 83 | + else { |
| 84 | + static_assert(requires { __c.insert(__c.end(), std::declval<_Ref>()); }); |
| 85 | + __c.insert(__c.end(), std::forward<_Ref>(__ref)); |
| 86 | + } |
| 87 | + }; |
| 88 | +} |
| 89 | + |
73 | 90 | template <class> |
74 | 91 | concept __always_false = false; |
75 | 92 |
|
@@ -109,24 +126,8 @@ template <class _Container, input_range _Range, class... _Args> |
109 | 126 | __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range))); |
110 | 127 | } |
111 | 128 |
|
112 | | - auto __iter = ranges::begin(__range); |
113 | | - auto __sent = ranges::end(__range); |
114 | | - for (; __iter != __sent; ++__iter) { |
115 | | - auto&& __ref = *__iter; |
116 | | - using _Ref = decltype(__ref); |
117 | | - if constexpr (requires { __result.emplace_back(std::declval<_Ref>()); }) { |
118 | | - __result.emplace_back(std::forward<_Ref>(__ref)); |
119 | | - } else if constexpr (requires { __result.push_back(std::declval<_Ref>()); }) { |
120 | | - __result.push_back(std::forward<_Ref>(__ref)); |
121 | | - } else if constexpr (requires { __result.emplace(__result.end(), std::declval<_Ref>()); }) { |
122 | | - __result.emplace(__result.end(), std::forward<_Ref>(__ref)); |
123 | | - } else { |
124 | | - static_assert(requires { __result.insert(__result.end(), std::declval<_Ref>()); }); |
125 | | - __result.insert(__result.end(), std::forward<_Ref>(__ref)); |
126 | | - } |
127 | | - } |
| 129 | + ranges::for_each(__range, ranges::__container_append(__result)); |
128 | 130 | return __result; |
129 | | - |
130 | 131 | } else { |
131 | 132 | static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type."); |
132 | 133 | } |
|
0 commit comments