diff --git a/libcxx/include/__iterator/segmented_iterator.h b/libcxx/include/__iterator/segmented_iterator.h index 7a8e1addeacd9..2533502d8883d 100644 --- a/libcxx/include/__iterator/segmented_iterator.h +++ b/libcxx/include/__iterator/segmented_iterator.h @@ -51,28 +51,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __segmented_iterator_traits; -/* exposition-only: -{ - using __segment_iterator = ...; - using __local_iterator = ...; +struct __segmented_iterator_traits { + using __is_segmented_iterator _LIBCPP_NODEBUG = false_type; + using __segment_iterator _LIBCPP_NODEBUG = void; + using __local_iterator _LIBCPP_NODEBUG = void; + /* exposition-only: static __segment_iterator __segment(_Iterator); static __local_iterator __local(_Iterator); static __local_iterator __begin(__segment_iterator); static __local_iterator __end(__segment_iterator); static _Iterator __compose(__segment_iterator, __local_iterator); + */ }; -*/ - -template -struct __has_specialization : false_type {}; - -template -struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {}; template -using __is_segmented_iterator _LIBCPP_NODEBUG = __has_specialization<__segmented_iterator_traits<_Iterator> >; +struct __is_segmented_iterator : __segmented_iterator_traits<_Iterator>::__is_segmented_iterator {}; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h index 327b349f476a7..266d6c11394ee 100644 --- a/libcxx/include/__ranges/join_view.h +++ b/libcxx/include/__ranges/join_view.h @@ -31,6 +31,7 @@ #include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> #include <__type_traits/common_type.h> +#include <__type_traits/integral_constant.h> #include <__type_traits/maybe_const.h> #include <__utility/as_lvalue.h> #include <__utility/empty.h> @@ -378,6 +379,7 @@ template __has_random_access_iterator_category::value && __has_random_access_iterator_category::value) struct __segmented_iterator_traits<_JoinViewIterator> { + using __is_segmented_iterator _LIBCPP_NODEBUG = true_type; using __segment_iterator _LIBCPP_NODEBUG = __iterator_with_data; using __local_iterator _LIBCPP_NODEBUG = typename _JoinViewIterator::_Inner; diff --git a/libcxx/test/libcxx/iterators/segmented_iterator.pass.cpp b/libcxx/test/libcxx/iterators/segmented_iterator.pass.cpp new file mode 100644 index 0000000000000..d2e2f35fe6f45 --- /dev/null +++ b/libcxx/test/libcxx/iterators/segmented_iterator.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// + +// + +// __segmented_iterator_traits<_Iter> + +// verifies that __segmented_iterator_traits<_Iter> does not result in implicit +// template instantaition, which may cause hard errors in SFINAE. + +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + +#include +#include +#include +#include +#include +#include <__iterator/segmented_iterator.h> +#include <__type_traits/integral_constant.h> + +#include "test_iterators.h" +#include "test_macros.h" + +template +struct is_segmented_random_access_iterator + : std::_BoolConstant::value && + std::__has_random_access_iterator_category< + typename std::__segmented_iterator_traits::__local_iterator>::value> {}; + +int main(int, char**) { + static_assert(is_segmented_random_access_iterator::iterator>::value, ""); + static_assert(!is_segmented_random_access_iterator::iterator>::value, ""); + static_assert(!is_segmented_random_access_iterator::iterator>::value, ""); + static_assert(!is_segmented_random_access_iterator::iterator>::value, ""); + static_assert(!is_segmented_random_access_iterator >::value, ""); + static_assert(!is_segmented_random_access_iterator >::value, ""); + static_assert(!is_segmented_random_access_iterator >::value, ""); + static_assert(!is_segmented_random_access_iterator::value, ""); + +#if TEST_STD_VER >= 20 + using join_view_iterator = decltype((std::declval >&>() | std::views::join).begin()); + static_assert(is_segmented_random_access_iterator::value, ""); +#endif + + return 0; +}