ViennaGrid - The Vienna Grid Library
2.1.0
|
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