// // traits.hpp // stream // // Created by Sam Jaffe on 6/24/17. // #pragma once namespace stream { namespace detail { template struct ref_or_val { ref_or_val operator=(T && val) { value = std::move(val); return *this; } operator T const &() const { return value; } T value; }; template struct ref_or_val { ref_or_val operator=(T & val) { value = &val; return *this; } operator T &() const { return *value; } T * value; }; template struct map_member_object; template struct map_member_object { using type = R const &; type operator()(T const & val) const { return val.*mem; } R T::*mem; }; template struct map_member_function; template struct map_member_function { using type = R; type operator()(T const & val) const { return (val.*mem)(); } R (T::*mem)() const; }; }} namespace stream { namespace traits { template using memvar_f = typename detail::map_member_object::type; template using memfun_f = typename detail::map_member_function::type; template using is_memvar_t = typename std::enable_if::value>::type; template using is_memfun_t = typename std::enable_if::value>::type; template struct is_dereferencable : public std::false_type {}; template <> struct is_dereferencable : public std::false_type {}; template struct is_dereferencable())>::value>::type> : public std::true_type {}; template using mapped_t = decltype(std::declval()(std::declval())); template using fmapped_t = typename decltype(std::declval()(std::declval()))::value_type; }}