00001 #ifndef VIENNAGRID_DOMAIN_ITERATORS_HPP
00002 #define VIENNAGRID_DOMAIN_ITERATORS_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00039
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
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
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
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
00123
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
00143
00144
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
00159 typedef typename result_of::element_container<domain_type, dim>::type container_type;
00160
00161 public:
00162
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
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
00241 typedef typename result_of::element_container<domain_type, dim>::type container_type;
00242
00243 public:
00244
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
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>
00335 struct ncell_range
00336 {
00337 typedef viennagrid::ncell_range<T, dim> type;
00338 };
00339
00344 template <typename T,
00345 long dim>
00346 struct const_ncell_range
00347 {
00348 typedef viennagrid::const_ncell_range<T, dim> type;
00349 };
00350
00351 }
00352
00353 }
00354 #endif
00355