xtd 0.2.0
arranged_element_collection.h
Go to the documentation of this file.
1 #pragma once
5 #include "sorter_none.h"
6 #include <xtd/argument_out_of_range_exception>
7 #include <xtd/event_args>
8 #include <xtd/event_handler>
9 #include <xtd/event>
10 #include <xtd/object>
11 #include <limits>
12 #include <ostream>
13 #include <vector>
14 
16 namespace xtd {
18  namespace forms {
20  namespace layout {
30  template<typename type_t, typename sorter_t = sorter_none>
32  public:
34  class value_type : public type_t {
35  public:
37  value_type() = default;
38  value_type(const value_type&) = default;
39  value_type(value_type&&) = default;
40  template <typename ...args_t>
41  value_type(args_t&& ...args) : type_t(args...) {}
42  value_type& operator =(const value_type& value) {
43  if (value.owner) owner = value.owner;
44  if (owner != nullptr && !owner->inserting_ && !owner->erasing_) owner->item_updated(pos, static_cast<type_t&>(const_cast<value_type&>(value)));
45  type_t::operator =(value);
46  return *this;
47  }
48  value_type& operator =(value_type&& value) {
49  if (value.owner) owner = value.owner;
50  if (owner != nullptr && !owner->inserting_ && !owner->erasing_) owner->item_updated(pos, static_cast<type_t&>(value));
51  type_t::operator =(value);
52  return *this;
53  }
54  operator type_t() {return *this;}
55  friend std::ostream& operator <<(std::ostream& os, const value_type& value) {return os << static_cast<const type_t&>(value);}
57 
58  private:
59  friend class arranged_element_collection;
60  size_t pos = std::numeric_limits<size_t>::max();
61  arranged_element_collection* owner = nullptr;
62  };
63 
65 
68  using allocator_type = std::allocator<value_type>;
70  using size_type = std::size_t;
72  using difference_type = std::ptrdiff_t;
74  using reference = value_type&;
76  using const_reference = const value_type&;
78  using pointer = typename std::allocator_traits<allocator_type>::pointer;
80  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
82  using iterator = typename std::vector<value_type>::iterator;
84  using const_iterator = typename std::vector<value_type>::const_iterator;
86  using reverse_iterator = typename std::vector<value_type>::reverse_iterator;
88  using const_reverse_iterator = typename std::vector<value_type>::const_reverse_iterator;
90 
92 
95  inline static const size_t npos = std::numeric_limits<size_t>::max();
97 
99 
104  explicit arranged_element_collection(const allocator_type& allocator = allocator_type()) : collection_(allocator) {}
107  arranged_element_collection(const std::initializer_list<type_t>& il) {
108  for (auto item : il)
109  push_back(item);
110  }
112 
114  explicit arranged_element_collection(const std::vector<type_t>& collection) {
115  for (auto item : collection)
116  push_back(item);
117  }
119  arranged_element_collection& operator =(const arranged_element_collection& collection) {
120  clear();
121  push_back_range(collection);
122  return *this;
123  }
125  bool operator ==(const arranged_element_collection& value) const {return collection_ == value.collection_;}
126  bool operator !=(const arranged_element_collection& value) const {return !operator ==(value);}
128 
130 
134  allocator_type get_allocator() const noexcept {return collection_.get_allocator();}
135 
140  collection_[pos].pos = pos;
141  collection_[pos].owner = this;
142  return collection_.at(pos);
143  }
147  const_reference at(size_type pos) const {return collection_.at(pos);}
148 
151  reference front() {return collection_.front();}
154  const_reference front() const {return collection_.front();}
155 
158  reference back() {return collection_.back();}
161  const_reference back() const {return collection_.back();}
162 
165  pointer data() {return collection_.data();}
168  const_pointer data() const {return collection_.data();}
169 
172  iterator begin() noexcept {return collection_.begin();}
175  const_iterator begin() const noexcept {return collection_.begin();}
178  const_iterator cbegin() const noexcept {return collection_.cbegin();}
179 
182  iterator end() noexcept {return collection_.end();}
185  const_iterator end() const noexcept {return collection_.end();}
188  const_iterator cend() const noexcept {return collection_.cend();}
189 
192  reverse_iterator rbegin() noexcept {return collection_.rbegin();}
195  const_reverse_iterator rbegin() const noexcept {return collection_.rbegin();}
198  const_reverse_iterator crbegin() const noexcept {return collection_.crbegin();}
199 
202  reverse_iterator rend() noexcept {return collection_.rend();}
205  const_reverse_iterator rend() const noexcept {return collection_.rend();}
208  const_reverse_iterator crend() const noexcept {return collection_.crend();}
209 
212  bool empty() const noexcept {return collection_.empty();}
213 
216  size_type size() const noexcept {return collection_.size();}
217 
220  size_type max_size() const noexcept {return collection_.max_size();}
221 
223  void reserve(size_type size) {collection_.reserve(size);}
224 
227  size_type capacity() const noexcept {return collection_.capacity();}
228 
230  void shrink_to_fit() {collection_.shrink_to_fit();}
231 
234  bool sorted() const noexcept {return sorted_;}
237  void sorted(bool value) {
238  if (sorted_ != value) {
239  sorted_ = value;
240  if (sorted_) sort();
241  }
242  }
243 
245  void clear() noexcept {
246  iterator it = begin();
247  while (it != end())
248  it = erase(it);
249  }
250 
254  iterator insert(const_iterator pos, const value_type& value) {
255  size_t index = pos - begin();
256  inserting_ = true;
257  iterator result = collection_.insert(pos, value);
258  inserting_ = false;
259  (*this)[index].owner = this;
260  (*this)[index].pos = index;
261  item_added(index, collection_[index]);
262  if (sorted_) sort();
263  return result;
264  }
268  iterator insert(const_iterator pos, const value_type&& value) {
269  size_t index = pos - begin();
270  inserting_ = true;
271  iterator result = collection_.insert(pos, value);
272  inserting_ = false;
273  (*this)[index].owner = this;
274  (*this)[index].pos = index;
275  item_added(index, collection_[index]);
276  if (sorted_) sort();
277  return result;
278  }
279 
283  void insert_at(size_t index, const value_type& value) {
284  if (index > size()) throw argument_out_of_range_exception {csf_};
285  insert(begin() + index, value);
286  }
287 
291  template<typename ...args_t>
292  void emplace(const_iterator pos, args_t&& ... args) {
293  size_t index = pos - begin();
294  inserting_ = true;
295  iterator result = collection_.insert(pos, args...);
296  inserting_ = false;
297  (*this)[index].owner = this;
298  (*this)[index].pos = index;
299  item_added(index, collection_[index]);
300  if (sorted_) sort();
301  return result;
302  }
303 
306  template<typename ...args_t>
307  void emplace_back(args_t&& ... args) {
308  collection_.push_back(args...);
309  size_t index = collection_.size() - 1;
310  (*this)[index].owner = this;
311  (*this)[index].pos = index;
312  item_added(index, collection_[index]);
313  if (sorted_) sort();
314  }
315 
319  item_removed(pos - begin(), *pos);
320  erasing_ = true;
321  iterator result = collection_.erase(pos);
322  erasing_ = false;
323  return result;
324  }
328  item_removed(pos - begin(), *pos);
329  erasing_ = true;
330  iterator result = collection_.erase(pos);
331  erasing_ = false;
332  return result;
333  }
334 
339  iterator result = end();
340  for (iterator it = first; it <= last; ++it)
341  result = erase(it);
342  return result;
343  }
348  iterator result = this->bend();
349  for (const_iterator it = first; it <= last; ++it)
350  result = erase(it);
351  return result;
352  }
353 
356  void erase_at(size_t index) {
357  if (index > size()) throw argument_out_of_range_exception {csf_};
358  erase(begin() + index);
359  }
360 
362  void pop_back() {
363  if (size() != 0) erase_at(size() - 1);
364  }
365 
368  void push_back(const value_type& item) {
369  collection_.push_back(item);
370  size_t index = collection_.size() - 1;
371  (*this)[index].owner = this;
372  (*this)[index].pos = index;
373  item_added(index, collection_[index]);
374  if (sorted_) sort();
375  }
378  void push_back(value_type&& item) {
379  collection_.push_back(item);
380  size_t index = collection_.size() - 1;
381  (*this)[index].owner = this;
382  (*this)[index].pos = index;
383  item_added(index, collection_[index]);
384  if (sorted_) sort();
385  }
386 
390  for (value_type item : collection)
391  push_back(item);
392  }
395  void push_back_range(const std::vector<value_type>& collection) {
396  for (value_type item : collection)
397  push_back(item);
398  }
401  void push_back_range(const std::initializer_list<value_type>& collection) {
402  for (value_type item : collection)
403  push_back(item);
404  }
407  template<typename collection_t>
408  void push_back_range(collection_t&& collection) {
409  for (auto& item : collection)
410  push_back(value_type(item));
411  }
414  template<typename iterator_t>
415  void push_back_range(iterator_t begin, iterator_t end) {
416  for (auto it = begin; it != end; ++it)
417  push_back(value_type(*it));
418  }
419 
421  void sort() {
422  sorter_t sorter;
423  sorter(begin(), end());
424  }
425 
428  std::vector<type_t> to_array() const noexcept {
429  std::vector<type_t> array;
430  std::for_each(collection_.begin(), collection_.end(), [&](auto item) {array.push_back(item);});
431  return array;
432  }
433 
436  std::vector<type_t> to_vector() const noexcept {return to_array();}
438 
440 
445  collection_[pos].pos = pos;
446  collection_[pos].owner = this;
447  return collection_[pos];
448  }
452  collection_[pos].pos = pos;
453  collection_[pos].owner = const_cast<arranged_element_collection*>(this);
454  return collection_[pos];
455  }
457 
459 
464 
468 
473 
474  private:
475  mutable std::vector<value_type, allocator_type> collection_;
476  bool inserting_ = false;
477  bool erasing_ = false;
478  bool sorted_ = false;
479  };
480  }
481  }
482 }
void shrink_to_fit()
Reduces memory usage by freeing unused memory.
Definition: arranged_element_collection.h:230
std::vector< type_t > to_vector() const noexcept
Gets an array with the elements of the container.
Definition: arranged_element_collection.h:436
const_iterator begin() const noexcept
Returns an iterator to the beginning.
Definition: arranged_element_collection.h:175
reference front()
Access the first element.
Definition: arranged_element_collection.h:151
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:198
void sorted(bool value)
Sets the container is sorted.
Definition: arranged_element_collection.h:237
arranged_element_collection(const allocator_type &allocator=allocator_type())
Creates a new object xtd::forms::layout::arranged_element_collection with specified allocator (option...
Definition: arranged_element_collection.h:104
void emplace(const_iterator pos, args_t &&... args)
Inserts specified element at specified position.
Definition: arranged_element_collection.h:292
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:192
const value_type & const_reference
Represents the value type const reference the collection.
Definition: arranged_element_collection.h:76
const_reference at(size_type pos) const
Access specified element with bounds checking.
Definition: arranged_element_collection.h:147
typename std::vector< value_type >::const_reverse_iterator const_reverse_iterator
Represents the const reverse iterator type of the collection.
Definition: arranged_element_collection.h:88
bool empty() const noexcept
Checks whether the container is empty.
Definition: arranged_element_collection.h:212
void erase_at(size_t index)
Erases element at specified index.
Definition: arranged_element_collection.h:356
void reserve(size_type size)
Reserves storage.
Definition: arranged_element_collection.h:223
pointer data()
Direct access to the underlying array.
Definition: arranged_element_collection.h:165
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
Represents the value type const pointer of the collection.
Definition: arranged_element_collection.h:80
iterator erase(iterator pos)
Erases element at specified position.
Definition: arranged_element_collection.h:318
iterator erase(const_iterator pos)
Erases element at specified position.
Definition: arranged_element_collection.h:327
reference back()
Access the last element.
Definition: arranged_element_collection.h:158
void push_back_range(const arranged_element_collection &collection)
Adds elements to the end.
Definition: arranged_element_collection.h:389
The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
Definition: system_report.h:17
reference operator[](size_type pos)
Access specified element.
Definition: arranged_element_collection.h:444
std::vector< type_t > to_array() const noexcept
Gets an array with the elements of the container.
Definition: arranged_element_collection.h:428
const_iterator cend() const noexcept
Returns an iterator to the end.
Definition: arranged_element_collection.h:188
value_type & reference
Represents the value type reference of the collection.
Definition: arranged_element_collection.h:74
void clear() noexcept
clears the contents.
Definition: arranged_element_collection.h:245
typename std::vector< value_type >::const_iterator const_iterator
Represents the const iterator type of the collection.
Definition: arranged_element_collection.h:84
void push_back(value_type &&item)
Adds an element to the end.
Definition: arranged_element_collection.h:378
#define csf_
Provides information about the current stack frame.
Definition: current_stack_frame.h:30
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:205
void push_back(const value_type &item)
Adds an element to the end.
Definition: arranged_element_collection.h:368
bool sorted() const noexcept
Checks whether the container is sorted.
Definition: arranged_element_collection.h:234
void push_back_range(collection_t &&collection)
Adds elements to the end.
Definition: arranged_element_collection.h:408
Represents a collection of objects.
Definition: arranged_element_collection.h:31
void pop_back()
Removes the last element of the container.
Definition: arranged_element_collection.h:362
arranged_element_collection(const std::initializer_list< type_t > &il)
Creates a new object xtd::diagnostics::trace_listener_collection with specified initializer list...
Definition: arranged_element_collection.h:107
void push_back_range(const std::vector< value_type > &collection)
Adds elements to the end.
Definition: arranged_element_collection.h:395
typename std::vector< value_type >::reverse_iterator reverse_iterator
Represents the reverse iterator type of the collection.
Definition: arranged_element_collection.h:86
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:208
const_iterator end() const noexcept
Returns an iterator to the end.
Definition: arranged_element_collection.h:185
Represents an event.
Definition: event.h:21
iterator insert(const_iterator pos, const value_type &value)
Inserts specified element at specified position.
Definition: arranged_element_collection.h:254
static const size_t npos
This is a special value equal to the maximum value representable by the type size_t.
Definition: arranged_element_collection.h:95
size_type size() const noexcept
Returns the number of elements.
Definition: arranged_element_collection.h:216
allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition: arranged_element_collection.h:134
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:195
void sort()
Sorts the content.
Definition: arranged_element_collection.h:421
iterator erase(iterator first, iterator last)
Erases elements at specified range.
Definition: arranged_element_collection.h:338
void emplace_back(args_t &&... args)
Adds an element to the end.
Definition: arranged_element_collection.h:307
const_reference back() const
Access the last element.
Definition: arranged_element_collection.h:161
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition: arranged_element_collection.h:178
void insert_at(size_t index, const value_type &value)
Inserts specified element at specified index.
Definition: arranged_element_collection.h:283
Contains xtd::forms::layout::sorter_none class.
typename std::allocator_traits< allocator_type >::pointer pointer
Represents the value type pointer of the collection.
Definition: arranged_element_collection.h:78
iterator end() noexcept
Returns an iterator to the end.
Definition: arranged_element_collection.h:182
The exception that is thrown when one of the arguments provided to a method is out of range...
Definition: argument_out_of_range_exception.h:20
size_type capacity() const noexcept
Returns the number of elements that can be held in currently allocated storage.
Definition: arranged_element_collection.h:227
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes...
Definition: object.h:32
event< arranged_element_collection, delegate< void(size_t, type_t &item)> > item_removed
Occurs when an item is removed from the collection.
Definition: arranged_element_collection.h:471
iterator erase(const_iterator first, const_iterator last)
Erases elements at specified range.
Definition: arranged_element_collection.h:347
std::allocator< value_type > allocator_type
Represents the allocator type of the collection.
Definition: arranged_element_collection.h:68
void push_back_range(iterator_t begin, iterator_t end)
Adds elements to the end.
Definition: arranged_element_collection.h:415
reverse_iterator rend() noexcept
Returns a reverse iterator to the end.
Definition: arranged_element_collection.h:202
The xtd::forms namespace contains classes for creating Windows-based applications that take full adva...
Definition: about_box.h:13
Represents the value type of the collection.
Definition: arranged_element_collection.h:34
size_type max_size() const noexcept
Returns the maximum possible number of elements.
Definition: arranged_element_collection.h:220
event< arranged_element_collection, delegate< void(size_t, type_t &item)> > item_updated
Occurs when an item is updated in the collection.
Definition: arranged_element_collection.h:467
typename std::vector< value_type >::iterator iterator
Represents the iterator type of the collection.
Definition: arranged_element_collection.h:82
iterator insert(const_iterator pos, const value_type &&value)
Inserts specified element at specified position.
Definition: arranged_element_collection.h:268
iterator begin() noexcept
Returns an iterator to the beginning.
Definition: arranged_element_collection.h:172
void push_back_range(const std::initializer_list< value_type > &collection)
Adds elements to the end.
Definition: arranged_element_collection.h:401
const_pointer data() const
Direct access to the underlying array.
Definition: arranged_element_collection.h:168
const_reference front() const
Access the first element.
Definition: arranged_element_collection.h:154
std::size_t size_type
Represents the size type of the collection.
Definition: arranged_element_collection.h:70
reference at(size_type pos)
Access specified element with bounds checking.
Definition: arranged_element_collection.h:139
event< arranged_element_collection, delegate< void(size_t, type_t &item)> > item_added
Occurs when an item is added to the collection.
Definition: arranged_element_collection.h:463
std::ptrdiff_t difference_type
Represents the pointer difference type of the collection.
Definition: arranged_element_collection.h:72
size_t size
Represents a size of any object in bytes.
Definition: types.h:195