traits.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //
  2. // traits.h
  3. // string-utils
  4. //
  5. // Created by Sam Jaffe on 6/12/22.
  6. // Copyright © 2022 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <tuple>
  10. #include <type_traits>
  11. namespace string_utils::detail {
  12. template <typename, typename = void> struct has_result : std::false_type {};
  13. template <typename F>
  14. struct has_result<F, std::void_t<std::invoke_result_t<F>>> : std::true_type {};
  15. template <typename, typename = void> struct is_tuple : std::false_type {};
  16. template <typename T>
  17. struct is_tuple<T, std::void_t<typename std::tuple_size<T>::type>>
  18. : std::true_type {};
  19. template <typename, typename = void> struct is_associative : std::false_type {};
  20. template <typename T>
  21. struct is_associative<T, std::void_t<typename T::mapped_type>>
  22. : std::true_type {};
  23. template <typename C>
  24. using insert_t =
  25. decltype(std::declval<C>().insert(std::declval<typename C::iterator>(),
  26. std::declval<typename C::value_type>()));
  27. template <typename, typename = void> struct is_container : std::false_type {};
  28. template <typename T>
  29. struct is_container<T, std::void_t<typename T::value_type, insert_t<T>>>
  30. : std::true_type {};
  31. template <typename T> struct decay { using type = std::decay_t<T>; };
  32. template <template <typename...> class C, typename... Ts>
  33. struct decay<C<Ts...>> {
  34. using type = C<std::decay_t<Ts>...>;
  35. };
  36. }
  37. namespace string_utils::detail {
  38. template <typename> struct always_false : std::false_type {};
  39. template <typename T> constexpr bool has_result_v = has_result<T>::value;
  40. template <typename T> constexpr bool is_tuple_v = is_tuple<T>::value;
  41. template <typename T>
  42. constexpr bool is_associative_v = is_associative<T>::value;
  43. template <typename T> constexpr bool is_container_v = is_container<T>::value;
  44. template <typename T> using decay_t = typename decay<std::decay_t<T>>::type;
  45. }