|
ViennaGrid
1.0.1
|
00001 #ifndef VIENNAGRID_DOMAIN_ITERATORS_HPP 00002 #define VIENNAGRID_DOMAIN_ITERATORS_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2012, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 Authors: Karl Rupp rupp@iue.tuwien.ac.at 00014 Josef Weinbub weinbub@iue.tuwien.ac.at 00015 00016 (A list of additional contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ======================================================================= */ 00020 00021 00022 #include <vector> 00023 #include <list> 00024 #include <map> 00025 #include <stack> 00026 #include <assert.h> 00027 00028 #include "viennagrid/forwards.h" 00029 00034 namespace viennagrid 00035 { 00036 00037 00038 // iterator over all subcells (not vertex or cell type) on the domain 00039 // transforms the map-like storage on the domain 00041 template <typename ElementType, typename MapIterator> 00042 class domain_subcell_iterator : public std::iterator < std::forward_iterator_tag, ElementType > 00043 { 00044 public: 00045 domain_subcell_iterator(MapIterator const & mit) : mit_(mit) {} 00046 00047 ElementType & operator*() const { return mit_->second; } 00048 ElementType* operator->() const { return &(mit_->second); } 00049 00050 domain_subcell_iterator & operator++() { ++mit_; return *this; } 00051 domain_subcell_iterator & operator++(int) { domain_subcell_iterator tmp = *this; ++*this; return tmp; } 00052 00053 bool operator==(const domain_subcell_iterator & i) const { return mit_ == i.mit_; } 00054 bool operator!=(const domain_subcell_iterator & i) const { return mit_ != i.mit_; } 00055 00056 private: 00057 MapIterator mit_; 00058 }; 00059 00060 00061 00063 //generic case: 00065 template <typename Config, 00066 long dim, 00067 long cell_level = Config::cell_tag::dim> 00068 struct domain_iterators 00069 { 00070 typedef domain_t<Config> domain_type; 00071 typedef element_t<Config, 00072 typename Config::cell_tag> cell_type; 00073 typedef element_t< Config, 00074 typename topology::bndcells<typename Config::cell_tag, dim>::tag 00075 > element_type; 00076 00077 typedef typename result_of::element_container<domain_type, dim>::type container_type; 00078 00079 typedef domain_subcell_iterator<element_type, 00080 typename container_type::iterator> iterator; 00081 typedef domain_subcell_iterator<const element_type, 00082 typename container_type::const_iterator> const_iterator; 00083 }; 00084 00085 //special case: vertices: 00087 template <typename Config, long cell_level> 00088 struct domain_iterators< Config, 0, cell_level> 00089 { 00090 typedef domain_t<Config> domain_type; 00091 typedef element_t<Config, 00092 typename Config::cell_tag> cell_type; 00093 00094 typedef typename result_of::element_container<domain_type, 0>::type container_type; 00095 00096 typedef typename container_type::iterator iterator; 00097 typedef typename container_type::const_iterator const_iterator; 00098 }; 00099 00100 //special case: cells: 00102 template <typename Config, long cell_level> 00103 struct domain_iterators< Config, cell_level, cell_level> 00104 { 00105 typedef domain_t<Config> domain_type; 00106 typedef element_t<Config, 00107 typename Config::cell_tag> cell_type; 00108 00109 typedef typename result_of::element_container<domain_type, 00110 Config::cell_tag::dim>::type container_type; 00111 00112 typedef typename container_type::iterator iterator; 00113 typedef typename container_type::const_iterator const_iterator; 00114 }; 00115 00116 00117 00119 template <typename ContainerType> 00120 struct assert_bracket_operator_access 00121 { 00122 // The user tried to do something like ncells<1>(domain)[0] to access the edge with ID 0 in the domain. 00123 // However, edges are configured not to carry IDs at all, therefore throw an error. 00124 typedef typename ContainerType::ERROR_BRACKET_OPERATOR_ACCESS_IMPOSSIBLE_AT_THIS_DOMAIN_LEVEL___USE_ITERATORS type; 00125 }; 00126 00128 template <typename ElementType> 00129 struct assert_bracket_operator_access< std::vector<ElementType> > 00130 { 00131 typedef void type; 00132 }; 00133 00135 template <typename ElementType> 00136 struct assert_bracket_operator_access< std::deque<ElementType> > 00137 { 00138 typedef void type; 00139 }; 00140 00141 00142 // interface function for container creation, 00143 // non-const: 00144 //container for iteration over a STL vector 00146 template <typename config_type, long dim> 00147 class ncell_range < domain_t<config_type>, dim, false > 00148 { 00149 typedef domain_t<config_type> domain_type; 00150 typedef element_t< config_type, 00151 typename topology::bndcells<typename config_type::cell_tag, dim>::tag 00152 > element_type; 00153 00154 typedef element_t< config_type, 00155 typename config_type::cell_tag 00156 > cell_type; 00157 00158 //typedef std::vector< element_type > container_type; 00159 typedef typename result_of::element_container<domain_type, dim>::type container_type; 00160 00161 public: 00162 //typedef typename container_type::iterator iterator; 00163 typedef typename domain_iterators<config_type, dim>::iterator iterator; 00164 00165 ncell_range() : cont_(NULL) {}; 00166 00167 ncell_range(ncell_proxy<domain_type> const & p) : cont_(p.get().container(dimension_tag<dim>())) {} 00168 00169 ncell_range(domain_type & d) : cont_(d.container(dimension_tag<dim>())) {} 00170 00171 ncell_range & operator=(ncell_proxy<domain_type> p) 00172 { 00173 cont_ = p.get().container(dimension_tag<dim>()); 00174 return *this; 00175 } 00176 00177 iterator begin() const { return cont_->begin(); } 00178 iterator end() const { return cont_->end(); } 00179 00180 std::size_t size() const { return cont_->size(); } 00181 00182 element_type & operator[](std::size_t index) 00183 { 00184 typedef typename assert_bracket_operator_access<container_type>::type asserted_type; 00185 assert(index < size()); 00186 return (*cont_)[index]; 00187 } 00188 00189 element_type const & operator[](std::size_t index) const 00190 { 00191 typedef typename assert_bracket_operator_access<container_type>::type asserted_type; 00192 assert(index < size()); 00193 return (*cont_)[index]; 00194 } 00195 00196 template <typename DomainType, long dim2, bool b2> 00197 friend class const_ncell_range; 00198 00199 private: 00200 container_type * cont_; 00201 }; 00202 00204 template <long dim, typename DomainConfig> 00205 ncell_range<domain_t<DomainConfig>, dim> 00206 ncells(domain_t<DomainConfig> & d) 00207 { 00208 return ncell_range<domain_t<DomainConfig>, dim>(d); 00209 } 00210 00216 template <typename DomainConfig> 00217 ncell_proxy< domain_t<DomainConfig> > 00218 ncells(domain_t<DomainConfig> & d) 00219 { 00220 return ncell_proxy< domain_t<DomainConfig> >(d); 00221 } 00222 00223 00224 // 00225 //const container: 00226 // 00228 template <typename config_type, long dim> 00229 class const_ncell_range < domain_t<config_type>, dim, false > 00230 { 00231 typedef domain_t<config_type> domain_type; 00232 typedef element_t< config_type, 00233 typename topology::bndcells<typename config_type::cell_tag, dim>::tag 00234 > element_type; 00235 00236 typedef element_t< config_type, 00237 typename config_type::cell_tag 00238 > cell_type; 00239 00240 //typedef std::vector< element_type > container_type; 00241 typedef typename result_of::element_container<domain_type, dim>::type container_type; 00242 00243 public: 00244 //typedef typename container_type::const_iterator iterator; 00245 typedef typename domain_iterators<config_type, dim>::const_iterator iterator; 00246 00247 const_ncell_range() : cont_(NULL) {}; 00248 00249 const_ncell_range(const_ncell_proxy<domain_type> const & p) : cont_(p.get().container(dimension_tag<dim>())) {} 00250 00251 const_ncell_range(ncell_proxy<domain_type> const & p) : cont_(p.get().container(dimension_tag<dim>())) {} 00252 00253 const_ncell_range(domain_type const & d) : cont_(d.container(dimension_tag<dim>())) {} 00254 00255 const_ncell_range(ncell_range<domain_type, dim > const & other) : cont_(other.cont_) {} 00256 00257 const_ncell_range & operator=(const_ncell_proxy<domain_type> const & p) 00258 { 00259 cont_ = p.get().container(dimension_tag<dim>()); 00260 return *this; 00261 } 00262 00263 const_ncell_range & operator=(ncell_proxy<domain_type> p) 00264 { 00265 cont_ = p.get().container(dimension_tag<dim>()); 00266 return *this; 00267 } 00268 00269 const_ncell_range & operator=(ncell_range<domain_type, dim > const & other) 00270 { 00271 cont_ = other.cont_; 00272 return *this; 00273 } 00274 00275 iterator begin() const { return cont_->begin(); } 00276 iterator end() const { return cont_->end(); } 00277 00278 element_type const & operator[](std::size_t index) const 00279 { 00280 typedef typename assert_bracket_operator_access<container_type>::type asserted_type; 00281 assert(index < size()); 00282 return (*cont_)[index]; 00283 } 00284 00285 size_t size() const { return cont_->size(); } 00286 00287 private: 00288 const container_type * cont_; 00289 }; 00290 00292 template <long dim, typename DomainConfig> 00293 const_ncell_range< domain_t<DomainConfig>, dim> 00294 ncells(domain_t<DomainConfig> const & d) 00295 { 00296 return const_ncell_range< domain_t<DomainConfig>, dim>(d); 00297 } 00298 00304 template <typename DomainConfig> 00305 const_ncell_proxy< domain_t<DomainConfig> > 00306 ncells(domain_t<DomainConfig> const & d) 00307 { 00308 return const_ncell_proxy< domain_t<DomainConfig> >(d); 00309 } 00310 00311 00312 //metafunction for return type: 00313 namespace result_of 00314 { 00316 template <typename T, long dim, bool is_coboundary> 00317 struct iterator<viennagrid::ncell_range<T, dim, is_coboundary>, 0> 00318 { 00319 typedef typename viennagrid::ncell_range<T, dim, is_coboundary>::iterator type; 00320 }; 00321 00323 template <typename T, long dim, bool is_coboundary> 00324 struct iterator<viennagrid::const_ncell_range<T, dim, is_coboundary>, 0> 00325 { 00326 typedef typename viennagrid::const_ncell_range<T, dim, is_coboundary>::iterator type; 00327 }; 00328 00333 template <typename T, 00334 long dim> //topological level 00335 struct ncell_range 00336 { 00337 typedef viennagrid::ncell_range<T, dim> type; 00338 }; 00339 00344 template <typename T, 00345 long dim> //topological level 00346 struct const_ncell_range 00347 { 00348 typedef viennagrid::const_ncell_range<T, dim> type; 00349 }; 00350 00351 } 00352 00353 } //namespace 00354 #endif 00355
1.7.6.1