00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00021 #ifndef _ARAGELI_vecalg_hpp_
00022 #define _ARAGELI_vecalg_hpp_
00023
00024 #include "config.hpp"
00025
00026
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 }
00060
00061
00062
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 {
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