1 /*
2 Scan Tailor - Interactive post-processing tool for scanned pages.
3 Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef VEC_T_H_
20 #define VEC_T_H_
21
22 #include <boost/scoped_array.hpp>
23 #include <cassert>
24 #include <cstddef>
25
26 /**
27 * \brief A (column) vector of elements of type T.
28 */
29 template <typename T>
30 class VecT {
31 public:
32 typedef T type;
33
34 /**
35 * \brief Constructs an empty vector.
36 */
37 VecT();
38
39 /**
40 * \brief Constructs a vector of specified size initialized with T().
41 */
42 explicit VecT(size_t size);
43
44 /**
45 * \brief Constructs a vector of specified size initializing to the provided value.
46 */
47 VecT(size_t size, T initial_value);
48
49 /**
50 * \brief Construction from an array of elements of possibly different type.
51 *
52 * Conversion is done by static casts.
53 */
54 template <typename OT>
55 explicit VecT(size_t size, const OT* data);
56
57 /**
58 * Ordinary copy-construction.
59 */
60 VecT(const VecT& other);
61
62 /**
63 * \brief Construction from a vector of a different type.
64 *
65 * Conversion is done by static casts.
66 */
67 template <typename OT>
68 explicit VecT(const VecT<OT>& other);
69
70 /**
71 * \brief Ordinary assignment.
72 */
73 VecT& operator=(const VecT& other);
74
75 /**
76 * \brief Assignment from a vector of a different type.
77 *
78 * Conversion is done by static casts.
79 */
80 template <typename OT>
81 VecT& operator=(const VecT<OT>& other);
82
83 VecT& operator+=(const VecT& rhs);
84
85 VecT& operator-=(const VecT& rhs);
86
87 VecT& operator*=(T scalar);
88
size()89 size_t size() const { return m_size; }
90
data()91 const T* data() const { return m_data.get(); }
92
data()93 T* data() { return m_data.get(); }
94
95 const T& operator[](size_t idx) const {
96 assert(idx < m_size);
97
98 return m_data[idx];
99 }
100
101 T& operator[](size_t idx) {
102 assert(idx < m_size);
103
104 return m_data[idx];
105 }
106
107 void fill(const T& value);
108
109 void swap(VecT& other);
110
111 private:
112 boost::scoped_array<T> m_data;
113 size_t m_size;
114 };
115
116
117 template <typename T>
VecT()118 VecT<T>::VecT() : m_size(0) {}
119
120 template <typename T>
VecT(size_t size)121 VecT<T>::VecT(size_t size)
122 : m_data(new T[size]()),
123 // The "()" will cause elements to be initialized to T().
124 m_size(size) {}
125
126 template <typename T>
VecT(size_t size,T initial_value)127 VecT<T>::VecT(size_t size, T initial_value) : m_data(new T[size]), m_size(size) {
128 for (size_t i = 0; i < size; ++i) {
129 m_data[i] = initial_value;
130 }
131 }
132
133 template <typename T>
134 template <typename OT>
VecT(size_t size,const OT * data)135 VecT<T>::VecT(size_t size, const OT* data) : m_data(new T[size]), m_size(size) {
136 for (size_t i = 0; i < size; ++i) {
137 m_data[i] = static_cast<T>(data[i]);
138 }
139 }
140
141 template <typename T>
VecT(const VecT & other)142 VecT<T>::VecT(const VecT& other) : m_data(new T[other.m_size]), m_size(other.m_size) {
143 const T* other_data = other.data();
144 for (size_t i = 0; i < m_size; ++i) {
145 m_data[i] = other_data[i];
146 }
147 }
148
149 template <typename T>
150 template <typename OT>
VecT(const VecT<OT> & other)151 VecT<T>::VecT(const VecT<OT>& other) : m_data(new T[other.m_size]), m_size(other.m_size) {
152 const T* other_data = other.data();
153 for (size_t i = 0; i < m_size; ++i) {
154 m_data[i] = other_data[i];
155 }
156 }
157
158 template <typename T>
159 VecT<T>& VecT<T>::operator=(const VecT& other) {
160 VecT(other).swap(*this);
161
162 return *this;
163 }
164
165 template <typename T>
166 template <typename OT>
167 VecT<T>& VecT<T>::operator=(const VecT<OT>& other) {
168 VecT(other).swap(*this);
169
170 return *this;
171 }
172
173 template <typename T>
174 VecT<T>& VecT<T>::operator+=(const VecT& rhs) {
175 assert(m_size == rhs.m_size);
176 for (size_t i = 0; i < m_size; ++i) {
177 m_data[i] += rhs.m_data[i];
178 }
179
180 return *this;
181 }
182
183 template <typename T>
184 VecT<T>& VecT<T>::operator-=(const VecT& rhs) {
185 assert(m_size == rhs.m_size);
186 for (size_t i = 0; i < m_size; ++i) {
187 m_data[i] -= rhs.m_data[i];
188 }
189
190 return *this;
191 }
192
193 template <typename T>
194 VecT<T>& VecT<T>::operator*=(const T scalar) {
195 for (size_t i = 0; i < m_size; ++i) {
196 m_data[i] *= scalar;
197 }
198
199 return *this;
200 }
201
202 template <typename T>
fill(const T & value)203 void VecT<T>::fill(const T& value) {
204 for (size_t i = 0; i < m_size; ++i) {
205 m_data[i] = value;
206 }
207 }
208
209 template <typename T>
swap(VecT & other)210 void VecT<T>::swap(VecT& other) {
211 size_t tmp = m_size;
212 m_size = other.m_size;
213 other.m_size = tmp;
214 m_data.swap(other.m_data);
215 }
216
217 template <typename T>
swap(const VecT<T> & o1,const VecT<T> & o2)218 void swap(const VecT<T>& o1, const VecT<T>& o2) {
219 o1.swap(o2);
220 }
221
222 template <typename T>
223 VecT<T> operator*(const VecT<T>& vec, double scalar) {
224 VecT<T> res(vec);
225 res *= scalar;
226
227 return res;
228 }
229
230 template <typename T>
231 VecT<T> operator*(double scalar, const VecT<T>& vec) {
232 VecT<T> res(vec);
233 res *= scalar;
234
235 return res;
236 }
237
238 #endif // ifndef VEC_T_H_
239