File indexing completed on 2025-01-18 09:28:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
0016 #define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <utility> // for std::pair and std::make_pair
0030
0031 #include <boost/config.hpp>
0032
0033 namespace boost {
0034
0035 namespace detail {
0036
0037
0038
0039 template <typename Iterator>
0040 struct less_over_iter {
0041 bool operator()(Iterator const& it1,
0042 Iterator const& it2) const { return *it1 < *it2; }
0043 };
0044
0045 template <typename Iterator, class BinaryPredicate>
0046 struct binary_pred_over_iter {
0047 explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {}
0048 bool operator()(Iterator const& it1,
0049 Iterator const& it2) const { return m_p(*it1, *it2); }
0050 private:
0051 BinaryPredicate m_p;
0052 };
0053
0054
0055
0056 template <typename ForwardIter, class Compare >
0057 std::pair<ForwardIter,ForwardIter>
0058 basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp)
0059 {
0060 if (first == last)
0061 return std::make_pair(last,last);
0062
0063 ForwardIter min_result = first;
0064 ForwardIter max_result = first;
0065
0066
0067 ForwardIter second = first; ++second;
0068 if (second == last)
0069 return std::make_pair(min_result, max_result);
0070
0071
0072 ForwardIter potential_min_result = last;
0073 if (comp(first, second))
0074 max_result = second;
0075 else {
0076 min_result = second;
0077 potential_min_result = first;
0078 }
0079
0080
0081 first = ++second; if (first != last) ++second;
0082 while (second != last) {
0083 if (comp(first, second)) {
0084 if (comp(first, min_result)) {
0085 min_result = first;
0086 potential_min_result = last;
0087 }
0088 if (comp(max_result, second))
0089 max_result = second;
0090 } else {
0091 if (comp(second, min_result)) {
0092 min_result = second;
0093 potential_min_result = first;
0094 }
0095 if (comp(max_result, first))
0096 max_result = first;
0097 }
0098 first = ++second;
0099 if (first != last) ++second;
0100 }
0101
0102
0103 if (first != last) {
0104 if (comp(first, min_result)) {
0105 min_result = first;
0106 potential_min_result = last;
0107 }
0108 else if (comp(max_result, first))
0109 max_result = first;
0110 }
0111
0112
0113
0114 if (potential_min_result != last
0115 && !comp(min_result, potential_min_result))
0116 min_result = potential_min_result;
0117
0118 return std::make_pair(min_result,max_result);
0119 }
0120
0121 }
0122
0123 template <typename ForwardIter>
0124 std::pair<ForwardIter,ForwardIter>
0125 minmax_element(ForwardIter first, ForwardIter last)
0126 {
0127 return detail::basic_minmax_element(first, last,
0128 detail::less_over_iter<ForwardIter>() );
0129 }
0130
0131 template <typename ForwardIter, class BinaryPredicate>
0132 std::pair<ForwardIter,ForwardIter>
0133 minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
0134 {
0135 return detail::basic_minmax_element(first, last,
0136 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0137 }
0138
0139 }
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 namespace boost {
0207
0208
0209
0210 namespace detail {
0211
0212 template <typename ForwardIter, class BinaryPredicate>
0213 ForwardIter
0214 basic_first_min_element(ForwardIter first, ForwardIter last,
0215 BinaryPredicate comp)
0216 {
0217 if (first == last) return last;
0218 ForwardIter min_result = first;
0219 while (++first != last)
0220 if (comp(first, min_result))
0221 min_result = first;
0222 return min_result;
0223 }
0224
0225 template <typename ForwardIter, class BinaryPredicate>
0226 ForwardIter
0227 basic_last_min_element(ForwardIter first, ForwardIter last,
0228 BinaryPredicate comp)
0229 {
0230 if (first == last) return last;
0231 ForwardIter min_result = first;
0232 while (++first != last)
0233 if (!comp(min_result, first))
0234 min_result = first;
0235 return min_result;
0236 }
0237
0238 template <typename ForwardIter, class BinaryPredicate>
0239 ForwardIter
0240 basic_first_max_element(ForwardIter first, ForwardIter last,
0241 BinaryPredicate comp)
0242 {
0243 if (first == last) return last;
0244 ForwardIter max_result = first;
0245 while (++first != last)
0246 if (comp(max_result, first))
0247 max_result = first;
0248 return max_result;
0249 }
0250
0251 template <typename ForwardIter, class BinaryPredicate>
0252 ForwardIter
0253 basic_last_max_element(ForwardIter first, ForwardIter last,
0254 BinaryPredicate comp)
0255 {
0256 if (first == last) return last;
0257 ForwardIter max_result = first;
0258 while (++first != last)
0259 if (!comp(first, max_result))
0260 max_result = first;
0261 return max_result;
0262 }
0263
0264 }
0265
0266 template <typename ForwardIter>
0267 ForwardIter
0268 first_min_element(ForwardIter first, ForwardIter last)
0269 {
0270 return detail::basic_first_min_element(first, last,
0271 detail::less_over_iter<ForwardIter>() );
0272 }
0273
0274 template <typename ForwardIter, class BinaryPredicate>
0275 ForwardIter
0276 first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
0277 {
0278 return detail::basic_first_min_element(first, last,
0279 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0280 }
0281
0282 template <typename ForwardIter>
0283 ForwardIter
0284 last_min_element(ForwardIter first, ForwardIter last)
0285 {
0286 return detail::basic_last_min_element(first, last,
0287 detail::less_over_iter<ForwardIter>() );
0288 }
0289
0290 template <typename ForwardIter, class BinaryPredicate>
0291 ForwardIter
0292 last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
0293 {
0294 return detail::basic_last_min_element(first, last,
0295 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0296 }
0297
0298 template <typename ForwardIter>
0299 ForwardIter
0300 first_max_element(ForwardIter first, ForwardIter last)
0301 {
0302 return detail::basic_first_max_element(first, last,
0303 detail::less_over_iter<ForwardIter>() );
0304 }
0305
0306 template <typename ForwardIter, class BinaryPredicate>
0307 ForwardIter
0308 first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
0309 {
0310 return detail::basic_first_max_element(first, last,
0311 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0312 }
0313
0314 template <typename ForwardIter>
0315 ForwardIter
0316 last_max_element(ForwardIter first, ForwardIter last)
0317 {
0318 return detail::basic_last_max_element(first, last,
0319 detail::less_over_iter<ForwardIter>() );
0320 }
0321
0322 template <typename ForwardIter, class BinaryPredicate>
0323 ForwardIter
0324 last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
0325 {
0326 return detail::basic_last_max_element(first, last,
0327 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0328 }
0329
0330
0331
0332
0333 namespace detail {
0334
0335 template <typename ForwardIter, class BinaryPredicate>
0336 std::pair<ForwardIter,ForwardIter>
0337 basic_first_min_last_max_element(ForwardIter first, ForwardIter last,
0338 BinaryPredicate comp)
0339 {
0340 if (first == last)
0341 return std::make_pair(last,last);
0342
0343 ForwardIter min_result = first;
0344 ForwardIter max_result = first;
0345
0346 ForwardIter second = ++first;
0347 if (second == last)
0348 return std::make_pair(min_result, max_result);
0349
0350 if (comp(second, min_result))
0351 min_result = second;
0352 else
0353 max_result = second;
0354
0355 first = ++second; if (first != last) ++second;
0356 while (second != last) {
0357 if (!comp(second, first)) {
0358 if (comp(first, min_result))
0359 min_result = first;
0360 if (!comp(second, max_result))
0361 max_result = second;
0362 } else {
0363 if (comp(second, min_result))
0364 min_result = second;
0365 if (!comp(first, max_result))
0366 max_result = first;
0367 }
0368 first = ++second; if (first != last) ++second;
0369 }
0370
0371 if (first != last) {
0372 if (comp(first, min_result))
0373 min_result = first;
0374 else if (!comp(first, max_result))
0375 max_result = first;
0376 }
0377
0378 return std::make_pair(min_result, max_result);
0379 }
0380
0381 template <typename ForwardIter, class BinaryPredicate>
0382 std::pair<ForwardIter,ForwardIter>
0383 basic_last_min_first_max_element(ForwardIter first, ForwardIter last,
0384 BinaryPredicate comp)
0385 {
0386 if (first == last) return std::make_pair(last,last);
0387
0388 ForwardIter min_result = first;
0389 ForwardIter max_result = first;
0390
0391 ForwardIter second = ++first;
0392 if (second == last)
0393 return std::make_pair(min_result, max_result);
0394
0395 if (comp(max_result, second))
0396 max_result = second;
0397 else
0398 min_result = second;
0399
0400 first = ++second; if (first != last) ++second;
0401 while (second != last) {
0402 if (comp(first, second)) {
0403 if (!comp(min_result, first))
0404 min_result = first;
0405 if (comp(max_result, second))
0406 max_result = second;
0407 } else {
0408 if (!comp(min_result, second))
0409 min_result = second;
0410 if (comp(max_result, first))
0411 max_result = first;
0412 }
0413 first = ++second; if (first != last) ++second;
0414 }
0415
0416 if (first != last) {
0417 if (!comp(min_result, first))
0418 min_result = first;
0419 else if (comp(max_result, first))
0420 max_result = first;
0421 }
0422
0423 return std::make_pair(min_result, max_result);
0424 }
0425
0426 template <typename ForwardIter, class BinaryPredicate>
0427 std::pair<ForwardIter,ForwardIter>
0428 basic_last_min_last_max_element(ForwardIter first, ForwardIter last,
0429 BinaryPredicate comp)
0430 {
0431 if (first == last) return std::make_pair(last,last);
0432
0433 ForwardIter min_result = first;
0434 ForwardIter max_result = first;
0435
0436 ForwardIter second = first; ++second;
0437 if (second == last)
0438 return std::make_pair(min_result,max_result);
0439
0440 ForwardIter potential_max_result = last;
0441 if (comp(first, second))
0442 max_result = second;
0443 else {
0444 min_result = second;
0445 potential_max_result = second;
0446 }
0447
0448 first = ++second; if (first != last) ++second;
0449 while (second != last) {
0450 if (comp(first, second)) {
0451 if (!comp(min_result, first))
0452 min_result = first;
0453 if (!comp(second, max_result)) {
0454 max_result = second;
0455 potential_max_result = last;
0456 }
0457 } else {
0458 if (!comp(min_result, second))
0459 min_result = second;
0460 if (!comp(first, max_result)) {
0461 max_result = first;
0462 potential_max_result = second;
0463 }
0464 }
0465 first = ++second;
0466 if (first != last) ++second;
0467 }
0468
0469 if (first != last) {
0470 if (!comp(min_result, first))
0471 min_result = first;
0472 if (!comp(first, max_result)) {
0473 max_result = first;
0474 potential_max_result = last;
0475 }
0476 }
0477
0478 if (potential_max_result != last
0479 && !comp(potential_max_result, max_result))
0480 max_result = potential_max_result;
0481
0482 return std::make_pair(min_result,max_result);
0483 }
0484
0485 }
0486
0487 template <typename ForwardIter>
0488 inline std::pair<ForwardIter,ForwardIter>
0489 first_min_first_max_element(ForwardIter first, ForwardIter last)
0490 {
0491 return minmax_element(first, last);
0492 }
0493
0494 template <typename ForwardIter, class BinaryPredicate>
0495 inline std::pair<ForwardIter,ForwardIter>
0496 first_min_first_max_element(ForwardIter first, ForwardIter last,
0497 BinaryPredicate comp)
0498 {
0499 return minmax_element(first, last, comp);
0500 }
0501
0502 template <typename ForwardIter>
0503 std::pair<ForwardIter,ForwardIter>
0504 first_min_last_max_element(ForwardIter first, ForwardIter last)
0505 {
0506 return detail::basic_first_min_last_max_element(first, last,
0507 detail::less_over_iter<ForwardIter>() );
0508 }
0509
0510 template <typename ForwardIter, class BinaryPredicate>
0511 inline std::pair<ForwardIter,ForwardIter>
0512 first_min_last_max_element(ForwardIter first, ForwardIter last,
0513 BinaryPredicate comp)
0514 {
0515 return detail::basic_first_min_last_max_element(first, last,
0516 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0517 }
0518
0519 template <typename ForwardIter>
0520 std::pair<ForwardIter,ForwardIter>
0521 last_min_first_max_element(ForwardIter first, ForwardIter last)
0522 {
0523 return detail::basic_last_min_first_max_element(first, last,
0524 detail::less_over_iter<ForwardIter>() );
0525 }
0526
0527 template <typename ForwardIter, class BinaryPredicate>
0528 inline std::pair<ForwardIter,ForwardIter>
0529 last_min_first_max_element(ForwardIter first, ForwardIter last,
0530 BinaryPredicate comp)
0531 {
0532 return detail::basic_last_min_first_max_element(first, last,
0533 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0534 }
0535
0536 template <typename ForwardIter>
0537 std::pair<ForwardIter,ForwardIter>
0538 last_min_last_max_element(ForwardIter first, ForwardIter last)
0539 {
0540 return detail::basic_last_min_last_max_element(first, last,
0541 detail::less_over_iter<ForwardIter>() );
0542 }
0543
0544 template <typename ForwardIter, class BinaryPredicate>
0545 inline std::pair<ForwardIter,ForwardIter>
0546 last_min_last_max_element(ForwardIter first, ForwardIter last,
0547 BinaryPredicate comp)
0548 {
0549 return detail::basic_last_min_last_max_element(first, last,
0550 detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
0551 }
0552
0553 }
0554
0555 #endif