ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 00025 // data::normal is defined in data_base.hpp 00026 00032 template <class T, class OPTS = data::mem<> > 00033 class array: 00034 00035 public array_common_base<array<T, OPTS> >, 00036 00037 public std::vector<T> 00038 { 00039 private: 00040 typedef array_common_base<array<T, OPTS> > common_base_class; 00041 00042 public: 00043 typedef typename types::t_not<types::is_bool<T> >::type has_c_ptr; 00044 00045 typedef typename common_base_class::data_type data_type; 00046 00047 typedef array <T, OPTS> this_type; 00048 00049 typedef this_type this_array_type; 00050 00051 typedef this_type array_type; 00052 00053 typedef T elem_type; 00054 00055 typedef typename this_type::derived_type derived_type; 00056 00057 typedef typename common_base_class::base_class base_class; 00058 00060 typedef size_t size_type; 00061 00063 typedef ptrdiff_t diff_type; 00064 00065 using base_class::derived; 00066 00067 typedef typename std::vector<T>::iterator iterator; 00068 typedef typename std::vector<T>::const_iterator const_iterator; 00069 typedef typename std::vector<T>::reverse_iterator reverse_iterator; 00070 typedef typename std::vector<T>:: 00071 const_reverse_iterator const_reverse_iterator; 00072 using std::vector<T>::begin; 00073 using std::vector<T>::end; 00074 using std::vector<T>::rbegin; 00075 using std::vector<T>::rend; 00076 00077 typedef iterator best_iterator; 00078 typedef typename const_iterator::reference const_reference; 00079 typedef typename iterator::reference reference; 00080 typedef reference best_reference; 00081 00082 using common_base_class::assign; // vector assign is not used 00083 // left here along with array.assign() for now, however might be removed. 00084 using std::vector<T>::assign; 00085 00086 void clear() 00087 { 00088 std::vector<T>().swap(static_cast<std::vector<T>&>(*this)); 00089 } 00090 00091 void swap(std::vector<T>& v) 00092 { 00093 std::vector<T>::swap(v); 00094 } 00095 00096 //TODO: fix 00097 template<class J, class D> 00098 void swap(array<J, D>& a) 00099 { 00100 this->derived() = a.derived(); 00101 } 00102 /*template <class J, class D, class P> 00103 void swap(array_nd<J, D, P>& a) 00104 { 00105 // error: can't swap array with array_nd. 00106 throw(ecomp); 00107 }*/ 00108 00109 //TODO: what happens with resize? with base members. do resolve. 00110 //in need, create resize function here that does the right thing. 00111 using std::vector<T>::resize; 00112 00114 void reshape(size_t len) { resize(len); } 00115 void reshape(size_t len, const T& s) { resize(len, s); } 00116 00117 00120 00121 void init() { this->clear(); } 00122 00124 void init(size_t count) { this->resize(count); /* does not need to keep data */ } 00125 00127 void init(int count) { this->init(size_t(count)); } 00128 00130 void init(long int count) { this->init(size_t(count)); } 00131 00133 void init(size_t count, const T& s) { std::vector<T>::assign(count, s); } 00134 00136 void init(size_t count, const T *ptr) { std::vector<T>::assign(ptr, ptr + count); } 00137 00139 template <class J> 00140 void init(const internal::tuple_rvalue<J>& r) 00141 { this->clear(); r.tuple_output(internal::reftpl(*this)); } 00142 00144 void init(const array& a) { std::vector<T>::assign(a.begin(), a.end()); } 00145 00147 template <class J, class S> 00148 void init(const array<J, S>& a, size_t n) 00149 { 00150 std::vector<T>::resize(n > 0 ? n : a.length()); 00151 ivl::copy_out(*this, a); 00152 } 00153 00155 template <class J, class S> 00156 void init(const array<J, S>& a) 00157 { 00158 // This implementation needs us to be careful. 00159 // while : std::vector<T>(a.begin(), a.end()) { } is always valid, 00160 // it consumes double time of iteration for non-random-access arrays. 00161 // so we will have to specialize it. 00162 std::vector<T>::resize(0); 00163 array_details:: 00164 vector_initializer<array<T, S>::has_random_access::value> 00165 ::operate(static_cast<std::vector<T>&>(*this), a); 00166 } 00167 00169 template <class J, class S> 00170 void init(size_t count, const array<J, S>& a) 00171 { 00172 std::vector<T>::resize(count); 00173 this->init_size_with(a); 00174 } 00175 00178 /* 00179 void resize(size_t sz) 00180 { 00181 if(sz == 0) 00182 std::vector<T>().swap(static_cast<std::vector<T>&>(*this)); 00183 else 00184 std::vector<T>::resize(sz); 00185 } 00186 00187 void resize(size_t sz, const T& s) 00188 { 00189 if(sz == 0) 00190 std::vector<T>().swap(static_cast<std::vector<T>&>(*this)); 00191 else 00192 std::vector<T>::resize(sz, s); 00193 } 00194 */ 00195 /* 00196 void reset(size_t sz, const T s = T()) 00197 { 00198 if(sz == 0 || sz > std::vector<T>::capacity() 00199 || sz < std::vector<T>::capacity() / 2) 00200 std::vector<T>().swap(static_cast<std::vector<T>&>(*this)); 00201 else 00202 std::vector<T>::resize(0); 00203 00204 std::vector<T>::resize(sz, s); 00205 } 00206 */ 00207 00208 typedef ptrdiff_t iter_border_walker; 00209 00210 // TODO: 00211 // warning: since bit vector does not return an actual pointer 00212 // this function is deceiving cause it doesn't return an actual c_ptr! 00213 // the solution to remove c_ptr from vector is not an option. 00214 // to remove it from bool vector is an option, or another option 00215 // is to get the bitmap data some way. 00216 // also would we need to have the pseudo pointer in some occasions? 00217 // by let's say another function, ptr(). ? 00218 typename std::vector<T>::pointer c_ptr() 00219 { return &(std::vector<T>::operator[](0)); } 00220 typename std::vector<T>::const_pointer c_ptr() const 00221 { return &(std::vector<T>::operator[](0)); } 00222 00225 //TODO: explain this better. 00227 size_t length() const { return std::vector<T>::size(); } 00229 size_type size() const { return length(); } 00231 size_t numel() const { return length(); } 00234 iter_border_walker first_to_last() const { return this->length() - 1; } 00235 iter_border_walker begin_to_end() const { return this->length(); } 00236 00242 00243 typename std::vector<T>::const_reference operator[](size_t offset) const 00244 { 00245 CHECK(offset >= 0 && offset < length(), erange); 00246 return std::vector<T>::operator[](offset); 00247 } 00249 typename std::vector<T>::reference operator[](size_t offset) 00250 { 00251 CHECK(offset >= 0 && offset < length(), erange); 00252 return std::vector<T>::operator[](offset); 00253 } 00254 00255 using common_base_class::operator[]; 00256 00262 00263 array() { } 00264 00266 explicit array(size_t count) : std::vector<T>(count) { } 00267 00269 explicit array(int count) : std::vector<T>(size_t(count)) { } 00270 00272 explicit array(long int count) : std::vector<T>(size_t(count)) { } 00273 00280 array(size_t count, const T& s) : std::vector<T>(count, s) { } 00281 00288 array(size_t count, const T *ptr) : std::vector<T>(ptr, ptr + count) { } 00289 00290 00296 template<class S, int J> 00297 array(S (&arr)[J]) : std::vector<T>(arr, arr + J) { } 00298 00299 00301 template <class J> 00302 array(const internal::tuple_rvalue<J>& r) 00303 { r.tuple_output(internal::reftpl(*this)); } 00304 00306 array(const array& a) : std::vector<T>(a.begin(), a.end()) { } 00307 00316 template <class J, class S> 00317 inline 00318 array(const array<J, S>& a, size_t n) : 00319 std::vector<T>(n > 0 ? n : a.length()) 00320 { 00321 ivl::copy_out(*this, a); 00322 } 00323 00324 00327 template <class J, class S> 00328 array(const array<J, S>& a) 00329 { 00330 // This implementation needs us to be careful. 00331 // while : std::vector<T>(a.begin(), a.end()) { } is always valid, 00332 // it consumes double time of iteration for non-random-access arrays. 00333 // so we will have to specialize it. 00334 array_details:: 00335 vector_initializer<array<T, S>::has_random_access::value> 00336 ::operate(static_cast<std::vector<T>&>(*this), a); 00337 } 00338 00350 template <class J, class S> 00351 array(size_t count, const array<J, S>& a) : std::vector<T>(count) 00352 { 00353 this->init_size_with(a); 00354 } 00355 00356 00357 00358 00361 00362 ~array() { } 00363 00364 00376 template<class K> 00377 derived_type& operator=(const K& k) 00378 { 00379 common_base_class::operator=(k); 00380 return derived(); 00381 } 00382 //using common_base_class::operator=; 00383 this_type& operator=(const this_type& a) // LEFT IN THE CONST MODE FOR A COPY CONSTRUCTOR! 00384 { 00385 // if(this != &a) TODO: make this a rule: make clear that ... 00386 // Note: the data class handles the check: if(this != &a), 00387 // and only IF needed, so there is no case of cpu waste 00388 common_base_class::operator=(a); 00389 return *this; 00390 } 00391 00392 00393 /* 00394 template<class S, class K> 00395 derived_type& operator=(const ivl::array<T, S, K>& a) 00396 { 00397 common_base_class::operator=(a); 00398 return derived(); 00399 } 00400 00401 derived_type& operator=(const T& s) 00402 */ 00403 00404 00405 00406 }; 00407