diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -2533,6 +2533,32 @@ const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving }; +// [iterator.concept.winc] +template +inline constexpr bool __is_signed_integer_like = signed_integral<_Tp>; + +template +concept weakly_incrementable = + default_initializable<_Ip> && + movable<_Ip> && + requires(_Ip __i) { + typename iter_difference_t<_Ip>; + requires __is_signed_integer_like>; + { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving + __i++; // not required to be equality-preserving + }; + +// [iterator.concept.inc] +template +concept incrementable = + regular<_Ip> && + weakly_incrementable<_Ip> && + requires(_Ip __i) { + { __i++ } -> same_as<_Ip>; + }; + +// [iterator.concept.inc] + #undef _LIBCPP_NOEXCEPT_RETURN #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/incrementable.h b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/incrementable.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/incrementable.h @@ -0,0 +1,189 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef LIBCPP_TEST_STD_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_CONCEPTS_INCREMENTABLE_H +#define LIBCPP_TEST_STD_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_CONCEPTS_INCREMENTABLE_H + +struct winc1 { + using difference_type = int; + winc1& operator++(); + void operator++(int); +}; + +struct winc2 { + using difference_type = int; + winc2& operator++(); + winc2 operator++(int); +}; + +struct winc3 { + winc3& operator++(); + winc3 operator++(int); + + long operator-(winc3) const; +}; + +struct winc4 { + using difference_type = short; + + winc4& operator++(); + winc4 operator++(int); + + long operator-(winc4) const; +}; + +struct missing_difference_type { + missing_difference_type& operator++(); + void operator++(int); +}; + +struct floating_difference_type { + using difference_type = float; + + floating_difference_type& operator++(); + void operator++(int); +}; + +struct non_const_minus { + non_const_minus& operator++(); + non_const_minus operator++(int); + + long operator-(non_const_minus); +}; + +struct non_integral_minus { + non_integral_minus& operator++(); + non_integral_minus operator++(int); + + void operator-(non_integral_minus); +}; + +struct bad_difference_type_good_minus { + using difference_type = float; + + bad_difference_type_good_minus& operator++(); + void operator++(int); + + int operator-(bad_difference_type_good_minus) const; +}; + +struct missing_default_initializable { + using difference_type = int; + missing_default_initializable() = delete; + + missing_default_initializable& operator++(); + void operator++(int); +}; + +struct missing_movable { + using difference_type = int; + + missing_movable() = default; + missing_movable(missing_movable&&) = delete; + + missing_movable& operator++(); + void operator++(int); +}; + +struct missing_preinc { + using difference_type = int; + + void operator++(int); +}; + +struct missing_postinc { + using difference_type = int; + + missing_postinc& operator++(); +}; + +struct inc1 { + using difference_type = int; + + inc1& operator++(); + inc1 operator++(int); + + bool operator==(inc1) const; + bool operator!=(inc1) const; +}; + +struct inc2 { + inc2& operator++(); + inc2 operator++(int); + + bool operator==(inc2) const; + bool operator!=(inc2) const; + + int operator-(inc2) const; +}; + +struct inc3 { + using difference_type = int; + + inc3& operator++(); + inc3 operator++(int); + + bool operator==(inc3) const; + bool operator!=(inc3) const; + + void operator-(inc3) const; +}; + +struct noncopyable1 { + using difference_type = int; + + noncopyable1() = default; + noncopyable1(noncopyable1&&) = default; + noncopyable1(noncopyable1 const&) = delete; + + noncopyable1& operator=(noncopyable1&&) = default; + noncopyable1& operator=(noncopyable1 const&) = delete; + + noncopyable1& operator++(); + noncopyable1 operator++(int); + + bool operator==(noncopyable1) const; + bool operator!=(noncopyable1) const; +}; + +struct noncopyable2 { + noncopyable2() = default; + noncopyable2(noncopyable2&&) = default; + noncopyable2(noncopyable2 const&) = delete; + + noncopyable2& operator=(noncopyable2&&) = default; + noncopyable2& operator=(noncopyable2 const&) = delete; + + noncopyable2& operator++(); + noncopyable2 operator++(int); + + int operator-(noncopyable2 const&) const; + + bool operator==(noncopyable2) const; + bool operator!=(noncopyable2) const; +}; + +struct noncopyable3 { + using difference_type = int; + + noncopyable3() = default; + noncopyable3(noncopyable3&&) = default; + noncopyable3(noncopyable3 const&) = delete; + + noncopyable3& operator=(noncopyable3&&) = default; + noncopyable3& operator=(noncopyable3 const&) = delete; + + noncopyable3& operator++(); + noncopyable3 operator++(int); + + int operator-(noncopyable3 const&) const; + + bool operator==(noncopyable3) const; + bool operator!=(noncopyable3) const; +}; + +#endif // #define LIBCPP_TEST_STD_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_CONCEPTS_INCREMENTABLE_H diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.inc/incrementable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.inc/incrementable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.inc/incrementable.compile.pass.cpp @@ -0,0 +1,202 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 + +// template +// concept indirectly_readable; + +#include + +#include +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../incrementable.h" + +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); + +struct S {}; +static_assert(!std::weakly_incrementable); + +#define CHECK_POINTER_TO_MEMBER_FUNCTIONS(qualifier) \ + static_assert(!std::incrementable); \ + static_assert(!std::incrementable); \ + static_assert(!std::incrementable); \ + static_assert(!std::incrementable); \ + static_assert(!std::incrementable); \ + static_assert(!std::incrementable < int (S::*)() qualifier&& noexcept >); + +#define NO_QUALIFIER +CHECK_POINTER_TO_MEMBER_FUNCTIONS(NO_QUALIFIER); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(const); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(volatile); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(const volatile); + +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); +static_assert(!std::incrementable); + +namespace standard_types { +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(!std::incrementable); +static_assert( + !std::incrementable); +#endif + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); + +// +static_assert( + !std::incrementable > >); +static_assert( + !std::incrementable > >); +static_assert(!std::incrementable > >); +static_assert(std::incrementable >); +static_assert(!std::incrementable >); +static_assert( + std::incrementable::iterator> >); +static_assert(!std::incrementable >); +static_assert(!std::incrementable >); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert( + std::incrementable::const_reverse_iterator>); + +// +static_assert(!std::incrementable >); +static_assert(!std::incrementable >); +static_assert(!std::incrementable >); +static_assert(!std::incrementable >); + +// +static_assert(!std::incrementable >); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); + +// +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); + +// +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); +static_assert(std::incrementable); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); + +static_assert(std::incrementable::iterator>); +static_assert( + std::incrementable::const_iterator>); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); + +static_assert(std::incrementable::iterator>); +static_assert( + std::incrementable::const_iterator>); + +// +static_assert(std::incrementable::iterator>); +static_assert(std::incrementable::const_iterator>); +static_assert(std::incrementable::reverse_iterator>); +static_assert(std::incrementable::const_reverse_iterator>); +static_assert(!std::incrementable >); +} // namespace standard_types diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.winc/weakly_incrementable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.winc/weakly_incrementable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.winc/weakly_incrementable.compile.pass.cpp @@ -0,0 +1,220 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 + +// template +// concept std::weakly_incrementable; + +#include + +#include +#include +#include +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../incrementable.h" + +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); + +struct S {}; +static_assert(!std::weakly_incrementable); + +#define CHECK_POINTER_TO_MEMBER_FUNCTIONS(qualifier) \ + static_assert(!std::weakly_incrementable); \ + static_assert(!std::weakly_incrementable); \ + static_assert(!std::weakly_incrementable); \ + static_assert( \ + !std::weakly_incrementable); \ + static_assert(!std::weakly_incrementable); \ + static_assert(!std::weakly_incrementable < int (S::*)() \ + qualifier&& noexcept >); + +#define NO_QUALIFIER +CHECK_POINTER_TO_MEMBER_FUNCTIONS(NO_QUALIFIER); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(const); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(volatile); +CHECK_POINTER_TO_MEMBER_FUNCTIONS(const volatile); + +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(!std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); + +namespace standard_types { +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +// +#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY +static_assert(std::weakly_incrementable); +static_assert( + std::weakly_incrementable); +#endif + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert( + std::weakly_incrementable::const_iterator>); + +// +static_assert( + !std::weakly_incrementable > >); +static_assert( + !std::weakly_incrementable > >); +static_assert( + !std::weakly_incrementable > >); +static_assert(std::weakly_incrementable >); +static_assert(std::weakly_incrementable >); +static_assert( + std::weakly_incrementable::iterator> >); +static_assert(!std::weakly_incrementable >); +static_assert(!std::weakly_incrementable >); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +static_assert(std::weakly_incrementable::iterator>); +static_assert( + std::weakly_incrementable::const_iterator>); +static_assert( + std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +// +static_assert(!std::weakly_incrementable >); +static_assert(!std::weakly_incrementable >); +static_assert(!std::weakly_incrementable >); +static_assert(!std::weakly_incrementable >); + +// +static_assert(!std::weakly_incrementable >); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert(std::weakly_incrementable::const_reverse_iterator>); + +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); + +// +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); + +// +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert(std::weakly_incrementable); +static_assert( + std::weakly_incrementable); + +// +static_assert( + std::weakly_incrementable::iterator>); +static_assert( + std::weakly_incrementable::const_iterator>); + +static_assert( + std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable< + std::unordered_multimap::const_iterator>); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert( + std::weakly_incrementable::const_iterator>); + +static_assert( + std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable< + std::unordered_multiset::const_iterator>); + +// +static_assert(std::weakly_incrementable::iterator>); +static_assert(std::weakly_incrementable::const_iterator>); +static_assert(std::weakly_incrementable::reverse_iterator>); +static_assert( + std::weakly_incrementable::const_reverse_iterator>); +static_assert(!std::weakly_incrementable >); +} // namespace standard_types