From 5d1ba0388af2f66d1d83db755361d3b2eb5f68ad Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 10 Aug 2015 18:30:25 +0200 Subject: Add streaming API to serializer Show what can be done with it in the xhtml example. --- xml/serializer | 16 ++++++++++++++++ xml/serializer.ixx | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) (limited to 'xml') 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 + serializer& + operator<< (serializer&, const T& value); } #include 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::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 + struct is_functor + { + typedef char no[1]; + typedef char yes[2]; + + template struct check; + + template + static no& test (...); + + template + static yes& test (check*); + + static const bool value = sizeof (test (0)) == sizeof (yes); + }; + + template ::value> + struct inserter; + + template + struct inserter + { + static void insert (serializer& s, const T& f) {f (s);} + }; + + template + struct inserter + { + static void insert (serializer& s, const T& v) {s.characters (v);} + }; + } + + template + inline serializer& + operator<< (serializer& s, const T& value) + { + details::inserter::insert (s, value); + return s; + } } -- cgit v1.1