00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef STLSOFT_INCL_H_STLSOFT
00058 # include <stlsoft.h>
00059 #endif
00060 #ifndef STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00061 # include <rangelib/range_categories.hpp>
00062 #endif
00063 #include <iterator>
00064 #include <functional>
00065
00066
00067
00068
00069
00070 #ifndef _STLSOFT_NO_NAMESPACE
00071 namespace stlsoft
00072 {
00073 #endif
00074
00075
00076
00081
00082
00083
00084
00085
00086 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00087 namespace
00088 {
00089 template <ss_typename_param_k T>
00090 struct accumulate_1_function
00091 {
00092 public:
00093 accumulate_1_function(T &total)
00094 : m_total(total)
00095 {}
00096
00097 public:
00098 template <ss_typename_param_k T2>
00099 ss_bool_t operator ()(T2 val)
00100 {
00101 m_total = m_total + val;
00102
00103 return true;
00104 }
00105
00106 private:
00107 T &m_total;
00108 };
00109
00110 template< ss_typename_param_k T
00111 , ss_typename_param_k P
00112 >
00113 struct accumulate_2_function
00114 {
00115 public:
00116 accumulate_2_function(T &total, P pr)
00117 : m_total(total)
00118 , m_pr(pr)
00119 {}
00120
00121 public:
00122 template <ss_typename_param_k T2>
00123 ss_bool_t operator ()(T2 val)
00124 {
00125 m_total = m_pr(m_total, val);
00126
00127 return true;
00128 }
00129
00130 private:
00131 T &m_total;
00132 P m_pr;
00133 };
00134
00135 template <ss_typename_param_k O>
00136 struct copy_function
00137 {
00138 public:
00139 copy_function(O o)
00140 : m_o(o)
00141 {}
00142
00143 public:
00144 template <ss_typename_param_k T2>
00145 ss_bool_t operator ()(T2 val)
00146 {
00147 *m_o++ = val;
00148
00149 return true;
00150 }
00151
00152 public:
00153 operator O()
00154 {
00155 return m_o;
00156 }
00157
00158 private:
00159 O m_o;
00160 };
00161
00162 template <ss_typename_param_k T>
00163 struct count_function
00164 {
00165 public:
00166 count_function(size_t &n, T const &val)
00167 : m_n(n)
00168 , m_val(val)
00169 {}
00170
00171 public:
00172 template <ss_typename_param_k T2>
00173 ss_bool_t operator ()(T2 val) const
00174 {
00175 if(m_val == val)
00176 {
00177 ++m_n;
00178 }
00179
00180 return true;
00181 }
00182 private:
00183 size_t &m_n;
00184 T const &m_val;
00185 };
00186
00187 template <ss_typename_param_k P>
00188 struct count_if_function
00189 {
00190 public:
00191 count_if_function(size_t &n, P pr)
00192 : m_n(n)
00193 , m_pr(pr)
00194 {}
00195
00196 public:
00197 template <ss_typename_param_k T2>
00198 ss_bool_t operator ()(T2 val) const
00199 {
00200 if(m_pr(val))
00201 {
00202 ++m_n;
00203 }
00204
00205 return true;
00206 }
00207 private:
00208 size_t &m_n;
00209 P m_pr;
00210 };
00211
00212 struct distance_function
00213 {
00214 public:
00215 distance_function(ptrdiff_t &count)
00216 : m_count(count)
00217 {}
00218 public:
00219 template <ss_typename_param_k T>
00220 ss_bool_t operator ()(T ) const
00221 {
00222 return (++m_count, true);
00223 }
00224 private:
00225 ptrdiff_t &m_count;
00226
00227 private:
00228 distance_function &operator =(distance_function const &);
00229 };
00230
00231 template <ss_typename_param_k T>
00232 struct exists_function
00233 {
00234 public:
00235 exists_function(ss_bool_t &b, T const &val)
00236 : m_b(b)
00237 , m_val(val)
00238 {
00239 stlsoft_assert(!b);
00240 }
00241
00242 public:
00243 template <ss_typename_param_k T2>
00244 ss_bool_t operator ()(T2 val) const
00245 {
00246 if(m_val == val)
00247 {
00248 m_b = true;
00249
00250 return false;
00251 }
00252
00253 return true;
00254 }
00255 private:
00256 ss_bool_t &m_b;
00257 T const &m_val;
00258 };
00259
00260 template <ss_typename_param_k P>
00261 struct exists_if_1_function
00262 {
00263 public:
00264 exists_if_1_function(ss_bool_t &b, P pr)
00265 : m_b(b)
00266 , m_pr(pr)
00267 {
00268 stlsoft_assert(!b);
00269 }
00270
00271 public:
00272 template <ss_typename_param_k T2>
00273 ss_bool_t operator ()(T2 val) const
00274 {
00275 if(pf(val))
00276 {
00277 m_b = true;
00278
00279 return false;
00280 }
00281
00282 return true;
00283 }
00284 private:
00285 ss_bool_t &m_b;
00286 P m_pr;
00287 };
00288
00289 template< ss_typename_param_k P
00290 , ss_typename_param_k V
00291 >
00292 struct exists_if_2_function
00293 {
00294 public:
00295 exists_if_2_function(ss_bool_t &b, P pr, V &result)
00296 : m_b(b)
00297 , m_pr(pr)
00298 , m_result(result)
00299 {
00300 stlsoft_assert(!b);
00301 }
00302
00303 public:
00304 template <ss_typename_param_k T2>
00305 ss_bool_t operator ()(T2 val) const
00306 {
00307 if(pf(val))
00308 {
00309 m_b = true;
00310 m_result = val;
00311
00312 return false;
00313 }
00314
00315 return true;
00316 }
00317 private:
00318 ss_bool_t &m_b;
00319 P m_pr;
00320 V &m_result;
00321 };
00322
00323 template <ss_typename_param_k F>
00324 struct for_each_function
00325 {
00326 public:
00327 for_each_function(F f)
00328 : m_f(f)
00329 {}
00330 public:
00331 template <ss_typename_param_k T>
00332 ss_bool_t operator ()(T v) const
00333 {
00334 return (m_f(v), true);
00335 }
00336 private:
00337 F m_f;
00338 };
00339
00340 template< ss_typename_param_k V
00341 , ss_typename_param_k P
00342 >
00343 struct minmax_element_2_function
00344 {
00345 public:
00346 minmax_element_2_function(ss_bool_t &bRetrieved, P pr, V &result)
00347 : m_bRetrieved(bRetrieved)
00348 , m_pr(pr)
00349 , m_result(result)
00350 {}
00351 public:
00352 template <ss_typename_param_k T>
00353 ss_bool_t operator ()(T val) const
00354 {
00355 if(!m_bRetrieved)
00356 {
00357 m_result = val;
00358
00359 m_bRetrieved = true;
00360 }
00361 else
00362 {
00363 if(m_pr(m_result, val))
00364 {
00365 m_result = val;
00366 }
00367 }
00368
00369 return true;
00370 }
00371 private:
00372 ss_bool_t &m_bRetrieved;
00373 P m_pr;
00374 V &m_result;
00375 };
00376
00377 }
00378
00379 #endif
00380
00381
00382
00383
00384
00386 template <ss_typename_param_k R>
00387 class indirect_range_adaptor
00388 : public indirect_range_tag
00389 {
00390 public:
00391 typedef R range_type;
00392 typedef ss_typename_type_k R::value_type value_type;
00393
00394 public:
00398 indirect_range_adaptor(range_type r)
00399 : m_r(r)
00400 {}
00401
00403 template <ss_typename_param_k T>
00404 T accumulate(T val) const
00405 {
00406 T total = val;
00407
00408 m_r.for_each_cancelable(accumulate_1_function<T>(total));
00409
00410 return total;
00411 }
00412
00414 template< ss_typename_param_k T
00415 , ss_typename_param_k P
00416 >
00417 T accumulate(T val, P pr) const
00418 {
00419 T total = val;
00420
00421 m_r.for_each_cancelable(accumulate_2_function<T, P>(total, pr));
00422
00423 return total;
00424 }
00425
00427 template <ss_typename_param_k O>
00428 O copy(O o) const
00429 {
00430 copy_function<O> cf(o);
00431
00432 m_r.for_each_cancelable(cf);
00433
00434 return cf;
00435 }
00436
00438 template <ss_typename_param_k T>
00439 size_t count(T const &val) const
00440 {
00441 size_t n = 0;
00442
00443 m_r.for_each_cancelable(count_function<T>(n, val));
00444
00445 return n;
00446 }
00447
00449 template <ss_typename_param_k P>
00450 size_t count_if(P pr) const
00451 {
00452 size_t n = 0;
00453
00454 m_r.for_each_cancelable(count_if_function<P>(n, pr));
00455
00456 return n;
00457 }
00458
00460 ptrdiff_t distance() const
00461 {
00462 ptrdiff_t n = 0;
00463
00464 m_r.for_each_cancelable(distance_function(n));
00465
00466 return n;
00467 }
00468
00470 template <ss_typename_param_k F>
00471 F for_each(F f)
00472 {
00473 m_r.for_each_cancelable(for_each_function<F>(f));
00474
00475 return f;
00476 }
00477
00479 template <ss_typename_param_k T>
00480 ss_bool_t exists(T const &val) const
00481 {
00482 ss_bool_t bExists = false;
00483
00484 m_r.for_each_cancelable(exists_function<T>(bExists, val));
00485
00486 return bExists;
00487 }
00488
00491 template <ss_typename_param_k P>
00492 ss_bool_t exists_if(P pr) const
00493 {
00494 ss_bool_t bExists = false;
00495
00496 m_r.for_each_cancelable(exists_if_1_function<P>(bExists, pr));
00497
00498 return bExists;
00499 }
00500
00503 template< ss_typename_param_k P
00504 , ss_typename_param_k T>
00505 ss_bool_t exists_if(P pr, T &result) const
00506 {
00507 ss_bool_t bExists = false;
00508
00509 m_r.for_each_cancelable(exists_if_2_function<P, T>(bExists, pr, result));
00510
00511 return bExists;
00512 }
00513
00515 value_type max_element() const
00516 {
00517 return minmax_element(std::less<value_type>());
00518 }
00519
00522 template <ss_typename_param_k P>
00523 value_type max_element(P pr) const
00524 {
00525 return minmax_element(pr);
00526 }
00527
00529 value_type min_element() const
00530 {
00531 return minmax_element(std::greater<value_type>());
00532 }
00533
00536 template <ss_typename_param_k P>
00537 value_type min_element(P pr) const
00538 {
00539 return minmax_element(std::not2(pr));
00540 }
00541
00542 private:
00543 template <ss_typename_param_k P>
00544 value_type minmax_element(P pr) const
00545 {
00546 ss_bool_t bRetrieved;
00547 value_type result;
00548
00549 m_r.for_each_cancelable(minmax_element_2_function<value_type, P>(bRetrieved, pr, result));
00550
00551 stlsoft_assert(bRetrieved);
00552
00553 return result;
00554 }
00555
00556 private:
00557 range_type m_r;
00558 };
00559
00561
00562
00563 #ifdef STLSOFT_UNITTEST
00564
00565 namespace unittest
00566 {
00567 ss_bool_t test_rangelib_indirect_range_adaptors(unittest_reporter *r)
00568 {
00569 using stlsoft::unittest::unittest_initialiser;
00570
00571 ss_bool_t bSuccess = true;
00572
00573 unittest_initialiser init(r, "RangeLib", "indirect_range_adaptors", __FILE__);
00574
00575 #if 0
00576 if(
00577 {
00578 r->report("construct() failed ", __LINE__);
00579 bSuccess = false;
00580 }
00581 #endif
00582
00583 return bSuccess;
00584 }
00585
00586 unittest_registrar unittest_rangelib_indirect_range_adaptors(test_rangelib_indirect_range_adaptors);
00587
00588 }
00589
00590 #endif
00591
00592
00593
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606