ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_STORAGE_CONTAINER_COLLECTION_HPP 00002 #define VIENNAGRID_STORAGE_CONTAINER_COLLECTION_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 "viennagrid/meta/typelist.hpp" 00017 #include "viennagrid/meta/typemap.hpp" 00018 #include "viennagrid/meta/algorithm.hpp" 00019 00020 #include "viennagrid/storage/container.hpp" 00021 #include "viennagrid/storage/collection.hpp" 00022 #include "viennagrid/storage/view.hpp" 00023 #include "viennagrid/storage/range.hpp" 00024 00029 namespace viennagrid 00030 { 00031 namespace detail 00032 { 00033 00034 namespace result_of 00035 { 00036 00037 // 00038 // generates a typemap with value type and container type from a typelist and a container config 00039 // 00040 00041 template<typename value_type, typename container_config> 00042 struct container_from_value_using_container_config 00043 { 00044 typedef typename viennagrid::detail::result_of::find<container_config, value_type>::type search_result; 00045 typedef typename viennagrid::detail::result_of::find<container_config, viennagrid::default_tag>::type default_container; 00046 00047 typedef typename viennagrid::detail::IF< 00048 !viennagrid::detail::EQUAL<search_result, viennagrid::not_found>::value, 00049 search_result, 00050 default_container 00051 >::type container_tag_pair; 00052 00053 typedef typename viennagrid::result_of::container<value_type, typename container_tag_pair::second>::type type; 00054 }; 00055 00056 00057 template<typename element_list, typename container_config> 00058 struct container_list_from_value_typelist_using_container_config; 00059 00060 template<typename container_config> 00061 struct container_list_from_value_typelist_using_container_config<viennagrid::null_type, container_config> 00062 { 00063 typedef viennagrid::null_type type; 00064 }; 00065 00066 template<typename value_type, typename tail, typename container_config> 00067 struct container_list_from_value_typelist_using_container_config<viennagrid::typelist<value_type, tail>, container_config> 00068 { 00069 typedef viennagrid::typelist< 00070 typename viennagrid::static_pair< 00071 value_type, 00072 typename container_from_value_using_container_config<value_type, container_config>::type 00073 >, 00074 typename container_list_from_value_typelist_using_container_config<tail, container_config>::type 00075 > type; 00076 }; 00077 00078 00079 } // namespace result_of 00080 00081 } // namespace detail 00082 00083 00084 namespace result_of 00085 { 00087 template<typename typemap_, typename element_type> 00088 struct container_of 00089 { 00090 typedef typename viennagrid::detail::result_of::second< 00091 typename viennagrid::detail::result_of::find< typemap_, element_type >::type 00092 >::type type; 00093 }; 00094 00096 template<typename typemap_, typename element_type> 00097 struct container_of< viennagrid::collection< typemap_ >, element_type > 00098 { 00099 typedef typename container_of<typemap_, element_type>::type type; 00100 }; 00101 00102 template<typename container_collection_1, typename container_collection_2> 00103 struct common_values; 00104 00105 template<typename container_typelist_1, typename container_typelist_2> 00106 struct common_values< viennagrid::collection<container_typelist_1>, 00107 viennagrid::collection<container_typelist_2> > 00108 { 00109 typedef viennagrid::collection<container_typelist_1> from_container_collection_type; 00110 typedef viennagrid::collection<container_typelist_2> to_container_collection_type; 00111 00112 typedef typename viennagrid::detail::result_of::key_typelist<typename from_container_collection_type::typemap>::type from_container_collection_value_typelist; 00113 typedef typename viennagrid::detail::result_of::key_typelist<typename to_container_collection_type::typemap>::type to_container_collection_value_typelist; 00114 00115 typedef typename viennagrid::detail::result_of::intersection< 00116 from_container_collection_value_typelist, 00117 to_container_collection_value_typelist 00118 >::type type; 00119 00120 }; 00122 } 00123 00124 00125 namespace detail 00126 { 00127 00128 typedef viennagrid::make_typemap< 00129 viennagrid::default_tag, viennagrid::handled_container_tag<viennagrid::std_deque_tag, viennagrid::pointer_handle_tag> 00130 >::type default_container_config; 00131 00132 00133 template<typename container_collection_type, typename element_type, typename search_result> 00134 struct insert_or_ignore_helper 00135 { 00136 static void insert_or_ignore( container_collection_type & collection, const element_type & element ) 00137 { 00138 collection.get( viennagrid::detail::tag<element_type>() ).insert(element); 00139 } 00140 00141 static void insert_or_ignore( container_collection_type & collection, element_type & element ) 00142 { 00143 collection.get( viennagrid::detail::tag<element_type>() ).insert(element); 00144 } 00145 }; 00146 00147 template<typename container_collection_type, typename element_type> 00148 struct insert_or_ignore_helper<container_collection_type, element_type, viennagrid::not_found> 00149 { 00150 static void insert_or_ignore( container_collection_type &, const element_type & ) {} 00151 00152 static void insert_or_ignore( container_collection_type &, element_type & ) {} 00153 }; 00154 00155 00156 template<typename container_collection_type, typename element_type> 00157 void insert_or_ignore( container_collection_type & collection, const element_type & element) 00158 { 00159 typedef typename viennagrid::result_of::container_of< container_collection_type, element_type>::type container_type; 00160 insert_or_ignore_helper<container_collection_type, element_type, container_type>::insert_or_ignore(collection, element); 00161 } 00162 00163 template<typename container_collection_type, typename element_type> 00164 void insert_or_ignore( container_collection_type & collection, element_type & element) 00165 { 00166 typedef typename viennagrid::result_of::container_of< container_collection_type, element_type>::type container_type; 00167 insert_or_ignore_helper<container_collection_type, element_type, container_type>::insert_or_ignore(collection, element); 00168 } 00169 00170 00171 00172 00173 00174 template<typename container_collection_type, typename handle_type, typename container_type> 00175 struct handle_or_ignore_helper 00176 { 00177 typedef typename viennagrid::detail::result_of::value_type<handle_type>::type value_type; 00178 00179 static void handle_or_ignore( container_collection_type & collection, const handle_type & handle ) 00180 { 00181 collection.get( viennagrid::detail::tag<value_type>() ).insert_unique_handle(handle); 00182 } 00183 00184 static void handle_or_ignore( container_collection_type & collection, handle_type & handle ) 00185 { 00186 collection.get( viennagrid::detail::tag<value_type>() ).insert_unique_handle(handle); 00187 } 00188 }; 00189 00190 template<typename container_collection_type, typename handle_type> 00191 struct handle_or_ignore_helper<container_collection_type, handle_type, viennagrid::not_found> 00192 { 00193 static void handle_or_ignore( container_collection_type &, const handle_type & ) {} 00194 00195 static void handle_or_ignore( container_collection_type &, handle_type & ) {} 00196 }; 00197 00198 00199 template<typename container_collection_type, typename handle_type, typename element_type> 00200 void handle_or_ignore( container_collection_type & collection, const handle_type & handle, viennagrid::detail::tag<element_type> ) 00201 { 00202 typedef typename viennagrid::result_of::container_of< container_collection_type, element_type>::type container_type; 00203 handle_or_ignore_helper<container_collection_type, handle_type, container_type>::handle_or_ignore(collection, handle); 00204 } 00205 00206 template<typename container_collection_type, typename handle_type, typename element_type> 00207 void handle_or_ignore( container_collection_type & collection, handle_type & handle, viennagrid::detail::tag<element_type> ) 00208 { 00209 typedef typename viennagrid::result_of::container_of< container_collection_type, element_type>::type container_type; 00210 handle_or_ignore_helper<container_collection_type, handle_type, container_type>::handle_or_ignore(collection, handle); 00211 } 00212 00213 00214 00215 00216 template<typename container_collection_type> 00217 struct clear_all_functor 00218 { 00219 clear_all_functor( container_collection_type & container_collection_ ) : container_collection(container_collection_) {} 00220 00221 template<typename type> 00222 void operator() ( viennagrid::detail::tag<type> ) 00223 { 00224 viennagrid::get<type>( container_collection ).clear(); 00225 } 00226 00227 container_collection_type & container_collection; 00228 }; 00229 00230 00231 template<typename container_collection_typemap> 00232 void clear_all( viennagrid::collection<container_collection_typemap> & container_collection) 00233 { 00234 clear_all_functor< viennagrid::collection<container_collection_typemap> > f( container_collection ); 00235 viennagrid::detail::for_each< typename viennagrid::detail::result_of::key_typelist<container_collection_typemap>::type >( f ); 00236 } 00237 00238 00239 00240 } // namespace detail 00241 00242 00243 00244 00245 namespace result_of 00246 { 00252 template<typename value_typelist, typename container_config> 00253 struct container_collection 00254 { 00255 typedef viennagrid::collection< 00256 typename viennagrid::detail::result_of::container_list_from_value_typelist_using_container_config< 00257 value_typelist, 00258 container_config 00259 >::type 00260 > type; 00261 }; 00262 } 00263 00264 } // namespace viennagrid 00265 00266 #endif