1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___TYPE_TRAITS_ADD_POINTER_H
10#define _LIBCPP___TYPE_TRAITS_ADD_POINTER_H
11
12#include <__config>
13#include <__type_traits/is_referenceable.h>
14#include <__type_traits/is_same.h>
15#include <__type_traits/is_void.h>
16#include <__type_traits/remove_cv.h>
17#include <__type_traits/remove_reference.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20#  pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
26
27template <class _Tp>
28using __add_pointer_t = __add_pointer(_Tp);
29
30#else
31template <class _Tp,
32          bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value>
33struct __add_pointer_impl {
34  typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp>* type;
35};
36template <class _Tp> struct __add_pointer_impl<_Tp, false>
37    {typedef _LIBCPP_NODEBUG _Tp type;};
38
39template <class _Tp>
40using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
41
42#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
43
44template <class _Tp>
45struct add_pointer {
46  using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>;
47};
48
49#if _LIBCPP_STD_VER > 11
50template <class _Tp> using add_pointer_t = __add_pointer_t<_Tp>;
51#endif
52
53_LIBCPP_END_NAMESPACE_STD
54
55#endif // _LIBCPP___TYPE_TRAITS_ADD_POINTER_H
56