Skip to content

Commit

Permalink
Merge pull request #153 from MarcDirven/dev
Browse files Browse the repository at this point in the history
forEachWhile & CI fix
  • Loading branch information
Kaaserne authored Mar 23, 2024
2 parents 5ee8d81 + 78db984 commit 315a94a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 67 deletions.
46 changes: 30 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
run: cmake -S tests -B build/tests -G Ninja
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache
-D CMAKE_BUILD_TYPE:STRING=Release
-D CPP-LAZY_CATCH_VERSION:STRING=$CATCH_VERSION
-D CPP-LAZY_CATCH_VERSION:STRING=${{ env.CATCH_VERSION }}
-D TEST_INSTALLED_VERSION:BOOL=YES
-D CMAKE_INSTALL_PREFIX=build/prefix
-D CMAKE_CXX_STANDARD:STRING=${{ matrix.standard }}
Expand Down Expand Up @@ -89,13 +89,20 @@ jobs:
env:
CC: clang-${{ matrix.version }}
CXX: clang-${{ matrix.version }}
run: cmake -S . -B build/install -G Ninja
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache
-D CMAKE_CXX_STANDARD:STRING=${{ matrix.standard }}
-D CMAKE_BUILD_TYPE:STRING=Release
-D CMAKE_INSTALL_PREFIX=build/prefix
-D CMAKE_CXX_COMPILER=clang++
-D "CMAKE_PROJECT_FMT_INCLUDE_BEFORE=$(pwd)/cmake/fmtPICFix.cmake"
run: |
if [ "${{ matrix.standard }}" == "20" ]; then
CXX_FLAGS="-stdlib=libc++"
else
CXX_FLAGS=""
fi
cmake -S . -B build/install -G Ninja \
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache \
-D CMAKE_CXX_STANDARD:STRING=${{ matrix.standard }} \
-D "CMAKE_CXX_FLAGS=$CXX_FLAGS" \
-D CMAKE_BUILD_TYPE:STRING=Release \
-D CMAKE_INSTALL_PREFIX=build/prefix \
-D CMAKE_CXX_COMPILER=clang++ \
-D "CMAKE_PROJECT_FMT_INCLUDE_BEFORE=$(pwd)/cmake/fmtPICFix.cmake"
- name: Build (install)
run: cmake --build build/install -j $(nproc)
Expand All @@ -104,14 +111,21 @@ jobs:
run: cmake --install build/install

- name: Configure tests
run: cmake -S tests -B build/tests -G Ninja
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache
-D CMAKE_BUILD_TYPE:STRING=Release
-D CPP-LAZY_CATCH_VERSION:STRING=$CATCH_VERSION
-D TEST_INSTALLED_VERSION:BOOL=YES
-D CMAKE_CXX_COMPILER=clang++
-D CMAKE_INSTALL_PREFIX=build/prefix
-D CMAKE_CXX_STANDARD:STRING=${{ matrix.standard }}
run: |
if [ "${{ matrix.standard }}" == "20" ]; then
CXX_FLAGS="-stdlib=libc++"
else
CXX_FLAGS=""
fi
cmake -S tests -B build/tests -G Ninja \
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache \
-D CMAKE_BUILD_TYPE:STRING=Release \
-D "CMAKE_CXX_FLAGS=$CXX_FLAGS" \
-D CPP-LAZY_CATCH_VERSION:STRING=${{ env.CATCH_VERSION }} \
-D TEST_INSTALLED_VERSION:BOOL=YES \
-D CMAKE_CXX_COMPILER=clang++ \
-D CMAKE_INSTALL_PREFIX=build/prefix \
-D CMAKE_CXX_STANDARD:STRING=${{ matrix.standard }}
- name: Build tests
run: cmake --build build/tests -j $(nproc)
Expand Down
21 changes: 17 additions & 4 deletions examples/FunctionTools.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#include "Lz/FunctionTools.hpp"
#include <Lz/FunctionTools.hpp>

#include <fmt/format.h>
#include <array>
#include <string>
#include <vector>

