traits.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // traits.hpp
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 6/24/17.
  6. //
  7. #pragma once
  8. #include <utility>
  9. namespace stream::detail {
  10. template <typename F> struct map_member_object;
  11. template <typename T, typename R> struct map_member_object<R T::*> {
  12. using type = R const &;
  13. type operator()(T const & val) const { return val.*mem; }
  14. R T::*mem;
  15. };
  16. template <typename F> struct map_member_function;
  17. template <typename T, typename R> struct map_member_function<R (T::*)() const> {
  18. using type = R;
  19. type operator()(T const & val) const { return (val.*mem)(); }
  20. R (T::*mem)() const;
  21. };
  22. template <typename F> struct map_member_function;
  23. template <typename T, typename R>
  24. struct map_member_function<R (T::*)() const noexcept> {
  25. using type = R;
  26. type operator()(T const & val) const noexcept { return (val.*mem)(); }
  27. R (T::*mem)() const;
  28. };
  29. }
  30. namespace stream::traits {
  31. template <typename F>
  32. using memvar_f = typename detail::map_member_object<F>::type;
  33. template <typename F>
  34. using memfun_f = typename detail::map_member_function<F>::type;
  35. template <typename F>
  36. using is_memvar_t =
  37. typename std::enable_if<std::is_member_object_pointer<F>::value>::type;
  38. template <typename F>
  39. using is_memfun_t =
  40. typename std::enable_if<std::is_member_function_pointer<F>::value>::type;
  41. template <typename T, typename = void>
  42. struct is_dereferencable : public std::false_type {};
  43. template <> struct is_dereferencable<void *> : public std::false_type {};
  44. template <typename T>
  45. struct is_dereferencable<T, typename std::enable_if<!std::is_void<
  46. decltype(*std::declval<T>())>::value>::type>
  47. : public std::true_type {};
  48. template <typename T>
  49. constexpr bool is_dereferencable_v = is_dereferencable<T>{};
  50. template <typename T, typename F>
  51. using mapped_t = decltype(std::declval<F>()(std::declval<T>()));
  52. template <typename T, typename F>
  53. using fmapped_t =
  54. typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
  55. }