|
|
@@ -0,0 +1,50 @@
|
|
|
+//
|
|
|
+// traits.hpp
|
|
|
+// stream
|
|
|
+//
|
|
|
+// Created by Sam Jaffe on 6/24/17.
|
|
|
+//
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+namespace stream { namespace detail {
|
|
|
+ template <typename T>
|
|
|
+ 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 <typename T>
|
|
|
+ struct ref_or_val<T&> {
|
|
|
+ ref_or_val operator=(T & val) { value = &val; return *this; }
|
|
|
+ operator T &() const { return *value; }
|
|
|
+ T * value;
|
|
|
+ };
|
|
|
+} }
|
|
|
+
|
|
|
+namespace stream { namespace detail {
|
|
|
+ template <typename F> struct map_member_object;
|
|
|
+ template <typename T, typename R>
|
|
|
+ struct map_member_object<R T::*> {
|
|
|
+ using type = R const &;
|
|
|
+ type operator()(T const & val) const { return val.*mem; }
|
|
|
+ R T::*mem;
|
|
|
+ };
|
|
|
+
|
|
|
+ template <typename F> struct map_member_function;
|
|
|
+ template <typename T, typename R>
|
|
|
+ struct map_member_function<R (T::*)() const> {
|
|
|
+ using type = R;
|
|
|
+ type operator()(T const & val) const { return val.*mem(); }
|
|
|
+ R (T::* mem)() const;
|
|
|
+ };
|
|
|
+}}
|
|
|
+
|
|
|
+namespace stream { namespace detail {
|
|
|
+ template <typename T, typename = void>
|
|
|
+ struct is_dereferencable : public std::false_type {};
|
|
|
+
|
|
|
+ template <typename T>
|
|
|
+ struct is_dereferencable<T, typename std::enable_if<!std::is_void<decltype(*std::declval<T>())>::value>::type> : public std::true_type {};
|
|
|
+}}
|