diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h --- a/libcxx/include/__iterator/insert_iterator.h +++ b/libcxx/include/__iterator/insert_iterator.h @@ -14,6 +14,7 @@ #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include <__ranges/access.h> #include <__utility/move.h> #include @@ -36,8 +37,12 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP protected: _Container* container; - typename _Container::iterator iter; // FIXME: `ranges::iterator_t` in C++20 mode -public: +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) + ranges::iterator_t<_Container> iter; +#else + typename _Container::iterator iter; +#endif + public: typedef output_iterator_tag iterator_category; typedef void value_type; #if _LIBCPP_STD_VER > 17 @@ -49,8 +54,13 @@ typedef void reference; typedef _Container container_type; +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) + _LIBCPP_INLINE_VISIBILITY constexpr insert_iterator(_Container& __x, ranges::iterator_t<_Container> __i) + : container(_VSTD::addressof(__x)), iter(__i) {} +#else _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i) : container(_VSTD::addressof(__x)), iter(__i) {} +#endif _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_) {iter = container->insert(iter, __value_); ++iter; return *this;} #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/cxx20_iter_member.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/cxx20_iter_member.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/cxx20_iter_member.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// insert_iterator + +#include +#include + +struct NoIteratorAlias { + int data_[3] = {}; + using value_type = int; + int* begin() { return nullptr; } + constexpr int* insert(int* pos, int value) { + *pos = value; + return pos; + } +}; + +constexpr bool test_no_iterator_alias() { + NoIteratorAlias c; + auto it = std::insert_iterator(c, c.data_); + *it++ = 1; + *it++ = 2; + assert(c.data_[0] == 1); + assert(c.data_[1] == 2); + assert(c.data_[2] == 0); + return true; +} + +int main(int, char**) { + test_no_iterator_alias(); + static_assert(test_no_iterator_alias()); + + return 0; +}