ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/storage/algorithm.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_STORAGE_ALGORITHM_HPP
00002 #define VIENNAGRID_STORAGE_ALGORITHM_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/collection.hpp"
00017 #include "viennagrid/storage/container_collection.hpp"
00018 #include "viennagrid/storage/view.hpp"
00019 
00020 #include "viennagrid/meta/algorithm.hpp"
00021 
00022 
00027 namespace viennagrid
00028 {
00029   namespace detail
00030   {
00031     template<typename collection_type, typename functor>
00032     struct for_each_functor
00033     {
00034       for_each_functor(collection_type & collection, functor f) : collection_(collection), f_(f) {}
00035 
00036       template<typename key_type, typename value_type>
00037       void operator()( viennagrid::detail::tag< viennagrid::static_pair<key_type, value_type> > )
00038       { f_( viennagrid::get<key_type>(collection_) ); }
00039 
00040       collection_type & collection_;
00041       functor           f_;
00042     };
00043 
00044     template<typename collection_type, typename functor>
00045     void for_each( collection_type & collection, functor f)
00046     {
00047       for_each_functor<collection_type, functor> ff(collection, f);
00048       viennagrid::detail::for_each< typename collection_type::typemap >(ff);
00049     }
00050 
00051     template<typename typelist, typename collection_type, typename functor>
00052     void for_each_typelist(collection_type & collection, functor & f)
00053     {
00054       for_each_functor<collection_type, functor> ff(collection, f);
00055       viennagrid::detail::for_each<typelist>(ff);
00056     }
00057 
00058 
00059     template<typename collection_type_1, typename collection_type_2, typename functor>
00060     class dual_for_each_functor
00061     {
00062     public:
00063 
00064       dual_for_each_functor(
00065           collection_type_1 & container_collection_1,
00066           collection_type_2 & container_collection_2,
00067           functor f) :
00068               container_collection_1_(container_collection_1),
00069               container_collection_2_(container_collection_2),
00070               f_(f) {}
00071 
00072       template<typename type>
00073       void operator() ( viennagrid::detail::tag<type> )
00074       {
00075           f_(
00076             viennagrid::get<type>(container_collection_1_),
00077             viennagrid::get<type>(container_collection_2_)
00078           );
00079       }
00080 
00081     private:
00082       collection_type_1 & container_collection_1_;
00083       collection_type_2 & container_collection_2_;
00084       functor             f_;
00085     };
00086 
00087 
00088     template<typename predicate>
00089     class copy_functor
00090     {
00091     public:
00092       copy_functor(predicate pred) : pred_(pred) {}
00093 
00094       template<typename src_container_type, typename dst_container_type>
00095       void operator() (const src_container_type & src_container, dst_container_type & dst_container)
00096       {
00097         for (typename src_container_type::const_iterator it = src_container.begin(); it != src_container.end(); ++it)
00098           if (pred_(*it))
00099               dst_container.insert( *it );
00100       }
00101 
00102     private:
00103       predicate pred_;
00104     };
00105 
00106 
00107 
00108 
00109     template<typename src_container_typelist, typename dst_container_typelist>
00110     void copy(const collection<src_container_typelist> & src, collection<dst_container_typelist> & dst)
00111     {
00112       detail::dual_for_each_functor<
00113           const collection<src_container_typelist>,
00114           collection<dst_container_typelist>,
00115           copy_functor<viennagrid::detail::true_predicate>
00116           > functor(src, dst, copy_functor<viennagrid::detail::true_predicate>(viennagrid::detail::true_predicate()));
00117 
00118       typedef typename viennagrid::result_of::common_values<
00119           collection<src_container_typelist>,
00120           collection<dst_container_typelist>
00121       >::type typelist;
00122 
00123       viennagrid::detail::for_each<typelist>(functor);
00124     }
00125 
00126     template<typename src_container_typelist, typename dst_container_typelist, typename predicate>
00127     void copy_if(const collection<src_container_typelist> & src, collection<dst_container_typelist> & dst, predicate pred)
00128     {
00129       detail::dual_for_each_functor<
00130           const collection<src_container_typelist>,
00131           collection<dst_container_typelist>,
00132           copy_functor<predicate>
00133           > functor(src, dst, copy_functor<predicate>(pred));
00134 
00135       typedef typename viennagrid::result_of::common_values<
00136           collection<src_container_typelist>,
00137           collection<dst_container_typelist>
00138       >::type typelist;
00139 
00140       viennagrid::detail::for_each<typelist>(functor);
00141     }
00142 
00143 
00144 
00145 
00146 
00147     template<typename predicate>
00148     class handle_functor
00149     {
00150     public:
00151       handle_functor(predicate pred) : pred_(pred) {}
00152 
00153       template<typename container_type, typename base_container_type, typename handle_container_tag>
00154       void operator() (container_type & src_container, viennagrid::view<base_container_type, handle_container_tag> & dst_view)
00155       {
00156           for (typename container_type::iterator it = src_container.begin(); it != src_container.end(); ++it)
00157               if (pred_( *it ))
00158                   dst_view.insert_handle( it.handle() );
00159       }
00160 
00161 
00162     private:
00163       predicate pred_;
00164     };
00165 
00166 
00167     template<typename src_container_typelist, typename dst_container_typelist>
00168     void handle(collection<src_container_typelist> & src, collection<dst_container_typelist> & dst)
00169     {
00170       detail::dual_for_each_functor<
00171           collection<src_container_typelist>,
00172           collection<dst_container_typelist>,
00173           handle_functor<viennagrid::detail::true_predicate>
00174           > functor(src, dst, handle_functor<viennagrid::detail::true_predicate>(viennagrid::detail::true_predicate()));
00175 
00176       typedef typename viennagrid::result_of::common_values<
00177           collection<src_container_typelist>,
00178           collection<dst_container_typelist>
00179       >::type typelist;
00180 
00181       viennagrid::detail::for_each<typelist>(functor);
00182     }
00183 
00184     template<typename src_container_typelist, typename dst_container_typelist, typename predicate>
00185     void handle_if(collection<src_container_typelist> & src, collection<dst_container_typelist> & dst, predicate pred)
00186     {
00187       detail::dual_for_each_functor<
00188           collection<src_container_typelist>,
00189           collection<dst_container_typelist>,
00190           handle_functor<predicate>
00191           > functor(src, dst, handle_functor<predicate>(pred));
00192 
00193       typedef typename viennagrid::result_of::common_values<
00194           collection<src_container_typelist>,
00195           collection<dst_container_typelist>
00196       >::type typelist;
00197 
00198       viennagrid::detail::for_each<typelist>(functor);
00199     }
00200 
00201   }
00202 }
00203 
00204 #endif