ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/accessor.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ACCESSOR_HPP
00002 #define VIENNAGRID_ACCESSOR_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    License:      MIT (X11), see file LICENSE in the base directory
00014 ======================================================================= */
00015 
00016 #include <stdexcept>
00017 #include <assert.h>
00018 
00019 #include "viennagrid/forwards.hpp"
00020 #include "viennagrid/storage/id.hpp"
00021 #include "viennagrid/storage/container_collection.hpp"
00022 
00027 #ifdef VIENNAGRID_WITH_VIENNADATA
00028 #include "viennadata/api.hpp"
00029 
00030 
00031 namespace viennadata
00032 {
00033   namespace result_of
00034   {
00035     template<typename value_type, typename base_id_type>
00036     struct offset< viennagrid::storage::smart_id<value_type, base_id_type> >
00037     {
00038       typedef viennagrid::storage::smart_id<value_type, base_id_type> id_type;
00039       typedef base_id_type type;
00040 
00041       static type get(id_type const & id) { return id.get(); }
00042     };
00043   }
00044 }
00045 #endif
00046 
00047 
00048 namespace viennagrid
00049 {
00051   template<typename value_type_, typename element_type>
00052   class appendix_accessor
00053   {
00054   public:
00055       typedef value_type_ value_type;
00056       typedef element_type access_type;
00057 
00058       bool is_valid() const { return true; }
00059 
00060       value_type       * find( access_type & element )              { return &element.appendix(); }
00061       value_type const * find( access_type const & element )  const { return &element.appendix(); }
00062 
00063       value_type       & at( access_type & element )             { return element.appendix(); }
00064       value_type const & at( access_type const & element ) const { return element.appendix(); }
00065 
00066       value_type       & operator()( access_type & element )             { return at(element); }
00067       value_type const & operator()( access_type const & element ) const { return at(element); }
00068   };
00069 
00070 
00071   namespace result_of
00072   {
00073 
00075     template<typename mesh_or_element_type>
00076     struct default_point_accessor
00077     {
00078       typedef viennagrid::appendix_accessor<
00079         typename viennagrid::result_of::point<mesh_or_element_type>::type,
00080         typename viennagrid::result_of::vertex<mesh_or_element_type>::type
00081       > type;
00082     };
00083 
00084   }
00085 
00087   template<typename mesh_or_element_type>
00088   typename result_of::default_point_accessor<mesh_or_element_type>::type default_point_accessor( mesh_or_element_type const & )
00089   {
00090     return viennagrid::appendix_accessor<
00091       typename viennagrid::result_of::point<mesh_or_element_type>::type,
00092       typename viennagrid::result_of::vertex<mesh_or_element_type>::type
00093     >();
00094   }
00095 
00096 
00097   namespace result_of
00098   {
00105     template<typename ElementT, typename ValueT, typename ContainerTagT = std_vector_tag>
00106     struct accessor_container {};
00107 
00109     template<typename ElementT, typename ValueT>
00110     struct accessor_container<ElementT, ValueT, std_vector_tag>
00111     {
00112       typedef std::vector<ValueT> type;
00113     };
00114 
00115     template<typename ElementT, typename ValueT>
00116     struct accessor_container<ElementT, ValueT, std_deque_tag>
00117     {
00118       typedef std::deque<ValueT> type;
00119     };
00120 
00121     template<typename ElementT, typename ValueT>
00122     struct accessor_container<ElementT, ValueT, std_map_tag>
00123     {
00124       typedef std::map< typename result_of::id<ElementT>::type, ValueT > type;
00125     };
00127   }
00128 
00129 
00130 
00131 
00132   struct id_unpack
00133   {
00134     template<typename ElementT>
00135     typename viennagrid::result_of::id<ElementT>::type operator()(ElementT const & element) const
00136     { return element.id(); }
00137   };
00138 
00139   struct base_id_unpack
00140   {
00141     template<typename ElementT>
00142     typename viennagrid::result_of::id<ElementT>::type::base_id_type operator()(ElementT const & element) const
00143     { return element.id().get(); }
00144   };
00145 
00146   namespace result_of
00147   {
00148     template<typename ContainerT>
00149     struct unpack;
00150 
00151     template<typename T, typename Alloc>
00152     struct unpack< std::vector<T, Alloc> >
00153     {
00154       typedef base_id_unpack type;
00155     };
00156 
00157     template<typename T, typename Alloc>
00158     struct unpack< const std::vector<T, Alloc> >
00159     {
00160       typedef base_id_unpack type;
00161     };
00162 
00163     template<typename T, typename Alloc>
00164     struct unpack< std::deque<T, Alloc> >
00165     {
00166       typedef base_id_unpack type;
00167     };
00168 
00169     template<typename T, typename Alloc>
00170     struct unpack< const std::deque<T, Alloc> >
00171     {
00172       typedef base_id_unpack type;
00173     };
00174 
00175     template<typename Key, typename T, typename Compare, typename Alloc>
00176     struct unpack< std::map<Key, T, Compare, Alloc> >
00177     {
00178       typedef id_unpack type;
00179     };
00180 
00181     template<typename Key, typename T, typename Compare, typename Alloc>
00182     struct unpack< const std::map<Key, T, Compare, Alloc> >
00183     {
00184       typedef id_unpack type;
00185     };
00186   }
00187 
00188 
00189 
00190 
00196   template<typename ContainerType, typename AccessType, typename UnpackT = base_id_unpack>
00197   class dense_container_accessor
00198   {
00199   public:
00200 
00201     typedef ContainerType                                           container_type;
00202     typedef typename ContainerType::value_type                      value_type;
00203     typedef AccessType                                              access_type;
00204 
00205     typedef typename ContainerType::reference       reference;
00206     typedef typename ContainerType::const_reference const_reference;
00207 
00208     typedef typename ContainerType::pointer         pointer;
00209     typedef typename ContainerType::const_pointer   const_pointer;
00210 
00211     typedef typename access_type::id_type::base_id_type offset_type;
00212 
00213     dense_container_accessor() : container(0) {}
00214     dense_container_accessor( ContainerType & container_ ) : container(&container_) {}
00215 
00216     bool is_valid() const { return container != NULL; }
00217 
00218     pointer find(AccessType const & element)
00219     {
00220       offset_type offset = unpack(element);
00221       return (static_cast<offset_type>((*container).size()) > unpack(element)) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00222     }
00223 
00224     const_pointer find(AccessType const & element) const
00225     {
00226       offset_type offset = unpack(element);
00227       return (static_cast<offset_type>((*container).size()) > unpack(element)) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00228     }
00229 
00230     reference operator()(AccessType const & element)
00231     {
00232       offset_type offset = unpack(element);
00233       if ( static_cast<offset_type>((*container).size()) <= offset) (*container).resize(static_cast<std::size_t>(offset+1));
00234       return (*container)[static_cast<std::size_t>(offset)];
00235     }
00236 
00237     const_reference operator()(AccessType const & element) const
00238     {
00239       offset_type offset = unpack(element);
00240       assert( static_cast<offset_type>((*container).size()) > offset );
00241       return (*container)[static_cast<std::size_t>(offset)];
00242     }
00243 
00244     reference at(AccessType const & element)
00245     {
00246       offset_type offset = unpack(element);
00247       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_accessor::at() failed");
00248       return (*container)[static_cast<std::size_t>(offset)];
00249     }
00250 
00251     const_reference at(AccessType const & element) const
00252     {
00253       offset_type offset = unpack(element);
00254       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_accessor::at() const failed");
00255       return (*container)[static_cast<std::size_t>(offset)];
00256     }
00257 
00258   protected:
00259     UnpackT unpack;
00260     ContainerType * container;
00261   };
00262 
00263 
00265   template<typename ContainerType, typename AccessType, typename UnpackT>
00266   class dense_container_accessor<const ContainerType, AccessType, UnpackT>
00267   {
00268   public:
00269 
00270     typedef const ContainerType                                     container_type;
00271     typedef typename ContainerType::value_type                      value_type;
00272     typedef AccessType                                              access_type;
00273 
00274     typedef typename ContainerType::const_reference       reference;
00275     typedef typename ContainerType::const_reference const_reference;
00276 
00277     typedef typename ContainerType::const_pointer         pointer;
00278     typedef typename ContainerType::const_pointer   const_pointer;
00279 
00280     typedef typename access_type::id_type::base_id_type offset_type;
00281 
00282     dense_container_accessor() : container(0) {}
00283     dense_container_accessor( container_type & container_ ) : container(&container_) {}
00284 
00285     bool is_valid() const { return container != NULL; }
00286 
00287     const_pointer find(AccessType const & element) const
00288     {
00289       offset_type offset = unpack(element);
00290       return (static_cast<offset_type>((*container).size()) > unpack(element)) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00291     }
00292 
00293     const_reference operator()(AccessType const & element) const
00294     {
00295       offset_type offset = unpack(element);
00296       assert( static_cast<offset_type>((*container).size()) > offset );
00297       return (*container)[static_cast<std::size_t>(offset)];
00298     }
00299 
00300     const_reference at(AccessType const & element) const
00301     {
00302       offset_type offset = unpack(element);
00303       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_accessor::at() const failed");
00304       return (*container)[static_cast<std::size_t>(offset)];
00305     }
00306 
00307     void erase(AccessType const & element);
00308     void clear();
00309     void resize( std::size_t size );
00310 
00311 
00312   protected:
00313     UnpackT unpack;
00314     container_type * container;
00315   };
00325   template<typename ContainerType, typename AccessType, typename UnpackT = id_unpack>
00326   class std_map_accessor
00327   {
00328   public:
00329 
00330     typedef ContainerType                                           container_type;
00331     typedef typename ContainerType::value_type::second_type         value_type;
00332     typedef typename ContainerType::value_type::first_type          key_type;
00333     typedef AccessType                                              access_type;
00334 
00335     typedef value_type &       reference;
00336     typedef value_type const & const_reference;
00337 
00338     typedef value_type *         pointer;
00339     typedef value_type const *   const_pointer;
00340 
00341     std_map_accessor() : container(0) {}
00342     std_map_accessor( ContainerType & container_ ) : container(&container_) {}
00343 
00344     bool is_valid() const { return container != NULL; }
00345 
00346     pointer find(AccessType const & element)
00347     {
00348       typename container_type::iterator it = (*container).find( unpack(element) );
00349       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00350     }
00351 
00352     const_pointer find(AccessType const & element) const
00353     {
00354       typename container_type::const_iterator it = (*container).find( unpack(element) );
00355       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00356     }
00357 
00358     reference operator()(AccessType const & element)
00359     {
00360       return (*container)[ unpack(element) ];
00361     }
00362 
00363     const_reference operator()(AccessType const & element) const
00364     {
00365       typename container_type::const_iterator it = (*container).find( unpack(element) );
00366       assert(it != (*container).end()); // no release-runtime check for accessing elements outside (*container)
00367       return it->second;
00368     }
00369 
00370     reference at(AccessType const & element)
00371     {
00372       return (*this)(element);
00373     }
00374 
00375     const_reference at(AccessType const & element) const
00376     {
00377       typename container_type::const_iterator it = (*container).find( unpack(element) );
00378       if (it == (*container).end()) throw std::out_of_range("std_map_accessor::at() const failed");
00379       return it->second;
00380     }
00381 
00382   protected:
00383     UnpackT unpack;
00384     ContainerType * container;
00385   };
00386 
00387 
00389   template<typename ContainerType, typename AccessType, typename UnpackT>
00390   class std_map_accessor<const ContainerType, AccessType, UnpackT>
00391   {
00392   public:
00393 
00394     typedef const ContainerType                                     container_type;
00395     typedef typename ContainerType::value_type::second_type         value_type;
00396     typedef typename ContainerType::value_type::first_type          key_type;
00397     typedef AccessType                                              access_type;
00398 
00399     typedef value_type const &       reference;
00400     typedef value_type const & const_reference;
00401 
00402     typedef value_type const *         pointer;
00403     typedef value_type const *   const_pointer;
00404 
00405     std_map_accessor() : container(0) {}
00406     std_map_accessor( container_type & container_ ) : container(&container_) {}
00407 
00408     bool is_valid() const { return container != NULL; }
00409 
00410     const_pointer find(AccessType const & element) const
00411     {
00412       typename container_type::const_iterator it = (*container).find( unpack(element) );
00413       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00414     }
00415 
00416     const_reference operator()(AccessType const & element) const
00417     {
00418       typename container_type::const_iterator it = (*container).find( unpack(element) );
00419       assert(it != (*container).end()); // no release-runtime check for accessing elements outside (*container)
00420       return it->second;
00421     }
00422 
00423     const_reference at(AccessType const & element) const
00424     {
00425       typename container_type::const_iterator it = (*container).find( unpack(element) );
00426       if (it == (*container).end()) throw std::out_of_range("std_map_accessor::at() const failed");
00427       return it->second;
00428     }
00429 
00430   protected:
00431     UnpackT unpack;
00432     container_type * container;
00433   };
00438   namespace result_of
00439   {
00445     template<typename ContainerType, typename AccessType, typename UnpackT = typename viennagrid::result_of::unpack<ContainerType>::type>
00446     struct accessor;
00447 
00449     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00450     struct accessor< std::vector<T, Alloc>, AccessType, UnpackT >
00451     {
00452       typedef viennagrid::dense_container_accessor<std::vector<T, Alloc>, AccessType, UnpackT> type;
00453     };
00454 
00455     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00456     struct accessor< const std::vector<T, Alloc>, AccessType, UnpackT >
00457     {
00458       typedef viennagrid::dense_container_accessor<const std::vector<T, Alloc>, AccessType, UnpackT> type;
00459     };
00460 
00461     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00462     struct accessor< std::deque<T, Alloc>, AccessType, UnpackT >
00463     {
00464       typedef viennagrid::dense_container_accessor<std::deque<T, Alloc>, AccessType, UnpackT> type;
00465     };
00466 
00467     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00468     struct accessor< const std::deque<T, Alloc>, AccessType, UnpackT >
00469     {
00470       typedef viennagrid::dense_container_accessor<const std::deque<T, Alloc>, AccessType, UnpackT> type;
00471     };
00472 
00473     template<typename Key, typename T, typename Compare, typename Alloc, typename AccessType, typename UnpackT>
00474     struct accessor< std::map<Key, T, Compare, Alloc>, AccessType, UnpackT >
00475     {
00476       typedef viennagrid::std_map_accessor<std::map<Key, T, Compare, Alloc>, AccessType, UnpackT> type;
00477     };
00478 
00479     template<typename Key, typename T, typename Compare, typename Alloc, typename AccessType, typename UnpackT>
00480     struct accessor< const std::map<Key, T, Compare, Alloc>, AccessType, UnpackT >
00481     {
00482       typedef viennagrid::std_map_accessor<const std::map<Key, T, Compare, Alloc>, AccessType, UnpackT> type;
00483     };
00485   }
00486 
00487 
00493   template<typename AccessType, typename ContainerType>
00494   typename result_of::accessor<ContainerType, AccessType>::type make_accessor( ContainerType & container )
00495   {
00496     return typename result_of::accessor<ContainerType, AccessType>::type(container);
00497   }
00498 
00504   template<typename AccessType, typename ContainerType>
00505   typename result_of::accessor<const ContainerType, AccessType>::type make_accessor( ContainerType const & container )
00506   {
00507     return typename result_of::accessor<const ContainerType, AccessType>::type(container);
00508   }
00509 
00510 
00511 
00517   template<typename AccessType, typename ContainerCollectionTypemapT>
00518   typename result_of::accessor<
00519       typename result_of::container_of<
00520           ContainerCollectionTypemapT,
00521           AccessType
00522       >::type,
00523       AccessType>::type make_accessor( collection<ContainerCollectionTypemapT> & collection_obj )
00524   {
00525     return make_accessor<AccessType>( get<AccessType>(collection_obj) );
00526   }
00527 
00533   template<typename AccessType, typename ContainerCollectionTypemapT>
00534   typename result_of::accessor<
00535       const typename result_of::container_of<
00536           ContainerCollectionTypemapT,
00537           AccessType
00538       >::type,
00539       AccessType>::type make_accessor( collection<ContainerCollectionTypemapT> const & collection_obj )
00540   {
00541     return make_accessor<AccessType>( get<AccessType>(collection_obj) );
00542   }
00543 
00544 
00545 
00551   template<typename ValueType, typename AccessType>
00552   class base_dynamic_accessor
00553   {
00554   public:
00555     typedef ValueType  value_type;
00556     typedef AccessType access_type;
00557 
00558     typedef value_type       &       reference;
00559     typedef value_type const & const_reference;
00560 
00561     typedef value_type       *       pointer;
00562     typedef value_type const * const_pointer;
00563 
00564     virtual ~base_dynamic_accessor() {}
00565 
00566     virtual       pointer find( access_type const & ) { return 0; }
00567     virtual const_pointer find( access_type const & ) const { return 0; }
00568 
00569     virtual       reference operator()( access_type const & element ) = 0;
00570     virtual const_reference operator()( access_type const & element ) const = 0;
00571 
00572     virtual       reference at( access_type const & element ) = 0;
00573     virtual const_reference at( access_type const & element ) const = 0;
00574   };
00575 
00577   template<typename ValueType, typename AccessType>
00578   class base_dynamic_accessor<const ValueType, AccessType>
00579   {
00580   public:
00581     typedef ValueType value_type;
00582     typedef AccessType access_type;
00583 
00584     typedef value_type const & reference;
00585     typedef value_type const & const_reference;
00586 
00587     typedef value_type const * pointer;
00588     typedef value_type const * const_pointer;
00589 
00590     virtual ~base_dynamic_accessor() {}
00591 
00592     virtual const_pointer find( access_type const & ) const { return 0; }
00593     virtual const_reference operator()( access_type const & element ) const = 0;
00594     virtual const_reference at( access_type const & element ) const = 0;
00595   };
00604   template<typename AccessorType>
00605   class dynamic_accessor_wrapper : public base_dynamic_accessor< typename AccessorType::value_type, typename AccessorType::access_type >
00606   {
00607   public:
00608     typedef base_dynamic_accessor< typename AccessorType::value_type, typename AccessorType::access_type > BaseAccessorType;
00609 
00610     typedef typename BaseAccessorType::value_type value_type;
00611     typedef typename BaseAccessorType::access_type access_type;
00612 
00613     typedef typename BaseAccessorType::reference reference;
00614     typedef typename BaseAccessorType::const_reference const_reference;
00615 
00616     typedef typename BaseAccessorType::pointer pointer;
00617     typedef typename BaseAccessorType::const_pointer const_pointer;
00618 
00619 
00620     dynamic_accessor_wrapper(AccessorType accessor_) : accessor(accessor_) {}
00621 
00622     virtual pointer find( access_type const & element ) { return accessor.find(element); }
00623     virtual const_pointer find( access_type const & element ) const { return accessor.find(element); }
00624 
00625     virtual reference operator()( access_type const & element )       { return access(element); }
00626     virtual const_reference operator()( access_type const & element ) const { return access(element); }
00627 
00628     virtual reference at( access_type const & element ) { return accessor.access(element); }
00629     virtual const_reference at( access_type const & element ) const { return accessor.access(element); }
00630 
00631   private:
00632     AccessorType accessor;
00633   };
00634 
00636   template<typename AccessorType>
00637   class dynamic_accessor_wrapper<const AccessorType> : public base_dynamic_accessor< const typename AccessorType::value_type, typename AccessorType::access_type >
00638   {
00639   public:
00640     typedef base_dynamic_accessor< const typename AccessorType::value_type, typename AccessorType::access_type > BaseAccessorType;
00641 
00642     typedef typename BaseAccessorType::value_type value_type;
00643     typedef typename BaseAccessorType::access_type access_type;
00644 
00645     typedef typename BaseAccessorType::const_reference reference;
00646     typedef typename BaseAccessorType::const_reference const_reference;
00647 
00648     typedef typename BaseAccessorType::const_pointer pointer;
00649     typedef typename BaseAccessorType::const_pointer const_pointer;
00650 
00651 
00652     dynamic_accessor_wrapper(AccessorType accessor_) : accessor(accessor_) {}
00653 
00654     virtual const_pointer find( access_type const & element ) const { return accessor.find(element); }
00655     virtual const_reference operator()( access_type const & element ) const { return access(element); }
00656     virtual const_reference at( access_type const & element ) const { return accessor.access(element); }
00657 
00658   private:
00659     AccessorType accessor;
00660   };
00679   template<typename ContainerType, typename AccessType, typename UnpackT = base_id_unpack>
00680   class dense_container_field
00681   {
00682   public:
00683 
00684     typedef ContainerType                                           container_type;
00685     typedef typename ContainerType::value_type                      value_type;
00686     typedef AccessType                                              access_type;
00687 
00688     typedef typename ContainerType::reference       reference;
00689     typedef typename ContainerType::const_reference const_reference;
00690 
00691     typedef typename ContainerType::pointer         pointer;
00692     typedef typename ContainerType::const_pointer   const_pointer;
00693 
00694     typedef typename access_type::id_type::base_id_type offset_type;
00695 
00696     dense_container_field() : default_value() {}
00697     dense_container_field( ContainerType & container_ ) : container(&container_), default_value() {}
00698     dense_container_field( ContainerType & container_, value_type const & value_type_ ) : container(&container_), default_value(value_type_) {}
00699 
00700     bool is_valid() const { return container != NULL; }
00701 
00702     pointer find(AccessType const & element)
00703     {
00704       offset_type offset = unpack(element);
00705       return (static_cast<offset_type>((*container).size()) > offset) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00706     }
00707 
00708     const_pointer find(AccessType const & element) const
00709     {
00710       offset_type offset = unpack(element);
00711       return (static_cast<offset_type>((*container).size()) > offset) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00712     }
00713 
00714     reference operator()(AccessType const & element)
00715     {
00716       offset_type offset = unpack(element);
00717       if ( static_cast<offset_type>((*container).size()) <= offset) (*container).resize(static_cast<std::size_t>(offset+1));
00718       return (*container)[static_cast<std::size_t>(offset)];
00719     }
00720 
00721     const_reference operator()(AccessType const & element) const
00722     {
00723       offset_type offset = unpack(element);
00724 
00725       if ( static_cast<offset_type>((*(this->container)).size()) <= offset)
00726         return default_value;
00727 
00728       return (*(this->container))[static_cast<std::size_t>(offset)];
00729     }
00730 
00731     reference at(AccessType const & element)
00732     {
00733       offset_type offset = unpack(element);
00734       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_field::at() failed");
00735       return (*container)[static_cast<std::size_t>(offset)];
00736     }
00737 
00738     const_reference at(AccessType const & element) const
00739     {
00740       offset_type offset = unpack(element);
00741       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_field::at() failed");
00742       return (*container)[static_cast<std::size_t>(offset)];
00743     }
00744 
00745 
00746 
00747   protected:
00748     UnpackT unpack;
00749     ContainerType * container;
00750     value_type default_value;
00751   };
00752 
00754   template<typename ContainerType, typename AccessType, typename UnpackT>
00755   class dense_container_field<const ContainerType, AccessType, UnpackT>
00756   {
00757   public:
00758 
00759     typedef const ContainerType                                     container_type;
00760     typedef typename ContainerType::value_type                      value_type;
00761     typedef AccessType                                              access_type;
00762 
00763     typedef typename ContainerType::const_reference       reference;
00764     typedef typename ContainerType::const_reference const_reference;
00765 
00766     typedef typename ContainerType::const_pointer         pointer;
00767     typedef typename ContainerType::const_pointer   const_pointer;
00768 
00769     typedef typename access_type::id_type::base_id_type offset_type;
00770 
00771     dense_container_field() : default_value() {}
00772     dense_container_field( ContainerType const & container_ ) : container(&container_), default_value() {}
00773     dense_container_field( ContainerType const & container_, value_type const & value_type_ ) : container(&container_), default_value(value_type_) {}
00774 
00775     bool is_valid() const { return container != NULL; }
00776 
00777     const_pointer find(AccessType const & element) const
00778     {
00779       offset_type offset = unpack(element);
00780       return (static_cast<offset_type>((*container).size()) > offset) ? (&(*container)[static_cast<std::size_t>(offset)]) : NULL;
00781     }
00782 
00783     const_reference operator()(AccessType const & element) const
00784     {
00785       offset_type offset = unpack(element);
00786 
00787       if ( static_cast<offset_type>((*(this->container)).size()) <= offset)
00788         return default_value;
00789 
00790       return (*(this->container))[static_cast<std::size_t>(offset)];
00791     }
00792 
00793     const_reference at(AccessType const & element) const
00794     {
00795       offset_type offset = unpack(element);
00796       if ( static_cast<offset_type>((*container).size()) <= offset) throw std::out_of_range("dense_container_field::at() failed");
00797       return (*container)[static_cast<std::size_t>(offset)];
00798     }
00799 
00800     void erase(AccessType const & element);
00801     void clear();
00802     void resize( std::size_t size );
00803 
00804 
00805   protected:
00806     UnpackT unpack;
00807     container_type * container;
00808     value_type default_value;
00809   };
00815   template<typename ContainerType, typename AccessType, typename UnpackT = id_unpack>
00816   class std_map_field
00817   {
00818   public:
00819 
00820     typedef ContainerType                                           container_type;
00821     typedef typename ContainerType::value_type::second_type         value_type;
00822     typedef typename ContainerType::value_type::first_type          key_type;
00823     typedef AccessType                                              access_type;
00824 
00825     typedef value_type &       reference;
00826     typedef value_type const & const_reference;
00827 
00828     typedef value_type *         pointer;
00829     typedef value_type const *   const_pointer;
00830 
00831     std_map_field() : default_value() {}
00832     std_map_field( ContainerType & container_ ) : container(&container_), default_value() {}
00833     std_map_field( ContainerType & container_, value_type const & value_type_ ) : container(&container_), default_value(value_type_) {}
00834 
00835     bool is_valid() const { return container != NULL; }
00836 
00837     pointer find(AccessType const & element)
00838     {
00839       typename container_type::iterator it = (*container).find( unpack(element) );
00840       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00841     }
00842 
00843     const_pointer find(AccessType const & element) const
00844     {
00845       typename container_type::const_iterator it = (*container).find( unpack(element) );
00846       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00847     }
00848 
00849     reference operator()(AccessType const & element)
00850     {
00851       return (*container)[ unpack(element) ];
00852     }
00853 
00854     const_reference operator()(AccessType const & element) const
00855     {
00856       typename container_type::const_iterator it = (*(this->container)).find( unpack(element) );
00857 
00858       if (it == (*(this->container)).end())
00859         return default_value;
00860 
00861       return it->second;
00862     }
00863 
00864     reference at(AccessType const & element)
00865     {
00866       return (*this)(element);
00867     }
00868 
00869     const_reference at(AccessType const & element) const
00870     {
00871       typename container_type::const_iterator it = (*container).find( unpack(element) );
00872       if (it == (*container).end()) throw std::out_of_range("std_map_field::at() const failed");
00873       return it->second;
00874     }
00875 
00876   protected:
00877     UnpackT unpack;
00878     ContainerType * container;
00879     value_type default_value;
00880   };
00881 
00882 
00884   template<typename ContainerType, typename AccessType, typename UnpackT>
00885   class std_map_field<const ContainerType, AccessType, UnpackT>
00886   {
00887   public:
00888 
00889     typedef const ContainerType                                     container_type;
00890     typedef typename ContainerType::value_type::second_type         value_type;
00891     typedef typename ContainerType::value_type::first_type          key_type;
00892     typedef AccessType                                              access_type;
00893 
00894     typedef value_type const &       reference;
00895     typedef value_type const & const_reference;
00896 
00897     typedef value_type const *         pointer;
00898     typedef value_type const *   const_pointer;
00899 
00900     std_map_field() : default_value() {}
00901     std_map_field( ContainerType const & container_ ) : container(&container_), default_value() {}
00902     std_map_field( ContainerType const & container_, value_type const & value_type_ ) : container(&container_), default_value(value_type_) {}
00903 
00904     bool is_valid() const { return container != NULL; }
00905 
00906     const_pointer find(AccessType const & element) const
00907     {
00908       typename container_type::const_iterator it = (*container).find( unpack(element) );
00909       return (it != (*container).end()) ? &it->second : NULL; // return NULL if not found
00910     }
00911 
00912     const_reference operator()(AccessType const & element) const
00913     {
00914       typename container_type::const_iterator it = (*(this->container)).find( unpack(element) );
00915 
00916       if (it == (*(this->container)).end())
00917         return default_value;
00918 
00919       return it->second;
00920     }
00921 
00922     const_reference at(AccessType const & element) const
00923     {
00924       typename container_type::const_iterator it = (*container).find( unpack(element) );
00925       if (it == (*container).end()) throw std::out_of_range("std_map_field::at() const failed");
00926       return it->second;
00927     }
00928 
00929   protected:
00930     UnpackT unpack;
00931     container_type * container;
00932     value_type default_value;
00933   };
00940   namespace result_of
00941   {
00947     template<typename ContainerType, typename AccessType, typename UnpackT = typename viennagrid::result_of::unpack<ContainerType>::type >
00948     struct field;
00949 
00951     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00952     struct field< std::vector<T, Alloc>, AccessType, UnpackT >
00953     {
00954       typedef viennagrid::dense_container_field<std::vector<T, Alloc>, AccessType, UnpackT> type;
00955     };
00956 
00957     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00958     struct field< const std::vector<T, Alloc>, AccessType, UnpackT >
00959     {
00960       typedef viennagrid::dense_container_field<const std::vector<T, Alloc>, AccessType, UnpackT> type;
00961     };
00962 
00963     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00964     struct field< std::deque<T, Alloc>, AccessType, UnpackT >
00965     {
00966       typedef viennagrid::dense_container_field<std::deque<T, Alloc>, AccessType, UnpackT> type;
00967     };
00968 
00969     template<typename T, typename Alloc, typename AccessType, typename UnpackT>
00970     struct field< const std::deque<T, Alloc>, AccessType, UnpackT >
00971     {
00972       typedef viennagrid::dense_container_field<const std::deque<T, Alloc>, AccessType, UnpackT> type;
00973     };
00974 
00975     template<typename Key, typename T, typename Compare, typename Alloc, typename AccessType, typename UnpackT>
00976     struct field< std::map<Key, T, Compare, Alloc>, AccessType, UnpackT >
00977     {
00978       typedef viennagrid::std_map_field<std::map<Key, T, Compare, Alloc>, AccessType, UnpackT> type;
00979     };
00980 
00981     template<typename Key, typename T, typename Compare, typename Alloc, typename AccessType, typename UnpackT>
00982     struct field< const std::map<Key, T, Compare, Alloc>, AccessType, UnpackT >
00983     {
00984       typedef viennagrid::std_map_field<const std::map<Key, T, Compare, Alloc>, AccessType, UnpackT> type;
00985     };
00987   }
00988 
00989 
00995   template<typename AccessType, typename ContainerType>
00996   typename result_of::field<ContainerType, AccessType>::type make_field( ContainerType & container )
00997   {
00998     return typename result_of::field<ContainerType, AccessType>::type(container);
00999   }
01000 
01006   template<typename AccessType, typename ContainerType>
01007   typename result_of::field<const ContainerType, AccessType>::type make_field( ContainerType const & container )
01008   {
01009     return typename result_of::field<const ContainerType, AccessType>::type(container);
01010   }
01011 
01012 
01013 
01019   template<typename AccessType, typename ContainerCollectionTypemapT>
01020   typename result_of::field<
01021       typename result_of::container_of<
01022           ContainerCollectionTypemapT,
01023           AccessType
01024       >::type,
01025       AccessType>::type make_field( collection<ContainerCollectionTypemapT> & collection_obj )
01026   {
01027     return make_field<AccessType>( get<AccessType>(collection_obj) );
01028   }
01029 
01035   template<typename AccessType, typename ContainerCollectionTypemapT>
01036   typename result_of::field<
01037       const typename result_of::container_of<
01038           ContainerCollectionTypemapT,
01039           AccessType
01040       >::type,
01041       AccessType>::type make_field( collection<ContainerCollectionTypemapT> const & collection_obj )
01042   {
01043     return make_field<AccessType>( get<AccessType>(collection_obj) );
01044   }
01045 
01046 
01047 
01048 
01049 
01050 
01052   template<typename ValueType, typename AccessType>
01053   class base_dynamic_field
01054   {
01055   public:
01056     typedef ValueType value_type;
01057     typedef AccessType access_type;
01058 
01059     typedef value_type & reference;
01060     typedef value_type const & const_reference;
01061 
01062     typedef value_type * pointer;
01063     typedef value_type const * const_pointer;
01064 
01065     virtual ~base_dynamic_field() {}
01066 
01067     virtual pointer find( access_type const & ) { return 0; }
01068     virtual const_pointer find( access_type const & ) const { return 0; }
01069 
01070     virtual reference operator()( access_type const & element ) = 0;
01071     virtual const_reference operator()( access_type const & element ) const = 0;
01072 
01073     virtual reference at( access_type const & element ) = 0;
01074     virtual const_reference at( access_type const & element ) const = 0;
01075   };
01076 
01078   template<typename ValueType, typename AccessType>
01079   class base_dynamic_field<const ValueType, AccessType>
01080   {
01081   public:
01082     typedef ValueType value_type;
01083     typedef AccessType access_type;
01084 
01085     typedef value_type const & reference;
01086     typedef value_type const & const_reference;
01087 
01088     typedef value_type const * pointer;
01089     typedef value_type const * const_pointer;
01090 
01091     virtual ~base_dynamic_field() {}
01092 
01093     virtual const_pointer find( access_type const & ) const { return 0; }
01094     virtual const_reference operator()( access_type const & element ) const = 0;
01095     virtual const_reference at( access_type const & element ) const = 0;
01096   };
01106   template<typename FieldType, typename AccessType = typename FieldType::access_type>
01107   class dynamic_field_wrapper : public base_dynamic_field< typename FieldType::value_type, AccessType >
01108   {
01109   public:
01110     typedef base_dynamic_field< typename FieldType::value_type, AccessType > BaseFieldType;
01111 
01112     typedef typename BaseFieldType::value_type value_type;
01113     typedef typename BaseFieldType::access_type access_type;
01114 
01115     typedef typename BaseFieldType::reference reference;
01116     typedef typename BaseFieldType::const_reference const_reference;
01117 
01118     typedef typename BaseFieldType::pointer pointer;
01119     typedef typename BaseFieldType::const_pointer const_pointer;
01120 
01121 
01122     dynamic_field_wrapper(FieldType field_) : field(field_) {}
01123 
01124     virtual pointer find( access_type const & element ) { return field.find(element); }
01125     virtual const_pointer find( access_type const & element ) const { return field.find(element); }
01126 
01127     virtual reference  operator()( access_type const & element )       { return field(element); }
01128     virtual const_reference operator()( access_type const & element ) const { return field(element); }
01129 
01130     virtual reference  at( access_type const & element )       { return field.at(element); }
01131     virtual const_reference at( access_type const & element ) const { return field.at(element); }
01132 
01133   private:
01134     FieldType field;
01135   };
01136 
01137 
01139   template<typename FieldType, typename AccessType>
01140   class dynamic_field_wrapper<const FieldType, AccessType> : public base_dynamic_field< const typename FieldType::value_type, AccessType >
01141   {
01142   public:
01143     typedef base_dynamic_field< const typename FieldType::value_type, AccessType > BaseFieldType;
01144 
01145     typedef typename BaseFieldType::value_type value_type;
01146     typedef typename BaseFieldType::access_type access_type;
01147 
01148     typedef typename BaseFieldType::const_reference reference;
01149     typedef typename BaseFieldType::const_reference const_reference;
01150 
01151     typedef typename BaseFieldType::const_pointer pointer;
01152     typedef typename BaseFieldType::const_pointer const_pointer;
01153 
01154 
01155     dynamic_field_wrapper(FieldType field_) : field(field_) {}
01156 
01157     virtual const_pointer find( access_type const & element ) const       { return field.find(element); }
01158     virtual const_reference    operator()( access_type const & element ) const { return field(element); }
01159     virtual const_reference    at( access_type const & element ) const         { return field.at(element); }
01160 
01161   private:
01162     FieldType field;
01163   };
01168 #ifdef VIENNAGRID_WITH_VIENNADATA
01169   namespace result_of
01170   {
01171     template<typename ContainerType, typename AccessType, typename AccessTag>
01172     struct point< viennadata::container_accessor<ContainerType, AccessType, AccessTag> >
01173     {
01174       typedef typename viennadata::container_accessor<ContainerType, AccessType, AccessTag>::value_type type;
01175     };
01176 
01177     template<typename ContainerType, typename AccessType, typename AccessTag>
01178     struct point< const viennadata::container_accessor<ContainerType, AccessType, AccessTag> >
01179     {
01180       typedef typename viennadata::container_accessor<ContainerType, AccessType, AccessTag>::value_type type;
01181     };
01182   }
01183 #endif
01184 
01185 
01186 }
01187 
01188 
01189 #endif