| //===----------------------------------------------------------------------===// |
| // |
| // 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 |
| // C++20 and above use ranges::iterator_t<Container> instead of Container::iterator. |
| |
| #include <iterator> |
| |
| #include <cassert> |
| #include <type_traits> |
| |
| #include "test_macros.h" |
| |
| struct NoIteratorAlias { |
| double data_[3] = {}; |
| double *begin(); |
| |
| struct value_type { |
| constexpr value_type(double d) : x(static_cast<int>(d)) {} |
| constexpr operator double() const { return x; } |
| |
| int x; |
| }; |
| |
| template <class T> |
| constexpr double *insert(double *pos, T value) { |
| static_assert(std::is_same_v<T, value_type>); |
| *pos = value; |
| return pos; |
| } |
| }; |
| |
| static_assert(std::is_constructible_v<std::insert_iterator<NoIteratorAlias>, NoIteratorAlias&, double*>); |
| static_assert( |
| !std::is_constructible_v<std::insert_iterator<NoIteratorAlias>, NoIteratorAlias&, NoIteratorAlias::value_type*>); |
| |
| constexpr bool test() { |
| NoIteratorAlias c; |
| double half = 0.5; |
| auto it = std::insert_iterator<NoIteratorAlias>(c, c.data_); |
| ASSERT_SAME_TYPE(decltype(std::inserter(c, c.data_)), std::insert_iterator<NoIteratorAlias>); |
| *it++ = 1 + half; // test that RHS is still implicitly converted to _Container::value_type |
| *it++ = 2 + half; |
| assert(c.data_[0] == 1.0); |
| assert(c.data_[1] == 2.0); |
| assert(c.data_[2] == 0.0); |
| return true; |
| } |
| |
| int main(int, char**) { |
| test(); |
| static_assert(test()); |
| |
| return 0; |
| } |