diff --git a/include/blt/iterator/iter_common.h b/include/blt/iterator/iter_common.h new file mode 100644 index 0000000..89f020e --- /dev/null +++ b/include/blt/iterator/iter_common.h @@ -0,0 +1,30 @@ +#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 new file mode 100644 index 0000000..5f9e9a7 --- /dev/null +++ b/include/blt/iterator/iterator.h @@ -0,0 +1,885 @@ +#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_H +#define BLT_ITERATOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace blt +{ + + // forward declare useful types + template> + class enumerator; + + template> + class enumerator_rev; + + template> + class pair_iterator; + + template> + class pair_iterator_rev; + + template + class zip_iterator; + + template + class zip_iterator_rev; + + namespace iterator + { + template> + class enumerate_wrapper; + + template> + class pair_wrapper; + + template + class zip_wrapper; + + template + class zip_iterator_storage; + + template + class zip_iterator_storage_rev; + + template + class zip_forward_iterator + { + public: + explicit zip_forward_iterator(Iter... iter): iter(std::make_tuple(iter...)) + {} + + std::tuple...> operator*() const + { + return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter); + } + + friend bool operator==(const zip_forward_iterator& a, const zip_forward_iterator& b) + { + return a.iter == b.iter; + } + + friend bool operator!=(const zip_forward_iterator& a, const zip_forward_iterator& b) + { + return !(a.iter == b.iter); + } + + zip_forward_iterator& operator++() + { + std::apply([](auto& ... i) { ((++i), ...); }, iter); + return *this; + } + + zip_forward_iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + auto base() + { + return iter; + } + + protected: + std::tuple iter; + }; + + template + class zip_bidirectional_iterator : public zip_forward_iterator + { + public: + using zip_forward_iterator::zip_forward_iterator; + + zip_bidirectional_iterator& operator--() + { + std::apply([](auto& ... i) { ((--i), ...); }, this->iter); + return *this; + } + + zip_bidirectional_iterator operator--(int) + { + auto tmp = *this; + --*this; + return tmp; + } + }; + + template + class zip_wrapper : public zip_forward_iterator + { + public: + using zip_forward_iterator::zip_forward_iterator; + + 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; + }; + + template + class zip_wrapper : public zip_bidirectional_iterator + { + public: + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + 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; + }; + + template + class zip_wrapper : public zip_bidirectional_iterator + { + public: + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + 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; + }; + + /** + * struct which is returned by the enumerator. + * @tparam T type to store. + */ + template + struct enumerate_item + { + blt::size_t index; + T value; + }; + + /** + * base class for iterators which operate on pairs of values. Handles comparison. + * @tparam Iter1 first iterator type. this will be used for comparison. + * @tparam Iter2 second iterator type. this value is not modified by this class. + */ + template + class dual_iterator_base + { + public: + explicit dual_iterator_base(Iter1 iter1, Iter2 iter2): m_iter1(std::move(iter1)), m_iter2(std::move(iter2)) + {} + + friend bool operator==(const dual_iterator_base& a, const dual_iterator_base& b) + { + return a.m_iter1 == b.m_iter1; + } + + friend bool operator!=(const dual_iterator_base& a, const dual_iterator_base& b) + { + return a.m_iter1 != b.m_iter1; + } + + auto iter1() const + { + return m_iter1; + } + + auto iter2() const + { + return m_iter2; + } + + protected: + Iter1 m_iter1; + Iter2 m_iter2; + }; + + /** + * Base class for all enumerator iterators. Handles the deference (*) operator. + * @tparam Iter iterator type + */ + template + class enumerate_iterator_base : public dual_iterator_base + { + public: + explicit enumerate_iterator_base(Iter iter, blt::size_t place = 0): + dual_iterator_base(std::move(iter), place) + {} + + enumerate_item> operator*() const + { + return {this->m_iter2, *this->m_iter1}; + } + }; + + template + class pair_iterator_base : public dual_iterator_base + { + public: + using dual_iterator_base::dual_iterator_base; + + std::pair, blt::meta::deref_return_t> operator*() const + { + return {*this->m_iter1, *this->m_iter2}; + } + }; + + /** + * Forward iterator base class. Contains the ++ operator. + * @tparam Base iterator base type. + */ + template + class forward_iterator_base : public Base + { + public: + using Base::Base; + + forward_iterator_base& operator++() + { + ++this->m_iter1; + ++this->m_iter2; + return *this; + } + + forward_iterator_base operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + }; + + /** + * Bidirectional iterator base class. Contains the -- operator. + * @tparam Base iterator base type. + */ + template + class bidirectional_iterator_base : public Base + { + public: + using Base::Base; + + bidirectional_iterator_base& operator--() + { + --this->m_iter1; + --this->m_iter2; + return *this; + } + + bidirectional_iterator_base operator--(int) + { + auto tmp = *this; + --*this; + return tmp; + } + }; + + template + using enumerate_forward_iterator = forward_iterator_base>; + + template + using enumerate_bidirectional_iterator = bidirectional_iterator_base>; + + template + using pair_forward_iterator = forward_iterator_base>; + + template + using pair_bidirectional_iterator = bidirectional_iterator_base>; + + /** + * Enumerator wrapper class specialization for forward iterators. + * @tparam Iter iterator type + */ + template + class enumerate_wrapper, std::void_t>> + : public enumerate_forward_iterator + { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = enumerate_item>; + using difference_type = typename std::iterator_traits::difference_type; + using pointer = value_type; + using reference = value_type; + + using enumerate_forward_iterator::enumerate_forward_iterator; + }; + + /** + * Pair wrapper class specialization for forward iterators. + * @tparam Iter iterator type + */ + template + class pair_wrapper>, + std::void_t>> : public pair_forward_iterator + { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = std::pair, blt::meta::deref_return_t>; + using difference_type = std::common_type_t::difference_type, typename std::iterator_traits::difference_type>; + using pointer = value_type; + using reference = value_type; + + using pair_forward_iterator::pair_forward_iterator; + }; + + /** + * Enumerator wrapper class for bidirectional iterators or random access iterators. + * @tparam Iter iterator type. + */ + template + class enumerate_wrapper, std::void_t>> + : public enumerate_bidirectional_iterator + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = enumerate_item>; + using difference_type = typename std::iterator_traits::difference_type; + using pointer = value_type; + using reference = value_type; + + using enumerate_bidirectional_iterator::enumerate_bidirectional_iterator; + }; + + /** + * Pair wrapper class for bidirectional iterators or random access iterators. + * @tparam Iter iterator type. + */ + template + class pair_wrapper>, + std::void_t>> : public pair_bidirectional_iterator + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair, blt::meta::deref_return_t>; + using difference_type = std::common_type_t::difference_type, typename std::iterator_traits::difference_type>; + using pointer = value_type; + using reference = value_type; + + using pair_bidirectional_iterator::pair_bidirectional_iterator; + }; + + /** + * Base class for storing begin/end iterators. + * @tparam IterWrapper wrapper used to iterate + * @tparam CompleteClass completed class returned from skip/take methods + */ + template + class iterator_storage_base + { + public: + explicit iterator_storage_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) + {} + + auto begin() + { + return begin_; + } + + auto end() + { + return end_; + } + + /** + * Creates an enumerator that skips the first n elements. + * @param amount amount of values to skip. + */ + auto skip(blt::size_t amount) + { + auto begin = this->begin_; + for (blt::size_t i = 0; i < amount; i++) + ++begin; + return CompleteClass{begin.iter1(), + this->end_.iter1(), + begin.iter2(), + this->end_.iter2()}; + } + + /** + * Creates an enumerator that yields the first n elements, or UB if the underlying iterator ends sooner. + * @param amount amount to take. + */ + auto take(blt::size_t amount) + { + auto end = this->begin(); + for (blt::size_t i = 0; i < amount; i++) + ++end; + return CompleteClass{this->begin_.iter1(), + end.iter1(), + this->begin_.iter2(), + end.iter2()}; + } + + protected: + IterWrapper begin_; + IterWrapper end_; + }; + + /** + * Reversible (bidirectional) base class storing the begin / end iterators. + * @tparam Iter iterator type. + * @tparam IterWrapper wrapper used to iterate. + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev + */ + template + class iterator_storage_reversible : public iterator_storage_base + { + public: + explicit iterator_storage_reversible(IterWrapper begin, IterWrapper end): + iterator_storage_base{std::move(begin), std::move(end)} + {} + + /** + * Reverses the enumerator’s direction. + */ + auto rev() const + { + return CompleteClassRev{this->end_.iter1(), + this->begin_.iter1(), + this->end_.iter2(), + this->begin_.iter2()}; + } + }; + + /** + * Random access base class storage for begin/end iterators. + * Has updated skip and take methods which make use of the random access nature of the iterator. + * @tparam Iter iterator type. + * @tparam IterWrapper wrapper used to iterate. + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev + */ + template + class iterator_storage_random_access : public iterator_storage_reversible + { + public: + using iterator_storage_reversible::iterator_storage_reversible; + + auto skip(blt::size_t amount) + { + return CompleteClass{this->begin_.iter1() + amount, + this->end_.iter1(), + this->begin_.iter2() + amount, + this->end_.iter2()}; + } + + auto take(blt::size_t amount) + { + return CompleteClass{this->begin_.iter1(), + this->begin_.iter1() + amount, + this->begin_.iter2(), + this->begin_.iter2() + amount}; + } + }; + + /** + * Reversible (bidirectional) base class for storing the begin/end iterators, operates in reverse for reverse iteration. + * @tparam Iter iterator type. + * @tparam IterWrapper wrapper used to iterate (std::reverse_iterator). + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev + */ + template + class iterator_storage_reversible_rev : public iterator_storage_reversible + { + public: + using iterator_storage_reversible::iterator_storage_reversible; + + auto rev() const + { + return CompleteClass{this->end_.base().iter1(), + this->begin_.base().iter1(), + this->end_.base().iter2(), + this->begin_.base().iter2()}; + } + + auto skip(blt::size_t amount) + { + auto begin = this->begin_.base(); + for (blt::size_t i = 0; i < amount; i++) + --begin; + return CompleteClassRev{begin.iter1(), + this->end_.base().iter1(), + begin.iter2(), + this->end_.base().iter2()}; + } + + auto take(blt::size_t amount) + { + auto end = this->begin_.base(); + for (blt::size_t i = 0; i < amount; i++) + --end; + return CompleteClassRev{ + this->begin_.base().iter1(), + end.iter1(), + this->begin_.base().iter2(), + end.iter2()}; + } + }; + + /** + * Random access base class for storing the begin/end iterator. + * Has updated skip and take methods which make use of the random access nature of the iterator. + * Operates in reverse for reverse iteration. + * @tparam Iter iterator type. + * @tparam IterWrapper wrapper used to iterate (std::reverse_iterator). + * @tparam CompleteClass completed class returned from skip/take methods + * @tparam CompleteClassRev reverse version of CompleteClass, returned from rev + */ + template + class iterator_storage_random_access_rev : public iterator_storage_reversible_rev + { + public: + using iterator_storage_reversible_rev::iterator_storage_reversible_rev; + + auto skip(blt::size_t amount) + { + return CompleteClassRev{this->begin_.base().iter1() - amount, + this->end_.base().iter1(), + this->begin_.base().iter2() - amount, + this->end_.base().iter2()}; + } + + auto take(blt::size_t amount) + { + return CompleteClassRev{this->begin_.base().iter1(), + this->begin_.base().iter1() - amount, + this->begin_.base().iter2(), + this->begin_.base().iter2() - amount}; + } + }; + + /** + * Base class for types which can be converted to an enumerator + */ + template + class enumerator_convertible + { + public: + auto enumerate() + { + auto* b = static_cast(this); + return CompleteEnumerator{b->begin(), b->end(), static_cast(std::distance(b->begin(), b->end()))}; + } + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; + + } + + /** + * Enumerator specialization for forward iterators + */ + template + class enumerator, std::void_t>> + : public iterator::iterator_storage_base, enumerator> + { + public: + explicit enumerator(Iter begin, Iter end, blt::size_t container_size): + iterator::iterator_storage_base, enumerator> + {iterator::enumerate_wrapper{std::move(begin), 0}, + iterator::enumerate_wrapper{std::move(end), container_size}} + {} + + explicit enumerator(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator::iterator_storage_base, enumerator>{ + iterator::enumerate_wrapper{std::move(begin), begin_index}, + iterator::enumerate_wrapper{std::move(end), end_index}} + {} + }; + + /** + * Enumerator specialization for bidirectional iterators + */ + template + class enumerator, std::void_t>> + : public iterator::iterator_storage_reversible, enumerator, enumerator_rev> + { + public: + explicit enumerator(Iter begin, Iter end, blt::size_t container_size): + iterator::iterator_storage_reversible, enumerator, enumerator_rev> + {iterator::enumerate_wrapper{std::move(begin), 0}, + iterator::enumerate_wrapper{std::move(end), container_size}} + {} + + explicit enumerator(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator::iterator_storage_reversible, enumerator, enumerator_rev>{ + iterator::enumerate_wrapper{std::move(begin), begin_index}, + iterator::enumerate_wrapper{std::move(end), end_index}} + {} + }; + + /** + * Enumerator specialization for random access iterators + */ + template + class enumerator, std::void_t>> + : public iterator::iterator_storage_random_access, enumerator, enumerator_rev> + { + public: + explicit enumerator(Iter begin, Iter end, blt::size_t container_size): + iterator::iterator_storage_random_access, enumerator, enumerator_rev> + {iterator::enumerate_wrapper{std::move(begin), 0}, + iterator::enumerate_wrapper{std::move(end), container_size}} + {} + + explicit enumerator(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator::iterator_storage_random_access, enumerator, enumerator_rev>{ + iterator::enumerate_wrapper{std::move(begin), begin_index}, + iterator::enumerate_wrapper{std::move(end), end_index}} + {} + }; + + /** + * Reverse enumerator specialization for bidirectional iterators + */ + template + class enumerator_rev, std::void_t>> + : public iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> + { + public: + explicit enumerator_rev(Iter begin, Iter end, blt::size_t container_size): + iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> + {std::reverse_iterator>{iterator::enumerate_wrapper{std::move(begin), 0}}, + std::reverse_iterator>{ + iterator::enumerate_wrapper{std::move(end), container_size}}} + {} + + explicit enumerator_rev(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev>{ + std::reverse_iterator>{ + iterator::enumerate_wrapper{std::move(begin), begin_index}}, + std::reverse_iterator>{iterator::enumerate_wrapper{std::move(end), end_index}}} + {} + }; + + /** + * Reverse enumerator specialization for random access iterators + */ + template + class enumerator_rev, std::void_t>> + : public iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> + { + public: + explicit enumerator_rev(Iter begin, Iter end, blt::size_t container_size): + iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> + {std::reverse_iterator>{iterator::enumerate_wrapper{std::move(begin), 0}}, + std::reverse_iterator>{ + iterator::enumerate_wrapper{std::move(end), container_size}}} + {} + + explicit enumerator_rev(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev>{ + std::reverse_iterator>{ + iterator::enumerate_wrapper{std::move(begin), begin_index}}, + std::reverse_iterator>{iterator::enumerate_wrapper{std::move(end), end_index}}} + {} + }; + + // CTAD for enumerators + + template + enumerator(Iter, Iter) -> enumerator; + + template + enumerator(Iter, Iter, blt::size_t) -> enumerator; + + template + enumerator(Iter, Iter, blt::size_t, blt::size_t) -> enumerator; + + template + class pair_iterator>, + std::void_t>> + : public iterator::iterator_storage_base, pair_iterator>, + public iterator::enumerator_convertible, enumerator>> + { + public: + explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): + iterator::iterator_storage_base, pair_iterator> + {iterator::pair_wrapper{std::move(begin1), std::move(begin2)}, + iterator::pair_wrapper{std::move(end1), std::move(end2)}} + {} + }; + + template + class pair_iterator>, + std::void_t>> + : public iterator::iterator_storage_reversible, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> + { + public: + explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): + iterator::iterator_storage_reversible, pair_iterator, pair_iterator_rev> + {iterator::pair_wrapper{std::move(begin1), std::move(begin2)}, + iterator::pair_wrapper{std::move(end1), std::move(end2)}} + {} + }; + + template + class pair_iterator>, + std::void_t>> + : public iterator::iterator_storage_random_access, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> + { + public: + explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): + iterator::iterator_storage_random_access, pair_iterator, pair_iterator_rev> + {iterator::pair_wrapper{std::move(begin1), std::move(begin2)}, + iterator::pair_wrapper{std::move(end1), std::move(end2)}} + {} + }; + + template + class pair_iterator_rev>, + std::void_t>> + : public iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> + { + public: + explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): + iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev> + {std::reverse_iterator>{ + iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, + std::reverse_iterator>{ + iterator::pair_wrapper{std::move(end1), std::move(end2)}}} + {} + }; + + template + class pair_iterator_rev>, + std::void_t>> + : public iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev>, + public iterator::enumerator_convertible, enumerator>> + { + public: + explicit pair_iterator_rev(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): + iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev> + {std::reverse_iterator>{ + iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, + std::reverse_iterator>{ + iterator::pair_wrapper{std::move(end1), std::move(end2)}}} + {} + }; + + // CTAD for pair iterators + + template + pair_iterator(Iter1, Iter1, Iter2, Iter2) -> pair_iterator; + + template + static inline auto enumerate(const T(& container)[size]) + { + return enumerator{&container[0], &container[size], size}; + } + + template + static inline auto enumerate(T(& container)[size]) + { + return enumerator{&container[0], &container[size], size}; + } + + template + static inline auto enumerate(T& container) + { + return enumerator{container.begin(), container.end(), container.size()}; + } + + template + static inline auto enumerate(T&& container) + { + return enumerator{container.begin(), container.end(), container.size()}; + } + + template + static inline auto enumerate(const T& container) + { + return enumerator{container.begin(), container.end(), container.size()}; + } + + template + static inline auto in_pairs(const T& container1, const G& container2) + { + return pair_iterator{container1.begin(), container1.end(), container2.begin(), container2.end()}; + } + + template + static inline auto in_pairs(T& container1, G& container2) + { + return pair_iterator{container1.begin(), container1.end(), container2.begin(), container2.end()}; + } + + template + static inline auto in_pairs(const T(& container1)[size], const G(& container2)[size]) + { + return pair_iterator{&container1[0], &container1[size], &container2[0], &container2[size]}; + } + + template + static inline auto in_pairs(T(& container1)[size], G(& container2)[size]) + { + return pair_iterator{&container1[0], &container1[size], &container2[0], &container2[size]}; + } + + template + static inline auto in_pairs(T&& container1, G&& container2) + { + return pair_iterator{container1.begin(), container1.end(), container2.begin(), container2.end()}; + } + +} + +#endif //BLT_ITERATOR_H diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h new file mode 100644 index 0000000..f8f197d --- /dev/null +++ b/include/blt/iterator/zip.h @@ -0,0 +1,30 @@ +#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_ZIP +#define BLT_ITERATOR_ZIP + +#include +#include + +namespace blt +{ + +} + +#endif //BLT_ITERATOR_ZIP diff --git a/include/blt/math/matrix.h b/include/blt/math/matrix.h index ec1a810..8f32b3c 100644 --- a/include/blt/math/matrix.h +++ b/include/blt/math/matrix.h @@ -122,7 +122,7 @@ namespace blt return *this; } - constexpr generalized_matrix transpose() const + [[nodiscard]] constexpr generalized_matrix transpose() const { generalized_matrix mat; @@ -135,7 +135,7 @@ namespace blt return mat; } - T magnitude() const + [[nodiscard]] constexpr T magnitude() const { T ret{}; for (blt::u32 i = 0; i < columns; i++) @@ -146,7 +146,7 @@ namespace blt return std::sqrt(ret); } - matrix_t normalize() const + [[nodiscard]] constexpr matrix_t normalize() const { auto mag = magnitude(); matrix_t mat = *this; @@ -155,6 +155,14 @@ namespace blt return mat / mag; } + [[nodiscard]] constexpr matrix_t abs() const + { + matrix_t copy = *this; + for (auto& v : copy.data) + v = v.abs(); + return copy; + } + constexpr inline const blt::vec& operator[](u32 column) const { return data[column]; @@ -179,7 +187,7 @@ namespace blt * Takes a value stored across a row, taking one from each column in the specified row * @param row the row to extract from. defaults to the first row */ - constexpr inline vec vec_from_column_row(blt::u32 row = 0) const + [[nodiscard]] constexpr inline vec vec_from_column_row(blt::u32 row = 0) const { vec ret; for (blt::u32 j = 0; j < columns; j++) @@ -187,21 +195,6 @@ namespace blt return ret; } - /** - * Assign to this matrix from the row information in each column of a matrix - * Where columns can be assigned directly from each-other, row stored data must be assigned this way - * this was hacked together for an assignment and a better way is a TODO; - * @param to_column column in this matrix to assign to - * @param row the row place that the value is store in to assign from. Defaults to the first element in each column - */ - template - constexpr inline matrix_t& assign_to_column_from_column_rows(generalized_matrix mat, blt::u32 to_column, blt::u32 row = 0) - { - for (blt::u32 j = 0; j < rows; j++) - data[to_column][j] = mat[j][row]; - return *this; - } - constexpr inline matrix_t& operator+=(const matrix_t& other) { for (blt::u32 i = 0; i < columns; i++) @@ -363,6 +356,16 @@ namespace blt { return !(left == right); } + + auto begin() const + { + return data.begin(); + } + + auto end() const + { + return data.end(); + } private: blt::vec data[columns]; diff --git a/include/blt/math/vectors.h b/include/blt/math/vectors.h index f7a88a9..17c5d67 100644 --- a/include/blt/math/vectors.h +++ b/include/blt/math/vectors.h @@ -124,6 +124,14 @@ namespace blt return elements[3]; } + [[nodiscard]] constexpr inline vec abs() const + { + auto copy = *this; + for (auto& v : copy.elements) + v = std::abs(v); + return copy; + } + [[nodiscard]] constexpr inline T magnitude() const { T total = 0;