1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_FEED_CORE_V2_ALGORITHM_H_
6 #define COMPONENTS_FEED_CORE_V2_ALGORITHM_H_
7 
8 namespace feed {
9 
10 // Compares two sorted ranges. Iterates each range, calling |fn()| for all
11 // items. |fn()| takes the parameters (left_pointer, right_pointer). A null
12 // value is passed in for items not appearing in either the left or right range.
13 // For each call to |fn|, at least one parameter will be non-null.
14 template <typename ITER_A, typename ITER_B, typename VISITOR>
DiffSortedRange(ITER_A left_begin,ITER_A left_end,ITER_B right_begin,ITER_B right_end,VISITOR fn)15 void DiffSortedRange(ITER_A left_begin,
16                      ITER_A left_end,
17                      ITER_B right_begin,
18                      ITER_B right_end,
19                      VISITOR fn) {
20   auto left = left_begin;
21   auto right = right_begin;
22   decltype(&*left) kLeftNull = nullptr;
23   decltype(&*right) kRightNull = nullptr;
24   for (;;) {
25     bool left_at_end = left == left_end, right_at_end = right == right_end;
26     if (left_at_end && right_at_end)
27       break;
28 
29     if (!left_at_end && (right_at_end || *left < *right)) {
30       fn(&*left, kRightNull);
31       ++left;
32       continue;
33     }
34     if (!right_at_end && (left_at_end || *right < *left)) {
35       fn(kLeftNull, &*right);
36       ++right;
37       continue;
38     }
39 
40     fn(&*left, &*right);
41     ++left;
42     ++right;
43   }
44 }
45 
46 }  // namespace feed
47 #endif  // COMPONENTS_FEED_CORE_V2_ALGORITHM_H_
48