codekingpro/portable-devtools
114k
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.8//9//===----------------------------------------------------------------------===//10 11#ifndef _LIBCUDACXX___ITERATOR_INCREMENTABLE_TRAITS_H12#define _LIBCUDACXX___ITERATOR_INCREMENTABLE_TRAITS_H13 14#ifndef __cuda_std__15#include <__config>16#endif // __cuda_std__17 18#include "../__concepts/arithmetic.h"19#include "../__concepts/same_as.h"20#include "../__type_traits/conditional.h"21#include "../__type_traits/enable_if.h"22#include "../__type_traits/is_const.h"23#include "../__type_traits/is_object.h"24#include "../__type_traits/is_pointer.h"25#include "../__type_traits/is_primary_template.h"26#include "../__type_traits/make_signed.h"27#include "../__type_traits/remove_cvref.h"28#include "../__type_traits/void_t.h"29#include "../__utility/declval.h"30#include "../cstddef"31 32#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)33# pragma GCC system_header34#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)35# pragma clang system_header36#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)37# pragma system_header38#endif // no system header39 40_LIBCUDACXX_BEGIN_NAMESPACE_STD41 42#if _LIBCUDACXX_STD_VER > 1743 44// [incrementable.traits]45template<class> struct incrementable_traits {};46 47template<class _Tp>48requires is_object_v<_Tp>49struct incrementable_traits<_Tp*> {50 using difference_type = ptrdiff_t;51};52 53template<class _Ip>54struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};55 56template<class _Tp>57concept __has_member_difference_type = requires { typename _Tp::difference_type; };58 59template<__has_member_difference_type _Tp>60struct incrementable_traits<_Tp> {61 using difference_type = typename _Tp::difference_type;62};63 64template<class _Tp>65concept __has_integral_minus =66 requires(const _Tp& __x, const _Tp& __y) {67 { __x - __y } -> integral;68 };69 70template<__has_integral_minus _Tp>71requires (!__has_member_difference_type<_Tp>)72struct incrementable_traits<_Tp> {73 using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;74};75 76template <class>77struct _LIBCUDACXX_TEMPLATE_VIS iterator_traits;78 79// Let `RI` be `remove_cvref_t<I>`. The type `iter_difference_t<I>` denotes80// `incrementable_traits<RI>::difference_type` if `iterator_traits<RI>` names a specialization81// generated from the primary template, and `iterator_traits<RI>::difference_type` otherwise.82template <class _Ip>83using iter_difference_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip>>>::value,84 incrementable_traits<remove_cvref_t<_Ip> >,85 iterator_traits<remove_cvref_t<_Ip> > >::difference_type;86 87#elif _LIBCUDACXX_STD_VER > 1488 89// [incrementable.traits]90template<class, class = void> struct incrementable_traits {};91 92template<class _Tp>93struct incrementable_traits<_Tp*, enable_if_t<_LIBCUDACXX_TRAIT(is_object, _Tp)>> {94 using difference_type = ptrdiff_t;95};96 97template<class _Ip>98struct incrementable_traits<const _Ip> : incrementable_traits<_Ip> {};99 100template<class _Tp, class = void>101_LIBCUDACXX_INLINE_VAR constexpr bool __has_member_difference_type = false;102 103template<class _Tp>104_LIBCUDACXX_INLINE_VAR constexpr bool __has_member_difference_type<_Tp, void_t<typename _Tp::difference_type>> = true;105 106template<class _Tp,class = void, class = void>107_LIBCUDACXX_INLINE_VAR constexpr bool __has_integral_minus = false;108 109// In C++17 we get issues trying to bind void* to a const& so special case it here110template<class _Tp>111_LIBCUDACXX_INLINE_VAR constexpr bool __has_integral_minus<_Tp, enable_if_t<!same_as<_Tp, void*>>,112 void_t<decltype(_CUDA_VSTD::declval<const _Tp&>() - _CUDA_VSTD::declval<const _Tp&>())>>113 = integral<decltype(_CUDA_VSTD::declval<const _Tp&>() - _CUDA_VSTD::declval<const _Tp&>())>;114 115template <class _Tp>116struct incrementable_traits<_Tp, enable_if_t<!_LIBCUDACXX_TRAIT(is_pointer, _Tp) && !_LIBCUDACXX_TRAIT(is_const, _Tp) &&117 __has_member_difference_type<_Tp>>> {118 using difference_type = typename _Tp::difference_type;119};120 121template <class _Tp>122struct incrementable_traits<_Tp, enable_if_t<!_LIBCUDACXX_TRAIT(is_pointer, _Tp) && !_LIBCUDACXX_TRAIT(is_const, _Tp) &&123 !__has_member_difference_type<_Tp> && __has_integral_minus<_Tp>>> {124 using difference_type = make_signed_t<decltype(declval<_Tp>() - declval<_Tp>())>;125};126 127template <class, class = void>128struct _LIBCUDACXX_TEMPLATE_VIS iterator_traits;129 130// Let `RI` be `remove_cvref_t<I>`. The type `iter_difference_t<I>` denotes131// `incrementable_traits<RI>::difference_type` if `iterator_traits<RI>` names a specialization132// generated from the primary template, and `iterator_traits<RI>::difference_type` otherwise.133template <class _Ip>134using iter_difference_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip>>>::value,135 incrementable_traits<remove_cvref_t<_Ip> >,136 iterator_traits<remove_cvref_t<_Ip> > >::difference_type;137 138#endif // _LIBCUDACXX_STD_VER > 14139 140_LIBCUDACXX_END_NAMESPACE_STD141 142#endif // _LIBCUDACXX___ITERATOR_INCREMENTABLE_TRAITS_H143 