Phi
is_assignable.hpp
1 #ifndef INCG_PHI_CORE_TYPE_TRAITS_IS_ASSIGNABLE_HPP
2 #define INCG_PHI_CORE_TYPE_TRAITS_IS_ASSIGNABLE_HPP
3 
4 #include "phi/phi_config.hpp"
5 
6 #if PHI_HAS_EXTENSION_PRAGMA_ONCE()
7 # pragma once
8 #endif
9 
10 #include "phi/compiler_support/constexpr.hpp"
11 #include "phi/compiler_support/inline_variables.hpp"
12 #include "phi/compiler_support/intrinsics/is_assignable.hpp"
13 #include "phi/type_traits/integral_constant.hpp"
14 
15 #if PHI_SUPPORTS_IS_ASSIGNABLE()
16 
17 DETAIL_PHI_BEGIN_NAMESPACE()
18 
19 template <typename TypeT, typename ArgT>
20 struct is_assignable : public integral_constant<bool, PHI_IS_ASSIGNABLE(TypeT, ArgT)>
21 {};
22 
23 template <typename TypeT, typename ArgT>
24 struct is_not_assignable : public integral_constant<bool, !PHI_IS_ASSIGNABLE(TypeT, ArgT)>
25 {};
26 
27 # if PHI_HAS_FEATURE_VARIABLE_TEMPLATE()
28 
29 template <typename TypeT, typename ArgT>
30 PHI_INLINE_VARIABLE PHI_CONSTEXPR bool is_assignable_v = PHI_IS_ASSIGNABLE(TypeT, ArgT);
31 
32 template <typename TypeT, typename ArgT>
33 PHI_INLINE_VARIABLE PHI_CONSTEXPR bool is_not_assignable_v = !PHI_IS_ASSIGNABLE(TypeT, ArgT);
34 
35 # endif
36 
37 #else
38 
39 # include "phi/core/declval.hpp"
40 # include "phi/type_traits/is_void.hpp"
41 
42 DETAIL_PHI_BEGIN_NAMESPACE()
43 
44 namespace detail
45 {
46  template <typename, typename TypeT>
47  struct select_2nd
48  {
49  using type = TypeT;
50  };
51 
52  template <typename TypeT, typename ArgT>
53  typename select_2nd<decltype((declval<TypeT>() = declval<ArgT>())), true_type>::type
54  is_assignable_test(int);
55 
56  template <typename, typename>
57  false_type is_assignable_test(...);
58 
59  template <typename TypeT, typename ArgT, bool = is_void<TypeT>::value || is_void<ArgT>::value>
60  struct is_assignable_imp : public decltype((is_assignable_test<TypeT, ArgT>(0)))
61  {};
62 
63  template <typename TypeT, typename ArgT>
64  struct is_assignable_imp<TypeT, ArgT, true> : public false_type
65  {};
66 } // namespace detail
67 
68 template <typename TypeT, typename ArgT>
69 struct is_assignable : public detail::is_assignable_imp<TypeT, ArgT>
70 {};
71 
72 template <typename TypeT, typename ArgT>
73 struct is_not_assignable : public integral_constant<bool, !is_assignable<TypeT, ArgT>::value>
74 {};
75 
76 # if PHI_HAS_FEATURE_VARIABLE_TEMPLATE()
77 
78 template <typename TypeT, typename ArgT>
79 PHI_INLINE_VARIABLE PHI_CONSTEXPR bool is_assignable_v = is_assignable<TypeT, ArgT>::value;
80 
81 template <typename TypeT, typename ArgT>
82 PHI_INLINE_VARIABLE PHI_CONSTEXPR bool is_not_assignable_v = is_not_assignable<TypeT, ArgT>::value;
83 
84 # endif
85 
86 #endif
87 
88 DETAIL_PHI_END_NAMESPACE()
89 
90 #endif // INCG_PHI_CORE_TYPE_TRAITS_IS_ASSIGNABLE_HPP
Definition: integral_constant.hpp:19
Definition: is_assignable.hpp:69
Definition: is_assignable.hpp:47
Definition: swap.hpp:23
Definition: is_assignable.hpp:60
Definition: is_assignable.hpp:73
Definition: is_void.hpp:17