1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 11 // template<class It, class T> 12 // concept output_iterator; 13 14 #include <iterator> 15 16 #include <cstddef> 17 #include "test_iterators.h" 18 19 struct T { }; 20 struct DerivedFromT : T { }; 21 22 static_assert( std::output_iterator<cpp17_output_iterator<int*>, int>); 23 static_assert( std::output_iterator<cpp17_output_iterator<int*>, short>); 24 static_assert( std::output_iterator<cpp17_output_iterator<int*>, long>); 25 static_assert( std::output_iterator<cpp17_output_iterator<T*>, T>); 26 static_assert(!std::output_iterator<cpp17_output_iterator<T const*>, T>); 27 static_assert( std::output_iterator<cpp17_output_iterator<T*>, T const>); 28 static_assert( std::output_iterator<cpp17_output_iterator<T*>, DerivedFromT>); 29 static_assert(!std::output_iterator<cpp17_output_iterator<DerivedFromT*>, T>); 30 31 static_assert( std::output_iterator<cpp20_output_iterator<int*>, int>); 32 static_assert( std::output_iterator<cpp20_output_iterator<int*>, short>); 33 static_assert( std::output_iterator<cpp20_output_iterator<int*>, long>); 34 static_assert( std::output_iterator<cpp20_output_iterator<T*>, T>); 35 static_assert(!std::output_iterator<cpp20_output_iterator<T const*>, T>); 36 static_assert( std::output_iterator<cpp20_output_iterator<T*>, T const>); 37 static_assert( std::output_iterator<cpp20_output_iterator<T*>, DerivedFromT>); 38 static_assert(!std::output_iterator<cpp20_output_iterator<DerivedFromT*>, T>); 39 40 // Not satisfied when the iterator is not an input_or_output_iterator 41 static_assert(!std::output_iterator<void, int>); 42 static_assert(!std::output_iterator<void (*)(), int>); 43 static_assert(!std::output_iterator<int&, int>); 44 static_assert(!std::output_iterator<T, int>); 45 46 // Not satisfied when we can't assign a T to the result of *it++ 47 struct WrongPostIncrement { 48 using difference_type = std::ptrdiff_t; 49 T const* operator++(int); 50 WrongPostIncrement& operator++(); 51 T& operator*(); 52 }; 53 static_assert( std::input_or_output_iterator<WrongPostIncrement>); 54 static_assert( std::indirectly_writable<WrongPostIncrement, T>); 55 static_assert(!std::output_iterator<WrongPostIncrement, T>); 56 57 // Not satisfied when we can't assign a T to the result of *it (i.e. not indirectly_writable) 58 struct NotIndirectlyWritable { 59 using difference_type = std::ptrdiff_t; 60 T* operator++(int); 61 NotIndirectlyWritable& operator++(); 62 T const& operator*(); // const so we can't write to it 63 }; 64 static_assert( std::input_or_output_iterator<NotIndirectlyWritable>); 65 static_assert(!std::indirectly_writable<NotIndirectlyWritable, T>); 66 static_assert(!std::output_iterator<NotIndirectlyWritable, T>); 67