traits.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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>
  10. struct ref_or_val {
  11. ref_or_val operator=(T && val) { value = std::move(val); return *this; }
  12. operator T const &() const { return value; }
  13. T value;
  14. };
  15. template <typename T>
  16. struct ref_or_val<T&> {
  17. ref_or_val operator=(T & val) { value = &val; return *this; }
  18. operator T &() const { return *value; }
  19. T * value;
  20. };
  21. template <typename F> struct map_member_object;
  22. template <typename T, typename R>
  23. struct map_member_object<R T::*> {
  24. using type = R const &;
  25. type operator()(T const & val) const { return val.*mem; }
  26. R T::*mem;
  27. };
  28. template <typename F> struct map_member_function;
  29. template <typename T, typename R>
  30. struct map_member_function<R (T::*)() const> {
  31. using type = R;
  32. type operator()(T const & val) const { return (val.*mem)(); }
  33. R (T::* mem)() const;
  34. };
  35. } }
  36. namespace stream { namespace traits {
  37. template <typename F>
  38. using memvar_f = typename detail::map_member_object<F>::type;
  39. template <typename F>
  40. using memfun_f = typename detail::map_member_function<F>::type;
  41. template <typename F>
  42. using is_memvar_t = typename std::enable_if<std::is_member_object_pointer<F>::value>::type;
  43. template <typename F>
  44. using is_memfun_t = typename std::enable_if<std::is_member_function_pointer<F>::value>::type;
  45. template <typename T, typename = void>
  46. struct is_dereferencable : public std::false_type {};
  47. template <>
  48. struct is_dereferencable<void*> : public std::false_type {};
  49. template <typename T>
  50. struct is_dereferencable<T, typename std::enable_if<!std::is_void<decltype(*std::declval<T>())>::value>::type> : public std::true_type {};
  51. template <typename T, typename F>
  52. using mapped_t = decltype(std::declval<F>()(std::declval<T>()));
  53. template <typename T, typename F>
  54. using fmapped_t = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
  55. } }