Split out marshall code into a new file
[invirt/third/libt4.git] / types.h
diff --git a/types.h b/types.h
index 9739a2a..e6b5895 100644 (file)
--- a/types.h
+++ b/types.h
@@ -107,7 +107,42 @@ template<class A> struct is_iterable<A,
     decltype(declval<A&>().cbegin(), declval<A&>().cend(), void())
 > : true_type {};
 
+template <class C>
+inline typename enable_if<is_iterable<C>::value, string>::type
+implode(const C & v, string delim=" ") {
+    if (v.begin() == v.end())
+        return string();
+    ostringstream oss;
+    auto last = prev(v.end());
+    copy(v.begin(), last, ostream_iterator<typename C::value_type>(oss, delim.c_str()));
+    oss << *last;
+    return oss.str();
+}
+
+inline vector<string> explode(const string &s, string delim=" ") {
+    vector<string> out;
+    size_t start = 0, end = 0;
+    while ((end = s.find(delim, start)) != string::npos) {
+        out.push_back(s.substr(start, end - start));
+        start = end + 1;
+    }
+    out.push_back(s.substr(start));
+    return out;
+}
+
 #include "lang/verify.h"
 #include "threaded_log.h"
 
+#define MEMBERS(...) \
+inline auto _tuple_() -> decltype(tie(__VA_ARGS__)) { return tie(__VA_ARGS__); } \
+inline auto _tuple_() const -> decltype(tie(__VA_ARGS__)) { return tie(__VA_ARGS__); }
+
+#define LEXICOGRAPHIC_OPERATOR(_c_, _op_) \
+inline bool operator _op_(const _c_ &b) const { return _tuple_() _op_ b._tuple_(); }
+
+#define LEXICOGRAPHIC_COMPARISON(_c_) \
+LEXICOGRAPHIC_OPERATOR(_c_, <) LEXICOGRAPHIC_OPERATOR(_c_, <=) \
+LEXICOGRAPHIC_OPERATOR(_c_, >) LEXICOGRAPHIC_OPERATOR(_c_, >=) \
+LEXICOGRAPHIC_OPERATOR(_c_, ==) LEXICOGRAPHIC_OPERATOR(_c_, !=)
+
 #endif