traits.hpp 2.1 KB

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