traits.hpp 2.1 KB

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