ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_STORAGE_CONTAINER_HPP 00002 #define VIENNAGRID_STORAGE_CONTAINER_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 <vector> 00017 #include <deque> 00018 #include <list> 00019 #include <set> 00020 #include <algorithm> 00021 00022 #include "viennagrid/meta/utils.hpp" 00023 #include "viennagrid/storage/forwards.hpp" 00024 #include "viennagrid/storage/handle.hpp" 00025 #include "viennagrid/storage/static_array.hpp" 00026 00031 namespace viennagrid 00032 { 00033 namespace detail 00034 { 00035 00036 template<typename container_type> 00037 void insert(container_type & container, const typename container_type::value_type & value) 00038 { 00039 container.push_back(value); 00040 } 00041 00042 template<typename type, typename compare, typename allocator> 00043 void insert(std::set<type, compare, allocator> & container, const typename std::set<type, compare, allocator>::value_type & value) 00044 { 00045 container.insert(value); 00046 } 00047 00048 00049 00050 template<typename ContainerT> 00051 typename ContainerT::iterator find(ContainerT & container, typename ContainerT::value_type::id_type id) 00052 { 00053 return std::find_if( container.begin(), container.end(), 00054 viennagrid::detail::id_compare<typename ContainerT::value_type::id_type>(id)); 00055 } 00056 00057 template<typename ContainerT> 00058 typename ContainerT::const_iterator find(ContainerT const & container, typename ContainerT::value_type::id_type id) 00059 { 00060 return std::find_if(container.begin(),container.end(), 00061 viennagrid::detail::id_compare<typename ContainerT::value_type::id_type>(id)); 00062 } 00063 00064 template<typename ContainerT> 00065 typename ContainerT::iterator find(ContainerT & container, typename ContainerT::value_type const & element) 00066 { 00067 return std::find(container.begin(), container.end(), element); 00068 } 00069 00070 template<typename ContainerT> 00071 typename ContainerT::const_iterator find(ContainerT const & container, typename ContainerT::value_type const & element) 00072 { 00073 return std::find(container.begin(), container.end(), element); 00074 } 00075 00076 00077 00078 00079 00080 template<typename base_iterator, typename base_const_iterator, typename handle_tag> 00081 class iterator; 00082 00083 template<typename base_iterator, typename base_const_iterator> 00084 class iterator<base_iterator, base_const_iterator, no_handle_tag> : public base_iterator 00085 { 00086 public: 00087 00088 typedef typename std::iterator_traits<base_iterator>::difference_type difference_type; 00089 typedef typename std::iterator_traits<base_iterator>::value_type value_type; 00090 typedef value_type * pointer; 00091 typedef value_type & reference; 00092 typedef typename std::iterator_traits<base_iterator>::iterator_category iterator_category; 00093 00094 iterator() {} 00095 iterator(base_iterator const & it) : base_iterator(it) {} 00096 00097 iterator & operator++() { base_iterator::operator++(); return *this; } 00098 iterator operator++(int) { base_iterator::operator++(int()); return *this; } 00099 00100 iterator & operator--() { base_iterator::operator--(); return *this; } 00101 iterator operator--(int) { base_iterator::operator--(int()); return *this; } 00102 00103 value_type & value() { return base_iterator::operator*(); } 00104 value_type const & value() const { return base_iterator::operator*(); } 00105 00106 value_type & operator* () { return value(); } 00107 value_type const & operator* () const { return value(); } 00108 }; 00109 00110 template<typename base_iterator, typename base_const_iterator> 00111 class iterator<base_iterator, base_const_iterator, pointer_handle_tag> : public base_iterator 00112 { 00113 public: 00114 00115 typedef typename std::iterator_traits<base_iterator>::difference_type difference_type; 00116 typedef typename std::iterator_traits<base_iterator>::value_type value_type; 00117 typedef value_type * pointer; 00118 typedef value_type & reference; 00119 typedef typename std::iterator_traits<base_iterator>::iterator_category iterator_category; 00120 00121 typedef value_type * handle_type; 00122 typedef value_type const * const_handle_type; 00123 00124 iterator() {} 00125 iterator(base_iterator const & it) : base_iterator(it) {} 00126 00127 iterator & operator++() { base_iterator::operator++(); return *this; } 00128 iterator operator++(int) { base_iterator::operator++(int()); return *this; } 00129 00130 iterator & operator--() { base_iterator::operator--(); return *this; } 00131 iterator operator--(int) { base_iterator::operator--(int()); return *this; } 00132 00133 value_type & value() { return base_iterator::operator*(); } 00134 value_type const & value() const { return base_iterator::operator*(); } 00135 00136 handle_type handle() { return &value(); } 00137 const_handle_type handle() const { return &value(); } 00138 00139 00140 value_type & operator* () { return value(); } 00141 value_type const & operator* () const { return value(); } 00142 }; 00143 00144 template<typename base_iterator, typename base_const_iterator> 00145 class iterator<base_iterator, base_const_iterator, iterator_handle_tag> : public base_iterator 00146 { 00147 public: 00148 00149 typedef typename std::iterator_traits<base_iterator>::difference_type difference_type; 00150 typedef typename std::iterator_traits<base_iterator>::value_type value_type; 00151 typedef value_type * pointer; 00152 typedef value_type & reference; 00153 typedef typename std::iterator_traits<base_iterator>::iterator_category iterator_category; 00154 00155 typedef base_iterator handle_type; 00156 typedef base_const_iterator const_handle_type; 00157 00158 iterator() {} 00159 iterator(base_iterator const & it) : base_iterator(it) {} 00160 00161 iterator & operator++() { base_iterator::operator++(); return *this; } 00162 iterator operator++(int) { base_iterator::operator++(int()); return *this; } 00163 00164 iterator & operator--() { base_iterator::operator--(); return *this; } 00165 iterator operator--(int) { base_iterator::operator--(int()); return *this; } 00166 00167 value_type & value() { return base_iterator::operator*(); } 00168 value_type const & value() const { return base_iterator::operator*(); } 00169 00170 handle_type handle() { return static_cast<base_iterator>(*this); } 00171 const_handle_type handle() const { return static_cast<base_iterator>(*this); } 00172 00173 00174 value_type & operator* () { return value(); } 00175 value_type const & operator* () const { return value(); } 00176 }; 00177 00178 template<typename base_iterator, typename base_const_iterator> 00179 class iterator<base_iterator, base_const_iterator, id_handle_tag> : public base_iterator 00180 { 00181 public: 00182 00183 typedef typename std::iterator_traits<base_iterator>::value_type::id_type id_type; 00184 00185 typedef typename std::iterator_traits<base_iterator>::difference_type difference_type; 00186 typedef typename std::iterator_traits<base_iterator>::value_type value_type; 00187 typedef value_type * pointer; 00188 typedef value_type & reference; 00189 typedef typename std::iterator_traits<base_iterator>::iterator_category iterator_category; 00190 00191 typedef id_type handle_type; 00192 typedef typename viennagrid::detail::result_of::const_id<id_type>::type const_handle_type; 00193 00194 iterator() {} 00195 iterator(base_iterator const & it) : base_iterator(it) {} 00196 00197 iterator & operator++() { base_iterator::operator++(); return *this; } 00198 iterator operator++(int) { base_iterator::operator++(int()); return *this; } 00199 00200 iterator & operator--() { base_iterator::operator--(); return *this; } 00201 iterator operator--(int) { base_iterator::operator--(int()); return *this; } 00202 00203 value_type & value() { return base_iterator::operator*(); } 00204 value_type const & value() const { return base_iterator::operator*(); } 00205 00206 handle_type handle() { return base_iterator::operator*().id(); } 00207 const_handle_type handle() const { return base_iterator::operator*().id(); } 00208 00209 00210 value_type & operator* () { return value(); } 00211 value_type const & operator* () const { return value(); } 00212 }; 00213 00214 00215 00216 00217 template<typename base_iterator, typename base_const_iterator, typename handle_tag> 00218 class const_iterator; 00219 00220 template<typename base_iterator, typename base_const_iterator> 00221 class const_iterator<base_iterator, base_const_iterator, no_handle_tag> : public base_const_iterator 00222 { 00223 public: 00224 00225 typedef typename std::iterator_traits<base_const_iterator>::difference_type difference_type; 00226 typedef typename std::iterator_traits<base_const_iterator>::value_type value_type; 00227 typedef value_type * pointer; 00228 typedef value_type & reference; 00229 typedef typename std::iterator_traits<base_const_iterator>::iterator_category iterator_category; 00230 00231 const_iterator() {} 00232 const_iterator(base_const_iterator const & it) : base_const_iterator(it) {} 00233 const_iterator(base_iterator const & it) : base_const_iterator(it) {} 00234 00235 const_iterator & operator++() { base_const_iterator::operator++(); return *this; } 00236 const_iterator operator++(int) { base_const_iterator::operator++(int()); return *this; } 00237 00238 const_iterator & operator--() { base_const_iterator::operator--(); return *this; } 00239 const_iterator operator--(int) { base_const_iterator::operator--(int()); return *this; } 00240 00241 value_type const & value() { return base_const_iterator::operator*(); } 00242 value_type const & value() const { return base_const_iterator::operator*(); } 00243 00244 value_type const & operator* () { return value(); } 00245 value_type const & operator* () const { return value(); } 00246 }; 00247 00248 template<typename base_iterator, typename base_const_iterator> 00249 class const_iterator<base_iterator, base_const_iterator, pointer_handle_tag> : public base_const_iterator 00250 { 00251 public: 00252 00253 typedef typename std::iterator_traits<base_const_iterator>::difference_type difference_type; 00254 typedef typename std::iterator_traits<base_const_iterator>::value_type value_type; 00255 typedef value_type * pointer; 00256 typedef value_type & reference; 00257 typedef typename std::iterator_traits<base_const_iterator>::iterator_category iterator_category; 00258 00259 typedef value_type * handle_type; 00260 typedef value_type const * const_handle_type; 00261 00262 const_iterator() {} 00263 const_iterator(base_const_iterator const & it) : base_const_iterator(it) {} 00264 const_iterator(base_iterator const & it) : base_const_iterator(it) {} 00265 00266 const_iterator & operator++() { base_const_iterator::operator++(); return *this; } 00267 const_iterator operator++(int) { base_const_iterator::operator++(int()); return *this; } 00268 00269 const_iterator & operator--() { base_const_iterator::operator--(); return *this; } 00270 const_iterator operator--(int) { base_const_iterator::operator--(int()); return *this; } 00271 00272 value_type const & value() { return base_const_iterator::operator*(); } 00273 value_type const & value() const { return base_const_iterator::operator*(); } 00274 00275 const_handle_type handle() { return &value(); } 00276 const_handle_type handle() const { return &value(); } 00277 00278 00279 value_type const & operator* () { return value(); } 00280 value_type const & operator* () const { return value(); } 00281 }; 00282 00283 template<typename base_iterator, typename base_const_iterator> 00284 class const_iterator<base_iterator, base_const_iterator, iterator_handle_tag> : public base_const_iterator 00285 { 00286 public: 00287 00288 typedef typename std::iterator_traits<base_const_iterator>::difference_type difference_type; 00289 typedef typename std::iterator_traits<base_const_iterator>::value_type value_type; 00290 typedef value_type * pointer; 00291 typedef value_type & reference; 00292 typedef typename std::iterator_traits<base_const_iterator>::iterator_category iterator_category; 00293 00294 typedef base_iterator handle_type; 00295 typedef base_const_iterator const_handle_type; 00296 00297 const_iterator() {} 00298 const_iterator(base_const_iterator const & it) : base_const_iterator(it) {} 00299 const_iterator(base_iterator const & it) : base_const_iterator(it) {} 00300 00301 const_iterator & operator++() { base_const_iterator::operator++(); return *this; } 00302 const_iterator operator++(int) { base_const_iterator::operator++(int()); return *this; } 00303 00304 const_iterator & operator--() { base_const_iterator::operator--(); return *this; } 00305 const_iterator operator--(int) { base_const_iterator::operator--(int()); return *this; } 00306 00307 value_type const & value() { return base_const_iterator::operator*(); } 00308 value_type const & value() const { return base_const_iterator::operator*(); } 00309 00310 const_handle_type handle() { return static_cast<base_const_iterator>(*this); } 00311 const_handle_type handle() const { return static_cast<base_const_iterator>(*this); } 00312 00313 00314 value_type const & operator* () { return value(); } 00315 value_type const & operator* () const { return value(); } 00316 }; 00317 00318 template<typename base_iterator, typename base_const_iterator> 00319 class const_iterator<base_iterator, base_const_iterator, id_handle_tag> : public base_const_iterator 00320 { 00321 public: 00322 00323 typedef typename std::iterator_traits<base_const_iterator>::value_type::id_type id_type; 00324 00325 typedef typename std::iterator_traits<base_const_iterator>::difference_type difference_type; 00326 typedef typename std::iterator_traits<base_const_iterator>::value_type value_type; 00327 typedef value_type * pointer; 00328 typedef value_type & reference; 00329 typedef typename std::iterator_traits<base_const_iterator>::iterator_category iterator_category; 00330 00331 typedef id_type handle_type; 00332 typedef typename viennagrid::detail::result_of::const_id<id_type>::type const_handle_type; 00333 00334 const_iterator() {} 00335 const_iterator(base_const_iterator const & it) : base_const_iterator(it) {} 00336 const_iterator(base_iterator const & it) : base_const_iterator(it) {} 00337 00338 const_iterator & operator++() { base_const_iterator::operator++(); return *this; } 00339 const_iterator operator++(int) { base_const_iterator::operator++(int()); return *this; } 00340 00341 const_iterator & operator--() { base_const_iterator::operator--(); return *this; } 00342 const_iterator operator--(int) { base_const_iterator::operator--(int()); return *this; } 00343 00344 value_type const & value() { return base_const_iterator::operator*(); } 00345 value_type const & value() const { return base_const_iterator::operator*(); } 00346 00347 const_handle_type handle() { return value().id(); } 00348 const_handle_type handle() const { return value().id(); } 00349 00350 00351 value_type const & operator* () { return value(); } 00352 value_type const & operator* () const { return value(); } 00353 }; 00354 00355 template<typename base_container_, typename handle_tag> 00356 class handled_container : public base_container_ 00357 { 00358 public: 00359 typedef base_container_ container_type; 00360 typedef typename container_type::value_type value_type; 00361 00362 typedef typename container_type::pointer pointer; 00363 typedef typename container_type::const_pointer const_pointer; 00364 00365 typedef typename container_type::reference reference; 00366 typedef typename container_type::const_reference const_reference; 00367 00368 typedef typename result_of::handle_type<container_type, handle_tag>::type handle_type; 00369 typedef typename result_of::const_handle_type<container_type, handle_tag>::type const_handle_type; 00370 00371 00372 00373 handle_type handle( value_type & element ) 00374 { 00375 return viennagrid::detail::handle( *this, element, handle_tag() ); 00376 } 00377 00378 const_handle_type handle( value_type const & element ) const 00379 { 00380 return viennagrid::detail::handle( *this, element, handle_tag() ); 00381 } 00382 00383 value_type & dereference_handle( handle_type handle ) 00384 { 00385 return viennagrid::detail::dereference_handle( *this, handle ); 00386 } 00387 00388 value_type const & dereference_handle( const_handle_type handle ) const 00389 { 00390 return viennagrid::detail::dereference_handle( *this, handle ); 00391 } 00392 00393 }; 00394 00395 00396 00397 template<typename base_container_, typename handle_tag> 00398 class container_base : public handled_container<base_container_, handle_tag> 00399 { 00400 public: 00401 00402 typedef handled_container<base_container_, handle_tag> handled_container_type; 00403 typedef typename handled_container_type::container_type container_type; 00404 00405 typedef typename handled_container_type::value_type value_type; 00406 00407 typedef typename handled_container_type::pointer pointer; 00408 typedef typename handled_container_type::const_pointer const_pointer; 00409 00410 typedef typename handled_container_type::reference reference; 00411 typedef typename handled_container_type::const_reference const_reference; 00412 00413 typedef typename handled_container_type::iterator iterator; 00414 typedef typename handled_container_type::const_iterator const_iterator; 00415 00416 typedef typename handled_container_type::handle_type handle_type; 00417 typedef typename handled_container_type::const_handle_type const_handle_type; 00418 00419 typedef std::pair<handle_type, bool> return_type; 00420 00421 00422 bool is_present( value_type const & ) const 00423 { 00424 return false; 00425 } 00426 00427 iterator find( value_type const & ) const 00428 { 00429 return container_type::end(); 00430 } 00431 00432 return_type insert( value_type const & element ) 00433 { 00434 container_type::push_back( element ); 00435 return std::make_pair( this->handle(container_type::back()), true); 00436 } 00437 }; 00438 00439 00440 template<typename key, typename compare, typename allocator, typename handle_tag> 00441 class container_base<std::set<key, compare, allocator>, handle_tag> : public handled_container<std::set<key, compare, allocator>, handle_tag> 00442 { 00443 public: 00444 00445 typedef handled_container<std::set<key, compare, allocator>, handle_tag> handled_container_type; 00446 typedef typename handled_container_type::container_type container_type; 00447 00448 typedef typename handled_container_type::value_type value_type; 00449 00450 typedef typename handled_container_type::pointer pointer; 00451 typedef typename handled_container_type::const_pointer const_pointer; 00452 00453 typedef typename handled_container_type::reference reference; 00454 typedef typename handled_container_type::const_reference const_reference; 00455 00456 typedef typename handled_container_type::iterator iterator; 00457 typedef typename handled_container_type::const_iterator const_iterator; 00458 00459 typedef typename handled_container_type::handle_type handle_type; 00460 typedef typename handled_container_type::const_handle_type const_handle_type; 00461 00462 typedef std::pair<handle_type, bool> return_type; 00463 00464 bool is_present( value_type const & element ) const 00465 { 00466 return container_type::find(element) != container_type::end(); 00467 } 00468 00469 typename container_type::iterator find( value_type const & element ) const 00470 { 00471 return container_type::find(element); 00472 } 00473 00474 return_type insert( value_type const & element ) 00475 { 00476 std::pair<typename container_type::iterator, bool> tmp = container_type::insert( element ); 00477 return std::make_pair( handled_container_type::handle(*tmp.first), tmp.second); 00478 } 00479 }; 00480 00481 00482 00483 template<typename base_container_, typename handle_tag_> 00484 class container : public container_base<base_container_, handle_tag_> 00485 { 00486 public: 00487 00488 typedef base_container_ base_container; 00489 00490 typedef handle_tag_ handle_tag; 00491 typedef typename result_of::handle_type<base_container, handle_tag>::type handle_type; 00492 typedef typename result_of::const_handle_type<base_container, handle_tag>::type const_handle_type; 00493 typedef std::pair<handle_type, bool> insert_return_type; 00494 00495 00496 typedef typename base_container::value_type value_type; 00497 00498 00499 typedef detail::iterator<typename base_container::iterator, typename base_container::const_iterator, handle_tag> iterator; 00500 iterator begin() { return iterator(base_container::begin()); } 00501 iterator end() { return iterator(base_container::end()); } 00502 00503 typedef detail::const_iterator<typename base_container::iterator, typename base_container::const_iterator, handle_tag> const_iterator; 00504 const_iterator cbegin() const { return const_iterator(base_container::begin()); } 00505 const_iterator cend() const { return const_iterator(base_container::end()); } 00506 00507 const_iterator begin() const { return cbegin(); } 00508 const_iterator end() const { return cend(); } 00509 00510 00511 handle_type handle_at(std::size_t pos) 00512 { 00513 iterator it = begin(); 00514 std::advance( it, static_cast<long>(pos) ); 00515 return it.handle(); 00516 } 00517 const_handle_type handle_at(std::size_t pos) const 00518 { 00519 const_iterator it = begin(); 00520 std::advance( it, static_cast<long>(pos) ); 00521 return it.handle(); 00522 } 00523 00524 private: 00525 }; 00526 00527 00528 00529 00530 template<typename ValueT> 00531 struct IDCompare 00532 { 00533 bool operator() (ValueT const & lhs, ValueT const & rhs) 00534 { 00535 return lhs->id() < rhs->id(); 00536 } 00537 }; 00538 00539 template<typename ValueT, typename BaseIDType> 00540 struct IDCompare< smart_id<ValueT, BaseIDType> > 00541 { 00542 bool operator() ( smart_id<ValueT, BaseIDType> const & lhs, smart_id<ValueT, BaseIDType> const & rhs) 00543 { 00544 return lhs->id() < rhs->id(); 00545 } 00546 }; 00547 } 00548 00549 00550 namespace result_of 00551 { 00557 template<typename value_type, typename container_tag> 00558 struct container {}; 00559 00561 template<typename value_type> 00562 struct container<value_type, std_vector_tag> 00563 { 00564 typedef std::vector<value_type> type; 00565 }; 00566 00567 template<typename value_type> 00568 struct container<value_type, std_deque_tag> 00569 { 00570 typedef std::deque<value_type> type; 00571 }; 00572 00573 template<typename value_type> 00574 struct container<value_type, std_list_tag> 00575 { 00576 typedef std::list<value_type> type; 00577 }; 00578 00579 00580 00581 template<typename ValueT> 00582 struct container<ValueT, std_set_tag<default_tag> > 00583 { 00584 typedef std::set<ValueT> type; 00585 }; 00586 00587 template<typename ValueT> 00588 struct container<ValueT, std_set_tag<id_compare_tag> > 00589 { 00590 typedef std::set<ValueT, viennagrid::detail::IDCompare<ValueT> > type; 00591 }; 00592 00593 00594 template<typename value_type, typename container_tag, typename handle_tag> 00595 struct container<value_type, handled_container_tag<container_tag, handle_tag> > 00596 { 00597 typedef viennagrid::detail::container< typename container<value_type, container_tag>::type, handle_tag > type; 00598 }; 00599 00600 00601 template<typename element_type, int size> 00602 struct container<element_type, static_array_tag<size> > 00603 { 00604 typedef static_array<element_type, size> type; 00605 }; 00607 } 00608 } 00609 00610 #endif