merge(3p/absl): subtree merge of Abseil up to e19260f
... notably, this includes Abseil's own StatusOr type, which conflicted with our implementation (that was taken from TensorFlow). Change-Id: Ie7d6764b64055caaeb8dc7b6b9d066291e6b538f
This commit is contained in:
parent
cc27324d02
commit
082c006c04
854 changed files with 11260 additions and 5296 deletions
|
|
@ -24,7 +24,7 @@ load(
|
|||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"]) # Apache 2.0
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "algorithm",
|
||||
|
|
|
|||
|
|
@ -90,10 +90,10 @@ using ContainerPointerType =
|
|||
// lookup of std::begin and std::end, i.e.
|
||||
// using std::begin;
|
||||
// using std::end;
|
||||
// std::foo(begin(c), end(c);
|
||||
// std::foo(begin(c), end(c));
|
||||
// becomes
|
||||
// std::foo(container_algorithm_internal::begin(c),
|
||||
// container_algorithm_internal::end(c));
|
||||
// container_algorithm_internal::end(c));
|
||||
// These are meant for internal use only.
|
||||
|
||||
template <typename C>
|
||||
|
|
@ -188,7 +188,7 @@ bool c_any_of(const C& c, Pred&& pred) {
|
|||
// c_none_of()
|
||||
//
|
||||
// Container-based version of the <algorithm> `std::none_of()` function to
|
||||
// test if no elements in a container fulfil a condition.
|
||||
// test if no elements in a container fulfill a condition.
|
||||
template <typename C, typename Pred>
|
||||
bool c_none_of(const C& c, Pred&& pred) {
|
||||
return std::none_of(container_algorithm_internal::c_begin(c),
|
||||
|
|
@ -340,24 +340,45 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
|
|||
// c_mismatch()
|
||||
//
|
||||
// Container-based version of the <algorithm> `std::mismatch()` function to
|
||||
// return the first element where two ordered containers differ.
|
||||
// return the first element where two ordered containers differ. Applies `==` to
|
||||
// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
|
||||
template <typename C1, typename C2>
|
||||
container_algorithm_internal::ContainerIterPairType<C1, C2>
|
||||
c_mismatch(C1& c1, C2& c2) {
|
||||
return std::mismatch(container_algorithm_internal::c_begin(c1),
|
||||
container_algorithm_internal::c_end(c1),
|
||||
container_algorithm_internal::c_begin(c2));
|
||||
auto first1 = container_algorithm_internal::c_begin(c1);
|
||||
auto last1 = container_algorithm_internal::c_end(c1);
|
||||
auto first2 = container_algorithm_internal::c_begin(c2);
|
||||
auto last2 = container_algorithm_internal::c_end(c2);
|
||||
|
||||
for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
|
||||
// Negates equality because Cpp17EqualityComparable doesn't require clients
|
||||
// to overload both `operator==` and `operator!=`.
|
||||
if (!(*first1 == *first2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(first1, first2);
|
||||
}
|
||||
|
||||
// Overload of c_mismatch() for using a predicate evaluation other than `==` as
|
||||
// the function's test condition.
|
||||
// the function's test condition. Applies `pred`to the first N elements of `c1`
|
||||
// and `c2`, where N = min(size(c1), size(c2)).
|
||||
template <typename C1, typename C2, typename BinaryPredicate>
|
||||
container_algorithm_internal::ContainerIterPairType<C1, C2>
|
||||
c_mismatch(C1& c1, C2& c2, BinaryPredicate&& pred) {
|
||||
return std::mismatch(container_algorithm_internal::c_begin(c1),
|
||||
container_algorithm_internal::c_end(c1),
|
||||
container_algorithm_internal::c_begin(c2),
|
||||
std::forward<BinaryPredicate>(pred));
|
||||
c_mismatch(C1& c1, C2& c2, BinaryPredicate pred) {
|
||||
auto first1 = container_algorithm_internal::c_begin(c1);
|
||||
auto last1 = container_algorithm_internal::c_end(c1);
|
||||
auto first2 = container_algorithm_internal::c_begin(c2);
|
||||
auto last2 = container_algorithm_internal::c_end(c2);
|
||||
|
||||
for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
|
||||
if (!pred(*first1, *first2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(first1, first2);
|
||||
}
|
||||
|
||||
// c_equal()
|
||||
|
|
@ -539,12 +560,20 @@ BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest) {
|
|||
// c_swap_ranges()
|
||||
//
|
||||
// Container-based version of the <algorithm> `std::swap_ranges()` function to
|
||||
// swap a container's elements with another container's elements.
|
||||
// swap a container's elements with another container's elements. Swaps the
|
||||
// first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
|
||||
template <typename C1, typename C2>
|
||||
container_algorithm_internal::ContainerIter<C2> c_swap_ranges(C1& c1, C2& c2) {
|
||||
return std::swap_ranges(container_algorithm_internal::c_begin(c1),
|
||||
container_algorithm_internal::c_end(c1),
|
||||
container_algorithm_internal::c_begin(c2));
|
||||
auto first1 = container_algorithm_internal::c_begin(c1);
|
||||
auto last1 = container_algorithm_internal::c_end(c1);
|
||||
auto first2 = container_algorithm_internal::c_begin(c2);
|
||||
auto last2 = container_algorithm_internal::c_end(c2);
|
||||
|
||||
using std::swap;
|
||||
for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
|
||||
swap(*first1, *first2);
|
||||
}
|
||||
return first2;
|
||||
}
|
||||
|
||||
// c_transform()
|
||||
|
|
@ -562,16 +591,23 @@ OutputIterator c_transform(const InputSequence& input, OutputIterator output,
|
|||
}
|
||||
|
||||
// Overload of c_transform() for performing a transformation using a binary
|
||||
// predicate.
|
||||
// predicate. Applies `binary_op` to the first N elements of `c1` and `c2`,
|
||||
// where N = min(size(c1), size(c2)).
|
||||
template <typename InputSequence1, typename InputSequence2,
|
||||
typename OutputIterator, typename BinaryOp>
|
||||
OutputIterator c_transform(const InputSequence1& input1,
|
||||
const InputSequence2& input2, OutputIterator output,
|
||||
BinaryOp&& binary_op) {
|
||||
return std::transform(container_algorithm_internal::c_begin(input1),
|
||||
container_algorithm_internal::c_end(input1),
|
||||
container_algorithm_internal::c_begin(input2), output,
|
||||
std::forward<BinaryOp>(binary_op));
|
||||
auto first1 = container_algorithm_internal::c_begin(input1);
|
||||
auto last1 = container_algorithm_internal::c_end(input1);
|
||||
auto first2 = container_algorithm_internal::c_begin(input2);
|
||||
auto last2 = container_algorithm_internal::c_end(input2);
|
||||
for (; first1 != last1 && first2 != last2;
|
||||
++first1, (void)++first2, ++output) {
|
||||
*output = binary_op(*first1, *first2);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// c_replace()
|
||||
|
|
|
|||
|
|
@ -57,9 +57,7 @@ class NonMutatingTest : public testing::Test {
|
|||
};
|
||||
|
||||
struct AccumulateCalls {
|
||||
void operator()(int value) {
|
||||
calls.push_back(value);
|
||||
}
|
||||
void operator()(int value) { calls.push_back(value); }
|
||||
std::vector<int> calls;
|
||||
};
|
||||
|
||||
|
|
@ -68,7 +66,6 @@ bool BinPredicate(int v1, int v2) { return v1 < v2; }
|
|||
bool Equals(int v1, int v2) { return v1 == v2; }
|
||||
bool IsOdd(int x) { return x % 2 != 0; }
|
||||
|
||||
|
||||
TEST_F(NonMutatingTest, Distance) {
|
||||
EXPECT_EQ(container_.size(), absl::c_distance(container_));
|
||||
EXPECT_EQ(sequence_.size(), absl::c_distance(sequence_));
|
||||
|
|
@ -151,13 +148,90 @@ TEST_F(NonMutatingTest, CountIf) {
|
|||
}
|
||||
|
||||
TEST_F(NonMutatingTest, Mismatch) {
|
||||
absl::c_mismatch(container_, sequence_);
|
||||
absl::c_mismatch(sequence_, container_);
|
||||
// Testing necessary as absl::c_mismatch executes logic.
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_);
|
||||
EXPECT_EQ(result.first, vector_.end());
|
||||
EXPECT_EQ(result.second, sequence_.end());
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_);
|
||||
EXPECT_EQ(result.first, sequence_.end());
|
||||
EXPECT_EQ(result.second, vector_.end());
|
||||
}
|
||||
|
||||
sequence_.back() = 5;
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_);
|
||||
EXPECT_EQ(result.first, std::prev(vector_.end()));
|
||||
EXPECT_EQ(result.second, std::prev(sequence_.end()));
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_);
|
||||
EXPECT_EQ(result.first, std::prev(sequence_.end()));
|
||||
EXPECT_EQ(result.second, std::prev(vector_.end()));
|
||||
}
|
||||
|
||||
sequence_.pop_back();
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_);
|
||||
EXPECT_EQ(result.first, std::prev(vector_.end()));
|
||||
EXPECT_EQ(result.second, sequence_.end());
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_);
|
||||
EXPECT_EQ(result.first, sequence_.end());
|
||||
EXPECT_EQ(result.second, std::prev(vector_.end()));
|
||||
}
|
||||
{
|
||||
struct NoNotEquals {
|
||||
constexpr bool operator==(NoNotEquals) const { return true; }
|
||||
constexpr bool operator!=(NoNotEquals) const = delete;
|
||||
};
|
||||
std::vector<NoNotEquals> first;
|
||||
std::list<NoNotEquals> second;
|
||||
|
||||
// Check this still compiles.
|
||||
absl::c_mismatch(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(NonMutatingTest, MismatchWithPredicate) {
|
||||
absl::c_mismatch(container_, sequence_, BinPredicate);
|
||||
absl::c_mismatch(sequence_, container_, BinPredicate);
|
||||
// Testing necessary as absl::c_mismatch executes logic.
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_, BinPredicate);
|
||||
EXPECT_EQ(result.first, vector_.begin());
|
||||
EXPECT_EQ(result.second, sequence_.begin());
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_, BinPredicate);
|
||||
EXPECT_EQ(result.first, sequence_.begin());
|
||||
EXPECT_EQ(result.second, vector_.begin());
|
||||
}
|
||||
|
||||
sequence_.front() = 0;
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_, BinPredicate);
|
||||
EXPECT_EQ(result.first, vector_.begin());
|
||||
EXPECT_EQ(result.second, sequence_.begin());
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_, BinPredicate);
|
||||
EXPECT_EQ(result.first, std::next(sequence_.begin()));
|
||||
EXPECT_EQ(result.second, std::next(vector_.begin()));
|
||||
}
|
||||
|
||||
sequence_.clear();
|
||||
{
|
||||
auto result = absl::c_mismatch(vector_, sequence_, BinPredicate);
|
||||
EXPECT_EQ(result.first, vector_.begin());
|
||||
EXPECT_EQ(result.second, sequence_.end());
|
||||
}
|
||||
{
|
||||
auto result = absl::c_mismatch(sequence_, vector_, BinPredicate);
|
||||
EXPECT_EQ(result.first, sequence_.end());
|
||||
EXPECT_EQ(result.second, vector_.begin());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(NonMutatingTest, Equal) {
|
||||
|
|
@ -519,11 +593,9 @@ TEST_F(SortingTest, IsSortedUntil) {
|
|||
TEST_F(SortingTest, NthElement) {
|
||||
std::vector<int> unsorted = {2, 4, 1, 3};
|
||||
absl::c_nth_element(unsorted, unsorted.begin() + 2);
|
||||
EXPECT_THAT(unsorted,
|
||||
ElementsAre(Lt(3), Lt(3), 3, Gt(3)));
|
||||
EXPECT_THAT(unsorted, ElementsAre(Lt(3), Lt(3), 3, Gt(3)));
|
||||
absl::c_nth_element(unsorted, unsorted.begin() + 2, std::greater<int>());
|
||||
EXPECT_THAT(unsorted,
|
||||
ElementsAre(Gt(2), Gt(2), 2, Lt(2)));
|
||||
EXPECT_THAT(unsorted, ElementsAre(Gt(2), Gt(2), 2, Lt(2)));
|
||||
}
|
||||
|
||||
TEST(MutatingTest, IsPartitioned) {
|
||||
|
|
@ -676,6 +748,15 @@ TEST(MutatingTest, SwapRanges) {
|
|||
absl::c_swap_ranges(odds, evens);
|
||||
EXPECT_THAT(odds, ElementsAre(1, 3, 5));
|
||||
EXPECT_THAT(evens, ElementsAre(2, 4, 6));
|
||||
|
||||
odds.pop_back();
|
||||
absl::c_swap_ranges(odds, evens);
|
||||
EXPECT_THAT(odds, ElementsAre(2, 4));
|
||||
EXPECT_THAT(evens, ElementsAre(1, 3, 6));
|
||||
|
||||
absl::c_swap_ranges(evens, odds);
|
||||
EXPECT_THAT(odds, ElementsAre(1, 3));
|
||||
EXPECT_THAT(evens, ElementsAre(2, 4, 6));
|
||||
}
|
||||
|
||||
TEST_F(NonMutatingTest, Transform) {
|
||||
|
|
@ -690,6 +771,20 @@ TEST_F(NonMutatingTest, Transform) {
|
|||
EXPECT_EQ(std::vector<int>({1, 5, 4}), z);
|
||||
*end = 7;
|
||||
EXPECT_EQ(std::vector<int>({1, 5, 4, 7}), z);
|
||||
|
||||
z.clear();
|
||||
y.pop_back();
|
||||
end = absl::c_transform(x, y, std::back_inserter(z), std::plus<int>());
|
||||
EXPECT_EQ(std::vector<int>({1, 5}), z);
|
||||
*end = 7;
|
||||
EXPECT_EQ(std::vector<int>({1, 5, 7}), z);
|
||||
|
||||
z.clear();
|
||||
std::swap(x, y);
|
||||
end = absl::c_transform(x, y, std::back_inserter(z), std::plus<int>());
|
||||
EXPECT_EQ(std::vector<int>({1, 5}), z);
|
||||
*end = 7;
|
||||
EXPECT_EQ(std::vector<int>({1, 5, 7}), z);
|
||||
}
|
||||
|
||||
TEST(MutatingTest, Replace) {
|
||||
|
|
@ -755,10 +850,9 @@ MATCHER_P2(IsElement, key, value, "") {
|
|||
TEST(MutatingTest, StableSort) {
|
||||
std::vector<Element> test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}};
|
||||
absl::c_stable_sort(test_vector);
|
||||
EXPECT_THAT(
|
||||
test_vector,
|
||||
ElementsAre(IsElement(1, 1), IsElement(1, 0), IsElement(2, 1),
|
||||
IsElement(2, 0), IsElement(2, 2)));
|
||||
EXPECT_THAT(test_vector,
|
||||
ElementsAre(IsElement(1, 1), IsElement(1, 0), IsElement(2, 1),
|
||||
IsElement(2, 0), IsElement(2, 2)));
|
||||
}
|
||||
|
||||
TEST(MutatingTest, StableSortWithPredicate) {
|
||||
|
|
@ -766,10 +860,9 @@ TEST(MutatingTest, StableSortWithPredicate) {
|
|||
absl::c_stable_sort(test_vector, [](const Element& e1, const Element& e2) {
|
||||
return e2 < e1;
|
||||
});
|
||||
EXPECT_THAT(
|
||||
test_vector,
|
||||
ElementsAre(IsElement(2, 1), IsElement(2, 0), IsElement(2, 2),
|
||||
IsElement(1, 1), IsElement(1, 0)));
|
||||
EXPECT_THAT(test_vector,
|
||||
ElementsAre(IsElement(2, 1), IsElement(2, 0), IsElement(2, 2),
|
||||
IsElement(1, 1), IsElement(1, 0)));
|
||||
}
|
||||
|
||||
TEST(MutatingTest, ReplaceCopyIf) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue