diff --git a/libc/src/__support/CPP/algorithm.h b/libc/src/__support/CPP/algorithm.h index fef3c18dc50bc8..5120fa0daae17e 100644 --- a/libc/src/__support/CPP/algorithm.h +++ b/libc/src/__support/CPP/algorithm.h @@ -25,6 +25,21 @@ template LIBC_INLINE constexpr const T &min(const T &a, const T &b) { return (a < b) ? a : b; } +template +LIBC_INLINE constexpr InputIt find_if_not(InputIt first, InputIt last, + UnaryPred q) { + for (; first != last; ++first) + if (!q(*first)) + return first; + + return last; +} + +template +LIBC_INLINE constexpr bool all_of(InputIt first, InputIt last, UnaryPred p) { + return find_if_not(first, last, p) == last; +} + } // namespace cpp } // namespace LIBC_NAMESPACE diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt index cec13afc8dd125..2b4d6107b767d3 100644 --- a/libc/test/src/__support/CPP/CMakeLists.txt +++ b/libc/test/src/__support/CPP/CMakeLists.txt @@ -1,5 +1,15 @@ add_custom_target(libc-cpp-utils-tests) +add_libc_test( + algorithm_test + SUITE + libc-cpp-utils-tests + SRCS + algorithm_test.cpp + DEPENDS + libc.src.__support.CPP.algorithm + ) + add_libc_test( array_test SUITE diff --git a/libc/test/src/__support/CPP/algorithm_test.cpp b/libc/test/src/__support/CPP/algorithm_test.cpp new file mode 100644 index 00000000000000..e52e5624e4a6b8 --- /dev/null +++ b/libc/test/src/__support/CPP/algorithm_test.cpp @@ -0,0 +1,47 @@ +//===-- Unittests for Algorithm -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/algorithm.h" +#include "src/__support/CPP/array.h" +#include "test/UnitTest/Test.h" + +// TODO(https://github.com/llvm/llvm-project/issues/94066): Add unittests for +// the remaining algorithm functions. +namespace LIBC_NAMESPACE::cpp { + +TEST(LlvmLibcAlgorithmTest, FindIfNot) { + array nums{1, 2, 3, 4}; + EXPECT_EQ(find_if_not(nums.begin(), nums.end(), [](int i) { return i == 0; }), + nums.begin()); + EXPECT_EQ(find_if_not(nums.begin(), nums.end(), [](int i) { return i == 1; }), + nums.begin() + 1); + EXPECT_EQ(find_if_not(nums.begin(), nums.end(), [](int i) { return i < 4; }), + nums.begin() + 3); + EXPECT_EQ(find_if_not(nums.begin(), nums.end(), [](int i) { return i < 5; }), + nums.end()); + + EXPECT_EQ( + find_if_not(nums.begin() + 1, nums.end(), [](int i) { return i == 0; }), + nums.begin() + 1); + EXPECT_EQ( + find_if_not(nums.begin(), nums.begin(), [](int i) { return i == 0; }), + nums.begin()); +} + +TEST(LlvmLibcAlgorithmTest, AllOf) { + array nums{1, 2, 3, 4}; + EXPECT_TRUE(all_of(nums.begin(), nums.end(), [](int i) { return i < 5; })); + EXPECT_FALSE(all_of(nums.begin(), nums.end(), [](int i) { return i < 4; })); + EXPECT_TRUE( + all_of(nums.begin(), nums.begin() + 3, [](int i) { return i < 4; })); + EXPECT_TRUE( + all_of(nums.begin() + 1, nums.end(), [](int i) { return i > 1; })); + EXPECT_TRUE(all_of(nums.begin(), nums.begin(), [](int i) { return i < 0; })); +} + +} // namespace LIBC_NAMESPACE::cpp