• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/export/development/ViennaGrid/release/ViennaGrid-1.0.0/viennagrid/detail/domain_iterators.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAGRID_DOMAIN_ITERATORS_HPP
00002 #define VIENNAGRID_DOMAIN_ITERATORS_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011, 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 

Generated on Wed Sep 14 2011 19:21:30 for ViennaGrid by  doxygen 1.7.1