diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index 923ba20..75ad640 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -17,69 +17,122 @@ namespace blt { + namespace itr + { + template> + class iterator; + + template + class iterator + { + public: + using iterator_category = std::input_iterator_tag; + using value_type = typename TYPE_ITR::value_type; + using difference_type = typename TYPE_ITR::difference_type; + using pointer = typename TYPE_ITR::pointer; + using reference = typename TYPE_ITR::reference; + using const_reference = const typename TYPE_ITR::reference; + private: + blt::size_t index = 0; + TYPE_ITR current; + public: + explicit iterator(TYPE_ITR current): current(std::move(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}; + }; + }; + + template + class iterator + { + public: + using iterator_category = std::input_iterator_tag; + using value_type = std::remove_pointer_t; + using difference_type = std::ptrdiff_t; + using pointer = TYPE_ITR; + using reference = std::remove_pointer_t&; + using const_reference = const std::remove_pointer_t&; + private: + blt::size_t index = 0; + TYPE_ITR current; + public: + explicit iterator(TYPE_ITR current): current(std::move(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}; + }; + }; + } + template class enumerator { public: - class iterator - { - public: - using iterator_category = std::input_iterator_tag; - using value_type = typename TYPE_ITR::value_type; - using difference_type = typename TYPE_ITR::difference_type; - using pointer = typename TYPE_ITR::pointer; - using reference = typename TYPE_ITR::reference; - private: - blt::size_t index = 0; - TYPE_ITR current; - public: - explicit iterator(TYPE_ITR current): current(std::move(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}; - }; - }; - explicit enumerator(TYPE_ITR begin, TYPE_ITR end): begin_(std::move(begin)), end_(std::move(end)) {} - iterator begin() + itr::iterator begin() { return begin_; } - iterator end() + itr::iterator end() { return end_; } private: - iterator begin_; - iterator end_; + itr::iterator begin_; + itr::iterator end_; }; template @@ -308,20 +361,20 @@ namespace blt {} template()))>(*)[], T(*)[]>), bool> = true> + (std::is_convertible_v()))>(*)[], T(*)[]>), bool> = true> constexpr span(element_type (& arr)[N]) noexcept: size_{N}, data_{arr} {} template()))>(*)[], T(*)[]>), bool> = true> + (std::is_convertible_v()))>(*)[], T(*)[]>), bool> = true> constexpr span(std::array& arr) noexcept: size_(N), data_{arr.data()} {} template()))>(*)[], T(*)[]>), bool> = true> + (std::is_convertible_v()))>(*)[], T(*)[]>), bool> = true> constexpr span(const std::array& arr) noexcept: size_(N), data_{arr.data()} {} @@ -337,11 +390,13 @@ namespace blt constexpr span(R&& range): size_(std::size(range)), data_(std::data(range)) {} - template, bool> = true> + template, bool> = true> explicit constexpr span(std::initializer_list il) noexcept: size_(il.size()), data_(&il.begin()) {} - template, bool> = true> + template, bool> = true> explicit span(std::initializer_list il) noexcept: size_(il.size()), data_(&il.begin()) {} diff --git a/include/blt/std/vector.h b/include/blt/std/vector.h index a218805..c4a6fb9 100644 --- a/include/blt/std/vector.h +++ b/include/blt/std/vector.h @@ -324,53 +324,55 @@ namespace blt template, bool> = true> constexpr iterator insert(const_iterator pos, G&& ref) { - difference_type loc = *pos - buffer_; + difference_type loc = pos - buffer_; if (size_ + 1 >= capacity_) expand(); - for (auto insert = end() - 1; (insert - buffer_) != loc; insert--) + for (auto insert = end() - 1; (insert - buffer_) != loc - 1; insert--) { auto new_pos = insert + 1; *new_pos = *insert; } - buffer_[loc] = std::forward(ref); + buffer_[loc] = ref; size_++; - return &buffer_[loc]; + return buffer_ + loc; } constexpr iterator erase(const_iterator pos) { - difference_type loc = *pos - buffer_; + difference_type loc = pos - buffer_; - for (auto fetch = pos + 1; fetch != cend(); fetch++) + for (auto fetch = begin() + loc + 1; fetch != end(); fetch++) { auto insert = fetch - 1; *insert = *fetch; } size_--; - return &buffer_[loc + 1]; + return buffer_ + loc + 1; } constexpr iterator erase(const_iterator first, const_iterator last) { - difference_type loc = *first - buffer_; - - for (auto fetch = last, insert = first; fetch != cend(); fetch++, insert++) + difference_type first_pos = first - buffer_; + difference_type last_pos = last - buffer_; + difference_type remove_amount = last_pos - first_pos; + + for (auto fetch = begin() + last_pos, insert = begin() + first_pos; fetch != end(); fetch++, insert++) { - *insert = fetch; + *insert = *fetch; } - size_ = loc; - return &buffer_[loc + 1]; + size_ -= remove_amount; + return buffer_ + first_pos + 1; } - constexpr inline iterator begin() noexcept + constexpr inline iterator begin() const noexcept { return data(); } - constexpr inline iterator end() noexcept + constexpr inline iterator end() const noexcept { return data() + size(); } @@ -385,12 +387,12 @@ namespace blt return data() + size(); } - constexpr inline reverse_iterator rbegin() noexcept + constexpr inline reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } - constexpr inline reverse_iterator rend() noexcept + constexpr inline reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } diff --git a/tests/include/blt_tests.h b/tests/include/blt_tests.h index 5fdc6b6..81702e1 100644 --- a/tests/include/blt_tests.h +++ b/tests/include/blt_tests.h @@ -35,6 +35,8 @@ namespace blt::test { } + + void vector_run(); } #endif //BLT_BLT_TESTS_H diff --git a/tests/src/container_test.cpp b/tests/src/container_test.cpp new file mode 100644 index 0000000..ed6abb2 --- /dev/null +++ b/tests/src/container_test.cpp @@ -0,0 +1,79 @@ +/* + * + * 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 . + */ + +#include +#include +#include +#include "blt/std/assert.h" + +namespace blt::test +{ + + template + void print(const T& ref) + { + BLT_TRACE_STREAM << "(" << ref.size() << ") ["; + for (auto v : blt::enumerate(ref)) + BLT_TRACE_STREAM << v.second << ((v.first != ref.size()-1) ? ", " : "]\n"); + } + + void vector_run() + { + + blt::vector vec; + + vec.push_back(10); + vec.push_back(20); + vec.push_back(30); + vec.push_back(40); + vec.push_back(50); + vec.push_back(60); + vec.push_back(70); + vec.push_back(80); + vec.push_back(90); + + print(vec); + BLT_ASSERT(vec.size() == 9 && "Failed at push_back"); + + vec.insert(vec.cbegin() + 2, 25); + BLT_ASSERT(vec.size() == 10 && "Failed at insert single"); + + print(vec); + + for (int i = 0; i < 128; i++) + vec.insert(vec.begin() + 2, i); + BLT_ASSERT(vec.size() == 138 && "Failed at insert 128"); + + print(vec); + + vec.erase(vec.begin() + 3, vec.begin() + 8); + BLT_ASSERT(vec.size() == 133 && "Failed at erase range (non end)"); + + print(vec); + + vec.erase(vec.begin() + 5); + + print(vec); + BLT_ASSERT(vec.size() == 132 && "Failed at erase single"); + + vec.erase(vec.begin() + 10, vec.end()); + + print(vec); + BLT_ASSERT(vec.size() == 10 && "Failed at erase range (end)"); + } +} diff --git a/tests/src/main.cpp b/tests/src/main.cpp index dc0f0b2..b12d587 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -84,6 +84,7 @@ int main(int argc, const char** argv) .setNArgs('?').build()); parser.addArgument(blt::arg_builder("--utility").setHelp("Run tests on utility functions").setAction(blt::arg_action_t::STORE_TRUE).build()); parser.addArgument(blt::arg_builder("--data").setHelp("Run tests on data functions").setAction(blt::arg_action_t::STORE_TRUE).build()); + parser.addArgument(blt::arg_builder("--vector").setHelp("Run tests for the vectors").setAction(blt::arg_action_t::STORE_TRUE).build()); auto args = parser.parse_args(argc, argv); @@ -103,6 +104,9 @@ int main(int argc, const char** argv) if (args.contains("--data")) blt::test::data::run(); + if (args.contains("--vector")) + blt::test::vector_run(); + if (args.contains("--nbt")) { auto v = blt::arg_parse::get(args["nbt"]); diff --git a/tests/src/memory_test.cpp b/tests/src/memory_test.cpp index 9aac4d5..f10881e 100644 --- a/tests/src/memory_test.cpp +++ b/tests/src/memory_test.cpp @@ -23,6 +23,7 @@ #include #include #include "blt/std/utility.h" +#include "blt/std/vector.h" #include #include