//===----------------------------------------------------------------------===//
//
// 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;
}