Samchon Framework for CPP  1.0.0
EntityGroup.hpp
1 #pragma once
2 #include <samchon/protocol/Entity.hpp>
3 #include <samchon/protocol/EntityGroupBase.hpp>
4 
5 #include <algorithm>
6 
7 namespace samchon
8 {
9 namespace protocol
10 {
39  template <typename Container, typename T, typename Key = std::string>
41  : public Container, // CONTAINS CHILD ENTITY ELEMENTS
42  public virtual Entity<Key>, // I AM A TYPE OF ENTITY TOO
43  public EntityGroupBase //INTERFACE
44  {
45  public:
46  typedef Container container_type;
47  typedef T child_type;
48 
49  public:
50  /* ------------------------------------------------------------------------------------
51  CONSTRUCTORS
52  ------------------------------------------------------------------------------------ */
53  using container_type::container_type;
54 
55  virtual ~EntityGroup() = default;
56 
71  virtual void construct(std::shared_ptr<library::XML> xml)
72  {
73  clear();
74  if (xml->has(CHILD_TAG()) == false)
75  return;
76 
77  std::shared_ptr<library::XMLList> &xml_list = xml->get(CHILD_TAG());
78 
79  if (std::is_same<container_type, std::vector<container_type::value_type, container_type::allocator_type>>::value == true)
80  {
81  //FOR RESERVE
82  assign(xml_list->size(), nullptr);
83  erase(begin(), end());
84  }
85 
86  for (size_t i = 0; i < xml_list->size(); i++)
87  {
88  std::shared_ptr<library::XML> &xmlElement = xml_list->at(i);
89 
90  child_type *entity = createChild(xmlElement);
91  if (entity != nullptr)
92  {
93  entity->construct(xml_list->at(i));
94  emplace_back(entity);
95  }
96  }
97  };
98 
99  protected:
110  virtual auto createChild(std::shared_ptr<library::XML>) -> child_type* = 0;
111 
112  public:
113  /* ------------------------------------------------------------------------------------
114  ACCESSORS
115  ------------------------------------------------------------------------------------ */
116  using container_type::erase;
117 
118  void erase(const typename child_type::key_type &key)
119  {
120  for (auto it = begin(); it != end(); )
121  if ((*it)->key() == key)
122  it = erase(it);
123  else
124  it++;
125  };
126 
144  auto find(const typename child_type::key_type &key) -> typename container_type::iterator
145  {
146  return std::find_if
147  (
148  begin(), end(),
149  [key](const container_type::value_type &entity) -> bool
150  {
151  return entity->key() == key;
152  }
153  );
154  };
155 
173  auto find(const typename child_type::key_type &key) const -> typename container_type::const_iterator
174  {
175  return std::find_if
176  (
177  begin(), end(),
178  [key](const container_type::value_type &entity) -> bool
179  {
180  return entity->key() == key;
181  }
182  );
183  };
184 
191  auto has(const typename child_type::key_type &key) const -> bool
192  {
193  return std::any_of
194  (
195  begin(), end(),
196  [key](const container_type::value_type &entity) -> bool
197  {
198  return entity->key() == key;
199  }
200  );
201  };
202 
209  auto count(const typename child_type::key_type &key) const -> size_t
210  {
211  return std::count_if
212  (
213  begin(), end(),
214  [key](const container_type::value_type &entity) -> bool
215  {
216  return entity->key() == key;
217  }
218  );
219  };
220 
227  auto get(const typename child_type::key_type &key) -> typename container_type::value_type&
228  {
229  auto it = std::find_if
230  (
231  begin(), end(),
232  [key](const container_type::value_type &entity) -> bool
233  {
234  return entity->key() == key;
235  }
236  );
237 
238  if (it == end())
239  throw std::out_of_range("out of range");
240 
241  return *it;
242  };
243 
250  auto get(const typename child_type::key_type &key) const -> const typename container_type::value_type&
251  {
252  auto it = std::find_if
253  (
254  begin(), end(),
255  [key](const container_type::value_type &entity) -> bool
256  {
257  return entity->key() == key;
258  }
259  );
260 
261  if (it == end())
262  throw std::out_of_range("out of range");
263 
264  return *it;
265  };
266 
267  /* ------------------------------------------------------------------------------------
268  EXPORTERS
269  ------------------------------------------------------------------------------------ */
285  virtual auto toXML() const -> std::shared_ptr<library::XML>
286  {
287  std::shared_ptr<library::XML> &xml = Entity::toXML();
288 
289  std::shared_ptr<library::XMLList> xmlList(new library::XMLList());
290  xmlList->reserve(this->size());
291 
292  for (auto it = begin(); it != end(); it++)
293  xmlList->push_back((*it)->toXML());
294 
295  xml->set(CHILD_TAG(), xmlList);
296  return xml;
297  };
298  };
299 };
300 };
An entity, a standard data class.
Definition: Entity.hpp:115
virtual auto createChild(std::shared_ptr< library::XML >) -> child_type *=0
Factory method of a child Entity.
virtual void construct(std::shared_ptr< library::XML > xml)
Construct data of the Entity from an XML object.
Definition: EntityGroup.hpp:71
auto find(const typename child_type::key_type &key) -> typename container_type::iterator
Get iterator to element.
auto count(const typename child_type::key_type &key) const -> size_t
Count elements with a specific key.
auto has(const typename child_type::key_type &key) const -> bool
Indicates whether a container has an object having the specified identifier.
auto find(const typename child_type::key_type &key) const -> typename container_type::const_iterator
Get const iterator to element.
virtual auto CHILD_TAG() const -> std::string=0
A tag name of children.
An Entity and a container of children Entity objects.
Definition: EntityGroup.hpp:40
virtual auto key() const -> Key
Get a key that can identify the Entity uniquely.
Definition: Entity.hpp:133
virtual auto toXML() const -> std::shared_ptr< library::XML >
Get an XML object represents the EntityGroup.
An iternface for entity group.