Bridges-C++  3.4.5-dev1-6-g935685a
Bridges(C++ API)
SLelement.h
Go to the documentation of this file.
1 #ifndef SLELEMENT_H
2 #define SLELEMENT_H
3 
4 #include "DataStructure.h"
5 #include "Element.h" //string, using std
6 
7 namespace bridges {
8  namespace datastructure {
25  template <typename E>
26  class SLelement : public Element<E>, public DataStructure {
27 
28  protected:
29  SLelement* next = nullptr;
30 
31  public:
43  SLelement(SLelement* next, const E& val = E(), const string& lab =
44  string()) : Element<E>(val, lab) {
45  setNext(next);
46  }
58  SLelement(const E& val = E(), const string& lab = string())
59  : SLelement(nullptr, val, lab) {
60  }
66  virtual const string getDStype() const override {
67  return "SinglyLinkedList";
68  }
69 
74  virtual SLelement* getNext() {
75  return next;
76  }
77 
83  virtual const SLelement* getNext() const {
84  return next;
85  }
86 
92  void setNext(SLelement* n) {
93  //if different, remove old link data
94  if (next != n) {
95  this->links.erase(next);
96  }
97 
98  next = n;
99  this->links[next]; //this creates an entry in links if it does not exist
100  }
101 
102  private:
108  virtual const string getDataStructureRepresentation() const override {
109  vector<const SLelement<E>*> nodes;
110  // get the list of nodes
111  getListElements(nodes);
112  // generate the JSON string
113 
114  if (MAX_ELEMENTS_ALLOWED <= nodes.size()) {
115  // cant exceed max number of elements
116  throw "Max allowed elements(for visualization) exceeded.. " +
117  to_string(nodes.size()) + " Must be less than " +
118  to_string(MAX_ELEMENTS_ALLOWED);
119  }
120 
121  pair<string, string> json_nodes_links = generateJSON(nodes);
122 
123  string sl_list_json =
124  QUOTE + "nodes" + QUOTE + COLON +
125  OPEN_BOX + json_nodes_links.first + CLOSE_BOX + COMMA +
126  QUOTE + "links" + QUOTE + COLON + OPEN_BOX +
127  json_nodes_links.second + CLOSE_BOX +
128  CLOSE_CURLY;
129 
130  return sl_list_json;
131  }
132 
133  /*
134  virtual void getDataStructureRepresentation(
135  rapidjson::Document& d) const override {
136  vector<const SLelement<E>*> nodes;
137  // get the list of nodes
138  getListElements(nodes);
139  // generate the JSON
140 
141  if (MAX_ELEMENTS_ALLOWED <= nodes.size()) {
142  // cant exceed max number of elements
143  throw "Max allowed elements(for visualization) exceeded.."
144  + to_string(nodes.size()) + " Must be less than " +
145  to_string(MAX_ELEMENTS_ALLOWED);
146  }
147  generateJSON(nodes, d);
148 
149  assert (d.IsObject());
150  assert (d["links"].IsObject());
151  cout << "in slelement:getds..\n";
152  StringBuffer sb; Writer<StringBuffer> w(sb);
153  d.Accept(w); cout << "DS Rep(nodes, links):\n" << sb.GetString() << endl;;
154  }
155  */
156 
157  protected:
165  virtual const pair<string, string> generateJSON(
166  vector<const SLelement<E>*> nodes) const {
167  // map the nodes to a sequence of ids, 0...N-1
168  // then get the JSON string for nodes placeholder
169  // nullptr prevents insertion of other nullptrs
170  unordered_map<const SLelement*, int> node_map { {nullptr, -1} };
171 
172  string nodes_JSON, links_JSON;
173 
174  int i = 0; // get the JSON string for nodes
175  for (const auto * e : nodes) {
176  if (node_map.emplace(e, i).second) {
177  // successful emplacement
178  i++;
179  nodes_JSON += e->getElementRepresentation() + COMMA;
180  }
181  }
182  //Remove trailing comma and nullptr entry
183  node_map.erase(nullptr);
184  if (nodes_JSON.size()) {
185  nodes_JSON = nodes_JSON.erase(nodes_JSON.size() - 1);
186  }
187  // for each pair<SLelement*,int> in map
188  for (unsigned int k = 0; k < nodes.size(); k++) {
189  if (nodes[k]->next != nullptr) { // link exists
190  links_JSON += this->getLinkRepresentation(nodes[k]->links.at(nodes[k]->next),
191  to_string(node_map[nodes[k]]),
192  to_string(node_map[nodes[k]->next]) ) + COMMA;
193  }
194  }
195 
196  //Remove trailing comma
197  if (links_JSON.size()) {
198  links_JSON = links_JSON.erase(links_JSON.size() - 1);
199  }
200 
201  return pair<string, string> (nodes_JSON, links_JSON);
202  }
203  /*
204  virtual void generateJSON( vector<const SLelement<E>*> nodes,
205  rapidjson::Document& d) const {
206  // map the nodes to a sequence of ids, 0...N-1
207  // then get the JSON string for nodes placeholder
208  // nullptr prevents insertion of other nullptrs
209 
210  using namespace rapidjson;
211  unordered_map<const SLelement*, int> node_map { {nullptr, -1} };
212 
213  d.SetObject();
214  Document::AllocatorType& allocator = d.GetAllocator();
215  Value key, val;
216 
217  Value node_arr(kArrayType);
218 
219  int i = 0, k = 0; // get the JSON string for nodes
220  Document dn;
221  for (const auto* e : nodes) {
222  if (node_map.emplace(e, i).second) {
223  // successful emplacement
224  i++;
225  e->getElementRepresentation(dn);
226  //cout << "printing dn[element]...\n";
227  //StringBuffer sb; Writer<StringBuffer> w(sb); dn["element"].Accept(w); cout << sb.GetString();
228  node_arr.PushBack(dn["element"], allocator);
229  }
230  }
231  //StringBuffer sb; Writer <StringBuffer> w(sb);
232  //node_arr.Accept(w); cout << "Element (in SLelement):" << sb.GetString() << "\n";
233  d.AddMember ("nodes", node_arr, allocator);
234  //assert(d["nodes"].IsArray());
235  //cout << "printing d[nodes]...\n";
236  //StringBuffer sb; Writer<StringBuffer> w(sb); d.Accept(w); cout << sb.GetString();
237 
238  // for each pair<SLelement*,int> in map
239  Value link_arr(kArrayType);
240  Document dl;
241  for (unsigned int k = 0; k < nodes.size(); k++) {
242  if (nodes[k]->next != nullptr) { // link exists
243 
244  this->getLinkRepresentation(
245  nodes[k]->links.at(nodes[k]->next),
246  to_string(node_map[nodes[k]]),
247  to_string(node_map[nodes[k]->next]), dl);
248  link_arr.PushBack(dl["link"], allocator);
249  }
250  }
251  d.AddMember ("links", link_arr, allocator);
252  }
253  */
254  protected:
260  virtual void getListElements(vector<const SLelement<E>*>& nodes) const {
261 
262  //prevents potential infinite loop
263  unordered_set<const SLelement<E>*> visited;
264  auto it = this;
265 
266  // using the visited array handles both regular and
267  // circular lists
268  while (it != nullptr && visited.emplace(it).second) {
269  nodes.push_back(it);
270  it = it->next;
271  }
272  }
273 
274  public:
275 
287  typename bridges::datastructure::SLelement<E> * start;
288 
289  public:
291  : start(s)
292  {}
293 
294  class iterator {
295  typename bridges::datastructure::SLelement<E> *current;
296  public:
298  : current(c)
299  {}
300 
301  bool operator!= (const iterator& it) const {
302  return this->current != it.current;
303  }
304 
305  E const & operator* () const {
306  return current->getValue();
307  }
308 
309  E & operator* () {
310  return current->getValue();
311  }
312 
314  current = current->getNext();
315  return *this;
316  }
318  iterator clone(*this);
319  current = current->getNext();
320  return clone;
321  }
322  };
323 
325  return iterator(start);
326  }
327 
329  return iterator(nullptr);
330  }
331  };
332 
343  typename bridges::datastructure::SLelement<E> const * start;
344 
345  public:
347  : start(s)
348  {}
349 
350  class iterator {
351 
352  typename bridges::datastructure::SLelement< E > const * current;
353  public:
355  : current(c)
356  {}
357 
358  bool operator!=(const iterator& it) const {
359  return this->current != it.current;
360  }
361 
362  E const & operator*() const {
363  return current->getValue();
364  }
365 
367  current = current->getNext();
368  return *this;
369  }
370  };
371 
373  return iterator(start);
374  }
375 
377  return iterator(nullptr);
378  }
379  };
380 
381  }; //end of SLelement class
382  // use some aliases for accessing iterators
383  template <class E>
385  template <class E>
387  }
388 }//end of bridges namespace
389 #endif
This is the superclass of all data structure types in BRIDGES.
Definition: DataStructure.h:74
This is the fundamental building block for all data structures in BRIDGES.
Definition: Element.h:51
static const string getLinkRepresentation(const LinkVisualizer &lv, const string &src, const string &dest)
Definition: Element.h:310
unordered_map< Element *, LinkVisualizer > links
Definition: Element.h:92
E const & getValue() const
Gets the object held in the generic object E.
Definition: Element.h:207
iterator(typename bridges::datastructure::SLelement< E > const *c)
Definition: SLelement.h:354
bool operator!=(const iterator &it) const
Definition: SLelement.h:358
E const & operator*() const
Definition: SLelement.h:362
These are helper classes for SLelement for easy iteration.
Definition: SLelement.h:342
SLelement_constlisthelper(typename bridges::datastructure::SLelement< E > const *s)
Definition: SLelement.h:346
iterator(typename bridges::datastructure::SLelement< E > *c)
Definition: SLelement.h:297
E const & operator*() const
Definition: SLelement.h:305
bool operator!=(const iterator &it) const
Definition: SLelement.h:301
These are helper classes for SLelement for easy iteration.
Definition: SLelement.h:286
iterator begin()
Definition: SLelement.h:324
iterator end()
Definition: SLelement.h:328
SLelement_listhelper(typename bridges::datastructure::SLelement< E > *s)
Definition: SLelement.h:290
The singly linked list element, derived from Element.
Definition: SLelement.h:26
SLelement(const E &val=E(), const string &lab=string())
Constructs an slelement with the provided value.
Definition: SLelement.h:58
virtual const string getDStype() const override
Returns the data structure name.
Definition: SLelement.h:66
virtual const SLelement * getNext() const
Returns the next element in the list - Constant version.
Definition: SLelement.h:83
virtual const pair< string, string > generateJSON(vector< const SLelement< E > * > nodes) const
Generates the JSON representation of the element.
Definition: SLelement.h:165
SLelement(SLelement *next, const E &val=E(), const string &lab=string())
Constructs an slelement with the provided value.
Definition: SLelement.h:43
void setNext(SLelement *n)
Definition: SLelement.h:92
virtual void getListElements(vector< const SLelement< E > * > &nodes) const
Get the list of nodes.
Definition: SLelement.h:260
virtual SLelement * getNext()
Returns the next element in the list.
Definition: SLelement.h:74
SLelement * next
Definition: SLelement.h:29
typename SLelement< E >::SLelement_listhelper SLelement_List
Definition: SLelement.h:384
constexpr int MAX_ELEMENTS_ALLOWED
Definition: DataStructure.h:62
typename SLelement< E >::SLelement_constlisthelper SLelement_ConstList
Definition: SLelement.h:386
Support for drawing Bar charts.
Definition: alltypes.h:4
const string COLON
Definition: DataStructure.h:52
const string OPEN_BOX
Definition: DataStructure.h:55
const string COMMA
Definition: DataStructure.h:51
const string CLOSE_BOX
Definition: DataStructure.h:56
const string CLOSE_CURLY
Definition: DataStructure.h:54
const string QUOTE
Definition: DataStructure.h:50