vecalg.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     vecalg.hpp -- generic functions on vector-like structures.
00004 
00005     This file is a part of the Arageli library.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005--2006
00009     University of Nizhni Novgorod, Russia
00010 
00011 *****************************************************************************/
00012 
00021 #ifndef _ARAGELI_vecalg_hpp_
00022 #define _ARAGELI_vecalg_hpp_
00023 
00024 #include "config.hpp"
00025 
00026 //#include "_utility.hpp"
00027 #include "frwrddecl.hpp"
00028 #include "misc.hpp"
00029 
00030 #include "functional.hpp"
00031 
00032 
00033 namespace Arageli
00034 {
00035 
00036     
00037 namespace _Internal
00038 {
00039 
00040 template <typename Vector, typename Index, typename Index_category>
00041 struct function_traits_subscript_select_index
00042 { typedef indexed_subvector<Vector, Index> type; };
00043 
00044 template <typename Vector, typename Index, typename Index_category>
00045 struct function_traits_subscript_select_index
00046     <const Vector, Index, Index_category>
00047 { typedef indexed_subvector<const Vector, Index> type; };
00048 
00049 template <typename Vector, typename Index>
00050 struct function_traits_subscript_select_index
00051     <Vector, Index, type_category::integer>
00052 { typedef typename Vector::reference type; };
00053 
00054 template <typename Vector, typename Index>
00055 struct function_traits_subscript_select_index
00056     <const Vector, Index, type_category::integer>
00057 { typedef typename Vector::const_reference type; };
00058 
00059 } // namespace _Internal
00060 
00061 
00062 // Ingerit from this class binary_function_traits specialization for some vector.
00063 template <typename Vec, typename Index>
00064 struct vec_binary_function_traits
00065 {
00066     static const bool is_specialized = true;
00067     typedef Vec first_argument_type;
00068     typedef Index second_argument_type;
00069     static const bool alternates_first_argument = false;
00070     static const bool alternates_second_argument = false;
00071     static const bool has_side_effect = false;
00072 
00073     typedef typename
00074         _Internal::function_traits_subscript_select_index
00075         <
00076             Vec, Index,
00077             typename type_traits<Index>::category_type
00078         >::type
00079             result_type;
00080 };
00081 
00082 
00083 template <typename Vec, typename Index>
00084 inline typename cnc_reference<Vec>::type
00085 vec_operator_sqbrackets_index_vector
00086 (Vec* vec, const Index& ind, const type_category::integer&)
00087 { return vec->el(ind); }
00088 
00089 
00090 template <typename Vec, typename Index>
00091 inline indexed_subvector<Vec, vector<typename Vec::size_type> >
00092 vec_operator_sqbrackets_index_vector
00093 (Vec* vec, const Index& ind, const type_category::string&)
00094 { return vec->subvector(vector<typename Vec::size_type>(ind)); }
00095 
00096 
00097 template <typename Vec, typename Index>
00098 inline indexed_subvector<Vec, Index>
00099 vec_operator_sqbrackets_index_vector
00100 (Vec* vec, const Index& ind, const type_category::type&)
00101 { return vec->subvector(ind); }
00102 
00103 
00104 // ---------------------------------------------------------------------
00105 
00106 
00107 template <typename Vec, typename UFunc>
00108 void apply1_wores_vec (Vec& a, UFunc f)
00109 {
00110     if(a.is_empty())return;
00111     typedef typename cnc_iterator<Vec>::type Iter;
00112     for(Iter i = a.begin(), iend = a.end(); i != iend; ++i)
00113         f(*i);
00114 }
00115 
00116 
00117 template <typename Vec1, typename Vec2, typename BinOp>
00118 void apply2_wores_vec_by_vec (Vec1& a, Vec2& b, BinOp f)
00119 {
00120     ARAGELI_ASSERT_0(a.size() == b.size());
00121     if(a.is_empty())return;
00122 
00123     typename cnc_iterator<Vec1>::type ai = a.begin(), aend = a.end();
00124     typename cnc_iterator<Vec2>::type bi = b.begin();
00125 
00126     for(; ai != aend; ++ai, ++bi)
00127         f(*ai, *bi);
00128 }
00129 
00130 template <typename Vec, typename Val, typename BinOp>
00131 void apply2_wores_vec_by_val (Vec& a, Val& b, BinOp f)
00132 {
00133     if(a.is_empty())return;
00134 
00135     typename cnc_iterator<Vec>::type ai = a.begin(), aend = a.end();
00136 
00137     for(; ai != aend; ++ai)
00138         f(*ai, b);
00139 }
00140 
00141 template <typename Val, typename Vec, typename BinOp>
00142 void apply2_wores_val_by_vec (Val& a, Vec& b, BinOp f)
00143 {
00144     if(b.is_empty())return;
00145 
00146     typename cnc_iterator<Vec>::type bi = b.begin(), bend = b.end();
00147 
00148     for(; bi != bend; ++bi)
00149         f(a, *bi);
00150 }
00151 
00152 template <typename Vec1, typename Vec2, typename VecRes, typename Func2>
00153 VecRes& apply2_vec_by_vec
00154 (const Vec1& a, const Vec2& b, VecRes& res, Func2 f)
00155 {
00156     ARAGELI_ASSERT_0(a.size() == b.size());         
00157                                                     
00158     res.resize(a.size());                           
00159     typename Vec1::const_iterator                   
00160         ia = a.begin(), iaend = a.end();            
00161     typename Vec2::const_iterator ib = b.begin();   
00162     typename VecRes::iterator ires = res.begin();   
00163                                                     
00164     for(; ia != iaend; ++ia, ++ib, ++ires)          
00165         *ires = f(*ia, *ib);                        
00166                                                     
00167     return res;                                     
00168 }                                                   
00169 
00170 
00171 template <typename Vec1, typename Vec2, typename Func2>             
00172 inline Vec1 apply2_vec_by_vec                       
00173 (const Vec1& a, const Vec2& b, Func2 f)                     
00174 {                                                   
00175     ARAGELI_ASSERT_0(a.size() == b.size());         
00176     Vec1 res(a.size());                             
00177     return apply2_vec_by_vec(a, b, res, f);         
00178 }                                                   
00179 
00180 
00181 template <typename Vec, typename Val, typename VecRes, typename Func2>
00182 VecRes& apply2_vec_by_val                       
00183 (const Vec& a, const Val& b, VecRes& res, Func2 f)      
00184 {                                               
00185     res.resize(a.size());                       
00186     typename Vec::const_iterator                
00187         ia = a.begin(), iaend = a.end();        
00188     typename VecRes::iterator ires = res.begin();
00189                                                 
00190     for(; ia != iaend; ++ia, ++ires)            
00191         *ires = f(*ia, b);                  
00192                                                 
00193     return res;                                 
00194 }                                               
00195 
00196 
00197 template <typename Vec, typename Val, typename Func2>           
00198 inline Vec apply2_vec_by_val                    
00199 (const Vec& a, const Val& b, Func2 f)                   
00200 {                                               
00201     Vec res(a.size());                          
00202     return apply2_vec_by_val(a, b, res, f);     
00203 }                                               
00204 
00205 
00206 template <typename Val, typename Vec, typename VecRes, typename Func2>
00207 VecRes& apply2_val_by_vec                       
00208 (const Val& a, const Vec& b, VecRes& res, Func2 f)      
00209 {                                               
00210     res.resize(b.size());                       
00211     typename Vec::const_iterator                
00212         ib = b.begin(), ibend = b.end();        
00213     typename VecRes::iterator ires = res.begin();
00214                                                 
00215     for(; ib != ibend; ++ib, ++ires)            
00216         *ires = f(a, *ib);                  
00217                                                 
00218     return res;                                 
00219 }                                               
00220 
00221 
00222 template <typename Val, typename Vec, typename Func2>           
00223 inline Vec apply2_val_by_vec                    
00224 (const Val& a, const Vec& b, Func2 f)                   
00225 {                                               
00226     Vec res(b.size());                          
00227     return apply2_val_by_vec(a, b, res, f);     
00228 }
00229 
00230 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00231 
00232 template <typename Vec1, typename Vec2, typename VecRes, typename Func3>
00233 VecRes& apply3_vec_by_vec
00234 (const Vec1& a, const Vec2& b, VecRes& res, Func3 f)
00235 {
00236     ARAGELI_ASSERT_0(a.size() == b.size());         
00237                                                     
00238     res.resize(a.size());                           
00239     typename Vec1::const_iterator                   
00240         ia = a.begin(), iaend = a.end();            
00241     typename Vec2::const_iterator ib = b.begin();   
00242     typename VecRes::iterator ires = res.begin();   
00243                                                     
00244     for(; ia != iaend; ++ia, ++ib, ++ires)          
00245         f(*ia, *ib, *ires);                     
00246                                                     
00247     return res;                                     
00248 }                                                   
00249 
00250 
00251 template <typename Vec1, typename Vec2, typename Func3>             
00252 inline Vec1 apply3_vec_by_vec                       
00253 (const Vec1& a, const Vec2& b, Func3 f)                     
00254 {                                                   
00255     ARAGELI_ASSERT_0(a.size() == b.size());         
00256     Vec1 res(a.size());                             
00257     return apply3_vec_by_vec(a, b, res, f);
00258 }                                                   
00259 
00260 
00261 template <typename Vec, typename Val, typename VecRes, typename Func3>
00262 VecRes& apply3_vec_by_val                       
00263 (const Vec& a, const Val& b, VecRes& res, Func3 f)      
00264 {                                               
00265     res.resize(a.size());                       
00266     typename Vec::const_iterator                
00267         ia = a.begin(), iaend = a.end();        
00268     typename VecRes::iterator ires = res.begin();
00269                                                 
00270     for(; ia != iaend; ++ia, ++ires)            
00271         f(*ia, b, *ires);                   
00272                                                 
00273     return res;                                 
00274 }                                               
00275 
00276 
00277 template <typename Vec, typename Val, typename Func3>
00278 inline Vec apply3_vec_by_val
00279 (const Vec& a, const Val& b, Func3 f)
00280 {                                               
00281     Vec res(a.size());                          
00282     return apply3_vec_by_val(a, b, res, f);
00283 }                                               
00284 
00285 
00286 template <typename Val, typename Vec, typename VecRes, typename Func3>
00287 VecRes& apply3_val_by_vec
00288 (const Val& a, const Vec& b, VecRes& res, Func3 f)
00289 {                                               
00290     res.resize(b.size());                       
00291     typename Vec::const_iterator                
00292         ib = b.begin(), ibend = b.end();        
00293     typename VecRes::iterator ires = res.begin();
00294                                                 
00295     for(; ib != ibend; ++ib, ++ires)            
00296         f(a, *ib, *ires);                   
00297                                                 
00298     return res;                                 
00299 }                                               
00300 
00301 
00302 template <typename Val, typename Vec, typename Func3>
00303 inline Vec apply3_val_by_vec
00304 (const Val& a, const Vec& b, Func3 f)
00305 {                                               
00306     Vec res(b.size());
00307     return apply3_val_by_vec(a, b, res, f);
00308 }
00309 
00310 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00311 
00312 template <typename Vec1, typename Vec2, typename Cmp>
00313 int cmp_vec_by_vec (const Vec1& a, const Vec2& b, Cmp cmp)
00314 {
00315     typename Vec1::const_iterator ai = a.begin(), aend = a.end();
00316     typename Vec2::const_iterator bi = b.begin(), bend = b.end();
00317     
00318     for(; ai != aend && bi != bend; ++ai, ++bi)
00319     {
00320         int lres = cmp(*ai, *bi);
00321         if(lres < 0)return -1;
00322         else if(lres > 0)return +1;
00323     }
00324 
00325     if(ai == aend)
00326         if(bi == bend)return 0;
00327         else return -1;
00328     else
00329     { // ai != aend
00330         ARAGELI_ASSERT_1(bi == bend);
00331         return +1;
00332     }
00333 }
00334 
00335 
00336 template <typename Vec, typename Val, typename Cmp>
00337 int cmp_vec_by_val (const Vec& a, const Val& val, Cmp cmp)
00338 {
00339     typename Vec::const_iterator ai = a.begin(), aend = a.end();
00340     
00341     for(; ai != aend; ++ai)
00342     {
00343         int lres = cmp(*ai, val);
00344         if(lres < 0)return -1;
00345         else if(lres > 0)return +1;
00346     }
00347 
00348     return 0;
00349 }
00350 
00351 
00352 template <typename Val, typename Vec, typename Cmp>
00353 int cmp_val_by_vec (const Val& val, const Vec& a, Cmp cmp)
00354 {
00355     typename Vec::const_iterator ai = a.begin(), aend = a.end();
00356     
00357     for(; ai != aend; ++ai)
00358     {
00359         int lres = cmp(val, *ai);
00360         if(lres < 0)return -1;
00361         else if(lres > 0)return +1;
00362     }
00363 
00364     return 0;
00365 }
00366 
00367 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00368 
00369 template <typename Vec1, typename Vec2>
00370 int cmpdef_vec_by_vec (const Vec1& a, const Vec2& b)
00371 { return cmp_vec_by_vec(a, b, gfunc::cmp()); }
00372 
00373 
00374 template <typename Vec, typename Val>
00375 int cmpdef_vec_by_val (const Vec& a, const Val& val)
00376 { return cmp_vec_by_val(a, val, gfunc::cmp()); }
00377 
00378 
00379 template <typename Val, typename Vec>
00380 int cmpdef_val_by_vec (const Val& val, const Vec& a)
00381 { return cmp_val_by_vec(val, a, gfunc::cmp()); }
00382 
00383 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00384 
00385 template <typename Vec1, typename Vec2, typename Cmp>
00386 bool allcmp_vec_by_vec (const Vec1& a, const Vec2& b, Cmp cmp)
00387 {
00388     ARAGELI_ASSERT_0(a.size() == b.size());
00389     
00390     typename Vec1::const_iterator                   
00391         ia = a.begin(), iaend = a.end();            
00392     typename Vec2::const_iterator ib = b.begin();
00393 
00394     for(; ia != iaend; ++ia, ++ib)
00395         if(!cmp(*ia, *ib))return false;
00396 
00397     return true;
00398 }
00399 
00400 
00401 template <typename Vec, typename Val, typename Cmp>
00402 bool allcmp_vec_by_val (const Vec& a, const Val& val, Cmp cmp)
00403 {
00404     typename Vec::const_iterator                    
00405         ia = a.begin(), iaend = a.end();            
00406 
00407     for(; ia != iaend; ++ia)
00408         if(!cmp(*ia, val))return false;
00409 
00410     return true;
00411 }
00412 
00413 
00414 template <typename Val, typename Vec, typename Cmp>
00415 bool allcmp_val_by_vec (const Val& val, const Vec& a, Cmp cmp)
00416 {
00417     typename Vec::const_iterator
00418         ia = a.begin(), iaend = a.end();
00419 
00420     for(; ia != iaend; ++ia)
00421         if(!cmp(val, *ia))return false;
00422 
00423     return true;
00424 }
00425 
00426 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00427 
00428 template <typename Vec1, typename Vec2, typename Cmp>
00429 inline typename Vec1::template other_element_type_refcnt<bool, true>::type
00430 eachcmp_vec_by_vec (const Vec1& a, const Vec2& b, Cmp cmp)
00431 {
00432     typename Vec1::template other_element_type_refcnt<bool, true>::type res;
00433     return apply2_vec_by_vec(a, b, res, cmp);
00434 }
00435 
00436 
00437 template <typename Vec, typename Val, typename Cmp>
00438 inline typename Vec::template other_element_type_refcnt<bool, true>::type
00439 eachcmp_vec_by_val (const Vec& a, const Val& val, Cmp cmp)
00440 {
00441     typename Vec::template other_element_type_refcnt<bool, true>::type res;
00442     return apply2_vec_by_val(a, val, res, cmp);
00443 }
00444 
00445 
00446 template <typename Val, typename Vec, typename Cmp>
00447 inline typename Vec::template other_element_type_refcnt<bool, true>::type
00448 eachcmp_val_by_vec (const Val& val, const Vec& a, Cmp cmp)
00449 {
00450     typename Vec::template other_element_type_refcnt<bool, true>::type res;
00451     return apply2_val_by_val(val, a, res, cmp);
00452 }
00453 
00454 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00455 
00456 template <typename Vec1, typename Vec2, typename Cmp>
00457 inline typename Vec1::template other_element_type_refcnt<int, true>::type
00458 elwisecmp_vec_by_vec (const Vec1& a, const Vec2& b, Cmp cmp)
00459 {
00460     typename Vec1::template other_element_type_refcnt<int, true>::type res;
00461     return apply2_vec_by_vec(a, b, res, cmp);
00462 }
00463 
00464 
00465 template <typename Vec, typename Val, typename Cmp>
00466 inline typename Vec::template other_element_type_refcnt<int, true>::type
00467 elwisecmp_vec_by_val (const Vec& a, const Val& val, Cmp cmp)
00468 {
00469     typename Vec::template other_element_type_refcnt<int, true>::type res;
00470     return apply2_vec_by_val(a, val, res, cmp);
00471 }
00472 
00473 
00474 template <typename Val, typename Vec, typename Cmp>
00475 inline typename Vec::template other_element_type_refcnt<int, true>::type
00476 elwisecmp_val_by_vec (const Val& val, const Vec& a, Cmp cmp)
00477 {
00478     typename Vec::template other_element_type_refcnt<int, true>::type res;
00479     return apply2_val_by_val(val, a, res, cmp);
00480 }
00481 
00482 
00483 template <typename Index, typename T>
00484 bool all_in_range (const Index& ind, const T& left, const T& right)
00485 {
00486     for(typename Index::const_pointer i = ind.begin(); i != ind.end(); ++i)
00487         if(!(*i >= left && *i <= right))return false;
00488     return true;
00489 }
00490 
00491 
00492 extern const char* vector_output_list_first_bracket_default;
00493 extern const char* vector_output_list_second_bracket_default;
00494 extern const char* vector_output_list_separator_default;
00495 extern const char* vector_input_list_first_bracket_default;
00496 extern const char* vector_input_list_second_bracket_default;
00497 extern const char* vector_input_list_separator_default;
00498 extern const char* vector_input_list_range_default;
00499 extern const char* vector_output_aligned_left_col_default;
00500 extern const char* vector_output_aligned_right_col_default;
00501 
00502 
00503 template <typename Out, typename Vec>
00504 Out& vec_output_list
00505 (
00506     Out& out,
00507     const Vec& x,
00508     const char* first_bracket = vector_output_list_first_bracket_default,
00509     const char* second_bracket = vector_output_list_second_bracket_default,
00510     const char* separator = vector_output_list_separator_default
00511 );
00512 
00513 
00514 }
00515 
00516 
00517 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00518     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_VECALG
00519     #include "vecalg.cpp"
00520     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_VECALG
00521 #endif
00522 
00523 
00524 #endif  //  #ifndef _ARAGELI_vector_hpp_
00525 

Generated on Thu Aug 31 17:38:12 2006 for Arageli by  doxygen 1.4.7