ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_STORAGE_INSERTER_HPP 00002 #define VIENNAGRID_STORAGE_INSERTER_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/storage/container_collection.hpp" 00017 #include "viennagrid/storage/container_collection_element.hpp" 00018 00023 namespace viennagrid 00024 { 00025 namespace detail 00026 { 00030 template <bool generate_id, typename ValueT> 00031 struct physical_insert_id_dispatcher 00032 { 00033 template <typename ContainerT, typename ElementT, typename IDGeneratorT> 00034 static void apply(ContainerT & container, ElementT & elem, IDGeneratorT & id_generator) 00035 { 00036 if (!container.is_present( elem ) ) 00037 viennagrid::detail::set_id(elem, id_generator( viennagrid::detail::tag<ValueT>() ) ); 00038 } 00039 }; 00040 00041 template <typename ValueT> 00042 struct physical_insert_id_dispatcher<false, ValueT> 00043 { 00044 template <typename ContainerT, typename ElementT, typename IDGeneratorT> 00045 static void apply(ContainerT &, ElementT & elem, IDGeneratorT & id_generator) 00046 { 00047 id_generator.set_max_id( elem.id() ); 00048 } 00049 }; 00050 00052 } 00053 00055 template<typename container_collection_type, typename change_counter_type, typename id_generator_type_> 00056 class physical_inserter 00057 { 00058 public: 00059 typedef container_collection_type physical_container_collection_type; 00060 typedef id_generator_type_ id_generator_type; 00061 00062 physical_inserter() : collection(0), change_counter(0) {} 00063 physical_inserter(container_collection_type & collection_obj) : collection(&collection_obj), change_counter(0) {} 00064 physical_inserter(container_collection_type & collection_obj, id_generator_type id_generator_) : collection(&collection_obj), change_counter(0), id_generator(id_generator_) {} 00065 00066 physical_inserter(container_collection_type & collection_obj, change_counter_type & change_counter_) : 00067 collection(&collection_obj), change_counter(&change_counter_) {} 00068 physical_inserter(container_collection_type & collection_obj, change_counter_type & change_counter_, id_generator_type id_generator_) : 00069 collection(&collection_obj), change_counter(&change_counter_), id_generator(id_generator_) {} 00070 00071 void set_mesh_info(container_collection_type & collection_obj, change_counter_type & change_counter_) 00072 { 00073 collection = &collection_obj; 00074 change_counter = &change_counter_; 00075 } 00076 00077 template<bool generate_id, bool call_callback, typename value_type> 00078 std::pair< 00079 typename viennagrid::result_of::container_of<container_collection_type, value_type>::type::handle_type, 00080 bool 00081 > 00082 insert( const value_type & element ) 00083 { 00084 return physical_insert<generate_id, call_callback>( element, *this ); 00085 } 00086 00087 template<typename value_type> 00088 std::pair< 00089 typename viennagrid::result_of::container_of<container_collection_type, value_type>::type::handle_type, 00090 bool 00091 > 00092 operator()( const value_type & element ) 00093 { 00094 return insert<true, true>( element ); 00095 } 00096 00097 container_collection_type & get_physical_container_collection() { return *collection; } 00098 container_collection_type const & get_physical_container_collection() const { return *collection; } 00099 00100 id_generator_type & get_id_generator() { return id_generator; } 00101 id_generator_type const & get_id_generator() const { return id_generator; } 00102 00103 template<bool generate_id, bool call_callback, typename value_type, typename inserter_type> 00104 std::pair< 00105 typename viennagrid::result_of::container_of<container_collection_type, value_type>::type::handle_type, 00106 bool 00107 > 00108 physical_insert( value_type element, inserter_type & inserter ) 00109 { 00110 typedef typename viennagrid::result_of::container_of<container_collection_type, value_type>::type container_type; 00111 typedef typename viennagrid::result_of::container_of<container_collection_type, value_type>::type::handle_type handle_type; 00112 00113 00114 container_type & container = viennagrid::get< value_type >( *collection ); 00115 00116 detail::physical_insert_id_dispatcher<generate_id, value_type>::apply(container, element, id_generator); 00117 //if ( generate_id && !container.is_present( element ) ) 00118 // viennagrid::detail::set_id(element, id_generator( viennagrid::detail::tag<value_type>() ) ); 00119 00120 //if (!generate_id) 00121 // id_generator.set_max_id( element.id() ); 00122 00123 std::pair<handle_type, bool> ret = container.insert( element ); 00124 if (change_counter) ++(*change_counter); 00125 00126 if (call_callback) 00127 viennagrid::detail::insert_callback( 00128 container.dereference_handle(ret.first), 00129 ret.second, 00130 inserter); 00131 00132 inserter.handle_insert( ret.first, viennagrid::detail::tag<value_type>() ); 00133 00134 return ret; 00135 } 00136 00137 template<typename handle_type, typename value_type> 00138 void handle_insert( handle_type, viennagrid::detail::tag<value_type> ) {} 00139 00140 private: 00141 00142 container_collection_type * collection; 00143 change_counter_type * change_counter; 00144 00145 id_generator_type id_generator; 00146 }; 00147 00148 00149 00150 00151 00152 00153 00158 template<typename view_collection_type, typename change_counter_type, typename dependent_inserter_type> 00159 class recursive_inserter 00160 { 00161 public: 00162 recursive_inserter() : view_collection(0), change_counter(0), dependent_inserter(0) {} 00163 recursive_inserter(view_collection_type & collection_) : view_collection(&collection_), change_counter(0), dependent_inserter(0) {} 00164 00165 recursive_inserter(view_collection_type & collection_obj, change_counter_type & change_counter_) : 00166 view_collection(&collection_obj), change_counter(&change_counter_) {} 00167 recursive_inserter(view_collection_type & collection_obj, dependent_inserter_type & dependent_inserter_) : 00168 view_collection(&collection_obj), change_counter(0), dependent_inserter(&dependent_inserter_) {} 00169 00170 recursive_inserter(view_collection_type & collection_obj, change_counter_type & change_counter_, dependent_inserter_type & dependent_inserter_) : 00171 view_collection(&collection_obj), change_counter(&change_counter_), dependent_inserter(&dependent_inserter_) {} 00172 00173 00174 // recursive_inserter(view_collection_type & collection_, dependent_inserter_type & dependent_inserter_) : 00175 // view_collection(&collection_), dependent_inserter(&dependent_inserter_) {} 00176 00177 00178 void set_mesh_info(view_collection_type & collection_obj, change_counter_type & change_counter_) 00179 { 00180 view_collection = &collection_obj; 00181 change_counter = &change_counter_; 00182 } 00183 00184 00185 template<typename handle_type, typename value_type> 00186 void handle_insert( handle_type ref, viennagrid::detail::tag<value_type> ) 00187 { 00188 viennagrid::detail::handle_or_ignore( *view_collection, ref, viennagrid::detail::tag<value_type>() ); 00189 00190 dependent_inserter->handle_insert( ref, viennagrid::detail::tag<value_type>() ); 00191 if (change_counter) ++(*change_counter); 00192 } 00193 00194 00195 typedef typename dependent_inserter_type::physical_container_collection_type physical_container_collection_type; 00196 00197 template<bool generate_id, bool call_callback, typename value_type, typename inserter_type> 00198 std::pair< 00199 typename viennagrid::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type, 00200 bool 00201 > 00202 physical_insert( const value_type & element, inserter_type & inserter ) 00203 { 00204 return dependent_inserter->template physical_insert<generate_id, call_callback>( element, inserter ); 00205 } 00206 00207 00208 00209 template<bool generate_id, bool call_callback, typename value_type> 00210 std::pair< 00211 typename viennagrid::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type, 00212 bool 00213 > 00214 insert( const value_type & element ) 00215 { 00216 return physical_insert<generate_id, call_callback>( element, *this ); 00217 } 00218 00219 template<typename value_type> 00220 std::pair< 00221 typename viennagrid::result_of::container_of<physical_container_collection_type, value_type>::type::handle_type, 00222 bool 00223 > 00224 operator()( const value_type & element ) 00225 { 00226 return insert<true, true>( element ); 00227 } 00228 00229 physical_container_collection_type & get_physical_container_collection() { return dependent_inserter->get_physical_container_collection(); } 00230 physical_container_collection_type const & get_physical_container_collection() const { return dependent_inserter->get_physical_container_collection(); } 00231 00232 typedef typename dependent_inserter_type::id_generator_type id_generator_type; 00233 id_generator_type & get_id_generator() { return dependent_inserter->get_id_generator(); } 00234 id_generator_type const & get_id_generator() const { return dependent_inserter->get_id_generator(); } 00235 00236 00237 private: 00238 view_collection_type * view_collection; 00239 change_counter_type * change_counter; 00240 00241 dependent_inserter_type * dependent_inserter; 00242 }; 00243 00244 00245 namespace result_of 00246 { 00253 template<typename container_collection_type, typename change_counter_type, typename dependent_inserter_type> 00254 struct recursive_inserter 00255 { 00256 typedef viennagrid::recursive_inserter<container_collection_type, change_counter_type, dependent_inserter_type> type; 00257 }; 00258 00265 template<typename container_collection_type, typename change_counter_type, typename id_generator_type> 00266 struct physical_inserter 00267 { 00268 typedef viennagrid::physical_inserter<container_collection_type, change_counter_type, id_generator_type> type; 00269 }; 00270 } 00271 } 00272 00273 #endif