diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6336797..a25f735 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake)
-set(BLT_VERSION 1.0.6)
+set(BLT_VERSION 1.1.1)
set(BLT_TARGET BLT)
diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h
new file mode 100644
index 0000000..6fa91b8
--- /dev/null
+++ b/include/blt/iterator/common.h
@@ -0,0 +1,130 @@
+#pragma once
+/*
+ * Copyright (C) 2024 Brett Terpstra
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef BLT_ITERATOR_ITER_COMMON
+#define BLT_ITERATOR_ITER_COMMON
+
+#include
+#include
+
+namespace blt::iterator
+{
+ template
+ struct wrapper_base
+ {
+ wrapper_base operator++(int)
+ {
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ wrapper_base operator--(int)
+ {
+ static_assert(std::is_same_v ||
+ std::is_same_v,
+ "Iterator must allow random access");
+ auto tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ auto operator[](blt::ptrdiff_t n) const
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ return *(*this + n);
+ }
+
+ friend wrapper_base operator+(const wrapper_base& a, blt::ptrdiff_t n)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ auto copy = a;
+ copy += n;
+ return copy;
+ }
+
+ friend wrapper_base operator+(blt::ptrdiff_t n, const wrapper_base& a)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ auto copy = a;
+ copy += n;
+ return copy;
+ }
+
+ friend wrapper_base operator-(const wrapper_base& a, blt::ptrdiff_t n)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ auto copy = a;
+ copy -= n;
+ return copy;
+ }
+
+ friend wrapper_base operator-(blt::ptrdiff_t n, const wrapper_base& a)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ auto copy = a;
+ copy -= n;
+ return copy;
+ }
+
+ friend bool operator<(const wrapper_base& a, const wrapper_base& b)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ return b - a > 0;
+ }
+
+ friend bool operator>(const wrapper_base& a, const wrapper_base& b)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ return b < a;
+ }
+
+ friend bool operator>=(const wrapper_base& a, wrapper_base& b)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ return !(a < b); // NOLINT
+ }
+
+ friend bool operator<=(const wrapper_base& a, const wrapper_base& b)
+ {
+ static_assert(std::is_same_v,
+ "Iterator must allow random access");
+ return !(a > b); // NOLINT
+ }
+
+ friend bool operator==(const wrapper_base& a, const wrapper_base& b)
+ {
+ return a.base() == b.base();
+ }
+
+ friend bool operator!=(const wrapper_base& a, const wrapper_base& b)
+ {
+ return !(a.base() == b.base()); // NOLINT
+ }
+ };
+}
+
+#endif //BLT_ITERATOR_ITER_COMMON
diff --git a/include/blt/iterator/iter_common.h b/include/blt/iterator/iter_common.h
deleted file mode 100644
index 89f020e..0000000
--- a/include/blt/iterator/iter_common.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2024 Brett Terpstra
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef BLT_ITERATOR_ITER_COMMON
-#define BLT_ITERATOR_ITER_COMMON
-
-#include
-#include
-
-namespace blt
-{
-
-}
-
-#endif //BLT_ITERATOR_ITER_COMMON
diff --git a/include/blt/iterator/iterator.h b/include/blt/iterator/iterator.h
index 51c4cfc..96400eb 100644
--- a/include/blt/iterator/iterator.h
+++ b/include/blt/iterator/iterator.h
@@ -21,7 +21,7 @@
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h
index b4e6efb..f5fd24b 100644
--- a/include/blt/iterator/zip.h
+++ b/include/blt/iterator/zip.h
@@ -19,7 +19,7 @@
#ifndef BLT_ITERATOR_ZIP
#define BLT_ITERATOR_ZIP
-#include
+#include
#include
#include
#include
@@ -28,14 +28,11 @@ namespace blt
{
namespace iterator
{
- template
- class zip_wrapper;
-
template
- class zip_wrapper
+ class zip_wrapper : public wrapper_base>
{
public:
- using iterator_category = std::input_iterator_tag;
+ using iterator_category = meta::lowest_iterator_category_t;
using value_type = std::tuple...>;
using difference_type = blt::ptrdiff_t;
using pointer = value_type;
@@ -49,99 +46,18 @@ namespace blt
return std::apply([](auto& ... i) { return std::tuple...>{*i...}; }, iter);
}
- friend bool operator==(const zip_wrapper& a, const zip_wrapper& b)
- {
- return a.iter == b.iter;
- }
-
- friend bool operator!=(const zip_wrapper& a, const zip_wrapper& b)
- {
- return !(a.iter == b.iter);
- }
-
zip_wrapper& operator++()
{
std::apply([](auto& ... i) { ((++i), ...); }, iter);
return *this;
}
- zip_wrapper operator++(int)
- {
- auto tmp = *this;
- ++*this;
- return tmp;
- }
-
- auto raw_tuple()
- {
- return iter;
- }
-
- protected:
- std::tuple iter;
- };
-
- template
- class zip_wrapper : public zip_wrapper
- {
- public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = std::tuple...>;
- using difference_type = blt::ptrdiff_t;
- using pointer = value_type;
- using reference = value_type;
-
- using zip_wrapper::zip_wrapper;
- };
-
- template
- class zip_wrapper : public zip_wrapper
- {
- public:
- using iterator_category = std::bidirectional_iterator_tag;
- using value_type = std::tuple...>;
- using difference_type = blt::ptrdiff_t;
- using pointer = value_type;
- using reference = value_type;
- public:
- using zip_wrapper::zip_wrapper;
-
zip_wrapper& operator--()
{
std::apply([](auto& ... i) { ((--i), ...); }, this->iter);
return *this;
}
- zip_wrapper operator--(int)
- {
- auto tmp = *this;
- --*this;
- return tmp;
- }
- };
-
- template
- class zip_wrapper : public zip_wrapper
- {
- public:
- using iterator_category = std::random_access_iterator_tag;
- using value_type = std::tuple...>;
- using difference_type = blt::ptrdiff_t;
- using pointer = value_type;
- using reference = value_type;
- private:
- template
- static blt::ptrdiff_t sub(const zip_wrapper& a, const zip_wrapper& b,
- std::integer_sequence)
- {
- blt::ptrdiff_t min = std::numeric_limits::max();
- ((min = std::min(min, std::get(a.iter) - std::get(b.iter))), ...);
- return min;
- }
-
- public:
- using zip_wrapper::zip_wrapper;
-
zip_wrapper& operator+=(blt::ptrdiff_t n)
{
std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter);
@@ -154,54 +70,26 @@ namespace blt
return *this;
}
- friend zip_wrapper operator+(const zip_wrapper& a, blt::ptrdiff_t n)
- {
- return std::apply([n](auto& ... i) { return zip_wrapper{(i + n)...}; }, a.iter);
- }
-
- friend zip_wrapper operator+(blt::ptrdiff_t n, const zip_wrapper& a)
- {
- return std::apply([n](auto& ... i) { return zip_wrapper{(i + n)...}; }, a.iter);
- }
-
- friend zip_wrapper operator-(const zip_wrapper& a, blt::ptrdiff_t n)
- {
- return std::apply([n](auto& ... i) { return zip_wrapper{(i - n)...}; }, a.iter);
- }
-
- friend zip_wrapper operator-(blt::ptrdiff_t n, const zip_wrapper& a)
- {
- return std::apply([n](auto& ... i) { return zip_wrapper{(i - n)...}; }, a.iter);
- }
-
friend blt::ptrdiff_t operator-(const zip_wrapper& a, const zip_wrapper& b)
{
return sub(a, b, std::index_sequence_for());
}
- auto operator[](blt::ptrdiff_t n) const
+ auto base()
{
- return *(*this + n);
+ return iter;
}
+
+ protected:
+ std::tuple iter;
- friend bool operator<(const zip_wrapper& a, const zip_wrapper& b)
+ template
+ static blt::ptrdiff_t sub(const zip_wrapper& a, const zip_wrapper& b,
+ std::integer_sequence)
{
- return b - a > 0;
- }
-
- friend bool operator>(const zip_wrapper& a, const zip_wrapper& b)
- {
- return b < a;
- }
-
- friend bool operator>=(const zip_wrapper& a, const zip_wrapper& b)
- {
- return !(a < b); // NOLINT
- }
-
- friend bool operator<=(const zip_wrapper& a, const zip_wrapper& b)
- {
- return !(a > b); // NOLINT
+ blt::ptrdiff_t min = std::numeric_limits::max();
+ ((min = std::min(min, std::get(a.iter) - std::get(b.iter))), ...);
+ return min;
}
};
@@ -294,7 +182,8 @@ namespace blt
{
for (blt::size_t i = 0; i < n; i++)
{
- if constexpr (check){
+ if constexpr (check)
+ {
if (begin == end)
break;
}
@@ -341,7 +230,7 @@ namespace blt
m_begins(std::move(iterator_pairs.begin)...), m_ends(std::move(iterator_pairs.end)...)
{}
- zip_iterator_storage(iterator::zip_wrapper begins, iterator::zip_wrapper ends):
+ zip_iterator_storage(iterator::zip_wrapper begins, iterator::zip_wrapper ends):
m_begins(std::move(begins)), m_ends(std::move(ends))
{}
@@ -372,8 +261,8 @@ namespace blt
}
private:
- iterator::zip_wrapper m_begins;
- iterator::zip_wrapper m_ends;
+ iterator::zip_wrapper m_begins;
+ iterator::zip_wrapper m_ends;
};
template
@@ -389,8 +278,8 @@ namespace blt
"reverse iteration is only supported on bidirectional or better iterators!");
}
- zip_iterator_storage_rev(iterator::zip_wrapper begins,
- iterator::zip_wrapper ends): m_begins(std::move(begins)), m_ends(std::move(ends))
+ zip_iterator_storage_rev(iterator::zip_wrapper begins,
+ iterator::zip_wrapper ends): m_begins(std::move(begins)), m_ends(std::move(ends))
{
static_assert((std::is_same_v ||
std::is_same_v),
@@ -413,8 +302,8 @@ namespace blt
}
private:
- std::reverse_iterator> m_begins;
- std::reverse_iterator> m_ends;
+ std::reverse_iterator> m_begins;
+ std::reverse_iterator> m_ends;
};
/*
diff --git a/tests/iterator_tests.cpp b/tests/iterator_tests.cpp
index e5a4a35..0ee82fc 100644
--- a/tests/iterator_tests.cpp
+++ b/tests/iterator_tests.cpp
@@ -126,17 +126,17 @@ void test_pairs()
void test_zip()
{
blt::log_box_t box(std::cout, "Zip Tests", 25);
- for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3))
+ for (auto [a1, a2, a3] : blt::zip(array_1, array_2, list_1))
{
BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n";
}
BLT_TRACE("================================");
- for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).take(3))
+ for (auto [a1, a2, a3] : blt::zip(array_1, array_2, list_1).take(3))
{
BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n";
}
BLT_TRACE("================================");
- for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).take(3).rev())
+ for (auto [a1, a2, a3] : blt::zip(array_1, array_2, list_1).take(3).rev())
{
BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n";
}