ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/storage/container.hpp
Go to the documentation of this file.
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