aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-05-08 15:23:33 -0700
committerBoris Kolpackov <boris@codesynthesis.com>2014-05-08 15:23:33 -0700
commitf37430cb52ff43c664d2eca08fa5ab51b0413925 (patch)
tree8fffe5ac104f98557577ccb115595d0866c845e1
parentc86af7c94b9dc4e378a6f87b5cab3b7a571c9961 (diff)
Add parser support for C++11 range-based for
-rw-r--r--tests/parser/driver.cxx23
-rw-r--r--xml/parser.hxx26
2 files changed, 49 insertions, 0 deletions
diff --git a/tests/parser/driver.cxx b/tests/parser/driver.cxx
index 3414c0c..a8230cd 100644
--- a/tests/parser/driver.cxx
+++ b/tests/parser/driver.cxx
@@ -7,6 +7,7 @@
#endif
#include <string>
+#include <vector>
#include <cassert>
#include <iostream>
#include <sstream>
@@ -389,4 +390,26 @@ main ()
{
// cerr << e.what () << endl;
}
+
+ // Test the iterator interface.
+ //
+ {
+ istringstream is ("<root><nested>X</nested></root>");
+ parser p (is, "iterator");
+
+ vector<parser::event_type> v;
+
+ for (parser::iterator i (p.begin ()); i != p.end (); ++i)
+ v.push_back (*i);
+
+ //for (parser::event_type e: p)
+ // v.push_back (e);
+
+ assert (v.size () == 5);
+ assert (v[0] == parser::start_element);
+ assert (v[1] == parser::start_element);
+ assert (v[2] == parser::characters);
+ assert (v[3] == parser::end_element);
+ assert (v[4] == parser::end_element);
+ }
}
diff --git a/xml/parser.hxx b/xml/parser.hxx
index c957b6d..2c42d4a 100644
--- a/xml/parser.hxx
+++ b/xml/parser.hxx
@@ -334,6 +334,32 @@ namespace xml
const std::string& ns, const std::string& name,
content_type);
+ // C++11 range-based for support. Generally, the iterator interface
+ // doesn't make much sense for the parser so for now we have an
+ // implementation that is just enough to the range-based for.
+ //
+ public:
+ struct iterator
+ {
+ typedef event_type value_type;
+
+ iterator (parser* p = 0, event_type e = eof): p_ (p), e_ (e) {}
+ value_type operator* () const {return e_;}
+ iterator& operator++ () {e_ = p_->next (); return *this;}
+
+ // Comparison only makes sense when comparing to end (eof).
+ //
+ bool operator== (iterator y) const {return e_ == eof && y.e_ == eof;}
+ bool operator!= (iterator y) const {return !(*this == y);}
+
+ private:
+ parser* p_;
+ event_type e_;
+ };
+
+ iterator begin () {return iterator (this, next ());}
+ iterator end () {return iterator (this, eof);}
+
private:
static void XMLCALL
start_element_ (void*, const XML_Char*, const XML_Char**);