Bridges-C++  3.2.0
Bridges(C++API)
MLelement.h
Go to the documentation of this file.
1 #ifndef ML_ELEMENT_H
2 
3 #define ML_ELEMENT_H
4 
5 #include "SLelement.h"
6 
7 namespace bridges {
8  namespace datastructure {
46  template <typename E>
47  class MLelement : public SLelement<E> {
48 
49  protected:
50  MLelement<E> *sub_list = nullptr; // link to a sublist
51  bool tag = false;
52 
53  public:
54 
66  MLelement(const E& val = E(), const string& lab = string())
67  : SLelement<E> (nullptr, val, lab) {
68  sub_list = nullptr;
69  tag = false;
70  }
71 
83  MLelement (string label) : SLelement<E> (nullptr, E(), label) {
84  sub_list = nullptr;
85  tag = false;
86  }
87 
98  MLelement (E e, MLelement<E> *next) : SLelement<E> (next, e, string()) {
99  sub_list = nullptr;
100  tag = false;
101  }
102 
110  // Hmmm, need to think about removing link data from
111  // an existing sublist
112  this->sub_list = sl;
113  tag = true;
114 
115  // create link data from node to head of sublist
116  if (sl)
117  this->links[sl];
118 
119  // by default, color and shape sublist nodes to distinguish them
120  this->getVisualizer()->setColor(Color("red"));
121  this->getVisualizer()->setShape(SQUARE);
122  }
123 
130  return sub_list;
131  }
132 
139  MLelement<E> *getNext() override {
140  return (MLelement<E>*) this->next;
141  }
142 
149  MLelement<E> *getNext() const override {
150  return (MLelement<E>*) this->next;
151  }
152 
159  if (n) {
160  if (this->next != n) // remove old link data, possibly
161  this->links.erase(this->next);
162 
163  this->next = n;
164  this->links[this->next];
165  }
166  }
167 
173  void setTag(bool t) {
174  tag = t;
175  }
176 
182  bool getTag() {
183  return tag;
184  }
190  virtual const string getDStype() const override {
191  return "Multilist";
192  }
193  private:
199  virtual const string getDataStructureRepresentation() const override final {
200  vector<const MLelement<E>*> nodes;
201 
202  // get the list of nodes
203  this->getListElements(this, nodes);
204 
205  // generate the JSON string
206 
207  // map the nodes to a sequence of ids, 0...N-1
208  // then get the JSON string for nodes placeholder
209  // nullptr prevents insertion of other nullptrs
210  unordered_map<const MLelement*, int> node_map { {nullptr, -1} };
211 
212  string nodes_JSON, links_JSON;
213 
214  int i = 0; // get the JSON string for nodes
215  for (const auto* e : nodes) {
216  if (node_map.emplace(e, i).second) {
217  // successful emplacement
218  i++;
219  nodes_JSON += e->getElementRepresentation() + COMMA;
220  }
221  }
222  //Remove trailing comma and nullptr entry
223  node_map.erase(nullptr);
224  if (nodes_JSON.size()) {
225  nodes_JSON = nodes_JSON.erase(nodes_JSON.size() - 1);
226  }
227 
228  // generate the links representation
229  for (int k = 0; k < nodes.size(); k++) {
230  if (nodes[k]->next != nullptr) { // link exists
231  links_JSON += this->getLinkRepresentation(nodes[k]->links.at(nodes[k]->next),
232  to_string(node_map[nodes[k]]),
233  to_string(node_map[nodes[k]->getNext()])) + COMMA;
234  }
235  if (nodes[k]->tag) { // sublist link
236 
237  if (nodes[k]->sub_list != nullptr) { // link exists
238  links_JSON += this->getLinkRepresentation(
239  nodes[k]->links.at(nodes[k]->sub_list),
240  to_string(node_map[nodes[k]]),
241  to_string(node_map[nodes[k]->sub_list])) + COMMA;
242  }
243  }
244  }
245 
246  //Remove trailing comma
247  if (links_JSON.size()) {
248  links_JSON = links_JSON.erase(links_JSON.size() - 1);
249  }
250 
251  string ml_list_json =
252  QUOTE + "nodes" + QUOTE + COLON +
253  OPEN_BOX + nodes_JSON + CLOSE_BOX + COMMA +
254  QUOTE + "links" + QUOTE + COLON + OPEN_BOX +
255  links_JSON + CLOSE_BOX +
256  CLOSE_CURLY;
257 
258  return ml_list_json;
259  }
266  void getListElements(const MLelement<E> *list,
267  vector<const MLelement<E>*>& nodes) const {
268 
269  auto it = list;
270  while (it != nullptr) {
271  nodes.push_back(it);
272  // if this node has a sublist, recurse
273  if (it->tag) {
274  getListElements(it->sub_list, nodes);
275  }
276  // iterate
277  it = (MLelement<E>*) it->next;
278  }
279  }
280  };
281  }
282 } // end namespace bridges
283 
284 #endif
MLelement< E > * sub_list
Definition: MLelement.h:50
static const string getLinkRepresentation(const LinkVisualizer &lv, const string &src, const string &dest)
Definition: Element.h:273
MLelement< E > * getNext() const override
Retrieves the element following this element - const version.
Definition: MLelement.h:149
MLelement< E > * getNext() override
Retrieves the element following this element.
Definition: MLelement.h:139
MLelement(const E &val=E(), const string &lab=string())
constructor
Definition: MLelement.h:66
const string COLON
Definition: DataStructure.h:51
void setNext(MLelement< E > *n)
Sets the element to point to the next MLelement.
Definition: MLelement.h:158
SLelement * next
Definition: SLelement.h:30
const string OPEN_BOX
Definition: DataStructure.h:54
virtual const string getDStype() const override
Return the string representaion of element.
Definition: MLelement.h:190
MLelement * getSubList()
Gets the sublist at this node, if it exists.
Definition: MLelement.h:129
void setColor(const Color &col)
Set the color to "col".
Definition: ElementVisualizer.h:94
MLelement(string label)
Creates an MLelement object.
Definition: MLelement.h:83
const string CLOSE_CURLY
Definition: DataStructure.h:53
This class represents Color, and supports rgba, hexadecimal and named color values.
Definition: Color.h:51
The singly linked list element, derived from Element.
Definition: SLelement.h:27
MLelement(E e, MLelement< E > *next)
Creates an MLelement object.
Definition: MLelement.h:98
bool getTag()
Gets the tag of the element.
Definition: MLelement.h:182
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
void setSubList(MLelement< E > *sl)
Sets the start of a new sublist to the MLelement "next".
Definition: MLelement.h:109
void setTag(bool t)
Sets the tag of the element.
Definition: MLelement.h:173
const string CLOSE_BOX
Definition: DataStructure.h:55
This class can be used to instantiate Multi-list Elements.
Definition: MLelement.h:47
ElementVisualizer * getVisualizer()
Get the element visualizer object.
Definition: Element.h:144
unordered_map< Element *, LinkVisualizer > links
Definition: Element.h:95
void setShape(const Shape &shp)
Set the shape of the element.
Definition: ElementVisualizer.h:140
const string COMMA
Definition: DataStructure.h:50
bool tag
Definition: MLelement.h:51
const string QUOTE
Definition: DataStructure.h:49
Definition: ElementVisualizer.h:10