mirror-llvm-project/libcxx/include/__iterator/readable_traits.h
Nikolas Klauser ad2fbea797
[libc++] Consistently use version guards outside namespace macros (#181136)
This has the benefit of consistent placement for these macros (outside
the namespace, not inside it). This, in turn, makes it more obvious that
the condition applies to the entire namespace scope. Compile times are
also reduced a bit, since the compiler doesn't have to open a namespace
just to close it again.

This is enforced with a clang-tidy check.
As a drive-by this also fixes a few macro comments.
2026-06-29 14:44:44 +02:00

81 lines
2.4 KiB
C++

// -*- 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 <__concepts/primary_template.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__type_traits/conditional.h>
#include <__type_traits/is_array.h>
#include <__type_traits/is_object.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/remove_extent.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
// [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> {};
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> {};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H