MVSim
Lightweight simulator for 2.5D vehicles and robots
JointXMLnode.h
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2026 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 #pragma once
10 
11 #include <rapidxml.hpp>
12 #include <stdexcept>
13 #include <vector>
14 
15 namespace mvsim
16 {
18 template <typename Ch>
20 {
21  public:
22  using TListNodes = std::vector<const rapidxml::xml_node<Ch>*>;
23 
24  private:
25  TListNodes nodes_;
26 
27  public:
28  void add(const rapidxml::xml_node<Ch>* node) { nodes_.push_back(node); }
29 
30  const rapidxml::xml_node<Ch>* first_node(const char* name) const
31  {
32  const rapidxml::xml_node<Ch>* ret = nullptr;
33  for (const auto& node : nodes_)
34  {
35  ret = node->first_node(name);
36  if (ret != nullptr) return ret;
37  }
38  return ret;
39  }
40 
41  TListNodes& getListOfNodes() { return nodes_; }
42  const TListNodes& getListOfNodes() const { return nodes_; }
43 
44  // Iterators-like interface ----------------------
45  class iterator
46  {
47  public:
48  template <typename Ch_>
49  friend class JointXMLnode;
50 
51  // ++it
52  iterator& operator++()
53  {
54  if (!current) throw std::runtime_error("++ called on end() iterator!?");
55  current = current->next_sibling();
56  JointXMLnode<Ch>::TListNodes& lst = parent.getListOfNodes();
57  while (!current && lst_idx < lst.size())
58  {
59  lst_idx++;
60  if (lst_idx < lst.size())
61  current = lst[lst_idx]->first_node();
62  else
63  current = nullptr;
64  }
65  return *this;
66  }
67 
68  rapidxml::xml_node<Ch>* operator->() const
69  {
70  if (!current) throw std::runtime_error("-> called on end() iterator!?");
71  return current;
72  }
73 
74  rapidxml::xml_node<Ch>* operator*() const
75  {
76  if (!current) throw std::runtime_error("* called on end() iterator!?");
77  return current;
78  }
79 
80  bool operator==(const iterator& it) const
81  {
82  return (this->current == it.current) && (this->lst_idx == it.lst_idx) &&
83  (&this->parent == &it.parent);
84  }
85  bool operator!=(const iterator& it) const { return !(*this == it); }
86 
87  private:
88  // begin():
89  iterator(JointXMLnode<Ch>& pa) : parent(pa), lst_idx(0), current(nullptr)
90  {
91  JointXMLnode<Ch>::TListNodes& lst = parent.getListOfNodes();
92  while (!current && lst_idx < lst.size())
93  {
94  current = lst[lst_idx]->first_node();
95  if (!current) lst_idx++;
96  }
97  }
98  // end()
99  iterator(JointXMLnode<Ch>& pa, size_t idx) : parent(pa), lst_idx(idx), current(nullptr) {}
100 
101  JointXMLnode<Ch>& parent;
102  size_t lst_idx; // => lst.size() means this is "end()"
103  rapidxml::xml_node<Ch>* current;
104 
105  }; // end class iterator
106 
107  iterator begin() { return iterator(*this); }
108  iterator end() { return iterator(*this, nodes_.size()); }
109 };
110 
111 } // namespace mvsim
Definition: JointXMLnode.h:46
Definition: JointXMLnode.h:20
Definition: basic_types.h:28