ViennaGrid - The Vienna Grid Library
2.1.0
|
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