[meta] Add add_const, add_pointer, add_lvalue_reference, add_rvalue_reference
authorBehdad Esfahbod <behdad@behdad.org>
Sat, 11 May 2019 02:29:32 +0000 (19:29 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Sat, 11 May 2019 02:29:32 +0000 (19:29 -0700)
src/hb-meta.hh

index 645eb54..4cf8466 100644 (file)
@@ -102,17 +102,28 @@ template <typename T> static inline T hb_declval ();
 template <typename T> struct hb_match_const            { typedef T type; static constexpr bool value = false; };
 template <typename T> struct hb_match_const<const T>   { typedef T type; static constexpr bool value = true;  };
 template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
+template <typename T> using hb_add_const = const T;
 #define hb_is_const(T) hb_match_const<T>::value
 template <typename T> struct hb_match_reference                { typedef T type; static constexpr bool value = false; };
 template <typename T> struct hb_match_reference<T &>   { typedef T type; static constexpr bool value = true;  };
 template <typename T> struct hb_match_reference<T &&>  { typedef T type; static constexpr bool value = true;  };
 template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
+template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference<T> (hb_prioritize));
+template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
+template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
+template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
 #define hb_is_reference(T) hb_match_reference<T>::value
 template <typename T> struct hb_match_pointer          { typedef T type; static constexpr bool value = false; };
 template <typename T> struct hb_match_pointer<T *>     { typedef T type; static constexpr bool value = true;  };
 template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
+template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
+template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
+template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
 #define hb_is_pointer(T) hb_match_pointer<T>::value
 
+
 /* TODO Add feature-parity to std::decay. */
 template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;