diff --git a/CMakeLists.txt b/CMakeLists.txt index c4437f4..5d8950e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 0.20.19) +set(BLT_VERSION 0.20.20) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index c18756c..4721fbe 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -19,6 +19,13 @@ namespace blt { + template + struct enumerate_item + { + blt::size_t index; + T value; + }; + template class enumerate_base { @@ -34,13 +41,15 @@ namespace blt class enumerate_base_fwd : public enumerate_base { public: - explicit enumerate_base_fwd(Iter iter): enumerate_base(std::move(iter)), index(0) + explicit enumerate_base_fwd(Iter iter, blt::size_t place = 0): enumerate_base(std::move(iter)), index(place) {} - explicit enumerate_base_fwd(Iter iter, blt::size_t place): enumerate_base(std::move(iter)), index(place) - {} + enumerate_item>* operator->() const + { + return &std::pair{index, *this->iter}; + } - std::pair> operator*() const + enumerate_item> operator*() const { return {index, *this->iter}; } @@ -59,15 +68,15 @@ namespace blt return tmp; } - bool operator==(const enumerate_base_fwd& other) const - { - return other.iter == this->iter; - } - friend bool operator==(const enumerate_base_fwd& a, const enumerate_base_fwd& b) { return a.iter == b.iter; } + + friend bool operator!=(const enumerate_base_fwd& a, const enumerate_base_fwd& b) + { + return a.iter != b.iter; + } protected: blt::size_t index; @@ -76,6 +85,7 @@ namespace blt template class enumerate_base_bidirectional : public enumerate_base_fwd { + public: using enumerate_base_fwd::enumerate_base_fwd; enumerate_base_bidirectional& operator--() @@ -93,11 +103,21 @@ namespace blt } }; + template::iterator_cateogry> + constexpr bool is_forward_only = std::is_same_v; + + template::iterator_category> + constexpr bool is_bidirectional_or_better = + std::is_same_v || std::is_same_v; + template> - class enumerate_wrapper; + class enumerate_wrapper + { + static_assert("Unsupported iterator type!"); + }; template - class enumerate_wrapper, bool>>> + class enumerate_wrapper, std::void_t>> : public enumerate_base_fwd { public: using iterator_category = std::forward_iterator_tag; @@ -105,17 +125,22 @@ namespace blt using difference_type = typename std::iterator_traits::difference_type; using pointer = typename std::iterator_traits::pointer; using reference = typename std::iterator_traits::reference; - public: - explicit enumerate_wrapper(Iter iter): iter(std::move(iter)), index(0) - {} - explicit enumerate_wrapper(Iter iter, blt::size_t place): iter(std::move(iter)), index(place) - {} - - - private: - Iter iter; - blt::size_t index; + using enumerate_base_fwd::enumerate_base_fwd; + }; + + template + class enumerate_wrapper, std::void_t>> + : public enumerate_base_bidirectional + { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + + using enumerate_base_bidirectional::enumerate_base_bidirectional; }; namespace itr @@ -143,56 +168,6 @@ namespace blt End end_; }; - template - class iterator - { - public: - using iterator_category = std::forward_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; - using pointer = typename std::iterator_traits::pointer; - using reference = typename std::iterator_traits::reference; - using const_reference = const reference; - private: - blt::size_t index; - TYPE_ITR current; - public: - explicit iterator(TYPE_ITR current, blt::size_t index): index(index), current(std::move(current)) - {} - - auto iter() - { - return current; - } - - iterator& operator++() - { - ++index; - ++current; - return *this; - } - - bool operator==(iterator other) const - { - return current == other.current; - } - - bool operator!=(iterator other) const - { - return current != other.current; - } - - std::pair> operator*() const - { - return {index, *current}; - }; - - std::pair> operator*() - { - return {index, *current}; - }; - }; - // TODO: cleanup! all of this! add support for reversing template class pair_iterator @@ -242,56 +217,6 @@ namespace blt C1_TYPE current_c1_iter; C2_TYPE current_c2_iter; }; - - template - class reverse_iterator - { - public: - using iterator_category = std::forward_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; - using pointer = typename std::iterator_traits::pointer; - using reference = typename std::iterator_traits::reference; - using const_reference = const reference; - private: - blt::size_t index; - TYPE_ITR current; - public: - explicit reverse_iterator(TYPE_ITR current, blt::size_t index): index(index), current(std::move(current)) - {} - - auto iter() - { - return current; - } - - reverse_iterator& operator++() - { - --index; - --current; - return *this; - } - - bool operator==(reverse_iterator other) const - { - return current == other.current; - } - - bool operator!=(reverse_iterator other) const - { - return current != other.current; - } - - std::pair operator*() const - { - return {index, *current}; - }; - - std::pair operator*() - { - return {index, *current}; - }; - }; } template @@ -306,60 +231,106 @@ namespace blt return itr::itr_container{std::reverse_iterator(std::forward(end)), std::reverse_iterator(std::forward(begin))}; } - template typename iterator = itr::iterator> - class enumerator + template + class enumerator_base { public: - explicit enumerator(TYPE_ITR begin, TYPE_ITR end): begin_(std::move(begin), 0), end_(std::move(end), 0) + explicit enumerator_base(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) {} - explicit enumerator(TYPE_ITR begin, TYPE_ITR end, blt::size_t i_begin, blt::size_t i_end): - begin_(std::move(begin), i_begin), end_(std::move(end), i_end) + explicit enumerator_base(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + begin_(std::move(begin), begin_index), end_(std::move(end), end_index) {} - itr::iterator begin() + auto begin() { return begin_; } - itr::iterator end() + auto end() { return end_; } - private: - iterator begin_; - iterator end_; + protected: + enumerate_wrapper begin_; + enumerate_wrapper end_; }; + template> + class enumerator + { + static_assert("Unsupported iterator type!"); + }; + + template + class enumerator, std::void_t>> : public enumerator_base + { + public: + using enumerator_base::enumerator_base; + }; + + template + class enumerator, std::void_t>> + : public enumerator_base + { + public: + //using enumerator_base::enumerator_base; + + explicit enumerator(Iter begin, Iter end, blt::size_t container_size): + enumerator_base(std::move(begin), std::move(end)), container_size(container_size) + {} + + explicit enumerator(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + enumerator_base(std::move(begin), std::move(end), begin_index, end_index), container_size(end_index - begin_index) + {} + + enumerator rev() + { + return enumerator{std::reverse_iterator{this->end_}, std::reverse_iterator{this->begin_}, container_size - 1, 0ul}; + } + + protected: + blt::size_t container_size; + }; + + 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 static inline auto enumerate(const T& container) { - return enumerator{container.begin(), container.end()}; + return enumerator{container.begin(), container.end(), container.size()}; } template static inline auto enumerate(const T(& container)[size]) { - return enumerator{&container[0], &container[size]}; + return enumerator{&container[0], &container[size], size}; } template static inline auto enumerate(T(& container)[size]) { - return enumerator{&container[0], &container[size]}; + return enumerator{&container[0], &container[size], size}; } template static inline auto enumerate(T& container) { - return enumerator{container.begin(), container.end()}; + return enumerator{container.begin(), container.end(), container.size()}; } template static inline auto enumerate(T&& container) { - return enumerator{container.begin(), container.end()}; + return enumerator{container.begin(), container.end(), container.size()}; } template typename iterator = itr::pair_iterator> diff --git a/src/blt/parse/argparse.cpp b/src/blt/parse/argparse.cpp index e42d85c..d6c34cf 100644 --- a/src/blt/parse/argparse.cpp +++ b/src/blt/parse/argparse.cpp @@ -122,10 +122,10 @@ namespace blt { std::string result = "["; - for (const auto& value : blt::enumerate(vec)) + for (const auto& [index, value] : blt::enumerate(vec)) { - result += to_string(value.second); - if (value.first != vec.size() - 1) + result += to_string(value); + if (index != vec.size() - 1) result += ", "; } result += "]"; diff --git a/src/blt/parse/obj_loader.cpp b/src/blt/parse/obj_loader.cpp index 0a012e2..d211be7 100644 --- a/src/blt/parse/obj_loader.cpp +++ b/src/blt/parse/obj_loader.cpp @@ -141,10 +141,9 @@ namespace blt::parse obj_model_t obj_loader::parseFile(std::string_view file) { auto lines = blt::fs::getLinesFromFile(std::string(file)); - for (auto line_e : blt::enumerate(lines)) + for (const auto& [index, line] : blt::enumerate(lines)) { - auto& line = line_e.second; - current_line = line_e.first; + current_line = index; char_tokenizer token(line); if (!token.has_next() || token.read_fully().empty()) continue; @@ -220,9 +219,9 @@ namespace blt::parse void obj_loader::handle_face_vertex(const std::vector& face_list, int32_t* arr) { - for (const auto& pair : blt::enumerate(face_list)) + for (const auto& [e_index, value] : blt::enumerate(face_list)) { - auto indices = blt::string::split(pair.second, '/'); + auto indices = blt::string::split(value, '/'); BLT_ASSERT(indices.size() == 3 && "Must have vertex, uv, and normal indices!!"); auto vi = get(indices[0]) - 1; @@ -242,14 +241,14 @@ namespace blt::parse BLT_DEBUG("Vertex: (%f, %f, %f), UV: (%f, %f), Normal: (%f, %f, %f)", vertices[vi].x(), vertices[vi].y(), vertices[vi].z(), uvs[ui].x(), uvs[ui].y(), normals[ni].x(), normals[ni].y(), normals[ni].z()); vertex_map.insert({face, index}); - arr[pair.first] = index; + arr[e_index] = index; } else { BLT_TRACE("Using cached data; %d; map size: %d", loc->second, vertex_data.size()); //const auto& d = vertex_data[loc->second]; BLT_TRACE("Vertex: (%f, %f, %f), UV: (%f, %f), Normal: (%f, %f, %f)", d.vertex.x(), d.vertex.y(), d.vertex.z(), d.uv.x(), d.uv.y(), d.normal.x(), d.normal.y(), d.normal.z()); - arr[pair.first] = loc->second; + arr[e_index] = loc->second; } } }