Skip to content

Commit

Permalink
Merge branch 'cpp20-support' into lars/fix-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLartians committed Oct 14, 2024
2 parents 174d3ea + a79b099 commit 5981a9c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 40 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ CPMAddPackage(

# ---- Header target ----

FILE(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
add_library(EasyIterator-headers EXCLUDE_FROM_ALL ${headers})
SET_TARGET_PROPERTIES(EasyIterator-headers PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(EasyIterator-headers PROPERTIES LINKER_LANGUAGE CXX)

# ---- Create library ----

Expand Down
91 changes: 56 additions & 35 deletions include/easy_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ namespace easy_iterator {
/**
* Base class for simple iterators. Takes several template parameters.
* Implementations must define `operator++()` to update the value of `value`.
* @param `T` - The data type held by the iterator
* @param `D` - A functional that dereferences the data. Determines the value type of the
* @param `T` - The data type held by the iterator.
* @param `D` - A function that dereferences the data. Determines the value type of the
* iterator.
* @param `C` - A function that compares two values of type `T`. Used to determine if two
* iterators are equal.
Expand Down Expand Up @@ -155,21 +155,35 @@ namespace easy_iterator {
value(std::forward<F>(first)) {}

DereferencedType operator*() { return dereferencer(value); }
auto *operator-> () const { return &**this; }
template <typename... Args> bool operator==(const IteratorPrototype<Args...> &other) const {
return compare(value, other.value);
}
template <typename... Args> bool operator!=(const IteratorPrototype<Args...> &other) const {
return !operator==(other);
}
auto *operator->() const { return &**this; }

template <typename... LArgs, typename... RArgs>
friend bool operator==(const IteratorPrototype<LArgs...> &lhs,
const IteratorPrototype<RArgs...> &rhs);

// required for C++17 or earlier
template <typename... LArgs, typename... RArgs>
friend bool operator!=(const IteratorPrototype<LArgs...> &lhs,
const IteratorPrototype<RArgs...> &rhs);
};

template <class T> IteratorPrototype(const T &)->IteratorPrototype<T>;
template <typename... LArgs, typename... RArgs>
bool operator==(const IteratorPrototype<LArgs...> &lhs, const IteratorPrototype<RArgs...> &rhs) {
return lhs.compare(lhs.value, rhs.value);
}

// required for C++17 or earlier
template <typename... LArgs, typename... RArgs>
bool operator!=(const IteratorPrototype<LArgs...> &lhs, const IteratorPrototype<RArgs...> &rhs) {
return !(lhs == rhs);
}

template <class T> IteratorPrototype(const T &) -> IteratorPrototype<T>;

template <class T, typename D> IteratorPrototype(const T &, const D &)->IteratorPrototype<T, D>;
template <class T, typename D> IteratorPrototype(const T &, const D &) -> IteratorPrototype<T, D>;

template <class T, typename D, typename C>
IteratorPrototype(const T &, const D &, const C &)->IteratorPrototype<T, D, C>;
IteratorPrototype(const T &, const D &, const C &) -> IteratorPrototype<T, D, C>;

namespace iterator_detail {
struct WithState {
Expand All @@ -185,7 +199,7 @@ namespace easy_iterator {
} // namespace iterator_detail

/**
* IteratorPrototype where advance is defined by the functional held by `F`.
* IteratorPrototype where advance is defined by the function held by `F`.
*/
template <class T, typename F = increment::ByValue<1>, typename D = dereference::ByValueReference,
typename C = compare::ByValue>
Expand Down Expand Up @@ -222,16 +236,13 @@ namespace easy_iterator {
}
return Base::dereferencer(Base::value);
}
using Base::operator==;
using Base::operator!=;
bool operator==(const IterationEnd &other) const { return !operator!=(other); }
bool operator!=(const IterationEnd &) const {
if constexpr (Iterator::hasState) {
return Iterator::state;
} else {
return true;
}
}

template <typename... Args>
friend bool operator==(const Iterator<Args...> &lhs, const IterationEnd &);
// required for C++17 or earlier
template <typename... Args>
friend bool operator!=(const Iterator<Args...> &lhs, const IterationEnd &);

explicit operator bool() const {
if constexpr (Iterator::hasState) {
return Iterator::state;
Expand All @@ -241,15 +252,25 @@ namespace easy_iterator {
}
};

template <class T> Iterator(const T &)->Iterator<T>;
template <typename... Args> bool operator==(const Iterator<Args...> &lhs, const IterationEnd &) {
return !static_cast<bool>(lhs);
}

// required for C++17 or earlier
template <typename... Args>
bool operator!=(const Iterator<Args...> &lhs, const IterationEnd &rhs) {
return !(lhs == rhs);
}

template <class T> Iterator(const T &) -> Iterator<T>;

template <class T, typename F> Iterator(const T &, const F &)->Iterator<T, F>;
template <class T, typename F> Iterator(const T &, const F &) -> Iterator<T, F>;

template <class T, typename F, typename D>
Iterator(const T &, const F &, const D &)->Iterator<T, F, D>;
Iterator(const T &, const F &, const D &) -> Iterator<T, F, D>;

template <class T, typename F, typename D, typename C>
Iterator(const T &, const F &, const D &, const C &)->Iterator<T, F, D, C>;
Iterator(const T &, const F &, const D &, const C &) -> Iterator<T, F, D, C>;

template <class T, typename F = increment::ByValue<1>, typename D = dereference::ByValueReference,
typename C = compare::ByValue>
Expand Down Expand Up @@ -310,25 +331,25 @@ namespace easy_iterator {
}

/**
* Returns an iterator that increases it's value from `begin` to `end` by `1` for each step.
* Returns an iterator that increases its value from `begin` to `end` by `1` for each step.
*/
template <class T> auto range(T begin, T end) { return range<T>(begin, end, 1); }

/**
* Returns an iterator that increases it's value from `0` to `end` by `1` for each step.
* Returns an iterator that increases its value from `0` to `end` by `1` for each step.
*/
template <class T> auto range(T end) { return range<T>(0, end); }

/**
* Wrappes the `rbegin` and `rend` iterators.
* Wraps the `rbegin` and `rend` iterators.
*/
template <class T> auto reverse(T &v) { return wrap(v.rbegin(), v.rend()); }

/**
* Returns an iterable object where all argument iterators are traversed simultaneously.
* Behaviour is undefined if the iterators do not have the same length.
*/
template <typename... Args> auto zip(Args &&... args) {
template <typename... Args> auto zip(Args &&...args) {
auto begin = Iterator(std::make_tuple(args.begin()...), increment::ByTupleIncrement(),
dereference::ByTupleDereference(), compare::ByLastTupleElementMatch());
auto end = Iterator(std::make_tuple(args.end()...), increment::ByTupleIncrement(),
Expand All @@ -344,7 +365,7 @@ namespace easy_iterator {
}

/**
* When used as a base class for a iterator type, `MakeIterable` will call the `bool init()`
* When used as a base class for an iterator type, `MakeIterable` will call the `bool init()`
* member before iteration. If `init()` returns false, the iterator is empty.
*/
struct InitializedIterable {};
Expand All @@ -368,7 +389,7 @@ namespace easy_iterator {
auto end() const { return IterationEnd(); }

explicit MakeIterable(T &&value) : start(std::move(value)) {}
template <typename... Args> explicit MakeIterable(Args &&... args)
template <typename... Args> explicit MakeIterable(Args &&...args)
: start(T(std::forward<Args>(args)...)) {}
};

Expand All @@ -380,7 +401,7 @@ namespace easy_iterator {
}

/**
* copy-assigns the given value to every element in a container
* Copy-assigns the given value to every element in a container
*/
template <class T, class A> void fill(A &arr, const T &value) {
for (auto &v : arr) {
Expand All @@ -389,7 +410,7 @@ namespace easy_iterator {
}

/**
* copies values from one container to another.
* Copies values from one container to another.
* @param `a` - the container with values to be copies.
* @param `b` - the target container.
* @param `f` (optional) - a function to transform values before copying.
Expand Down
6 changes: 3 additions & 3 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ include(../cmake/CPM.cmake)
CPMAddPackage(
NAME doctest
GITHUB_REPOSITORY onqtam/doctest
GIT_TAG 2.3.7
GIT_TAG v2.4.11
)

if (TEST_INSTALLED_VERSION)
Expand Down Expand Up @@ -53,11 +53,11 @@ endif()

# ---- Add EasyIteratorTests ----

ENABLE_TESTING()
enable_testing()

# Note: doctest and similar testing frameworks can automatically configure CMake tests
# For other testing frameworks add the tests target instead:
# ADD_TEST(EasyIteratorTests EasyIteratorTests)
# add_test(EasyIteratorTests EasyIteratorTests)

include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake)
doctest_discover_tests(EasyIteratorTests)
Expand Down

0 comments on commit 5981a9c

Please sign in to comment.