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