[libc++][NFC] Move incrementable_traits and indirectly_readable_traits into separate headers.

Differential Revision: https://reviews.llvm.org/D100682
This commit is contained in:
zoecarver
2021-04-19 14:28:27 -04:00
committed by Louis Dionne
parent 87afefcd22
commit e0adf7e06a
6 changed files with 196 additions and 93 deletions

View File

@@ -11,6 +11,9 @@ set(files
__functional_base
__functional_base_03
__hash_table
__iterator/concepts.h
__iterator/incrementable_traits.h
__iterator/readable_traits.h
__libcpp_version
__locale
__memory/addressof.h

View File

@@ -0,0 +1,46 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_CONCEPTS_H
#define _LIBCPP___ITERATOR_CONCEPTS_H
#include <__config>
#include <concepts>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
template<class _Tp>
using __with_reference = _Tp&;
template<class _Tp>
concept __referenceable = requires {
typename __with_reference<_Tp>;
};
template<class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
{ *__t } -> __referenceable; // not required to be equality-preserving
};
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ITERATOR_CONCEPTS_H

View File

@@ -0,0 +1,65 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_INCREMENTABLE_TRAITS_H
#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H
#include <__config>
#include <__iterator/concepts.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
// [incrementable.traits]
template<class> struct incrementable_traits {};
template<class _Tp>
requires is_object_v<_Tp>
struct incrementable_traits<_Tp*> {
using difference_type = ptrdiff_t;
};
template<class _Ip>
struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
template<class _Tp>
concept __has_member_difference_type = requires { typename _Tp::difference_type; };
template<__has_member_difference_type _Tp>
struct incrementable_traits<_Tp> {
using difference_type = typename _Tp::difference_type;
};
template<class _Tp>
concept __has_integral_minus =
requires(const _Tp& __x, const _Tp& __y) {
{ __x - __y } -> integral;
};
template<__has_integral_minus _Tp>
requires (!__has_member_difference_type<_Tp>)
struct incrementable_traits<_Tp> {
using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
};
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H

View File

@@ -0,0 +1,79 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_READABLE_TRAITS_H
#define _LIBCPP___ITERATOR_READABLE_TRAITS_H
#include <__config>
#include <__iterator/concepts.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
// [readable.traits]
template<class> struct __cond_value_type {};
template<class _Tp>
requires is_object_v<_Tp>
struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; };
template<class _Tp>
concept __has_member_value_type = requires { typename _Tp::value_type; };
template<class _Tp>
concept __has_member_element_type = requires { typename _Tp::element_type; };
template<class> struct indirectly_readable_traits {};
template<class _Ip>
requires is_array_v<_Ip>
struct indirectly_readable_traits<_Ip> {
using value_type = remove_cv_t<remove_extent_t<_Ip>>;
};
template<class _Ip>
struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {};
template<class _Tp>
struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {};
template<__has_member_value_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
template<__has_member_element_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::element_type> {};
// Pre-emptively applies LWG3541
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp>
struct indirectly_readable_traits<_Tp> {};
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp> &&
same_as<remove_cv_t<typename _Tp::element_type>,
remove_cv_t<typename _Tp::value_type>>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H

View File

@@ -439,6 +439,7 @@ concept equivalence_relation = relation<_Rp, _Tp, _Up>;
// [concept.strictweakorder]
template<class _Rp, class _Tp, class _Up>
concept strict_weak_order = relation<_Rp, _Tp, _Up>;
#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
_LIBCPP_END_NAMESPACE_STD

View File

@@ -429,6 +429,8 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <concepts>
#include <cstddef>
#include <initializer_list>
#include <__iterator/incrementable_traits.h>
#include <__iterator/readable_traits.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
#include <version>
@@ -443,99 +445,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
template<class _Tp>
using __with_reference = _Tp&;
template<class _Tp>
concept __referenceable = requires {
typename __with_reference<_Tp>;
};
template<class _Tp>
concept __dereferenceable = requires(_Tp& __t) {
{ *__t } -> __referenceable; // not required to be equality-preserving
};
// [incrementable.traits]
template<class> struct incrementable_traits {};
template<class _Tp>
requires is_object_v<_Tp>
struct incrementable_traits<_Tp*> {
using difference_type = ptrdiff_t;
};
template<class _Ip>
struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};
template<class _Tp>
concept __has_member_difference_type = requires { typename _Tp::difference_type; };
template<__has_member_difference_type _Tp>
struct incrementable_traits<_Tp> {
using difference_type = typename _Tp::difference_type;
};
template<class _Tp>
concept __has_integral_minus =
requires(const _Tp& __x, const _Tp& __y) {
{ __x - __y } -> integral;
};
template<__has_integral_minus _Tp>
requires (!__has_member_difference_type<_Tp>)
struct incrementable_traits<_Tp> {
using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;
};
// TODO(cjdb): add iter_difference_t once iterator_traits is cleaned up.
// [readable.traits]
template<class> struct __cond_value_type {};
template<class _Tp>
requires is_object_v<_Tp>
struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; };
template<class _Tp>
concept __has_member_value_type = requires { typename _Tp::value_type; };
template<class _Tp>
concept __has_member_element_type = requires { typename _Tp::element_type; };
template<class> struct indirectly_readable_traits {};
template<class _Ip>
requires is_array_v<_Ip>
struct indirectly_readable_traits<_Ip> {
using value_type = remove_cv_t<remove_extent_t<_Ip>>;
};
template<class _Ip>
struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {};
template<class _Tp>
struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {};
template<__has_member_value_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
template<__has_member_element_type _Tp>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::element_type> {};
// Pre-emptively applies LWG3541
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp>
struct indirectly_readable_traits<_Tp> {};
template<__has_member_value_type _Tp>
requires __has_member_element_type<_Tp> &&
same_as<remove_cv_t<typename _Tp::element_type>,
remove_cv_t<typename _Tp::value_type>>
struct indirectly_readable_traits<_Tp>
: __cond_value_type<typename _Tp::value_type> {};
// [iterator.traits]
template<__dereferenceable _Tp>
using iter_reference_t = decltype(*declval<_Tp&>());