if constexpr (requires { _M_cont.insert_range(_M_cont.end(), __rg); })
__it = _M_cont.insert_range(_M_cont.end(), __rg);
else if constexpr (ranges::common_range<_Rg>
- && __detail::__cpp17_input_iterator<ranges::iterator_t<_Rg>>)
+ && __has_input_iter_cat<ranges::iterator_t<_Rg>>)
__it = _M_cont.insert(_M_cont.end(), ranges::begin(__rg), ranges::end(__rg));
else
{
void insert_range(typename std::vector<T>::const_iterator, R&&) = delete;
};
+struct NoCatIterator {
+ using difference_type = int;
+ using value_type = int;
+
+ NoCatIterator() : v(0) {}
+ NoCatIterator(int x) : v(x) {}
+
+ int operator*() const
+ { return v; }
+
+ NoCatIterator& operator++()
+ {
+ ++v;
+ return *this;
+ }
+
+ NoCatIterator operator++(int)
+ {
+ ++v;
+ return NoCatIterator(v-1);
+ }
+
+ bool operator==(const NoCatIterator& rhs) const
+ { return v == rhs.v; }
+
+private:
+ int v;
+};
+
+template<>
+struct std::iterator_traits<NoCatIterator> {
+ using difference_type = int;
+ using value_type = int;
+ using iterator_concept = std::input_iterator_tag;
+ // no iterator_category, happens also for common_iterator
+};
+
void test07()
{
+ std::flat_multiset<int> s;
+ std::flat_multiset<int, std::less<int>, NoInsertRange<int>> s2;
+
+ auto r = std::ranges::subrange<NoCatIterator>(1, 6);
+ s.insert_range(r);
+ VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
+ s2.insert_range(r);
+ VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
+
#ifdef __SIZEOF_INT128__
// PR libstdc++/119415 - flat_foo::insert_range cannot handle common ranges
// on c++20 only iterators
- auto r = std::views::iota(__int128(1), __int128(6));
-
- std::flat_multiset<int> s;
- s.insert_range(r);
+ auto r2 = std::views::iota(__int128(1), __int128(6));
+ s.clear();
+ s.insert_range(r2);
VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
- std::flat_multiset<int, std::less<int>, NoInsertRange<int>> s2;
- s2.insert_range(r);
+ s2.clear();
+ s2.insert_range(r2);
VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
#endif
}
void insert_range(typename std::vector<T>::const_iterator, R&&) = delete;
};
+struct NoCatIterator {
+ using difference_type = int;
+ using value_type = int;
+
+ NoCatIterator() : v(0) {}
+ NoCatIterator(int x) : v(x) {}
+
+ int operator*() const
+ { return v; }
+
+ NoCatIterator& operator++()
+ {
+ ++v;
+ return *this;
+ }
+
+ NoCatIterator operator++(int)
+ {
+ ++v;
+ return NoCatIterator(v-1);
+ }
+
+ bool operator==(const NoCatIterator& rhs) const
+ { return v == rhs.v; }
+
+private:
+ int v;
+};
+
+template<>
+struct std::iterator_traits<NoCatIterator> {
+ using difference_type = int;
+ using value_type = int;
+ using iterator_concept = std::input_iterator_tag;
+ // no iterator_category, happens also for common_iterator
+};
+
void test07()
{
+ std::flat_set<int> s;
+ std::flat_set<int, std::less<int>, NoInsertRange<int>> s2;
+
+ auto r = std::ranges::subrange<NoCatIterator>(1, 6);
+ s.insert_range(r);
+ VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
+ s2.insert_range(r);
+ VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
+
#ifdef __SIZEOF_INT128__
// PR libstdc++/119415 - flat_foo::insert_range cannot handle common ranges
// on c++20 only iterators
- auto r = std::views::iota(__int128(1), __int128(6));
-
- std::flat_set<int> s;
- s.insert_range(r);
+ auto r2 = std::views::iota(__int128(1), __int128(6));
+ s.clear();
+ s.insert_range(r2);
VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
- std::flat_set<int, std::less<int>, NoInsertRange<int>> s2;
- s2.insert_range(r);
+ s2.clear();
+ s2.insert_range(r2);
VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
#endif
}