aboutsummaryrefslogtreecommitdiff
path: root/xml
diff options
context:
space:
mode:
Diffstat (limited to 'xml')
-rw-r--r--xml/serializer16
-rw-r--r--xml/serializer.ixx55
2 files changed, 71 insertions, 0 deletions
diff --git a/xml/serializer b/xml/serializer
index 316a501..eb592df 100644
--- a/xml/serializer
+++ b/xml/serializer
@@ -185,6 +185,8 @@ namespace xml
// namespace is declared. If both prefix and namespace are empty,
// then the default namespace declaration is cleared (xmlns="").
//
+ // This function should be called after start_element().
+ //
void
namespace_decl (const std::string& ns, const std::string& prefix);
@@ -251,6 +253,20 @@ namespace xml
genxSender sender_;
std::size_t depth_;
};
+
+ // Stream-like interface for serializer. If the passed argument
+ // is a function with the void f(serializer&) signature or is a
+ // function object with the void operator() (serializer&) const
+ // operator, then this function (object) is called with the passed
+ // serializer. Otherwise, the argument is passed to the serializer's
+ // characters() function.
+ //
+ serializer&
+ operator<< (serializer&, void (*func) (serializer&));
+
+ template <typename T>
+ serializer&
+ operator<< (serializer&, const T& value);
}
#include <xml/serializer.ixx>
diff --git a/xml/serializer.ixx b/xml/serializer.ixx
index ea3dcf0..5cff976 100644
--- a/xml/serializer.ixx
+++ b/xml/serializer.ixx
@@ -118,4 +118,59 @@ namespace xml
{
characters (value_traits<T>::serialize (value, *this));
}
+
+ // operator<<
+ //
+
+ inline serializer&
+ operator<< (serializer& s, void (*func) (serializer&))
+ {
+ func (s);
+ return s;
+ }
+
+ namespace details
+ {
+ // Detect whether T defines void operator(A) const.
+ //
+ template <typename T, typename A>
+ struct is_functor
+ {
+ typedef char no[1];
+ typedef char yes[2];
+
+ template <typename X, X> struct check;
+
+ template <typename>
+ static no& test (...);
+
+ template <typename X>
+ static yes& test (check<void (X::*) (A) const, &X::operator ()>*);
+
+ static const bool value = sizeof (test<T> (0)) == sizeof (yes);
+ };
+
+ template <typename T, bool = is_functor<T, serializer&>::value>
+ struct inserter;
+
+ template <typename T>
+ struct inserter<T, true>
+ {
+ static void insert (serializer& s, const T& f) {f (s);}
+ };
+
+ template <typename T>
+ struct inserter<T, false>
+ {
+ static void insert (serializer& s, const T& v) {s.characters (v);}
+ };
+ }
+
+ template <typename T>
+ inline serializer&
+ operator<< (serializer& s, const T& value)
+ {
+ details::inserter<T>::insert (s, value);
+ return s;
+ }
}