ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/storage/handle.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_STORAGE_HANDLE_HPP
00002 #define VIENNAGRID_STORAGE_HANDLE_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 <iterator>
00017 #include <vector>
00018 #include <map>
00019 #include <algorithm>
00020 
00021 #include "viennagrid/meta/typemap.hpp"
00022 #include "viennagrid/storage/id.hpp"
00023 #include "viennagrid/storage/forwards.hpp"
00024 
00029 namespace viennagrid
00030 {
00031   namespace detail
00032   {
00033 
00034     namespace result_of
00035     {
00036 
00037       template<typename base_container_type, typename handle_tag>
00038       struct handle_type
00039       {};
00040 
00041       template<typename base_container_type>
00042       struct handle_type<base_container_type, no_handle_tag>
00043       {
00044         typedef viennagrid::null_type type;
00045       };
00046 
00047       template<typename base_container_type>
00048       struct handle_type<base_container_type, pointer_handle_tag>
00049       {
00050         typedef typename base_container_type::pointer type;
00051       };
00052 
00053       template<typename base_container_type>
00054       struct handle_type<base_container_type, iterator_handle_tag>
00055       {
00056         typedef typename base_container_type::iterator type;
00057       };
00058 
00059       template<typename base_container_type>
00060       struct handle_type<base_container_type, id_handle_tag>
00061       {
00062         typedef typename base_container_type::value_type::id_type type;
00063       };
00064 
00065 
00066 
00067 
00068       template<typename base_container_type, typename handle_tag>
00069       struct const_handle_type
00070       {};
00071 
00072       template<typename base_container_type>
00073       struct const_handle_type<base_container_type, no_handle_tag>
00074       {
00075         typedef viennagrid::null_type type;
00076       };
00077 
00078       template<typename base_container_type>
00079       struct const_handle_type<base_container_type, pointer_handle_tag>
00080       {
00081         typedef typename base_container_type::const_pointer type;
00082       };
00083 
00084       template<typename base_container_type>
00085       struct const_handle_type<base_container_type, iterator_handle_tag>
00086       {
00087         typedef typename base_container_type::const_iterator type;
00088       };
00089 
00090       template<typename base_container_type>
00091       struct const_handle_type<base_container_type, id_handle_tag>
00092       {
00093         typedef typename base_container_type::value_type::const_id_type type;
00094       };
00095 
00096 
00097 
00098 
00099       // default = iterator
00100       template<typename handle_type>
00101       struct value_type
00102       {
00103         typedef typename viennagrid::detail::IF<
00104             viennagrid::detail::is_const_iterator<handle_type>::value,
00105             const typename handle_type::value_type,
00106             typename handle_type::value_type
00107         >::type type;
00108       };
00109 
00110       // pointer
00111       template<typename value_type_>
00112       struct value_type< value_type_ * >
00113       {
00114         typedef value_type_ type;
00115       };
00116 
00117       template<typename value_type_>
00118       struct value_type< const value_type_ * >
00119       {
00120         typedef value_type_ type;
00121       };
00122 
00123       // id
00124       template<typename value_type_, typename base_id_type_>
00125       struct value_type< smart_id<value_type_, base_id_type_> >
00126       {
00127         typedef value_type_ type;
00128       };
00129 
00130       template<typename value_type_, typename base_id_type_>
00131       struct value_type< smart_id<const value_type_, base_id_type_> >
00132       {
00133         typedef value_type_ type;
00134       };
00135 
00136 
00137 
00138 
00139       // default = iterator
00140       template<typename handle_type>
00141       struct handle_tag
00142       {
00143         typedef iterator_handle_tag type;
00144       };
00145 
00146       // no handle
00147       template<>
00148       struct handle_tag<viennagrid::null_type>
00149       {
00150         typedef no_handle_tag type;
00151       };
00152 
00153       // pointer
00154       template<typename value_type>
00155       struct handle_tag<value_type *>
00156       {
00157         typedef pointer_handle_tag type;
00158       };
00159 
00160       // id
00161       template<typename value_type_, typename base_id_type_>
00162       struct handle_tag< smart_id<value_type_, base_id_type_> >
00163       {
00164         typedef id_handle_tag type;
00165       };
00166 
00167     }
00168 
00169 
00170 
00171     template<typename container_type, typename handle_type>
00172     void set_handle_invalid( container_type const &, handle_type & handle, pointer_handle_tag )
00173     { handle = NULL; }
00174 
00175     template<typename container_type, typename handle_type>
00176     void set_handle_invalid( container_type & container, handle_type & handle, iterator_handle_tag )
00177     { handle = container.end(); }
00178 
00179     template<typename container_type, typename handle_type>
00180     void set_handle_invalid( container_type const & container, handle_type & handle, iterator_handle_tag )
00181     { handle = container.end(); }
00182 
00183     template<typename container_type, typename handle_type>
00184     void set_handle_invalid( container_type & /*container*/, handle_type & handle, id_handle_tag )
00185     { handle = handle_type(); }
00186 
00187     template<typename container_type, typename handle_type>
00188     void set_handle_invalid( container_type const & /*container*/, handle_type & handle, id_handle_tag )
00189     { handle = handle_type(); }
00190 
00191 
00192     template<typename container_type, typename handle_type>
00193     void set_handle_invalid( container_type const & container, handle_type & handle )
00194     { set_handle_invalid(container, handle, typename result_of::handle_tag<handle_type>::type()); }
00195 
00196     template<typename container_type, typename handle_type>
00197     void set_handle_invalid( container_type & container, handle_type & handle )
00198     { set_handle_invalid(container, handle, typename result_of::handle_tag<handle_type>::type()); }
00199 
00200 
00201 
00202 
00203     template<typename container_type, typename handle_type>
00204     bool is_handle_invalid( container_type const & container, handle_type handle )
00205     {
00206       handle_type tmp;
00207       set_handle_invalid(container, tmp);
00208       return handle == tmp;
00209     }
00210 
00211     template<typename container_type, typename handle_type>
00212     bool is_handle_invalid( container_type & container, handle_type handle )
00213     {
00214       handle_type tmp;
00215       set_handle_invalid(container, tmp);
00216       return handle == tmp;
00217     }
00218 
00219 
00220 
00221 
00222 
00223 
00224     template<typename HandleTagT>
00225     struct dereference_handle_helper;
00226 
00227     template<typename HandleTagT>
00228     struct dereference_handle_helper
00229     {
00230       template<typename ContainerT, typename HandleT>
00231       static typename result_of::value_type<HandleT>::type & dereference_handle( ContainerT &, HandleT handle )
00232       { return *handle; }
00233 
00234       template<typename ContainerT, typename HandleT>
00235       static typename result_of::value_type<HandleT>::type const & dereference_handle( ContainerT const &, HandleT handle )
00236       { return *handle; }
00237     };
00238 
00239 
00240     template<>
00241     struct dereference_handle_helper<id_handle_tag>
00242     {
00243       template<typename ContainerT, typename HandleT>
00244       static typename result_of::value_type<HandleT>::type & dereference_handle( ContainerT & container, HandleT handle )
00245       {
00246         typedef typename result_of::value_type<HandleT>::type ElementType;
00247         typedef typename result_of::id<ElementType>::type IDType;
00248 
00249         return *std::find_if(
00250             container.begin(),
00251             container.end(),
00252             id_compare<IDType>(handle)
00253         );
00254       }
00255 
00256       template<typename ContainerT, typename HandleT>
00257       static typename result_of::value_type<HandleT>::type const & dereference_handle( ContainerT const & container, HandleT handle )
00258       {
00259         typedef typename result_of::value_type<HandleT>::type ElementType;
00260         typedef typename result_of::id<ElementType>::type IDType;
00261 
00262         return *std::find_if(
00263             container.begin(),
00264             container.end(),
00265             id_compare<IDType>(handle)
00266         );
00267       }
00268     };
00269 
00270 
00271     template<typename ContainerT, typename HandleT>
00272     typename result_of::value_type<HandleT>::type & dereference_handle( ContainerT & container, HandleT handle )
00273     { return dereference_handle_helper< typename result_of::handle_tag<HandleT>::type >::dereference_handle(container, handle); }
00274 
00275     template<typename ContainerT, typename HandleT>
00276     typename result_of::value_type<HandleT>::type const & dereference_handle( ContainerT const & container, HandleT handle )
00277     { return dereference_handle_helper< typename result_of::handle_tag<HandleT>::type >::dereference_handle(container, handle); }
00278 
00279     template<typename ContainerT, typename HandleT>
00280     typename result_of::value_type<HandleT>::type const & dereference_handle_const( ContainerT const & container, HandleT handle )
00281     { return dereference_handle_helper< typename result_of::handle_tag<HandleT>::type >::dereference_handle(container, handle); }
00282 
00283 
00284 
00285 
00286     template<typename container_type, typename value_type, typename handle_tag>
00287     struct handle_helper;
00288 
00289 
00290     template<typename container_type, typename value_type>
00291     struct handle_helper<container_type, value_type, no_handle_tag>
00292     {
00293         static typename result_of::handle_type<container_type, no_handle_tag>::type handle( container_type &, value_type & )
00294         { return typename result_of::handle_type<container_type, no_handle_tag>::type(); }
00295 
00296         static typename result_of::const_handle_type<container_type, no_handle_tag>::type handle( container_type const &, value_type const & )
00297         { return typename result_of::handle_type<container_type, no_handle_tag>::type(); }
00298     };
00299 
00300     template<typename container_type, typename value_type>
00301     struct handle_helper<container_type, value_type, iterator_handle_tag>
00302     {
00303         static typename result_of::handle_type<container_type, iterator_handle_tag>::type handle( container_type & container, value_type & value )
00304         {
00305           for (typename container_type::iterator it = container.begin(); it != container.end(); ++it)
00306             if ( &(*it) == &value ) return it;
00307           return container.end();
00308         }
00309 
00310         static typename result_of::const_handle_type<container_type, iterator_handle_tag>::type handle( container_type const & container, value_type const & value )
00311         {
00312           for (typename container_type::const_iterator it = container.begin(); it != container.end(); ++it)
00313             if ( &(*it) == &value ) return it;
00314           return container.end();
00315         }
00316     };
00317 
00318     template<typename container_type, typename value_type>
00319     struct handle_helper<container_type, value_type, pointer_handle_tag>
00320     {
00321       static typename result_of::handle_type<container_type, pointer_handle_tag>::type handle( container_type &, value_type & value )
00322       { return &value; }
00323 
00324       static typename result_of::const_handle_type<container_type, pointer_handle_tag>::type handle( container_type const &, value_type const & value )
00325       { return &value; }
00326     };
00327 
00328     template<typename container_type, typename value_type>
00329     struct handle_helper<container_type, value_type, id_handle_tag>
00330     {
00331       static typename result_of::handle_type<container_type, id_handle_tag>::type handle( container_type &, value_type & value )
00332       { return value.id(); }
00333 
00334       static typename result_of::const_handle_type<container_type, id_handle_tag>::type handle( container_type const &, value_type const & value )
00335       { return value.id(); }
00336     };
00337 
00338 
00339 
00340     template<typename container_type, typename value_type, typename handle_tag>
00341     typename result_of::handle_type<container_type, handle_tag>::type handle( container_type & container, value_type & value, handle_tag )
00342     { return handle_helper<container_type, value_type, handle_tag>::handle( container,value ); }
00343 
00344     template<typename container_type, typename value_type, typename handle_tag>
00345     typename result_of::const_handle_type<container_type, handle_tag>::type handle( container_type const & container, value_type const & value, handle_tag )
00346     { return handle_helper<container_type, value_type, handle_tag>::handle( container,value ); }
00347 
00348 
00349   }
00350 
00351 }
00352 
00353 #endif