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_IS_ASSIGNABLE_H
10 #define _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H
11 
12 #include <__config>
13 #include <__type_traits/integral_constant.h>
14 
15 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16 #  pragma GCC system_header
17 #endif
18 
19 _LIBCPP_BEGIN_NAMESPACE_STD
20 
21 template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG _Tp type; };
22 
23 #if __has_builtin(__is_assignable)
24 
25 template<class _Tp, class _Up>
26 struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
27 
28 #if _LIBCPP_STD_VER > 14
29 template <class _Tp, class _Arg>
30 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg);
31 #endif
32 
33 #else // __has_builtin(__is_assignable)
34 
35 template <class _Tp, class _Arg>
36 typename __select_2nd<decltype((declval<_Tp>() = declval<_Arg>())), true_type>::type
37 __is_assignable_test(int);
38 
39 template <class, class>
40 false_type __is_assignable_test(...);
41 
42 
43 template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
44 struct __is_assignable_imp
45     : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
46 
47 template <class _Tp, class _Arg>
48 struct __is_assignable_imp<_Tp, _Arg, true>
49     : public false_type
50 {
51 };
52 
53 template <class _Tp, class _Arg>
54 struct is_assignable
55     : public __is_assignable_imp<_Tp, _Arg> {};
56 
57 #if _LIBCPP_STD_VER > 14
58 template <class _Tp, class _Arg>
59 inline constexpr bool is_assignable_v = is_assignable<_Tp, _Arg>::value;
60 #endif
61 
62 #endif // __has_builtin(__is_assignable)
63 
64 _LIBCPP_END_NAMESPACE_STD
65 
66 #endif // _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H
67