Gorgon Game Engine
Collection.h
Go to the documentation of this file.
1 
3 #pragma once
4 
5 #pragma warning(error: 4239)
6 
7 #include <vector>
8 #include <stdexcept>
9 #include <algorithm>
10 
11 #include "Iterator.h"
12 
13 namespace Gorgon {
14  namespace Containers {
15 
20  template <class T_>
21  class Collection {
22 
23  template<class P_>
24  struct sorter {
25  sorter(const P_ &predicate) : predicate(predicate) {}
26 
27  bool operator ()(const T_ *left, const T_*right) const {
28  if(left==NULL || right==NULL)
29  return false;
30 
31  return predicate(*left,*right);
32  }
33 
34  const P_ &predicate;
35  };
36 
39  template<class O_, class C_>
40  class Iterator_ : public Containers::Iterator<Iterator_<O_, C_>, O_> {
41  friend class Containers::Iterator<Iterator_, O_>;
42  friend class Collection;
43 
44  public:
46  Iterator_() : col(NULL), offset(-1) {
47  }
49  Iterator_(const Iterator_ &it) : col(it.col), offset(it.offset) {
50  }
51 
55  void Remove() {
56  col->Remove(offset);
57  offset--;
58  }
59 
63  void Delete() {
64  col->Delete(offset);
65  offset--;
66  }
67 
68  protected:
69  Iterator_(C_ &c, long offset=0) : col(&c), offset(offset) {
70  }
71 
72  protected:
75  O_ &current() const {
76  if(!isvalid())
77  throw std::out_of_range("Iterator is not valid.");
78 
79  return *col->list[offset];
80  }
81 
82  bool isvalid() const {
83  return offset>=0 && offset<(col->GetCount());
84  }
85 
86  bool isinrange() const {
87  return offset>=0 || offset<(col->GetCount());
88  }
89 
90  bool moveby(long amount) {
91  //sanity check
92  if(amount==0) return isvalid();
93 
94  offset+=amount;
95 
96  return isvalid();
97  }
98 
99  bool compare(const Iterator_ &it) const {
100  if(!it.isvalid() && !isvalid()) return true;
101  return it.offset==offset;
102  }
103 
104  void set(const Iterator_ &it) {
105  col=it.col;
106  offset=it.offset;
107  }
108 
109  long distance(const Iterator_ &it) const {
110  return it.offset-offset;
111  }
112 
113  bool isbefore(const Iterator_ &it) const {
114  return offset<it.offset;
115  }
117 
118  public:
119 
121  Iterator_ &operator =(const Iterator_ &iterator) {
122  set(iterator);
123 
124  return *this;
125  }
126 
127  private:
128  C_ *col;
129  long offset;
130  };
131 
132  public:
134  typedef Iterator_<T_, Collection> Iterator;
135 
137  class ConstIterator : public Iterator_<T_,const Collection> {
138  friend class Collection;
139  public:
141  ConstIterator(const Iterator &it) {
142  this->col=it.col;
143  this->offset=it.offset;
144  }
145 
146  private:
147  ConstIterator(const Collection &c, long offset=0) : Iterator_<T_,const Collection>(c, offset) {
148  }
149 
150  void Remove() {}
151  void Delete() {}
152  };
153 
155  class Adder {
156  friend class Collection;
157  Adder(Collection &col) : col(col) { }
158  Collection &col;
159  public:
160 
161  Adder &operator ,(T_ &item) {
162  col.Add(item);
163  return *this;
164  }
165 
166  Adder &operator ,(T_ *item) {
167  col.Add(item);
168  return *this;
169  }
170 
171  Adder &operator =(Adder &) =delete;
172  };
174 
175  public:
177  Collection() = default;
178 
185  template<typename... Args_>
186  Collection(T_ &t, Args_ &... args) {
187  list.reserve(sizeof...(Args_)+1);
188  Add(t, args...);
189  }
190 
197  template<typename... Args_>
198  Collection(T_ *t, Args_ *... args) {
199  list.reserve(sizeof...(Args_)+1);
200  Add(t, args...);
201  }
202 
204  Collection(const Collection &) = delete;
205 
207  Collection &operator =(const Collection &) = delete;
208 
210  Collection(Collection &&col) : list(std::move(col.list)) {
211  }
212 
215  Collapse();
216  list.swap(col.list);
217 
218  return *this;
219  }
220 
222  void Swap(Collection &col) {
223  list.swap(col.list);
224  }
225 
229  Collection c;
230  c.list=list;
231 
232  return c;
233  }
234 
236  long GetCount() const {
237  return (long)list.size();
238  }
239 
241  long GetSize() const {
242  return (long)list.size();
243  }
244 
245 
248  bool Add(T_* Data) {
249  if(std::find(list.begin(), list.end(), Data)==list.end()) {
250  list.push_back(Data);
251 
252  return true;
253  }
254 
255  return false;
256  }
257 
260  bool Add(T_& data) {
261  return Add(&data);
262  }
263 
266  bool Push(T_* Data) {
267  return Add(Data);
268  }
269 
272  bool Push(T_& data) {
273  return Add(data);
274  }
275 
277  T_ &Pop() {
278  if(!GetCount()) {
279  throw std::out_of_range("No items in the collection");
280  }
281 
282  T_ &ret = Get(GetCount()-1);
283  Remove(GetCount()-1);
284 
285  return ret;
286  }
287 
290  template<typename... Args_>
291  int Add(T_* Data, Args_ *... args) {
292  int ret = Add(Data) ? 1 : 0;
293  ret += Add(args...);
294 
295  return ret;
296  }
297 
299  template<typename... Args_>
300  int Add(T_& data, Args_ &... args) {
301  int ret = Add(&data) ? 1 : 0;
302  ret += Add(args...);
303 
304  return ret;
305  }
306 
308  template<typename... Args_>
309  T_ &AddNew(Args_&&... args) {
310  auto t = new T_(std::forward<Args_>(args)...);
311  Add(t);
312 
313  return *t;
314  }
315 
318  bool Insert(T_* data, long before) {
319  if(std::find(list.begin(), list.end(), data)!=list.end()) return false;
320 
321  if(before==-1)
322  before=(long)list.size();
323 
324  if(before<0 || before>(long)list.size())
325  throw std::out_of_range("Invalid location");
326 
327  if(before==list.size()) {
328  return Add(data);
329  }
330 
331  list.resize(list.size()+1);
332 
333  for(long i=(long)list.size()-1;i>before;i--)
334  list[i]=list[i-1];
335 
336  list[before]=data;
337 
338  return true;
339  }
340 
343  bool Insert(T_& data, long before) {
344  return Insert(&data, before);
345  }
346 
349  bool Insert(T_* data, const T_ &before) {
350  return Insert(data, FindLocation(before));
351  }
352 
355  bool Insert(T_& data, const T_ &before) {
356  return Insert(&data, FindLocation(before));
357  }
358 
361  template<typename... Args_>
362  T_ &InsertNew(const T_ &before, Args_... args) {
363  auto t=new T_(args...);
364  Insert(t, before);
365 
366  return *t;
367  }
368 
371  template<typename... Args_>
372  T_ &InsertNew(long before, Args_... args) {
373  auto t=new T_(args...);
374  Insert(t, before);
375 
376  return *t;
377  }
378 
380  void MoveBefore(long index, long before) {
381  if(before == -1)
382  before = list.size();
383  if(index>=list.size())
384  throw std::out_of_range("Invalid location");
385  if(before>list.size())
386  throw std::out_of_range("Invalid location");
387 
388  if(index==before)
389  return;
390 
391  if(index>before) {
392  T_ *t=list[index];
393  for(long i=index; i>before; i--)
394  list[i]=list[i-1];
395 
396  list[before]=t;
397  }
398  else if(before==list.size()) {
399  T_ *t=list[index];
400 
401  for(long i=index; i<list.size()-1; i++)
402  list[i]=list[i+1];
403 
404  list[list.size()-1]=t;
405  }
406  else {
407  T_ *t=list[index];
408  for(long i=index; i<before; i++)
409  list[i]=list[i+1];
410 
411  list[before]=t;
412  }
413  }
414 
416  void MoveBefore(long index, const T_ &before) {
417  MoveBefore(index, FindLocation(before));
418  }
419 
421  void MoveBefore(const T_ &index, long before) {
422  MoveBefore(FindLocation(index), before);
423  }
424 
426  void MoveBefore(const T_ &index, const T_ &before) {
427  MoveBefore(FindLocation(index), FindLocation(before));
428  }
429 
431  Adder operator +=(T_* Data) {
432  Add(Data);
433 
434  return Adder(*this);
435  }
436 
438  Adder operator +=(T_& data) {
439  Add(&data);
440 
441  return Adder(*this);
442  }
443 
445  void Remove(long index) {
446  list.erase(list.begin()+index);
447  }
448 
451  void Remove(const T_ *item) {
452  auto l=FindLocation(item);
453  if(l==-1) return;
454 
455  Remove(l);
456  }
457 
460  void Remove(const T_ &data) {
461  Remove(&data);
462  }
463 
464  void Remove(ConstIterator &it) {
465  auto tmp = it;
466  ++it;
467  list.erase(list.begin() + tmp.offset);
468  }
469 
470  void Remove(Iterator &it) {
471  auto tmp = it;
472  ++it;
473  list.erase(list.begin() + tmp.offset);
474  }
475 
478  void Delete(long index) {
479  delete list[index];
480 
481  list.erase(list.begin()+index);
482  }
483 
487  void Delete(const T_ *item) {
488  auto l=FindLocation(item);
489  if(l==-1) {
490  delete item;
491  return;
492  }
493  Delete(l);
494  }
495 
499  void Delete(T_& data) {
500  Delete(&data);
501  }
502 
503  void Delete(ConstIterator &it) {
504  auto tmp = it;
505  ++it;
506  delete tmp.CurrentPtr();
507  list.erase(list.begin() + tmp.offset);
508  }
509 
510  void Delete(Iterator &it) {
511  auto tmp = it;
512  ++it;
513  delete tmp.CurrentPtr();
514  list.erase(list.begin() + tmp.offset);
515  }
516 
518  Iterator Find(const T_ *item) {
519  return Iterator(*this, FindLocation(item));
520  }
521 
523  Iterator Find(const T_ &item) {
524  return Iterator(*this, FindLocation(item));;
525  }
526 
528  ConstIterator Find(const T_ *item) const {
529  return ConstIterator(*this, FindLocation(item));
530  }
531 
533  ConstIterator Find(const T_ &item) const {
534  return ConstIterator(*this, FindLocation(item));
535  }
536 
538  long FindLocation(const T_ *item) const {
539  auto it=find(list.begin(), list.end(), item);
540 
541  if(it==list.end())
542  return -1;
543  else
544  return long(it-list.begin());
545  }
546 
548  long FindLocation(const T_ &item) const {
549  return FindLocation(&item);
550  }
551 
554  template<class P_>
555  void Sort(P_ predicate=P_()) {
556  std::sort(list.begin(), list.end(), sorter<P_>(predicate));
557  }
558 
561  void Sort() {
562  std::sort(list.begin(), list.end(), sorter<std::less<T_>>(std::less<T_>()));
563  }
564 
566  T_ &Get(long index) {
567  T_ *r=get_(index);
568 
569  if(r==NULL)
570  throw std::out_of_range("Index out of range");
571 
572  return *r;
573  }
574 
576  T_ &Get(long index) const {
577  const T_ *r=get_(index);
578 
579  if(r==NULL)
580  throw std::out_of_range("Index out of range");
581 
582  return *r;
583  }
584 
586  T_& operator [] (long index) {
587  return *list[index];
588  }
589 
591  T_& operator [] (long index) const {
592  return *list[index];
593  }
594 
599  return Iterator(*this, 0);
600  }
601 
604  return Iterator(*this, (long)list.size());
605  }
606 
609  return Iterator(*this, 0);
610  }
611 
614  return Iterator(*this, long(list.size()-1));
615  }
616 
618  ConstIterator begin() const {
619  return ConstIterator(*this, 0);
620  }
621 
623  ConstIterator end() const {
624  return ConstIterator(*this, (long)list.size());
625  }
626 
628  ConstIterator First() const {
629  return ConstIterator(*this, 0);
630  }
631 
633  ConstIterator Last() const {
634  return ConstIterator(*this, long(list.size()-1));
635  }
637 
639  void Clear() {
640  list.clear();
641  }
642 
645  void Collapse() {
646  std::vector<T_*> newlist;
647  using std::swap;
648 
649  swap(newlist, list);
650  }
651 
653  void DeleteAll() {
654  for(auto e : list)
655  delete e;
656 
657  list.clear();
658  }
659 
662  void Destroy() {
663  for(auto e : list)
664  delete e;
665 
666  std::vector<T_*> newlist;
667  using std::swap;
668 
669  swap(newlist, list);
670  }
671 
673  void Reserve(long amount) {
674  list.reserve(amount);
675  }
676 
677  protected:
679  std::vector<T_ *> list;
680 
681  void removeat(long absolutepos) {
682  Remove(absolutepos);
683  }
684 
685  void deleteat(long absolutepos) {
686  Delete(absolutepos);
687  }
688 
689  T_ *get_(long Index) {
690  if(Index<0 || Index>=(long)list.size())
691  return NULL;
692 
693  return list[Index];
694  }
695 
696  const T_ *get_(long Index) const {
697  if(Index<0 || Index>list.size())
698  return NULL;
699 
700  return list[Index];
701  }
703  };
704 
706  template<class T_>
707  inline void swap(Collection<T_> &l, Collection<T_> &r) {
708  l.Swap(r);
709  }
710  }
711 }
712 
Gorgon::Containers::Remove
void Remove(const I_ &first, const I_ &end)
This function works with collection iterators.
Definition: Iterator.h:386
Gorgon::Containers::Collection::Remove
void Remove(long index)
Removes an item from the collection using its index.
Definition: Collection.h:445
Gorgon::Containers::Collection::Remove
void Remove(Iterator &it)
Definition: Collection.h:470
Gorgon::Resource::GID::Data
constexpr Type Data
Data resource.
Definition: GID.h:164
Gorgon::Containers::Collection::Remove
void Remove(const T_ &data)
Removes an item from the collection using its reference.
Definition: Collection.h:460
Gorgon::Containers::Collection::Remove
void Remove(const T_ *item)
Removes an item from the collection using its pointer.
Definition: Collection.h:451
Gorgon::Containers::swap
void swap(Collection< T_ > &l, Collection< T_ > &r)
Swaps two collections.
Definition: Collection.h:707
Gorgon::Containers::Collection::Last
ConstIterator Last() const
returns the iterator to the last item
Definition: Collection.h:633
Gorgon::Containers::Collection::Collection
Collection(T_ &t, Args_ &... args)
Initializing constructor.
Definition: Collection.h:186
Gorgon::Containers::Collection::Add
bool Add(T_ *Data)
Adds the given item to the end of the list if it is not already in the list.
Definition: Collection.h:248
Gorgon::Containers::Collection::MoveBefore
void MoveBefore(long index, const T_ &before)
this method moves the given object in the collection in front of the reference
Definition: Collection.h:416
Gorgon::Containers::Collection::operator+=
Adder operator+=(T_ *Data)
Adds items to the end of the list. Use comma to add more than one item.
Definition: Collection.h:431
Gorgon::Containers::Collection::end
Iterator end()
end iterator
Definition: Collection.h:603
Gorgon::Containers::Collection::MoveBefore
void MoveBefore(const T_ &index, const T_ &before)
this method moves the given object in the collection in front of the reference
Definition: Collection.h:426
Gorgon::Containers::Collection::Add
int Add(T_ *Data, Args_ *... args)
Adds the given item to the end of the list, returns the number of added elements.
Definition: Collection.h:291
Gorgon::Containers::Collection::GetSize
long GetSize() const
Returns number of elements.
Definition: Collection.h:241
Gorgon::Containers::Collection::Remove
void Remove(ConstIterator &it)
Definition: Collection.h:464
Gorgon::Containers::Collection::begin
Iterator begin()
Definition: Collection.h:598
Gorgon::Containers::Collection::Sort
void Sort()
Sorts items in the collection.
Definition: Collection.h:561
Gorgon::Containers::Collection::Insert
bool Insert(T_ &data, const T_ &before)
this method adds the given object in front of the reference.
Definition: Collection.h:355
Gorgon::Containers::Collection::Last
Iterator Last()
returns the iterator to the last item
Definition: Collection.h:613
Gorgon::Containers::Collection::operator=
Collection & operator=(Collection &&col)
Move assignment.
Definition: Collection.h:214
Gorgon::Containers::Collection::Find
Iterator Find(const T_ *item)
Searches the position of a given item, if not found end iterator returned.
Definition: Collection.h:518
Gorgon::Containers::Collection::Delete
void Delete(const T_ *item)
Deletes an item from the collection using its pointer.
Definition: Collection.h:487
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Containers::Collection::MoveBefore
void MoveBefore(long index, long before)
this method moves the given object in the collection in front of the reference
Definition: Collection.h:380
Gorgon::Containers::Collection::Delete
void Delete(ConstIterator &it)
Definition: Collection.h:503
Gorgon::Containers::Collection::Sort
void Sort(P_ predicate=P_())
Sorts items in the collection.
Definition: Collection.h:555
Gorgon::Containers::Collection::Delete
void Delete(T_ &data)
Deletes an item from the collection using its reference.
Definition: Collection.h:499
Gorgon::Containers::Collection::end
ConstIterator end() const
end iterator
Definition: Collection.h:623
Gorgon::Containers::Collection::Add
bool Add(T_ &data)
Adds a the given item to the end of the list if it is not already in the list.
Definition: Collection.h:260
Gorgon::Containers::Collection
Collection is a container for reference typed objects.
Definition: Collection.h:21
Gorgon::Containers::Collection::Insert
bool Insert(T_ *data, const T_ &before)
this method adds the given object in front of the reference.
Definition: Collection.h:349
Gorgon::Containers::Collection::Collection
Collection(Collection &&col)
Move constructor.
Definition: Collection.h:210
Iterator.h
contains filesystem Iterator. Lists file and directories.
Gorgon::Containers::Collection::ConstIterator
Const iterator allows iteration of const collections.
Definition: Collection.h:137
Gorgon::Containers::Collection::Iterator
Iterator_< T_, Collection > Iterator
Regular iterator.
Definition: Collection.h:134
Gorgon::Containers::Collection::First
Iterator First()
returns the iterator to the first item
Definition: Collection.h:608
Gorgon::Containers::Collection::GetCount
long GetCount() const
Returns number of elements.
Definition: Collection.h:236
Gorgon::Containers::Collection::Collection
Collection(const Collection &)=delete
Disabled.
Gorgon::Input::Keyboard::Keycodes::Delete
constexpr Key Delete
Definition: Keyboard.h:43
Gorgon::Containers::Collection::Reserve
void Reserve(long amount)
Allocates memory for the given amount of items.
Definition: Collection.h:673
Gorgon::Containers::Collection::Find
Iterator Find(const T_ &item)
Searches the position of a given item, if not found end iterator returned.
Definition: Collection.h:523
Gorgon::Containers::Collection::ConstIterator::ConstIterator
ConstIterator(const Iterator &it)
Regular iterators can be converted to const iterators.
Definition: Collection.h:141
Gorgon::Containers::Collection::InsertNew
T_ & InsertNew(const T_ &before, Args_... args)
Creates a new item and inserts it before the given reference.
Definition: Collection.h:362
Gorgon::Containers::Collection::Collapse
void Collapse()
Clears the contents of the collection and releases the memory used for the list.
Definition: Collection.h:645
Gorgon::Containers::Collection::Clear
void Clear()
Removes all items from the list, allocated memory for the list stays.
Definition: Collection.h:639
Gorgon::Containers::Collection::AddNew
T_ & AddNew(Args_ &&... args)
Creates a new item and adds to the end of the collection.
Definition: Collection.h:309
Gorgon::Containers::Collection::begin
ConstIterator begin() const
begin iterator
Definition: Collection.h:618
Gorgon::Containers::Collection::Add
int Add(T_ &data, Args_ &... args)
Adds a the given item to the end of the list.
Definition: Collection.h:300
Gorgon::Containers::Collection::Get
T_ & Get(long index) const
Returns the element at the given index. Checks and throws if out of range.
Definition: Collection.h:576
Gorgon::Containers::Collection::Swap
void Swap(Collection &col)
Swaps the given collection with this one.
Definition: Collection.h:222
Gorgon::Containers::Collection::MoveBefore
void MoveBefore(const T_ &index, long before)
this method moves the given object in the collection in front of the reference
Definition: Collection.h:421
Gorgon::Containers::Collection::InsertNew
T_ & InsertNew(long before, Args_... args)
Creates a new item and inserts it before the given reference.
Definition: Collection.h:372
Gorgon::Containers::Collection::First
ConstIterator First() const
returns the iterator to the first item
Definition: Collection.h:628
Gorgon::Containers::Collection::operator[]
T_ & operator[](long index)
Returns the item at a given index.
Definition: Collection.h:586
Gorgon::Containers::Collection::Delete
void Delete(long index)
Deletes an item from the collection using its index.
Definition: Collection.h:478
Gorgon::Containers::Collection::Destroy
void Destroy()
Destroys the entire collection, effectively deleting the contents and the list including all the memo...
Definition: Collection.h:662
Gorgon::Containers::Collection::Insert
bool Insert(T_ *data, long before)
this method adds the given object in front of the reference.
Definition: Collection.h:318
Gorgon::Containers::Collection::operator=
Collection & operator=(const Collection &)=delete
Disabled.
Gorgon::Containers::Collection::DeleteAll
void DeleteAll()
Deletes and removes all elements in the collection.
Definition: Collection.h:653
Gorgon::Containers::Collection::Get
T_ & Get(long index)
Returns the element at the given index. Checks and throws if out of range.
Definition: Collection.h:566
Gorgon::Containers::Collection::Push
bool Push(T_ *Data)
Adds the given item to the end of the list if it is not already in the list.
Definition: Collection.h:266
Gorgon::Containers::Collection::Pop
T_ & Pop()
Removes and returns the last item in the collection.
Definition: Collection.h:277
Gorgon::Containers::Collection::Delete
void Delete(Iterator &it)
Definition: Collection.h:510
Gorgon::Containers::Collection::Collection
Collection(T_ *t, Args_ *... args)
Initializing constructor.
Definition: Collection.h:198
Gorgon::Containers::Iterator
Generic iterator interface.
Definition: Iterator.h:31
Gorgon::Containers::Collection::Find
ConstIterator Find(const T_ &item) const
Searches the position of a given item, if not found end iterator returned.
Definition: Collection.h:533
Gorgon::Containers::Collection::FindLocation
long FindLocation(const T_ &item) const
Searches the position of a given item, if not found -1 is returned.
Definition: Collection.h:548
Gorgon::Containers::Collection::Insert
bool Insert(T_ &data, long before)
this method adds the given object in front of the reference.
Definition: Collection.h:343
Gorgon::Containers::Collection::Collection
Collection()=default
Default constructor.
Gorgon::Containers::Collection::Push
bool Push(T_ &data)
Adds a the given item to the end of the list if it is not already in the list.
Definition: Collection.h:272
Gorgon::Containers::Collection::FindLocation
long FindLocation(const T_ *item) const
Searches the position of a given item, if not found -1 is returned.
Definition: Collection.h:538
Gorgon::Containers::Collection::Duplicate
Collection Duplicate() const
Duplicates this collection.
Definition: Collection.h:228
Gorgon::Containers::Collection::Find
ConstIterator Find(const T_ *item) const
Searches the position of a given item, if not found end iterator returned.
Definition: Collection.h:528