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 #ifndef ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP 00025 #define ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP 00026 00027 namespace ivl { 00028 00029 namespace array_nd_details { 00030 00031 template <class T, class DATA, class DERIVED_INFO> 00032 class basic_iterator_nd_interface 00033 { 00034 private: 00035 typedef array_nd<T, DATA, DERIVED_INFO> C; 00036 typedef typename types::derive<C>::type derived_type; 00037 typedef array<T, DATA, derived_type> base_class; 00038 00039 typedef typename base_class::iterator iterator; 00040 typedef typename base_class::const_iterator const_iterator; 00041 typedef typename base_class::reverse_iterator reverse_iterator; 00042 typedef typename base_class::const_reverse_iterator const_reverse_iterator; 00043 00044 C& nd() { return static_cast<C&>(*this); } 00045 const C& nd() const { return static_cast<const C&>(*this); } 00046 00047 public: 00048 typedef data::basic_iterator_nd<iterator> iterator_nd; 00049 typedef data::basic_iterator_nd<const_iterator> const_iterator_nd; 00050 typedef std::reverse_iterator<iterator_nd> reverse_iterator_nd; 00051 typedef std::reverse_iterator<const_iterator_nd> const_reverse_iterator_nd; 00052 00053 size_t begin_pos(size_t d, size_t pos) 00054 { 00055 size_t mod = pos % nd().stride(d); 00056 if(d == nd().ndim() - 1) return mod; 00057 return pos - pos % nd().stride(d + 1) + mod; 00058 } 00059 00060 size_t end_pos(size_t d, size_t pos) 00061 { 00062 size_t mod = pos % nd().stride(d); 00063 if(d == nd().ndim() - 1) return mod + nd().length(); 00064 return pos - pos % nd().stride(d + 1) + mod + 00065 nd().stride(d + 1); 00066 } 00067 00068 // non-const iterator 00069 00070 iterator_nd iter(size_t d) 00071 { return iterator_nd(nd().stride(d), nd().begin()); } 00072 00073 iterator_nd iter(size_t d, size_t pos) 00074 { return iterator_nd(nd().stride(d), nd().begin() + pos); } 00075 00076 iterator_nd iter(size_t d, const size_array& idx) 00077 { return iterator_nd(nd().stride(d), nd().begin() + nd().sub2ind(nd(), idx) ); } 00078 00079 iterator_nd iter(size_t d, const iterator_nd& it) 00080 { return iterator_nd(nd().stride(d), it); } 00081 00082 iterator_nd iter(size_t d, const iterator& it, int offset) 00083 { 00084 size_t s = nd().stride(d); 00085 return iterator_nd(s, it + offset * s); 00086 } 00087 00088 iterator_nd begin(size_t d) 00089 { return iterator_nd(nd().stride(d), nd().begin()); } 00090 00091 iterator_nd begin(size_t d, size_t pos) 00092 { return iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, pos)); } 00093 00094 iterator_nd begin(size_t d, const size_array& idx) 00095 { return iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, sub2ind(nd(), idx) )); } 00096 00097 iterator_nd begin(size_t d, const iterator& it) 00098 { return iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, it - nd().begin())); } 00099 00100 iterator_nd begin(size_t d, const iterator& it, int offset) 00101 { 00102 size_t s = nd().stride(d); 00103 return iterator_nd(s, nd().begin() + begin_pos(d, it - nd.begin() + offset * s)); 00104 } 00105 00106 iterator_nd end(size_t d, size_t pos) 00107 { return iterator_nd(nd().stride(d), nd().begin() + end_pos(d, pos)); } 00108 00109 iterator_nd end(size_t d, const size_array& idx) 00110 { return iterator_nd(nd().stride(d), nd().begin() + end_pos(d, sub2ind(nd(), idx) )); } 00111 00112 iterator_nd end(size_t d, const iterator& it) 00113 { return iterator_nd(nd().stride(d), nd().begin() + end_pos(d, it - nd().begin())); } 00114 00115 iterator_nd end(size_t d, const iterator& it, int offset) 00116 { 00117 size_t s = nd().stride(d); 00118 return iterator_nd(s, nd().begin() + end_pos(d, it - nd.begin() + offset * s)); 00119 } 00120 00121 // const iterator 00122 00123 const_iterator_nd iter(size_t d) const 00124 { return const_iterator_nd(nd().stride(d), nd().begin()); } 00125 00126 const_iterator_nd iter(size_t d, size_t pos) const 00127 { return const_iterator_nd(nd().stride(d), nd().begin() + pos); } 00128 00129 const_iterator_nd iter(size_t d, const size_array& idx) const 00130 { return const_iterator_nd(nd().stride(d), nd().begin() + nd().sub2ind(nd(), idx) ); } 00131 00132 const_iterator_nd iter(size_t d, const const_iterator_nd& it) const 00133 { return const_iterator_nd(nd().stride(d), it); } 00134 00135 const_iterator_nd iter(size_t d, const const_iterator& it, int offset) const 00136 { 00137 size_t s = nd().stride(d); 00138 return const_iterator_nd(s, it + offset * s); 00139 } 00140 00141 const_iterator_nd begin(size_t d) const 00142 { return const_iterator_nd(nd().stride(d), nd().begin()); } 00143 00144 const_iterator_nd begin(size_t d, size_t pos) const 00145 { return const_iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, pos)); } 00146 00147 const_iterator_nd begin(size_t d, const size_array& idx) const 00148 { return const_iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, sub2ind(nd(), idx) )); } 00149 00150 const_iterator_nd begin(size_t d, const const_iterator& it) const 00151 { return const_iterator_nd(nd().stride(d), nd().begin() + begin_pos(d, it - nd().begin())); } 00152 00153 const_iterator_nd begin(size_t d, const const_iterator& it, int offset) const 00154 { 00155 size_t s = nd().stride(d); 00156 return const_iterator_nd(s, nd().begin() + begin_pos(d, it - nd.begin() + offset * s)); 00157 } 00158 00159 const_iterator_nd end(size_t d, size_t pos) const 00160 { return const_iterator_nd(nd().stride(d), nd().begin() + end_pos(d, pos)); } 00161 00162 const_iterator_nd end(size_t d, const size_array& idx) const 00163 { return const_iterator_nd(nd().stride(d), nd().begin() + end_pos(d, sub2ind(nd(), idx) )); } 00164 00165 const_iterator_nd end(size_t d, const const_iterator& it) const 00166 { return const_iterator_nd(nd().stride(d), nd().begin() + end_pos(d, it - nd().begin())); } 00167 00168 const_iterator_nd end(size_t d, const const_iterator& it, int offset) const 00169 { 00170 size_t s = nd().stride(d); 00171 return const_iterator_nd(s, nd().begin() + end_pos(d, it - nd().begin() + offset * s)); 00172 } 00173 00174 // non-const reverse iterator 00175 00176 reverse_iterator_nd riter(size_t d) 00177 { return reverse_iterator_nd(nd().stride(d), nd().rbegin()); } 00178 00179 reverse_iterator_nd riter(size_t d, size_t pos) 00180 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + pos); } 00181 00182 reverse_iterator_nd riter(size_t d, const size_array& idx) 00183 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + nd().sub2ind(nd(), idx) ); } 00184 00185 reverse_iterator_nd riter(size_t d, const reverse_iterator_nd& it) 00186 { return reverse_iterator_nd(nd().stride(d), it); } 00187 00188 reverse_iterator_nd riter(size_t d, const reverse_iterator& it, int offset) 00189 { 00190 size_t s = nd().stride(d); 00191 return reverse_iterator_nd(s, it + offset * s); 00192 } 00193 00194 reverse_iterator_nd rbegin(size_t d) 00195 { return reverse_iterator_nd(nd().stride(d), nd().rbegin()); } 00196 00197 reverse_iterator_nd rbegin(size_t d, size_t pos) 00198 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, pos)); } 00199 00200 reverse_iterator_nd rbegin(size_t d, const size_array& idx) 00201 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, sub2ind(nd(), idx) )); } 00202 00203 reverse_iterator_nd rbegin(size_t d, const reverse_iterator& it) 00204 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, it - nd.rbegin())); } 00205 00206 reverse_iterator_nd rbegin(size_t d, const reverse_iterator& it, int offset) 00207 { 00208 size_t s = nd().stride(d); 00209 return reverse_iterator_nd(s, nd().rbegin() + begin_pos(d, it - nd().rbegin() + offset * s)); 00210 } 00211 00212 reverse_iterator_nd rend(size_t d, size_t pos) 00213 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, pos)); } 00214 00215 reverse_iterator_nd rend(size_t d, const size_array& idx) 00216 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, sub2ind(nd(), idx) )); } 00217 00218 reverse_iterator_nd rend(size_t d, const reverse_iterator& it) 00219 { return reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, it - nd().rbegin())); } 00220 00221 reverse_iterator_nd rend(size_t d, const reverse_iterator& it, int offset) 00222 { 00223 size_t s = nd().stride(d); 00224 return reverse_iterator_nd(s, nd().rbegin() + end_pos(d, it - nd().rbegin() + offset * s)); 00225 } 00226 00227 // const reverse reverse_iterator 00228 00229 const_reverse_iterator_nd riter(size_t d) const 00230 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin()); } 00231 00232 const_reverse_iterator_nd riter(size_t d, size_t pos) const 00233 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + pos); } 00234 00235 const_reverse_iterator_nd riter(size_t d, const size_array& idx) const 00236 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + nd().sub2ind(nd(), idx) ); } 00237 00238 const_reverse_iterator_nd riter(size_t d, const const_reverse_iterator_nd& it) const 00239 { return const_reverse_iterator_nd(nd().stride(d), it); } 00240 00241 const_reverse_iterator_nd riter(size_t d, const const_reverse_iterator& it, int offset) const 00242 { 00243 size_t s = nd().stride(d); 00244 return const_reverse_iterator_nd(s, it + offset * s); 00245 } 00246 00247 const_reverse_iterator_nd rbegin(size_t d) const 00248 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin()); } 00249 00250 const_reverse_iterator_nd rbegin(size_t d, size_t pos) const 00251 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, pos)); } 00252 00253 const_reverse_iterator_nd rbegin(size_t d, const size_array& idx) const 00254 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, sub2ind(nd(), idx) )); } 00255 00256 const_reverse_iterator_nd rbegin(size_t d, const const_reverse_iterator& it) const 00257 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + begin_pos(d, it - nd().rbegin())); } 00258 00259 const_reverse_iterator_nd rbegin(size_t d, const const_reverse_iterator& it, int offset) const 00260 { 00261 size_t s = nd().stride(d); 00262 return const_reverse_iterator_nd(s, nd().rbegin() + begin_pos(d, it - nd().rbegin() + offset * s)); 00263 } 00264 00265 const_reverse_iterator_nd rend(size_t d, size_t pos) const 00266 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, pos)); } 00267 00268 const_reverse_iterator_nd rend(size_t d, const size_array& idx) const 00269 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, sub2ind(nd(), idx) )); } 00270 00271 const_reverse_iterator_nd rend(size_t d, const const_reverse_iterator& it) const 00272 { return const_reverse_iterator_nd(nd().stride(d), nd().rbegin() + end_pos(d, it - nd().rbegin())); } 00273 00274 const_reverse_iterator_nd rend(size_t d, const const_reverse_iterator& it, int offset) const 00275 { 00276 size_t s = nd().stride(d); 00277 return const_reverse_iterator_nd(s, nd().rbegin() + end_pos(d, it - nd().rbegin() + offset * s)); 00278 } 00279 00280 }; 00281 00282 }; /* namespace array_nd_details */ 00283 00284 }; /* namespace ivl */ 00285 00286 00287 00288 #endif //ARRAY_ND_DETAILS_ARRAY_ND_ITERATOR_ND_INTERFACE_HPP