Otclient  14/8/2020
packed_vector.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef STDEXT_PACKEDVECTOR_H
24 #define STDEXT_PACKEDVECTOR_H
25 
26 #include <algorithm>
27 
28 namespace stdext {
29 
30 // disable memory alignment
31 #pragma pack(push,1)
32 
33 template<class T, class U = uint8_t>
35 {
36 public:
37  typedef U size_type;
38  typedef T* iterator;
39  typedef const T* const_iterator;
40  typedef std::reverse_iterator<iterator> reverse_iterator;
41  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
42 
43  packed_vector() : m_size(0), m_data(nullptr) { }
44  packed_vector(size_type size) : m_size(size), m_data(new T[size]) { }
45  packed_vector(size_type size, const T& value) : m_size(size), m_data(new T[size]) { std::fill(begin(), end(), value); }
46  template <class InputIterator>
47  packed_vector(InputIterator first, InputIterator last) : m_size(last - first), m_data(new T[m_size]) { std::copy(first, last, m_data); }
48  packed_vector(const packed_vector<T>& other) : m_size(other.m_size), m_data(new T[other.m_size]) { std::copy(other.begin(), other.end(), m_data); }
49  ~packed_vector() { delete[] m_data; }
50 
51  packed_vector<T,U>& operator=(packed_vector<T,U> other) { other.swap(*this); return *this; }
52 
53  iterator begin() { return m_data; }
54  const_iterator begin() const { return m_data; }
55  const_iterator cbegin() const { return m_data; }
56  iterator end() { return m_data + m_size; }
57  const_iterator end() const { return m_data + m_size; }
58  const_iterator cend() const { return m_data + m_size; }
59 
66 
67  size_type size() const { return m_size; }
68  bool empty() const { return m_size == 0; }
69 
70  T& operator[](size_type i) { return m_data[i]; }
71  const T& operator[](size_type i) const { return m_data[i]; }
72  T& at(size_type i) { return m_data[i]; }
73  const T& at(size_type i) const { return m_data[i]; }
74 
75  T& front() { return m_data[0]; }
76  const T& front() const { return m_data[0]; }
77  T& back() { return m_data[m_size-1]; }
78  const T& back() const { return m_data[m_size-1]; }
79 
80  T *data() { return m_data; }
81  const T *data() const { return m_data; }
82 
83  void clear() {
84  if(m_data) {
85  delete[] m_data;
86  m_data = nullptr;
87  }
88  m_size = 0;
89  }
90 
92  clear();
93  if(size > 0) {
94  m_data = new T[size];
95  m_size = size;
96  }
97  }
98 
99  void push_back(const T& x) {
100  T *tmp = new T[m_size+1];
101  std::copy(m_data, m_data + m_size, tmp);
102  tmp[m_size] = x;
103  delete[] m_data;
104  m_data = tmp;
105  m_size++;
106  }
107 
108  void pop_back() {
109  if(m_size == 1) {
110  clear();
111  return;
112  }
113  T *tmp = new T[m_size-1];
114  std::copy(m_data, m_data + m_size - 1, tmp);
115  delete[] m_data;
116  m_data = tmp;
117  m_size--;
118  }
119 
120  iterator insert(const_iterator position, const T& x) {
121  T *tmp = new T[m_size+1];
122  size_type i = position - m_data;
123  std::copy(m_data, m_data + i, tmp);
124  tmp[i] = x;
125  std::copy(m_data + i, m_data + m_size, tmp + i + 1);
126  delete[] m_data;
127  m_data = tmp;
128  m_size++;
129  return tmp + i;
130  }
131 
133  T *tmp = new T[m_size-1];
134  size_type i = position - m_data;
135  std::copy(m_data, m_data + i, tmp);
136  std::copy(m_data + i + 1, m_data + m_size, tmp + i);
137  delete[] m_data;
138  m_data = tmp;
139  m_size--;
140  return tmp + i;
141  }
142 
143  void swap(packed_vector<T,U>& other) { std::swap(m_size, other.m_size); std::swap(m_data, other.m_data); }
144 
145  operator std::vector<T>() const { return std::vector<T>(begin(), end()); }
146 
147 private:
148  size_type m_size;
149  T* m_data;
150 };
151 
152 // restore memory alignment
153 #pragma pack(pop)
154 
155 }
156 
157 namespace std {
158 template<class T, class U> void swap(stdext::packed_vector<T,U>& lhs, stdext::packed_vector<T,U>& rhs) { lhs.swap(rhs); }
159 }
160 
161 #endif
stdext::packed_vector::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: packed_vector.h:40
stdext::packed_vector
Definition: packed_vector.h:34
stdext::packed_vector::begin
const_iterator begin() const
Definition: packed_vector.h:54
stdext::packed_vector::rbegin
const_reverse_iterator rbegin() const
Definition: packed_vector.h:61
std::swap
void swap(stdext::packed_vector< T, U > &lhs, stdext::packed_vector< T, U > &rhs)
Definition: packed_vector.h:158
stdext::packed_vector::back
T & back()
Definition: packed_vector.h:77
stdext::packed_vector::size_type
U size_type
Definition: packed_vector.h:37
stdext::packed_vector::const_iterator
const typedef T * const_iterator
Definition: packed_vector.h:39
stdext::packed_vector::end
iterator end()
Definition: packed_vector.h:56
stdext::packed_vector::pop_back
void pop_back()
Definition: packed_vector.h:108
stdext::packed_vector::cend
const_iterator cend() const
Definition: packed_vector.h:58
stdext::packed_vector::at
T & at(size_type i)
Definition: packed_vector.h:72
stdext::packed_vector::iterator
T * iterator
Definition: packed_vector.h:38
stdext::packed_vector::front
T & front()
Definition: packed_vector.h:75
stdext::packed_vector::packed_vector
packed_vector(size_type size)
Definition: packed_vector.h:44
stdext::packed_vector::operator=
packed_vector< T, U > & operator=(packed_vector< T, U > other)
Definition: packed_vector.h:51
stdext::packed_vector::crbegin
const_reverse_iterator crbegin() const
Definition: packed_vector.h:62
stdext::packed_vector::clear
void clear()
Definition: packed_vector.h:83
stdext::packed_vector::rend
reverse_iterator rend()
Definition: packed_vector.h:63
stdext::packed_vector::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: packed_vector.h:41
stdext::packed_vector::empty
bool empty() const
Definition: packed_vector.h:68
stdext::packed_vector::packed_vector
packed_vector(size_type size, const T &value)
Definition: packed_vector.h:45
stdext::packed_vector::rend
const_reverse_iterator rend() const
Definition: packed_vector.h:64
stdext::packed_vector::operator[]
const T & operator[](size_type i) const
Definition: packed_vector.h:71
stdext::packed_vector::back
const T & back() const
Definition: packed_vector.h:78
stdext::packed_vector::begin
iterator begin()
Definition: packed_vector.h:53
stdext::packed_vector::data
const T * data() const
Definition: packed_vector.h:81
stdext::packed_vector::packed_vector
packed_vector(const packed_vector< T > &other)
Definition: packed_vector.h:48
stdext::packed_vector::~packed_vector
~packed_vector()
Definition: packed_vector.h:49
stdext::packed_vector::at
const T & at(size_type i) const
Definition: packed_vector.h:73
stdext::packed_vector::crend
const_reverse_iterator crend() const
Definition: packed_vector.h:65
stdext::packed_vector::packed_vector
packed_vector(InputIterator first, InputIterator last)
Definition: packed_vector.h:47
stdext::packed_vector::cbegin
const_iterator cbegin() const
Definition: packed_vector.h:55
stdext::packed_vector::data
T * data()
Definition: packed_vector.h:80
stdext::packed_vector::swap
void swap(packed_vector< T, U > &other)
Definition: packed_vector.h:143
stdext::packed_vector::size
size_type size() const
Definition: packed_vector.h:67
stdext::packed_vector::push_back
void push_back(const T &x)
Definition: packed_vector.h:99
stdext::packed_vector::end
const_iterator end() const
Definition: packed_vector.h:57
stdext::packed_vector::resize
void resize(size_type size)
Definition: packed_vector.h:91
stdext::packed_vector::packed_vector
packed_vector()
Definition: packed_vector.h:43
std
Definition: packed_vector.h:157
stdext::packed_vector::erase
iterator erase(const_iterator position)
Definition: packed_vector.h:132
stdext::shared_object_ptr
Definition: shared_object.h:39
stdext::packed_vector::operator[]
T & operator[](size_type i)
Definition: packed_vector.h:70
stdext::packed_vector::front
const T & front() const
Definition: packed_vector.h:76
stdext::packed_vector::insert
iterator insert(const_iterator position, const T &x)
Definition: packed_vector.h:120
stdext
Definition: any.h:30
stdext::packed_vector::rbegin
reverse_iterator rbegin()
Definition: packed_vector.h:60