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