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 namespace array_details { 00025 00026 template <class RESIZEABLE> 00027 struct force_resize_details { }; 00028 00029 template <class HAS_C_PTR, class T> 00030 struct force_ptr_details { }; 00031 00032 } /* namespace array_details */ 00033 00043 template <class T, 00044 class A, 00045 class DERIVED_INFO 00046 > 00047 class array<T, data::forced<A, DERIVED_INFO> > 00048 : 00049 public array_common_base<array<T, 00050 data::forced<A, DERIVED_INFO> > > 00051 00052 { 00053 00054 private: 00055 typedef array_common_base<array<T, 00056 data::forced<A, DERIVED_INFO> > > common_base_class; 00057 00058 typedef typename types::t_if<typename array::is_writeable, 00059 typename types::best_iterator<A>::type, 00060 typename A::const_iterator>::type a_best_iterator; 00061 00062 typedef typename types::t_if<typename array::is_writeable, 00063 typename types::best_reverse_iterator<A>::type, 00064 typename A::const_reverse_iterator>::type a_best_reverse_iterator; 00065 00066 typedef typename A::this_array_type a_t; 00067 00068 protected: 00069 typedef typename array::has_random_access prv_has_random_access; 00070 00071 typedef array_details::elem_func_tools<T, 00072 prv_has_random_access::value> tool; 00073 00074 friend class tool::not_a_type; // allow disabled types only in our class 00075 00076 A* a_ptr; 00077 a_best_iterator a_begin; 00078 size_t len; 00079 00080 public: 00081 typedef array this_type; 00082 00083 typedef this_type this_array_type; 00084 00085 typedef this_type array_type; 00086 00087 typedef T elem_type; 00088 00089 typedef typename this_type::derived_type derived_type; 00090 00091 typedef typename common_base_class::base_class base_class; 00092 00094 typedef size_t size_type; 00095 00097 typedef ptrdiff_t diff_type; 00098 00099 using base_class::derived; 00100 00101 00102 void resize(size_t len) 00103 { 00104 if(array_details::force_resize_details<typename array::is_resizeable> 00105 ::resize(a_ptr, len)) { 00106 a_begin = a_ptr->begin(); 00107 len = a_ptr->length(); 00108 } 00109 } 00110 00111 void resize(size_t len, const T& s) // with padding 00112 { 00113 if(array_details::force_resize_details<typename array::is_resizeable> 00114 ::resize(static_cast<a_t*>(a_ptr), len, s)) { 00115 a_begin = a_ptr->begin(); 00116 len = a_ptr->length(); 00117 } 00118 } 00119 00121 void reshape(size_t len) { resize(len); } 00122 void reshape(size_t len, const T& s) { resize(len, s); } 00123 00124 void clear() { resize(0); } 00125 00126 typedef typename types::t_if<typename array::is_writeable, 00127 a_best_iterator, types::not_a_type>::type iterator; 00128 00129 typedef typename A::const_iterator const_iterator; 00130 00131 typedef typename types::t_if<typename array::is_writeable, 00132 typename types::best_reverse_iterator<A>::type, 00133 types::not_a_type>::type reverse_iterator; 00134 00135 typedef typename A::const_reverse_iterator const_reverse_iterator; 00136 00137 typedef typename A::iter_border_walker iter_border_walker; 00138 00139 typedef a_best_iterator best_iterator; 00140 typedef typename std::iterator_traits<best_iterator>::reference reference; 00141 typedef typename std::iterator_traits<const_iterator>:: 00142 reference const_reference; 00143 typedef reference best_reference; 00144 00145 best_iterator begin() { return a_begin; } 00146 best_iterator end() { return a_ptr->end(); } 00147 const_iterator begin() const { return const_iterator(a_begin); } 00148 const_iterator end() const { return a_ptr->end(); } 00149 00150 a_best_reverse_iterator rbegin() { return a_ptr->rbegin(); } 00151 a_best_reverse_iterator rend() { return a_ptr->rend(); } 00152 const_reverse_iterator rbegin() const { return a_ptr->rbegin(); } 00153 const_reverse_iterator rend() const { return a_ptr->rend(); } 00154 00155 typename types::apply_const<T, types::is_const<A> >::type c_ptr() 00156 { 00157 return array_details::force_ptr_details<typename array::has_c_ptr, T> 00158 ::c_ptr(a_ptr); 00159 } 00160 00161 const T* c_ptr() const 00162 { 00163 return array_details::force_ptr_details<typename array::has_c_ptr, T> 00164 ::const_c_ptr(a_ptr); 00165 } 00166 00169 //TODO: explain this better. 00171 size_t length() const { return len; } 00173 size_type size() const { return length(); } 00175 size_t numel() const { return length(); } 00178 iter_border_walker first_to_last() const { return a_ptr->first_to_last(); } 00179 iter_border_walker begin_to_end() const { return a_ptr->begin_to_end(); } 00180 00186 00187 typename best_reference operator[] 00188 (typename tool::brackets_arg i) 00189 { 00190 CHECK(i >= 0 && i < length(), erange); 00191 return tool::brackets(a_begin, i); 00192 } 00193 00195 typename const_reference operator[] 00196 (typename tool::brackets_arg i) const 00197 { 00198 CHECK(i >= 0 && i < length(), erange); 00199 return tool::brackets(a_begin, i); 00200 } 00205 template <class D> 00206 bool overlap(const D& a) const { return false; } 00207 00208 void setref(A& a) 00209 { 00210 a_ptr = &a; 00211 a_begin = a.begin(); 00212 len = a.length(); 00213 } 00218 00219 array() : a_ptr(0), len(0) { } 00220 00222 array(A& a) { setref(a); } 00223 00225 array(const array& o) { setref(*o.a_ptr); } 00231 00232 array(size_t) {} 00233 00235 template <class J, class D> 00236 array(size_t, const array<J, D>&) {} 00237 00239 array(size_t, const T*) {} 00240 00242 template<class J, class S> 00243 array(const array<J, S>& a) {} 00244 00257 using base_class::operator=; 00258 00259 this_type& operator=(const this_type& a) 00260 { 00261 common_base_class::operator=(a); 00262 return *this; 00263 } 00266 00267 ~array() { } 00268 00269 }; 00270 00271 namespace array_details { 00272 00273 template <> 00274 struct force_resize_details<types::t_false> 00275 { 00276 template <class A, class S> 00277 static inline 00278 bool resize(A* a, const S& l) { return false; } 00279 00280 template <class A, class S, class T> 00281 static inline 00282 bool resize(A* a, const S& l, const T& t) { return false; } 00283 }; 00284 00285 template <> 00286 struct force_resize_details<types::t_true> 00287 { 00288 template <class A, class S> 00289 static inline 00290 bool resize(A* a, const S& l) { a->resize(l); return true; } 00291 00292 template <class A, class S, class T> 00293 static inline 00294 bool resize(A* a, const S& l, const T& t) { a->resize(l, t); return true; } 00295 }; 00296 00297 template <class T> 00298 struct force_ptr_details <types::t_false, T> 00299 { 00300 template <class A> 00301 static inline T* c_ptr(A* a) { return 0; } 00302 template <class A> 00303 static inline const T* c_ptr(const A* a) { return 0; } 00304 }; 00305 00306 template <class T> 00307 struct force_ptr_details <types::t_true, T> 00308 { 00309 template <class A> 00310 static inline T* c_ptr(A* a) { return a->c_ptr(); } 00311 template <class A> 00312 static inline const T* c_ptr(const A* a) { return a->c_ptr(); } 00313 }; 00314 00315 } /* namespace array_details */