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