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 00027 template <class T, 00028 class OPTS = data::normal_2d<> 00029 > 00030 class array_2d : 00031 public 00032 array_common_base<array_2d<T, OPTS> > 00033 { 00034 private: 00035 typedef array_common_base<array_2d<T, OPTS> > common_base_class; 00036 00037 public: 00038 typedef array_2d this_type; 00039 00040 typedef this_type this_array_2d_type; 00041 00042 typedef typename this_type::derived_type derived_type; 00043 00044 typedef typename common_base_class::base_class base_class; 00045 00046 typedef this_type array_type; 00047 00048 typedef typename this_type::size_type size_type; 00049 00050 using base_class::derived; 00051 00052 typedef typename this_type::is_resizeable is_resizeable; 00053 00054 typedef typename this_type::all_init_arg_base all_init_arg; 00055 typedef typename this_type::data_init_arg_base data_init_arg; 00056 00058 base_class& base() { return *this; } 00059 const base_class& base() const { return *this; } 00060 00062 size_t rows() const { return this->size_nd()[0]; } 00063 00065 size_t columns() const { return this->size_nd()[1]; } 00067 size_t cols() const { return this->size_nd()[1]; } 00068 00070 bool is_square() const { return rows() == columns(); } 00071 00074 00075 template <class S> 00076 void resize(const array<size_t, S>& newsize, const T& s, 00077 types::enable_if<is_resizeable> = 0) 00078 { 00079 CHECK(newsize.length() == 2, eshape()); 00080 base_class::resize(newsize, s); 00081 } 00082 00084 template <class S> 00085 void resize(const array<size_t, S>& newsize) 00086 { 00087 CHECK(newsize.length() == 2, eshape()); 00088 base_class::resize(newsize); 00089 } 00090 00092 void resize(size_t rows, size_t cols, const T& s, 00093 types::enable_if<is_resizeable> = 0) 00094 { 00095 base_class::resize(size_dims<2>(rows, cols), s); 00096 } 00097 00099 void resize(size_t rows, size_t cols, 00100 types::enable_if<is_resizeable> = 0) 00101 { 00102 data::call_if<is_resizeable>:: 00103 resize(base(), size_dims<2>(rows, cols)); 00104 } 00116 array_2d() { } 00117 00124 array_2d(size_t r, size_t c) : 00125 common_base_class(size_dims<2>(r, c)) {} ; 00126 00136 template <class D> 00137 array_2d(const array<size_t, D>& sz) : 00138 common_base_class(sz) {} ; 00139 00140 00149 array_2d(size_t r, size_t c, const T& s) : 00150 common_base_class(size_dims<2>(r, c), s) {} ; 00151 00164 array_2d(size_t r, size_t c, const T* data) : 00165 common_base_class(size_dims<2>(r, c), data) {} ; 00166 00167 00175 array_2d(size_t r, size_t c, const data_init_arg& data) : 00176 common_base_class(size_dims<2>(r, c), data) {} ; 00177 00178 00188 template <class J, class D> 00189 array_2d(size_t r, size_t c, const array<J, D>& data) : 00190 common_base_class(size_dims<2>(r, c), data) 00191 { } 00192 00193 00194 00205 template <class D> 00206 array_2d(const array<size_t, D>& sz, const T& s) : 00207 common_base_class(sz, s) {} ; 00208 00209 00224 template <class D> 00225 array_2d(const array<size_t, D>& sz, const T* data) : 00226 common_base_class(sz, data) {} ; 00227 00236 template <class D> 00237 array_2d(const array<size_t, D>& sz, const data_init_arg& data) : 00238 common_base_class(sz, data) {} ; 00239 00240 00252 template <class D, class J, class S> 00253 array_2d(const array<size_t, D>& sz, const array<J, S>& data) : 00254 common_base_class(sz, data) 00255 { 00256 CHECK(sz.length() == 2, edims); 00257 CHECK(data.length() >= sz[0] * sz[1], erange); 00258 } 00259 00268 template <class J, class D> 00269 array_2d(const array_nd<J, D>& a) : 00270 common_base_class(a) 00271 { 00272 // code to assert 2 dimensions 00273 if(a.ndims() != 2) this->reshape(array_details::dims_for_2d(a.size())); 00274 } 00275 00279 template <class J, class D> 00280 array_2d(array_nd<J, D>& a) : 00281 common_base_class(a) 00282 { 00283 // code to assert 2 dimensions 00284 if(a.ndims() != 2) this->reshape(array_details::dims_for_2d(a.size())); 00285 } 00286 00287 00288 // ---------------------- 00289 00290 template <class J, class D> 00291 array_2d(const array_2d<J, D>& a) : 00292 common_base_class(a) 00293 { } 00294 00295 //(special for ref_iterator) 00296 template <class J, class D> 00297 array_2d(array_2d<J, D>& a) : 00298 common_base_class(a) 00299 { } 00300 00301 // ---------------------- 00302 00304 array_2d(const this_type& a) : 00305 common_base_class(a) {} ; 00306 00307 00308 00309 #ifdef IVL_MATLAB 00310 00319 array_2d(const mxArray* mx); 00320 #endif 00321 00322 00323 00330 //using base_class::operator=; 00331 00332 using common_base_class::operator (); 00333 00334 template <class K> 00335 derived_type& operator=(const K& a) 00336 { common_base_class::operator=(a); return derived(); } 00337 00338 this_type& operator=(const this_type& a) 00339 { common_base_class::operator=(a); return *this; } 00340 00341 //array_2d <T, DerivedInfo>& operator=(const array_2d<T, DerivedInfo>& a) 00342 // { base_class::operator=(a); return *this; /*TODO: assure check for self assignment (in all classes!)*/ }; 00343 00344 // 00345 // template<class S> 00346 // Derived& operator=(const array_2d<T, S>& a) 00347 // { return base_class::operator=(a); /*TODO: assure check for self assignment*/ }; 00348 00349 #ifdef IVL_MATLAB 00350 00360 array_2d<T>& operator=(const mxArray* mx); 00361 #endif 00362 00364 /* 00365 std::ostream& print_me(std::ostream& os) const 00366 { return ivl::print(os, *this); } 00367 */ 00368 00369 #ifdef IVL_MATLAB 00370 00371 mxArray* mx(); 00372 #endif 00373 00374 }; 00375