int main() {
std::vector<int> ints = {1, 2, 3, 4};
Expand Down Expand Up @@ -66,9 +71,6 @@ int main() {
// 3 4
}

int summed = lz::sumTo(50000); // 1 + 2 + 3 + 4 + 5 + ... 50'000
// summed == 1250025000

s = {"hello world", "what's up"};
toFind = "hel";
def = "default";
Expand All @@ -95,4 +97,15 @@ int main() {

std::string trimMe = "\t\t\n trim me \t\t";
fmt::print("{}\n", lz::trimString(trimMe).toString()); // 'trim me'

std::array<int, 10> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lz::forEachWhile(numbers, [](int& i) {
const auto performNextIteration = i < 5;
if (i < 5) {
i = 0;
}
return performNextIteration;
});
fmt::print("{}\n", numbers[3]); // prints 0
fmt::print("{}\n", numbers[4]); // prints 5
}
73 changes: 36 additions & 37 deletions include/Lz/FunctionTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,38 @@ LZ_MODULE_EXPORT_SCOPE_BEGIN
*/
constexpr LZ_INLINE_VAR std::size_t npos = (std::numeric_limits<std::size_t>::max)();

/**
* @brief Keeps iterating over [ @p begin, @p end ) while @p predicate returns true. Essentially the same as lz::filter, however filter is
* not generally used to alter variables in a range
*
* @param begin Beginning of the range
* @param end Ending of the range
* @param predicate Predicate that must either return true or false
*/
template<LZ_CONCEPT_ITERATOR Iterator, class BinaryPredicate>
void forEachWhile(Iterator begin, const Iterator end, BinaryPredicate predicate) {
static_assert(std::is_convertible<internal::Decay<decltype(predicate(*begin))>, bool>::value, "Predicate must return boolean like value");
while (begin != end) {
if (!predicate(*begin)) {
break;
}
++begin;
}
}

/**
* @brief Keeps iterating over @p iterable while @p predicate returns true. Essentially the same as lz::filter, however filter is
* not generally used to alter variables in a range
*
* @param iterable A range
* @param predicate Predicate that must either return true or false
*/
template<LZ_CONCEPT_ITERABLE Iterable, class BinaryPredicate>
void forEachWhile(Iterable&& iterable, BinaryPredicate predicate) {
forEachWhile(internal::begin(std::forward<Iterable>(iterable)), internal::end(std::forward<Iterable>(iterable)),
std::move(predicate));
}

/**
* Returns a StringSplitter iterator, that splits the string on `'\n'`.
* @tparam SubString The string type that the `StringSplitter::value_type` must return. Must either be std::string or
Expand All @@ -65,41 +97,6 @@ LZ_NODISCARD StringSplitter<SubString, String, char> lines(const String& string)
return lz::split<SubString>(string, '\n');
}

/**
* Sums all the values from [from, upToAndIncluding]
* @tparam T An integral value.
* @param from The start to sum from
* @param upToAndIncluding The end of the sum
* @return The result of the sum from [from, upToAndIncluding]
*/
template<class T>
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 T sumTo(const T from, const T upToAndIncluding) {
static_assert(std::is_integral<T>::value, "T must be integral type");
const T fromAbs = from < 0 ? -from : from;
const T toAbs = upToAndIncluding < 0 ? -upToAndIncluding : upToAndIncluding;
const T error = ((fromAbs - 1) * fromAbs) / 2;
const T sum = (toAbs * (toAbs + 1)) / 2;
if (upToAndIncluding < 0) {
return error - sum;
}
if (from < 0) {
return -(error + fromAbs - sum);
}
LZ_ASSERT(from < upToAndIncluding, "`from` cannot be smaller than `upToAndIncluding` if both are positive");
return sum - error;
}

/**
* Sums all the values from [0, upToAndIncluding]
* @tparam T An integral value.
* @param upToAndIncluding The end of the sum
* @return The result of the sum from [0, upToAndIncluding]
*/
template<class T>
LZ_NODISCARD LZ_CONSTEXPR_CXX_14 T sumTo(const T upToAndIncluding) {
return lz::sumTo(0, upToAndIncluding);
}

/**
* The exact opposite of `lines`. It joins a container of `std::string` or `std::string_view` container with `'\n'` as delimiter.
* @param strings The container of `std::string` or `std::string_view`.
Expand Down Expand Up @@ -1300,8 +1297,10 @@ select(Iterator begin, Iterator end, SelectorIterator beginSelector, SelectorIte
* @return A map object that can be iterated over with the excluded elements that `selectors` specify.
*/
template<class Iterable, class SelectorIterable>
Map<internal::FilterIterator<internal::ZipIterator<internal::IterTypeFromIterable<Iterable>,
internal::IterTypeFromIterable<SelectorIterable>>, internal::GetFn<1>>, internal::GetFn<0>>
Map<internal::FilterIterator<
internal::ZipIterator<internal::IterTypeFromIterable<Iterable>, internal::IterTypeFromIterable<SelectorIterable>>,
internal::GetFn<1>>,
internal::GetFn<0>>
select(Iterable&& iterable, SelectorIterable&& selectors) {
return lz::select(internal::begin(std::forward<Iterable>(iterable)), internal::end(std::forward<Iterable>(iterable)),
internal::begin(std::forward<SelectorIterable>(selectors)),
Expand Down
5 changes: 5 additions & 0 deletions include/Lz/Lz.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ class IterView final : public internal::BasicIteratorView<Iterator> {

LZ_CONSTEXPR_CXX_20 IterView() = default;

template<LZ_CONCEPT_ITERABLE Iterable, class BinaryPredicate>
void forEachWhile(Iterable&& iterable, BinaryPredicate&& predicate) {
lz::forEachWhile(std::forward<Iterable>(iterable), std::forward<BinaryPredicate>(predicate));
}

//! See Concatenate.hpp for documentation.
template<LZ_CONCEPT_ITERABLE... Iterables>
LZ_NODISCARD
Expand Down
21 changes: 11 additions & 10 deletions tests/function-tools-tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ TEST_CASE("Function tools") {
CHECK(median == Approx(3.3));
}

SECTION("Sum to") {
CHECK(lz::sumTo(4) == 10);
CHECK(lz::sumTo(5, 10) == 45);
CHECK(lz::sumTo(4, 10) == 49);

CHECK(lz::sumTo(-4) == -10);
CHECK(lz::sumTo(-4, 3) == -4);
CHECK(lz::sumTo(-4, -10) == -49);

CHECK(lz::sumTo(-10, -20) == -165);
SECTION("For each while") {
std::array<int, 10> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lz::forEachWhile(arr, [](int& i) {
const auto performNextIteration = i < 5;
if (performNextIteration) {
i = 0;
}
return performNextIteration;
});
CHECK(arr[4] == 5);
CHECK(arr[3] == 0);
}

SECTION("Keys and values") {
Expand Down

0 comments on commit 315a94a

Please sign in to comment.