From 369ab664b6faff15c7b4a7fa73723722e21ec56e Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 26 Sep 2024 13:51:07 -0400 Subject: [PATCH 01/19] iterator! --- CMakeLists.txt | 2 +- include/blt/std/iterator.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 997dcec..44a26ae 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.21.2) +set(BLT_VERSION 0.21.3) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index 79c1411..2cd2e63 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -50,18 +50,18 @@ namespace blt }; template - class pair_iterator_base + class dual_iterator_base { public: - explicit pair_iterator_base(Iter1 iter1, Iter2 iter2): m_iter1(std::move(iter1)), m_iter2(std::move(iter2)) + explicit dual_iterator_base(Iter1 iter1, Iter2 iter2): m_iter1(std::move(iter1)), m_iter2(std::move(iter2)) {} - friend bool operator==(const pair_iterator_base& a, const pair_iterator_base& b) + friend bool operator==(const dual_iterator_base& a, const dual_iterator_base& b) { return a.m_iter1 == b.m_iter1; } - friend bool operator!=(const pair_iterator_base& a, const pair_iterator_base& b) + friend bool operator!=(const dual_iterator_base& a, const dual_iterator_base& b) { return a.m_iter1 != b.m_iter1; } @@ -82,11 +82,11 @@ namespace blt }; template - class enumerate_iterator_base : public pair_iterator_base + class enumerate_iterator_base : public dual_iterator_base { public: explicit enumerate_iterator_base(Iter iter, blt::size_t place = 0): - pair_iterator_base(std::move(iter), place) + dual_iterator_base(std::move(iter), place) {} enumerate_item> operator*() const From 0d13e9738f6f666faec827940948337cef644aba Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 26 Sep 2024 17:02:05 -0400 Subject: [PATCH 02/19] make generic --- CMakeLists.txt | 2 +- include/blt/meta/iterator.h | 66 +++++++-- include/blt/std/iterator.h | 279 ++++++++++++++++++++++-------------- 3 files changed, 232 insertions(+), 115 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44a26ae..ecfc9ba 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.21.3) +set(BLT_VERSION 0.21.4) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/meta/iterator.h b/include/blt/meta/iterator.h index e5873f6..58ec2e8 100644 --- a/include/blt/meta/iterator.h +++ b/include/blt/meta/iterator.h @@ -24,27 +24,71 @@ namespace blt::meta { + template + struct is_input_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_forward_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_bidirectional_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + struct is_random_access_iterator_category + { + constexpr static bool value = std::is_same_v; + }; + + template + inline constexpr bool is_input_iterator_category_v = is_input_iterator_category::value; + + template + inline constexpr bool is_forward_iterator_category_v = is_forward_iterator_category::value; + + template + inline constexpr bool is_bidirectional_iterator_category_v = is_bidirectional_iterator_category::value; + + template + inline constexpr bool is_random_access_iterator_category_v = is_random_access_iterator_category::value; + + template + inline constexpr bool is_bidirectional_or_better_category_v = + is_bidirectional_iterator_category_v || is_random_access_iterator_category_v; + // this is required! :/ template - struct is_input_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::input_iterator_tag>; + struct is_input_iterator + { + constexpr static bool value = is_input_iterator_category_v::iterator_category>; }; template - struct is_forward_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::forward_iterator_tag>; + struct is_forward_iterator + { + constexpr static bool value = is_forward_iterator_category_v::iterator_category>; }; template - struct is_bidirectional_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::bidirectional_iterator_tag>; + struct is_bidirectional_iterator + { + constexpr static bool value = is_bidirectional_iterator_category_v::iterator_category>; }; template - struct is_random_access_iterator { - constexpr static bool value = std::is_same_v::iterator_category, std::random_access_iterator_tag>; + struct is_random_access_iterator + { + constexpr static bool value = is_random_access_iterator_category_v::iterator_category>; }; template @@ -61,6 +105,12 @@ namespace blt::meta template inline constexpr bool is_bidirectional_or_better_v = is_bidirectional_iterator_v || is_random_access_iterator_v; + + template + struct lowest_iterator_category + { + using type = std::common_type_t::iterator_category...>; + }; } #endif //BLT_META_ITERATOR_H diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index 7fa9ec2..5096fa9 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -41,6 +41,9 @@ namespace blt template> class enumerate_wrapper; + template> + class pair_wrapper; + /** * struct which is returned by the enumerator. * @tparam T type to store. @@ -105,36 +108,38 @@ namespace blt { return {this->m_iter2, *this->m_iter1}; } + }; + + template + class pair_iterator_base : public dual_iterator_base + { + public: + using dual_iterator_base::dual_iterator_base; - auto base() const + std::pair, blt::meta::deref_return_t> operator*() const { - return this->iter1(); - } - - auto get_index() const - { - return this->iter2(); + return {*this->m_iter1, *this->m_iter2}; } }; /** - * Forward iterator base class for the enumerator. Contains the ++ operator. - * @tparam Iter iterator type. + * Forward iterator base class. Contains the ++ operator. + * @tparam Base iterator base type. */ - template - class enumerate_forward_iterator : public enumerate_iterator_base + template + class forward_iterator_base : public Base { public: - using enumerate_iterator_base::enumerate_iterator_base; + using Base::Base; - enumerate_forward_iterator& operator++() + forward_iterator_base& operator++() { ++this->m_iter1; ++this->m_iter2; return *this; } - enumerate_forward_iterator operator++(int) + forward_iterator_base operator++(int) { auto tmp = *this; ++*this; @@ -143,23 +148,23 @@ namespace blt }; /** - * Bidirectional iterator base class for the enumerator. Contains the -- operator. - * @tparam Iter iterator type. + * Bidirectional iterator base class. Contains the -- operator. + * @tparam Base iterator base type. */ - template - class enumerate_bidirectional_iterator : public enumerate_forward_iterator + template + class bidirectional_iterator_base : public Base { public: - using enumerate_forward_iterator::enumerate_forward_iterator; + using Base::Base; - enumerate_bidirectional_iterator& operator--() + bidirectional_iterator_base& operator--() { --this->m_iter1; --this->m_iter2; return *this; } - enumerate_bidirectional_iterator operator--(int) + bidirectional_iterator_base operator--(int) { auto tmp = *this; --*this; @@ -167,8 +172,20 @@ namespace blt } }; + 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>; + /** - * Wrapper class specialization for forward iterators. + * Enumerator wrapper class specialization for forward iterators. * @tparam Iter iterator type */ template @@ -181,13 +198,32 @@ namespace blt using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type; using reference = value_type; - using iterator_type = Iter; using enumerate_forward_iterator::enumerate_forward_iterator; }; /** - * Wrapper class for bidirectional iterators or random access iterators. + * 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 @@ -200,24 +236,44 @@ namespace blt using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type; using reference = value_type; - using iterator_type = Iter; using enumerate_bidirectional_iterator::enumerate_bidirectional_iterator; }; /** - * Base class for the enumerator. Holds the begin and end iterators. + * Pair wrapper class for bidirectional iterators or random access iterators. * @tparam Iter iterator type. - * @tparam IterWrapper wrapper used to iterate (enumerate_wrapper) */ - template - class enumerator_base + template + class pair_wrapper>, + std::void_t + >> : public pair_bidirectional_iterator { public: - explicit enumerator_base(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) + using iterator_category = typename blt::meta::lowest_iterator_category::type; + 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 Iter iterator type. + * @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(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) {} - explicit enumerator_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) + explicit iterator_storage_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) {} auto begin() @@ -239,10 +295,10 @@ namespace blt auto begin = this->begin_; for (blt::size_t i = 0; i < amount; i++) ++begin; - return enumerator{begin.base(), - this->end_.base(), - begin.get_index(), - this->end_.get_index()}; + return CompleteClass{begin.iter1(), + this->end_.iter1(), + begin.iter2(), + this->end_.iter2()}; } /** @@ -254,33 +310,36 @@ namespace blt auto end = this->begin(); for (blt::size_t i = 0; i < amount; i++) ++end; - return enumerator{this->begin_.base(), - end.base(), - this->begin_.get_index(), - end.get_index()}; + return CompleteClass{this->begin_.iter1(), + end.iter1(), + this->begin_.iter2(), + end.iter2()}; } + protected: IterWrapper begin_; IterWrapper end_; }; /** - * Reversible (bidirectional) base class for the enumerator. + * Reversible (bidirectional) base class storing the begin / end iterators. * @tparam Iter iterator type. - * @tparam IterWrapper wrapper used to iterate (enumerate_wrapper). + * @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 enumerator_reversible : public enumerator_base + template + class iterator_storage_reversible : public iterator_storage_base { public: - explicit enumerator_reversible(Iter begin, Iter end, blt::size_t container_size): - enumerator_base{IterWrapper{enumerate_wrapper{std::move(begin), 0}}, - IterWrapper{enumerate_wrapper{std::move(end), container_size}}} + explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t container_size): + iterator_storage_base{IterWrapper{enumerate_wrapper{std::move(begin), 0}}, + IterWrapper{enumerate_wrapper{std::move(end), container_size}}} {} - explicit enumerator_reversible(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): - enumerator_base(IterWrapper{enumerate_wrapper{std::move(begin), begin_index}}, - IterWrapper{enumerate_wrapper{std::move(end), end_index}}) + explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): + iterator_storage_base(IterWrapper{enumerate_wrapper{std::move(begin), begin_index}}, + IterWrapper{enumerate_wrapper{std::move(end), end_index}}) {} /** @@ -288,58 +347,63 @@ namespace blt */ auto rev() const { - return enumerator_rev{this->end_.base(), - this->begin_.base(), - this->end_.get_index(), - this->begin_.get_index()}; + return CompleteClassRev{this->end_.iter1(), + this->begin_.iter1(), + this->end_.iter2(), + this->begin_.iter2()}; } }; /** - * Random access base class for the enumerator. Has updated skip and take methods which make use of the random access nature of the iterator. + * 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 (enumerate_wrapper). + * @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 enumerator_random_access : public enumerator_reversible + template + class iterator_storage_random_access : public iterator_storage_reversible { public: - using enumerator_reversible::enumerator_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto skip(blt::size_t amount) { - return enumerator{this->begin_.base() + amount, - this->end_.base(), - this->begin_.get_index() + amount, - this->end_.get_index()}; + return CompleteClass{this->begin_.iter1() + amount, + this->end_.iter1(), + this->begin_.iter2() + amount, + this->end_.iter2()}; } auto take(blt::size_t amount) { - return enumerator{this->begin_.base(), - this->begin_.base() + amount, - this->begin_.get_index(), - this->begin_.get_index() + amount}; + return CompleteClass{this->begin_.iter1(), + this->begin_.iter1() + amount, + this->begin_.iter2(), + this->begin_.iter2() + amount}; } }; /** - * Reversible (bidirectional) base class for the enumerator, operates in reverse for reverse enumeration. + * 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 enumerator_reversible_rev : public enumerator_reversible + template + class iterator_storage_reversible_rev : public iterator_storage_reversible { public: - using enumerator_reversible::enumerator_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto rev() const { - return enumerator{this->end_.base().base(), - this->begin_.base().base(), - this->end_.base().get_index(), - this->begin_.base().get_index()}; + return CompleteClass{this->end_.base().iter1(), + this->begin_.base().iter1(), + this->end_.base().iter2(), + this->begin_.base().iter2()}; } auto skip(blt::size_t amount) @@ -347,10 +411,10 @@ namespace blt auto begin = this->begin_.base(); for (blt::size_t i = 0; i < amount; i++) --begin; - return enumerator_rev{begin.base(), - this->end_.base().base(), - begin.get_index(), - this->end_.base().get_index()}; + return CompleteClassRev{begin.iter1(), + this->end_.base().iter1(), + begin.iter2(), + this->end_.base().iter2()}; } auto take(blt::size_t amount) @@ -358,40 +422,43 @@ namespace blt auto end = this->begin_.base(); for (blt::size_t i = 0; i < amount; i++) --end; - return enumerator_rev{ - this->begin_.base().base(), - end.base(), - this->begin_.base().get_index(), - end.get_index()}; + return CompleteClassRev{ + this->begin_.base().iter1(), + end.iter1(), + this->begin_.base().iter2(), + end.iter2()}; } }; /** - * Random access base class for the enumerator. Has updated skip and take methods which make use of the random access nature of the iterator. - * Operates in reverse for reverse enumeration. + * 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 enumerator_random_access_rev : public enumerator_reversible_rev + template + class iterator_storage_random_access_rev : public iterator_storage_reversible_rev { public: - using enumerator_reversible_rev::enumerator_reversible_rev; + using iterator_storage_reversible_rev::iterator_storage_reversible_rev; auto skip(blt::size_t amount) { - return enumerator_rev{this->begin_.base().base() - amount, - this->end_.base().base(), - this->begin_.base().get_index() - amount, - this->end_.base().get_index()}; + 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 enumerator_rev{this->begin_.base().base(), - this->begin_.base().base() - amount, - this->begin_.base().get_index(), - this->begin_.base().get_index() - amount}; + return CompleteClassRev{this->begin_.base().iter1(), + this->begin_.base().iter1() - amount, + this->begin_.base().iter2(), + this->begin_.base().iter2() - amount}; } }; @@ -403,10 +470,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_base> + : public iterator::iterator_storage_base, enumerator> { public: - using iterator::enumerator_base>::enumerator_base; + using iterator::iterator_storage_base, enumerator>::iterator_storage_base; }; /** @@ -414,10 +481,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_reversible> + : public iterator::iterator_storage_reversible, enumerator, enumerator_rev> { public: - using iterator::enumerator_reversible>::enumerator_reversible; + using iterator::iterator_storage_reversible, enumerator, enumerator_rev>::iterator_storage_reversible; }; /** @@ -425,10 +492,10 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::enumerator_random_access> + : public iterator::iterator_storage_random_access, enumerator, enumerator_rev> { public: - using iterator::enumerator_random_access>::enumerator_random_access; + using iterator::iterator_storage_random_access, enumerator, enumerator_rev>::iterator_storage_random_access; }; /** @@ -436,10 +503,10 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::enumerator_reversible_rev>> + : public iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> { public: - using iterator::enumerator_reversible_rev>>::enumerator_reversible_rev; + using iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev>::iterator_storage_reversible_rev; }; /** @@ -447,10 +514,10 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::enumerator_random_access_rev>> + : public iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> { public: - using iterator::enumerator_random_access_rev>>::enumerator_random_access_rev; + using iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev>::iterator_storage_random_access_rev; }; // CTAD for enumerators From 0ecee088f6a633be523468843c55b925550ca691 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Fri, 27 Sep 2024 15:12:08 -0400 Subject: [PATCH 03/19] working on pair iterators --- CMakeLists.txt | 2 +- commit.py | 264 ++++++++++++++++++++++++++++++++++--- include/blt/std/iterator.h | 234 ++++++++++++++++++++++++++------ include/blt/std/ranges.h | 58 ++++---- 4 files changed, 473 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecfc9ba..fb9f575 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.21.4) +set(BLT_VERSION 0.21.5) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/commit.py b/commit.py index e8b8443..a940032 100755 --- a/commit.py +++ b/commit.py @@ -1,6 +1,13 @@ #!/usr/bin/python3 import subprocess +import argparse +import sys +import os +import itertools +import requests +import json +from pathlib import Path #--------------------------------------- # CONFIG @@ -8,12 +15,110 @@ import subprocess VERSION_BEGIN_STR = "set(BLT_VERSION " VERSION_END_STR = ")" -PATCH_LIMIT = 1000 #--------------------------------------- # DO NOT TOUCH #--------------------------------------- +USER_HOME = Path.home() +ENVIRONMENT_DATA_LOCATION = USER_HOME / ".brett_scripts.env" + +if sys.platform.startswith("win"): + CONFIG_FILE_DIRECTORY = Path(os.getenv('APPDATA') + "\blt") + CONFIG_FILE_LOCATION = Path(CONFIG_FILE_DIRECTORY + "\commit_config.json") +else: + XDG_CONFIG_HOME = os.environ.get('XDG_CONFIG_HOME') + if XDG_CONFIG_HOME is None: + XDG_CONFIG_HOME = USER_HOME / ".config" + else: + XDG_CONFIG_HOME = Path(XDG_CONFIG_HOME) + + if len(str(XDG_CONFIG_HOME)) == 0: + XDG_CONFIG_HOME = USER_HOME + CONFIG_FILE_DIRECTORY = XDG_CONFIG_HOME / "blt" + CONFIG_FILE_LOCATION = CONFIG_FILE_DIRECTORY / "commit_config.json" + +class Config: + def __init__(self): + # Inline with semantic versioning it doesn't make sense to branch / release on minor + self.branch_on_major = True + self.branch_on_minor = False + self.release_on_major = True + self.release_on_minor = True + self.main_branch = "main" + self.patch_limit = -1 + + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + + def fromJSON(file): + with open(file, "r") as f: + j = json.load(f) + obj = Config() + [setattr(obj, key, val) for key, val in j.items() if hasattr(obj, key)] + if obj.branch_on_minor: + obj.branch_on_major = True + return obj + + def from_file(file): + values = {} + if (not os.path.exists(file)): + return Config() + + with open(file, "r") as f: + j = json.load(f) + obj = Config() + [setattr(obj, key, val) for key, val in j.items() if hasattr(obj, key)] + return obj + + def save_to_file(self, file): + dir_index = str(file).rfind("/") + dir = str(file)[:dir_index] + if not os.path.exists(dir): + print(f"Creating config directory {dir}") + os.makedirs(dir) + with open(file, "w") as f: + json.dump(self, f, default=lambda o: o.__dict__, sort_keys=True, indent=4) + + +class EnvData: + def __init__(self, github_username = '', github_token = ''): + self.github_token = github_token + self.github_username = github_username + + def get_env_from_file(file): + f = open(file, "rt") + values = {} + for line in f: + if line.startswith("export"): + content = line.split("=") + for idx, c in enumerate(content): + content[idx] = c.replace("export", "").strip() + values[content[0]] = content[1].replace("\"", "").replace("'", "") + try: + github_token = values["github_token"] + except Exception: + print("Failed to parse github token!") + try: + github_username = values["github_username"] + except: + print("Failed to parse github username! Assuming you are me!") + github_username = "Tri11Paragon" + return EnvData(github_username=github_username, github_token=github_token) + +def open_process(command, print_out = True): + process = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + stdout, stderr = process.communicate() + exit_code = process.wait() + str_out = stdout.decode('utf8') + str_err = stderr.decode('utf8') + if print_out and len(str_out) > 0: + print(str_out, end='') + if print_out and len(str_err) > 0: + print(str_err, end='') + #print(stdout, stderr, exit_code) + return (stdout, stderr, exit_code) + def load_cmake(): cmake_file = open("CMakeLists.txt", 'r') cmake_text = cmake_file.read() @@ -38,9 +143,8 @@ def split_version(cmake_text): def recombine(cmake_text, version_parts, begin, end): constructed_version = version_parts[0] + '.' + version_parts[1] + '.' + version_parts[2] constructed_text_begin = cmake_text[0:begin] - constrcuted_text_end = cmake_text[end::] - return constructed_text_begin + constructed_version + constrcuted_text_end - + constructed_text_end = cmake_text[end::] + return constructed_text_begin + constructed_version + constructed_text_end def inc_major(cmake_text): version_parts, begin, end = split_version(cmake_text) @@ -55,32 +159,158 @@ def inc_minor(cmake_text): version_parts[2] = '0' return recombine(cmake_text, version_parts, begin, end) -def inc_patch(cmake_text): +def inc_patch(config: Config, cmake_text): version_parts, begin, end = split_version(cmake_text) - if int(version_parts[2]) + 1 >= PATCH_LIMIT: + if config.patch_limit > 0 and int(version_parts[2]) + 1 >= config.patch_limit: return inc_minor(cmake_text) version_parts[2] = str(int(version_parts[2]) + 1) return recombine(cmake_text, version_parts, begin, end) -cmake_text = load_cmake() -cmake_version = get_version(cmake_text)[0] -print(f"Current Version: {cmake_version}") +def make_branch(config: Config, name): + print(f"Making new branch {name}") + subprocess.call(["git", "checkout", "-b", name]) + subprocess.call(["git", "merge", config.main_branch]) + subprocess.call(["git", "checkout", config.main_branch]) + +def sync_branch(config: Config, version_parts, args): + if config.branch_on_major: + # Branch will be created. + if args.minor: + return; -try: - type = input("What kind of commit is this ((M)ajor, (m)inor, (p)atch)? ") +def make_release(env: EnvData, name): + print(f"Making new release {name}") + repos_v = open_process(["git", "remote", "-v"])[0].splitlines() + urls = [] + for line in repos_v: + origin = ''.join(itertools.takewhile(str.isalpha, line.decode('utf8'))) + urls.append("https://api.github.com/repos/" + open_process(["git", "remote", "get-url", origin], False)[0].decode('utf8').replace("\n", "").replace("https://github.com/", "") + "/releases") + urls = set(urls) + data = { + 'tag_name': name, + 'name': name, + 'body': "Automated Release '" + name + "'", + 'draft': False, + 'prerelease': False + } + headers = { + 'Authorization': f'Bearer {env.github_token}', + 'Accept': 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28' + } + for url in urls: + response = requests.post(url, headers=headers, data=json.dumps(data)) + if response.status_code == 201: + print('Release created successfully!') + release_data = response.json() + print(f"Release URL: {release_data['html_url']}") + else: + print(f"Failed to create release: {response.status_code}") + print(response.json()) - if type.startswith('M'): + +def main(): + parser = argparse.ArgumentParser( + prog="Commit Helper", + description="Help you make pretty commits :3") + + parser.add_argument("action", nargs='?', default=None) + parser.add_argument("-p", "--patch", action='store_true', default=False, required=False) + parser.add_argument("-m", "--minor", action='store_true', default=False, required=False) + parser.add_argument("-M", "--major", action='store_true', default=False, required=False) + parser.add_argument('-e', "--env", help="environment file", required=False, default=None) + parser.add_argument('-c', "--config", help="config file", required=False, default=None) + parser.add_argument("--create-default-config", action="store_true", default=False, required=False) + parser.add_argument("--no-release", action="store_true", default=False, required=False) + parser.add_argument("--no-branch", action="store_true", default=False, required=False) + + args = parser.parse_args() + + if args.create_default_config: + config = Config() + config.save_to_file(args.config if args.config is not None else CONFIG_FILE_LOCATION) + return + + if args.env is not None: + env = EnvData.get_env_from_file(args.e) + else: + env = EnvData.get_env_from_file(ENVIRONMENT_DATA_LOCATION) + + if args.config is not None: + config = Config.from_file(args.config) + else: + config = Config.from_file(CONFIG_FILE_LOCATION) + + cmake_text = load_cmake() + cmake_version = get_version(cmake_text)[0] + print(f"Current Version: {cmake_version}") + + if not (args.patch or args.minor or args.major): + try: + if args.action is not None: + type = args.action + else: + type = input("What kind of commit is this ((M)ajor, (m)inor, (p)atch)? ") + + if type.startswith('M'): + args.major = True + elif type.startswith('m'): + args.minor = True + elif type.startswith('p') or type.startswith('P') or len(type) == 0: + args.patch = True + except KeyboardInterrupt: + print("\nCancelling!") + return + + if args.major: print("Selected major") write_cmake(inc_major(cmake_text)) - elif type.startswith('m'): + elif args.minor: print("Selected minor") write_cmake(inc_minor(cmake_text)) - elif type.startswith('p') or type.startswith('P') or len(type) == 0: + elif args.patch: print("Selected patch") - write_cmake(inc_patch(cmake_text)) + write_cmake(inc_patch(config, cmake_text)) subprocess.call(["git", "add", "*"]) subprocess.call(["git", "commit"]) + + cmake_text = load_cmake() + version_parts = split_version(cmake_text)[0] + if args.major: + if config.branch_on_major: + if not args.no_branch: + make_branch(config, "v" + str(version_parts[0])) + + if args.minor: + if config.branch_on_minor: + if not args.no_branch: + make_branch(config, "v" + str(version_parts[0]) + "." + str(version_parts[1])) + elif config.branch_on_major: + subprocess.call(["git", "checkout", "v" + str(version_parts[0])]) + subprocess.call(["git", "rebase", config.main_branch]) + subprocess.call(["git", "checkout", config.main_branch]) + + if args.patch: + if config.branch_on_minor: + subprocess.call(["git", "checkout", "v" + str(version_parts[0]) + "." + str(version_parts[1])]) + subprocess.call(["git", "rebase", config.main_branch]) + subprocess.call(["git", "checkout", config.main_branch]) + elif config.branch_on_major: + subprocess.call(["git", "checkout", "v" + str(version_parts[0])]) + subprocess.call(["git", "rebase", config.main_branch]) + subprocess.call(["git", "checkout", config.main_branch]) + + sync_branch(config=config, version_parts=version_parts, args=args) + subprocess.call(["sh", "-c", "git remote | xargs -L1 git push --all"]) -except KeyboardInterrupt: - print("\nCancelling!") + + if args.major: + if not args.no_release and config.release_on_major: + make_release(env, "v" + str(version_parts[0])) + if args.minor: + if not args.no_release and config.release_on_minor: + make_release(env, "v" + str(version_parts[0]) + "." + str(version_parts[1])) + +if __name__ == "__main__": + main() diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index 5096fa9..ec5e682 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -36,6 +36,12 @@ namespace blt template> class enumerator_rev; + template> + class pair_iterator; + + template> + class pair_iterator_rev; + namespace iterator { template> @@ -209,8 +215,7 @@ namespace blt template class pair_wrapper>, - std::void_t - >> : public pair_forward_iterator + std::void_t>> : public pair_forward_iterator { public: using iterator_category = std::forward_iterator_tag; @@ -247,8 +252,7 @@ namespace blt template class pair_wrapper>, - std::void_t - >> : public pair_bidirectional_iterator + std::void_t>> : public pair_bidirectional_iterator { public: using iterator_category = typename blt::meta::lowest_iterator_category::type; @@ -262,17 +266,13 @@ namespace blt /** * Base class for storing begin/end iterators. - * @tparam Iter iterator type. * @tparam IterWrapper wrapper used to iterate * @tparam CompleteClass completed class returned from skip/take methods */ - template + template class iterator_storage_base { public: - explicit iterator_storage_base(Iter begin, Iter end): begin_(std::move(begin)), end_(std::move(end)) - {} - explicit iterator_storage_base(IterWrapper begin, IterWrapper end): begin_(std::move(begin)), end_(std::move(end)) {} @@ -328,18 +328,12 @@ namespace blt * @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 + template + class iterator_storage_reversible : public iterator_storage_base { public: - explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t container_size): - iterator_storage_base{IterWrapper{enumerate_wrapper{std::move(begin), 0}}, - IterWrapper{enumerate_wrapper{std::move(end), container_size}}} - {} - - explicit iterator_storage_reversible(Iter begin, Iter end, blt::size_t begin_index, blt::size_t end_index): - iterator_storage_base(IterWrapper{enumerate_wrapper{std::move(begin), begin_index}}, - IterWrapper{enumerate_wrapper{std::move(end), end_index}}) + explicit iterator_storage_reversible(IterWrapper begin, IterWrapper end): + iterator_storage_base{std::move(begin), std::move(end)} {} /** @@ -362,11 +356,11 @@ namespace blt * @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 + template + class iterator_storage_random_access : public iterator_storage_reversible { public: - using iterator_storage_reversible::iterator_storage_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto skip(blt::size_t amount) { @@ -392,11 +386,11 @@ namespace blt * @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 + template + class iterator_storage_reversible_rev : public iterator_storage_reversible { public: - using iterator_storage_reversible::iterator_storage_reversible; + using iterator_storage_reversible::iterator_storage_reversible; auto rev() const { @@ -439,11 +433,11 @@ namespace blt * @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 + template + class iterator_storage_random_access_rev : public iterator_storage_reversible_rev { public: - using iterator_storage_reversible_rev::iterator_storage_reversible_rev; + using iterator_storage_reversible_rev::iterator_storage_reversible_rev; auto skip(blt::size_t amount) { @@ -470,10 +464,20 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::iterator_storage_base, enumerator> + : public iterator::iterator_storage_base, enumerator> { public: - using iterator::iterator_storage_base, enumerator>::iterator_storage_base; + 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}} + {} }; /** @@ -481,10 +485,20 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::iterator_storage_reversible, enumerator, enumerator_rev> + : public iterator::iterator_storage_reversible, enumerator, enumerator_rev> { public: - using iterator::iterator_storage_reversible, enumerator, enumerator_rev>::iterator_storage_reversible; + 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}} + {} }; /** @@ -492,10 +506,20 @@ namespace blt */ template class enumerator, std::void_t>> - : public iterator::iterator_storage_random_access, enumerator, enumerator_rev> + : public iterator::iterator_storage_random_access, enumerator, enumerator_rev> { public: - using iterator::iterator_storage_random_access, enumerator, enumerator_rev>::iterator_storage_random_access; + 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}} + {} }; /** @@ -503,10 +527,22 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> + : public iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev> { public: - using iterator::iterator_storage_reversible_rev>, enumerator, enumerator_rev>::iterator_storage_reversible_rev; + 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}}} + {} }; /** @@ -514,10 +550,22 @@ namespace blt */ template class enumerator_rev, std::void_t>> - : public iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> + : public iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev> { public: - using iterator::iterator_storage_random_access_rev>, enumerator, enumerator_rev>::iterator_storage_random_access_rev; + 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 @@ -531,6 +579,86 @@ namespace blt 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: + 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: + 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: + 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: + 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: + 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]) { @@ -560,6 +688,36 @@ namespace blt { 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()}; + } } diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index f987b9e..1e8693b 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -134,35 +134,35 @@ namespace blt iterator end_; }; - template - static inline auto in_pairs(const T& container1, const G& container2) - { - return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; - } - - template - static inline auto in_pairs(T& container1, G& container2) - { - return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; - } - - template - static inline auto in_pairs(const T(& container1)[size], const G(& container2)[size]) - { - return pair_enumerator{&container1[0], &container1[size], &container2[0], &container2[size]}; - } - - template - static inline auto in_pairs(T(& container1)[size], G(& container2)[size]) - { - return pair_enumerator{&container1[0], &container1[size], &container2[0], &container2[size]}; - } - - template - static inline auto in_pairs(T&& container1, G&& container2) - { - return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; - } +// template +// static inline auto in_pairs(const T& container1, const G& container2) +// { +// return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; +// } +// +// template +// static inline auto in_pairs(T& container1, G& container2) +// { +// return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; +// } +// +// template +// static inline auto in_pairs(const T(& container1)[size], const G(& container2)[size]) +// { +// return pair_enumerator{&container1[0], &container1[size], &container2[0], &container2[size]}; +// } +// +// template +// static inline auto in_pairs(T(& container1)[size], G(& container2)[size]) +// { +// return pair_enumerator{&container1[0], &container1[size], &container2[0], &container2[size]}; +// } +// +// template +// static inline auto in_pairs(T&& container1, G&& container2) +// { +// return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()}; +// } template struct range From 88e8e8fc5b1e79f0a91469ef9668bfaa3504b3d3 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Fri, 27 Sep 2024 18:18:02 -0400 Subject: [PATCH 04/19] zip storage. i am in hell --- CMakeLists.txt | 2 +- include/blt/meta/iterator.h | 3 + include/blt/std/iterator.h | 207 +++++++++++++++++++++++++++++++----- 3 files changed, 187 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb9f575..039d660 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.21.5) +set(BLT_VERSION 0.21.6) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/meta/iterator.h b/include/blt/meta/iterator.h index 58ec2e8..77084d0 100644 --- a/include/blt/meta/iterator.h +++ b/include/blt/meta/iterator.h @@ -111,6 +111,9 @@ namespace blt::meta { using type = std::common_type_t::iterator_category...>; }; + + template + using lowest_iterator_category_t = typename lowest_iterator_category::type; } #endif //BLT_META_ITERATOR_H diff --git a/include/blt/std/iterator.h b/include/blt/std/iterator.h index ec5e682..cb95c4c 100644 --- a/include/blt/std/iterator.h +++ b/include/blt/std/iterator.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace blt { @@ -42,6 +43,12 @@ namespace blt template> class pair_iterator_rev; + template + class zip_iterator; + + template + class zip_iterator_rev; + namespace iterator { template> @@ -50,6 +57,118 @@ namespace blt 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. @@ -188,7 +307,7 @@ namespace blt using pair_forward_iterator = forward_iterator_base>; template - using pair_bidirectional_iterator = bidirectional_iterator_base>; + using pair_bidirectional_iterator = bidirectional_iterator_base>; /** * Enumerator wrapper class specialization for forward iterators. @@ -214,7 +333,7 @@ namespace blt */ template class pair_wrapper>, + blt::meta::is_forward_iterator_category_v>, std::void_t>> : public pair_forward_iterator { public: @@ -236,7 +355,7 @@ namespace blt : public enumerate_bidirectional_iterator { public: - using iterator_category = typename std::iterator_traits::iterator_category; + 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; @@ -251,11 +370,11 @@ namespace blt */ template class pair_wrapper>, + blt::meta::is_bidirectional_or_better_category_v>, std::void_t>> : public pair_bidirectional_iterator { public: - using iterator_category = typename blt::meta::lowest_iterator_category::type; + 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; @@ -456,6 +575,37 @@ namespace blt } }; + /** + * 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 + { + + }; } @@ -582,9 +732,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_forward_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_base, pair_iterator> + : public iterator::iterator_storage_base, pair_iterator>, + public iterator::enumerator_convertible, enumerator>> { public: explicit pair_iterator(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2): @@ -597,9 +748,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_bidirectional_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_reversible, pair_iterator, pair_iterator_rev> + : 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): @@ -612,9 +764,10 @@ namespace blt template class pair_iterator>, + blt::meta::is_random_access_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_random_access, pair_iterator, pair_iterator_rev> + : 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): @@ -627,30 +780,36 @@ namespace blt template class pair_iterator_rev>, + blt::meta::is_bidirectional_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_reversible_rev>, pair_iterator, pair_iterator_rev> + : 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)}}} + {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>, + blt::meta::is_random_access_iterator_category_v>, std::void_t>> - : public iterator::iterator_storage_random_access_rev>, pair_iterator, pair_iterator_rev> + : 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)}}} + {std::reverse_iterator>{ + iterator::pair_wrapper{std::move(begin1), std::move(begin2)}}, + std::reverse_iterator>{ + iterator::pair_wrapper{std::move(end1), std::move(end2)}}} {} }; @@ -688,31 +847,31 @@ namespace blt { 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) { From aabb9d801dea45f5de138b0d3d80e87223d13587 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 28 Sep 2024 16:40:57 -0400 Subject: [PATCH 05/19] breaking change: iterator is now in blt/iterator --- CMakeLists.txt | 2 +- include/blt/{std => iterator}/iterator.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename include/blt/{std => iterator}/iterator.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 039d660..c5a9e91 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.21.6) +set(BLT_VERSION 1.0.0) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) diff --git a/include/blt/std/iterator.h b/include/blt/iterator/iterator.h similarity index 100% rename from include/blt/std/iterator.h rename to include/blt/iterator/iterator.h From 709401e4da95657b88a4e67c4569d53aa8c75318 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 28 Sep 2024 16:43:46 -0400 Subject: [PATCH 06/19] breaking change. iterator is now in its own package --- CMakeLists.txt | 2 +- commit.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5a9e91..55dd286 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,4 +164,4 @@ if (${BUILD_TESTS}) message("Built tests") endif () -project(BLT) \ No newline at end of file +project(BLT) diff --git a/commit.py b/commit.py index a940032..00d0d95 100755 --- a/commit.py +++ b/commit.py @@ -184,7 +184,7 @@ def make_release(env: EnvData, name): urls = [] for line in repos_v: origin = ''.join(itertools.takewhile(str.isalpha, line.decode('utf8'))) - urls.append("https://api.github.com/repos/" + open_process(["git", "remote", "get-url", origin], False)[0].decode('utf8').replace("\n", "").replace("https://github.com/", "") + "/releases") + urls.append(open_process(["git", "remote", "get-url", origin], False)[0].decode('utf8').replace("\n", "").replace(".git", "").replace("https://github.com/", "https://api.github.com/repos/") + "/releases") urls = set(urls) data = { 'tag_name': name, From fb3ed3aa5ee9ac4185dc6228e06b07466fc38e91 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 28 Sep 2024 16:50:19 -0400 Subject: [PATCH 07/19] new files --- CMakeLists.txt | 2 +- include/blt/iterator/iter_common.h | 30 ++++++++++++++++++++++++++++++ include/blt/iterator/iterator.h | 2 ++ include/blt/iterator/zip.h | 30 ++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 include/blt/iterator/iter_common.h create mode 100644 include/blt/iterator/zip.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 55dd286..11b7c39 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.0) +set(BLT_VERSION 1.0.1) set(BLT_TEST_VERSION 0.0.1) set(BLT_TARGET BLT) 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 index cb95c4c..5f9e9a7 100644 --- a/include/blt/iterator/iterator.h +++ b/include/blt/iterator/iterator.h @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include 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 From 7580fa544a11404bee61e26eb8b019853260ee0c Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 28 Sep 2024 18:31:49 -0400 Subject: [PATCH 08/19] zip iterator, random access --- CMakeLists.txt | 67 ++++-- include/blt/iterator/iterator.h | 131 ------------ include/blt/iterator/zip.h | 352 +++++++++++++++++++++++++++++++- include/blt/std/allocator.h | 8 +- include/blt/std/random.h | 6 + include/blt/std/vector.h | 20 +- libraries/parallel-hashmap | 2 +- src/blt/parse/argparse.cpp | 2 +- src/blt/parse/obj_loader.cpp | 2 +- tests/iterator_tests.cpp | 123 +++++++++++ tests/src/container_test.cpp | 4 +- tests/src/nbt_tests.cpp | 2 +- tests/src/nbt_tests.h | 2 +- tests/src/profiling_tests.h | 2 +- tests/src/string_tests.cpp | 17 +- tests/src/utility_test.cpp | 2 +- 16 files changed, 563 insertions(+), 179 deletions(-) create mode 100644 tests/iterator_tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 11b7c39..9495926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 1.0.1) -set(BLT_TEST_VERSION 0.0.1) +set(BLT_VERSION 1.0.2) set(BLT_TARGET BLT) @@ -34,6 +33,8 @@ if(${BLT_DISABLE_STATS}) add_compile_definitions(BLT_DISABLE_STATS) endif () +find_program(MOLD "mold") + configure_file(include/blt/config.h.in config/blt/config.h @ONLY) message("Enabling library compilation") @@ -138,28 +139,62 @@ install(FILES ${CMAKE_BINARY_DIR}/config/blt/config.h DESTINATION ${CMAKE_INSTAL set_target_properties(${BLT_TARGET} PROPERTIES VERSION ${BLT_VERSION}) set_target_properties(${BLT_TARGET} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) +if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND) + target_compile_options(${BLT_TARGET} PUBLIC -fuse-ld=mold) +endif () install(TARGETS ${BLT_TARGET} CONFIGURATIONS RelWithDebInfo LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +macro(blt_add_project name source type) + + project(${name}-${type}) + + add_executable(${name}-${type} ${source}) + + target_link_libraries(${name}-${type} PRIVATE BLT) + + target_compile_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) + target_link_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) + target_compile_definitions(${name}-${type} PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) + + if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND) + target_compile_options(${name}-${type} PUBLIC -fuse-ld=mold) + endif () + + if (${TRACK_ALLOCATIONS}) + target_compile_definitions(${name}-${type} PRIVATE BLT_TRACK_ALLOCATIONS=1) + endif () + + if (${ENABLE_ADDRSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=address) + target_link_options(${name}-${type} PRIVATE -fsanitize=address) + endif () + + if (${ENABLE_UBSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=undefined) + target_link_options(${name}-${type} PRIVATE -fsanitize=undefined) + endif () + + if (${ENABLE_TSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=thread) + target_link_options(${name}-${type} PRIVATE -fsanitize=thread) + endif () + + add_test(NAME ${name} COMMAND ${name}-${type}) + + set(failRegex "\\[WARN\\]" "FAIL" "ERROR" "FATAL" "exception") + set_property(TEST ${name} PROPERTY FAIL_REGULAR_EXPRESSION "${failRegex}") + + project(${BLT_TARGET}) +endmacro() + if (${BUILD_TESTS}) - message("Building test version ${BLT_TEST_VERSION}") - project(BLT_TESTS VERSION ${BLT_TEST_VERSION}) + message("Building tests for version ${BLT_VERSION}") - include_directories(tests/include) - - file(GLOB_RECURSE TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.cpp") - - message("Using files ${TEST_FILES}") - - add_executable(BLT_TESTS ${TEST_FILES}) - - target_link_libraries(BLT_TESTS PRIVATE BLT) - - include(cmake/warnings.cmake) - include(cmake/sanitizers.cmake) + blt_add_project(blt-iterator tests/iterator_tests.cpp test) message("Built tests") endif () diff --git a/include/blt/iterator/iterator.h b/include/blt/iterator/iterator.h index 5f9e9a7..51c4cfc 100644 --- a/include/blt/iterator/iterator.h +++ b/include/blt/iterator/iterator.h @@ -59,118 +59,6 @@ namespace blt 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. @@ -590,25 +478,6 @@ namespace blt 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 - { - - }; - } /** diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index f8f197d..812b7cd 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -24,7 +24,357 @@ namespace blt { - + + namespace iterator + { + 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_random_access_iterator : public zip_bidirectional_iterator + { + private: + template + static blt::ptrdiff_t sub(const zip_random_access_iterator& a, const zip_random_access_iterator& b, + std::integer_sequence) + { + auto min = std::min(std::get(a.iter) - std::get(b.iter)...); + return min; + } + public: + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + zip_random_access_iterator& operator+=(blt::ptrdiff_t n) + { + std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter); + return *this; + } + + zip_random_access_iterator& operator-=(blt::ptrdiff_t n) + { + std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter); + return *this; + } + + friend zip_random_access_iterator operator+(const zip_random_access_iterator& a, blt::ptrdiff_t n) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); + } + + friend zip_random_access_iterator operator+(blt::ptrdiff_t n, const zip_random_access_iterator& a) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); + } + + friend zip_random_access_iterator operator-(const zip_random_access_iterator& a, blt::ptrdiff_t n) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter); + } + + friend zip_random_access_iterator operator-(blt::ptrdiff_t n, const zip_random_access_iterator& a) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter); + } + + friend blt::ptrdiff_t operator-(const zip_random_access_iterator& a, const zip_random_access_iterator& b) + { + return sub(a, b, std::index_sequence_for()); + } + + auto operator[](blt::ptrdiff_t n) const + { + return *(*this + n); + } + + friend bool operator<(const zip_random_access_iterator& a, const zip_random_access_iterator& b) + { + return b - a > 0; + } + + friend bool operator>(const zip_random_access_iterator& a, const zip_random_access_iterator& b) + { + return b < a; + } + + friend bool operator>=(const zip_random_access_iterator& a, const zip_random_access_iterator& b) + { + return !(a < b); // NOLINT + } + + friend bool operator<=(const zip_random_access_iterator& a, const zip_random_access_iterator& b) + { + return !(a > b); // NOLINT + } + }; + + template + class 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; + + explicit zip_wrapper(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_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 base() + { + return iter; + } + + protected: + std::tuple iter; + }; + + template + class zip_wrapper : public zip_wrapper + { + public: + using zip_wrapper::zip_wrapper; + + 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; + + 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 + { + private: + template + static blt::ptrdiff_t sub(const zip_wrapper& a, const zip_wrapper& b, + std::integer_sequence) + { + auto min = std::min(std::get(a.iter) - std::get(b.iter)...); + return min; + } + public: + using zip_wrapper::zip_wrapper; + + 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; + + using zip_bidirectional_iterator::zip_bidirectional_iterator; + + zip_wrapper& operator+=(blt::ptrdiff_t n) + { + std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter); + return *this; + } + + zip_wrapper& operator-=(blt::ptrdiff_t n) + { + std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter); + return *this; + } + + friend zip_wrapper operator+(const zip_wrapper& a, blt::ptrdiff_t n) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); + } + + friend zip_wrapper operator+(blt::ptrdiff_t n, const zip_wrapper& a) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); + } + + friend zip_wrapper operator-(const zip_wrapper& a, blt::ptrdiff_t n) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter); + } + + friend zip_wrapper operator-(blt::ptrdiff_t n, const zip_wrapper& a) + { + return std::apply([n](auto& ... i) { return zip_random_access_iterator{(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 + { + return *(*this + n); + } + + friend bool operator<(const zip_wrapper& a, const zip_wrapper& b) + { + 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 + } + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage + { + + }; + + template + class zip_iterator_storage_rev + { + + }; + + template + class zip_iterator_storage_rev + { + + }; + + template + class zip_iterator_storage_rev + { + + }; + } + } #endif //BLT_ITERATOR_ZIP diff --git a/include/blt/std/allocator.h b/include/blt/std/allocator.h index 91e7e5d..873c0e4 100644 --- a/include/blt/std/allocator.h +++ b/include/blt/std/allocator.h @@ -22,7 +22,7 @@ #include #include #include - #include + #include #include #include #include @@ -159,10 +159,10 @@ namespace blt */ inline std::optional search_for_block(block_storage* blk, size_t n) { - for (auto kv : blt::enumerate(blk->unallocated_blocks)) + for (auto [index, item] : blt::enumerate(blk->unallocated_blocks)) { - if (kv.second.n >= n) - return block_view{blk, kv.first, kv.second.n - n}; + if (item.n >= n) + return block_view{blk, index, item.n - n}; } return {}; } diff --git a/include/blt/std/random.h b/include/blt/std/random.h index 1e33e66..9ffad57 100644 --- a/include/blt/std/random.h +++ b/include/blt/std/random.h @@ -174,6 +174,12 @@ namespace blt::random return BLT_RANDOM_FUNCTION(seed, min, max); } + template + constexpr T get(T min, T max) + { + return BLT_RANDOM_FUNCTION(seed, min, max); + } + constexpr bool choice() { return BLT_RANDOM_DOUBLE(seed) < 0.5; diff --git a/include/blt/std/vector.h b/include/blt/std/vector.h index 5ed4d12..2cc3233 100644 --- a/include/blt/std/vector.h +++ b/include/blt/std/vector.h @@ -42,8 +42,8 @@ namespace blt using pointer = T*; using const_reference = const T&; using const_pointer = const T*; - using iterator = blt::ptr_iterator; - using const_iterator = blt::ptr_iterator; + using iterator = T*; + using const_iterator = const T*; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; public: @@ -131,24 +131,24 @@ namespace blt return buffer_[index]; } - constexpr inline pointer operator*() + constexpr inline reference operator*() { - return buffer_; + return *buffer_.data(); } - constexpr inline const_pointer operator*() const + constexpr inline const_reference operator*() const { - return buffer_; + return *buffer_.data(); } constexpr inline pointer data() { - return buffer_; + return buffer_.data(); } constexpr inline const_pointer data() const { - return buffer_; + return buffer_.data(); } constexpr inline reference front() @@ -290,8 +290,8 @@ namespace blt using const_reference = const value_type&; using pointer = value_type*; using const_pointer = const pointer; - using iterator = blt::ptr_iterator; - using const_iterator = blt::ptr_iterator; + using iterator = T*; + using const_iterator = const T*; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 63acc33..7ef2e73 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 63acc3336f941c6f324c88eb9ee4ce623a460cd5 +Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5 diff --git a/src/blt/parse/argparse.cpp b/src/blt/parse/argparse.cpp index a467e2a..4f8477c 100644 --- a/src/blt/parse/argparse.cpp +++ b/src/blt/parse/argparse.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include "blt/std/utility.h" diff --git a/src/blt/parse/obj_loader.cpp b/src/blt/parse/obj_loader.cpp index af5eb3d..82a3c2d 100644 --- a/src/blt/parse/obj_loader.cpp +++ b/src/blt/parse/obj_loader.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include "blt/std/assert.h" diff --git a/tests/iterator_tests.cpp b/tests/iterator_tests.cpp new file mode 100644 index 0000000..5922a7a --- /dev/null +++ b/tests/iterator_tests.cpp @@ -0,0 +1,123 @@ +/* + * + * 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 +#include +#include +#include +#include +#include + +constexpr auto increasing_reverse_pairs = [](blt::size_t i, blt::size_t index, blt::size_t size) { return i == 0 ? index : (size - 1) - index; }; +constexpr auto increasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t) { return index; }; +constexpr auto decreasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t size) { return size - index; }; + +template +std::array make_array(Func&& func) +{ + std::array array; + for (auto&& [index, value] : blt::enumerate(array)) + value = blt::vec2(func(0, index, n), func(1, index, n)); + return array; +} + +constexpr blt::size_t array_size = 10; +auto array_1 = make_array(increasing_reverse_pairs); +auto array_2 = make_array(increasing_pairs); +auto array_3 = make_array(decreasing_pairs); + +void test_enumerate() +{ + blt::log_box_t box(std::cout, "Enumerate Tests", 25); + for (const auto& [index, item] : blt::enumerate(array_1)) + BLT_TRACE_STREAM << index << " : " << item << "\n"; + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).rev()) + BLT_TRACE_STREAM << index << " : " << item << "\n"; + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).take(3)) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index < 3); + } + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).take(3).rev()) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index < 3); + } + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).skip(3)) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index >= 3); + } + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).skip(3).rev()) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index >= 3); + } + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).skip(3).take(5)) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index >= 3 && index < (array_1.size() - 5) + 3); + } + + BLT_TRACE(""); + + for (const auto& [index, item] : blt::enumerate(array_1).skip(3).rev().take(5)) + { + BLT_TRACE_STREAM << index << " : " << item << "\n"; + BLT_ASSERT(index >= 5); + } +} + +void test_pairs() +{ + blt::log_box_t box(std::cout, "Pairs Tests", 25); +} + +void test_zip() +{ + blt::log_box_t box(std::cout, "Zip Tests", 25); +} + +int main() +{ + test_enumerate(); + std::cout << std::endl; + test_pairs(); + std::cout << std::endl; + test_zip(); +} \ No newline at end of file diff --git a/tests/src/container_test.cpp b/tests/src/container_test.cpp index ed6abb2..4f967f1 100644 --- a/tests/src/container_test.cpp +++ b/tests/src/container_test.cpp @@ -28,8 +28,8 @@ namespace blt::test 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"); + for (auto [index, item] : blt::enumerate(ref)) + BLT_TRACE_STREAM << item << ((index != ref.size()-1) ? ", " : "]\n"); } void vector_run() diff --git a/tests/src/nbt_tests.cpp b/tests/src/nbt_tests.cpp index 1dc9ba3..44990d5 100644 --- a/tests/src/nbt_tests.cpp +++ b/tests/src/nbt_tests.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/src/nbt_tests.h b/tests/src/nbt_tests.h index 187023d..a6eb0d0 100644 --- a/tests/src/nbt_tests.h +++ b/tests/src/nbt_tests.h @@ -15,7 +15,7 @@ namespace blt::tests { template T* generateRandomData(T* arr, size_t size, uint32_t seed = 0) { for (size_t i = 0; i < size; i++) - arr[i] = blt::random::randomInt_c(i * size + seed, std::numeric_limits::min(), std::numeric_limits::max()); + arr[i] = blt::random::random_t(i * size + seed).get(std::numeric_limits::min(), std::numeric_limits::max()); return arr; } diff --git a/tests/src/profiling_tests.h b/tests/src/profiling_tests.h index ac27a6c..94ebcd0 100644 --- a/tests/src/profiling_tests.h +++ b/tests/src/profiling_tests.h @@ -10,7 +10,7 @@ #include "blt/profiling/profiler_v2.h" #include "blt/std/logging.h" #include "blt/std/time.h" -#include "blt/std/format.h" +#include "blt/format/format.h" void print(const std::vector& vtr) { for (const auto& line : vtr) diff --git a/tests/src/string_tests.cpp b/tests/src/string_tests.cpp index 4f3216e..444b7cb 100644 --- a/tests/src/string_tests.cpp +++ b/tests/src/string_tests.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace blt::test { @@ -32,27 +33,27 @@ namespace blt::test auto sv_splits_c = blt::string::split_sv(str, ' '); auto sv_splits_s = blt::string::split_sv(str, "LOT"); - for (auto v : blt::enumerate(s_splits_c)) + for (auto [index, item] : blt::enumerate(s_splits_c)) { - if (v.second != sv_splits_c[v.first]) + if (item != sv_splits_c[index]) { - BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_c[v.first]).c_str()); + BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", item.c_str(), std::string(sv_splits_c[index]).c_str()); } else { - BLT_DEBUG(v.second); + BLT_DEBUG(item); } } BLT_INFO(""); - for (auto v : blt::enumerate(s_splits_s)) + for (auto [index, item] : blt::enumerate(s_splits_s)) { - if (v.second != sv_splits_s[v.first]) + if (item != sv_splits_s[index]) { - BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_s[v.first]).c_str()); + BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", item.c_str(), std::string(sv_splits_s[index]).c_str()); } else { - BLT_DEBUG(v.second); + BLT_DEBUG(item); } } } diff --git a/tests/src/utility_test.cpp b/tests/src/utility_test.cpp index 20bd404..7dd5c9f 100644 --- a/tests/src/utility_test.cpp +++ b/tests/src/utility_test.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ #include -#include +#include #include #include #include From 2c0ace639fd2dac0c201e732e3bf9f23b1fc4f51 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 28 Sep 2024 18:32:30 -0400 Subject: [PATCH 09/19] remove the base class crap --- CMakeLists.txt | 2 +- include/blt/iterator/zip.h | 141 ------------------------------------- 2 files changed, 1 insertion(+), 142 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9495926..df2a4bf 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.2) +set(BLT_VERSION 1.0.3) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index 812b7cd..21bea96 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -36,147 +36,6 @@ namespace blt 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_random_access_iterator : public zip_bidirectional_iterator - { - private: - template - static blt::ptrdiff_t sub(const zip_random_access_iterator& a, const zip_random_access_iterator& b, - std::integer_sequence) - { - auto min = std::min(std::get(a.iter) - std::get(b.iter)...); - return min; - } - public: - using zip_bidirectional_iterator::zip_bidirectional_iterator; - - zip_random_access_iterator& operator+=(blt::ptrdiff_t n) - { - std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter); - return *this; - } - - zip_random_access_iterator& operator-=(blt::ptrdiff_t n) - { - std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter); - return *this; - } - - friend zip_random_access_iterator operator+(const zip_random_access_iterator& a, blt::ptrdiff_t n) - { - return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); - } - - friend zip_random_access_iterator operator+(blt::ptrdiff_t n, const zip_random_access_iterator& a) - { - return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); - } - - friend zip_random_access_iterator operator-(const zip_random_access_iterator& a, blt::ptrdiff_t n) - { - return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter); - } - - friend zip_random_access_iterator operator-(blt::ptrdiff_t n, const zip_random_access_iterator& a) - { - return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter); - } - - friend blt::ptrdiff_t operator-(const zip_random_access_iterator& a, const zip_random_access_iterator& b) - { - return sub(a, b, std::index_sequence_for()); - } - - auto operator[](blt::ptrdiff_t n) const - { - return *(*this + n); - } - - friend bool operator<(const zip_random_access_iterator& a, const zip_random_access_iterator& b) - { - return b - a > 0; - } - - friend bool operator>(const zip_random_access_iterator& a, const zip_random_access_iterator& b) - { - return b < a; - } - - friend bool operator>=(const zip_random_access_iterator& a, const zip_random_access_iterator& b) - { - return !(a < b); // NOLINT - } - - friend bool operator<=(const zip_random_access_iterator& a, const zip_random_access_iterator& b) - { - return !(a > b); // NOLINT - } - }; - template class zip_wrapper { From 5f61e2be4c3e6e20c71f4528b38569f59f8a612a Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 29 Sep 2024 18:26:34 -0400 Subject: [PATCH 10/19] zip iterators work. now have .take --- .idea/misc.xml | 3 + .vscode/launch.json | 32 ++++ .vscode/settings.json | 75 ++++++++++ CMakeLists.txt | 2 +- include/blt/iterator/zip.h | 286 ++++++++++++++++++++++++++++-------- include/blt/meta/iterator.h | 12 ++ libraries/parallel-hashmap | 2 +- tests/iterator_tests.cpp | 47 +++++- 8 files changed, 392 insertions(+), 67 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.idea/misc.xml b/.idea/misc.xml index 79b3c94..0b76fe5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..887d4ca --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/cmake-build-debug/BLT_TESTS", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d3f548b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,75 @@ +{ + "files.associations": { + "iostream": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "strstream": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "variant": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index df2a4bf..e3365ca 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.3) +set(BLT_VERSION 1.0.4) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index 21bea96..aa6cf47 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -20,28 +20,23 @@ #define BLT_ITERATOR_ZIP #include +#include +#include #include namespace blt { - namespace iterator { template class zip_wrapper; - template - class zip_iterator_storage; - - template - class zip_iterator_storage_rev; - template - class zip_wrapper + class zip_wrapper { public: - using iterator_category = std::forward_iterator_tag; - using value_type = std::tuple...>; + using iterator_category = std::input_iterator_tag; + using value_type = std::tuple...>; using difference_type = blt::ptrdiff_t; using pointer = value_type; using reference = value_type; @@ -49,9 +44,9 @@ namespace blt explicit zip_wrapper(Iter... iter): iter(std::make_tuple(iter...)) {} - std::tuple...> operator*() const + std::tuple...> operator*() const { - return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter); + return std::apply([](auto& ... i) { return std::tuple...>{*i...}; }, iter); } friend bool operator==(const zip_wrapper& a, const zip_wrapper& b) @@ -87,17 +82,30 @@ namespace blt }; template - class zip_wrapper : public zip_wrapper + class zip_wrapper : public zip_wrapper { public: - using zip_wrapper::zip_wrapper; - - using iterator_category = std::bidirectional_iterator_tag; - using value_type = std::tuple...>; + 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); @@ -115,25 +123,25 @@ namespace blt 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) { - auto min = std::min(std::get(a.iter) - std::get(b.iter)...); + 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; - 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; - - using zip_bidirectional_iterator::zip_bidirectional_iterator; - zip_wrapper& operator+=(blt::ptrdiff_t n) { std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter); @@ -148,22 +156,22 @@ namespace blt friend zip_wrapper operator+(const zip_wrapper& a, blt::ptrdiff_t n) { - return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter); + 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_random_access_iterator{(i + n)...}; }, a.iter); + 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_random_access_iterator{(i - n)...}; }, a.iter); + 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_random_access_iterator{(i - n)...}; }, a.iter); + 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) @@ -197,43 +205,199 @@ namespace blt } }; - template - class zip_iterator_storage + template + auto get_base(Iter iter) { + if constexpr (meta::is_reverse_iterator_v) + { + return std::move(iter).base(); + } else + { + return std::move(iter); + } + } - }; - - template - class zip_iterator_storage + template + class take_impl { - - }; - - template - class zip_iterator_storage - { - - }; - - template - class zip_iterator_storage_rev - { - - }; - - template - class zip_iterator_storage_rev - { - - }; - - template - class zip_iterator_storage_rev - { - + private: + template + auto take_base(blt::size_t n) + { + static_assert(!std::is_same_v, + "Cannot .take() on an input iterator!"); + auto* d = static_cast(this); + auto begin = d->begin(); + auto end = d->end(); + + // take variant for forward and bidirectional iterators + if constexpr (std::is_same_v || + std::is_same_v) + { + // with these guys we have to loop forward to move the iterators. an unfortunate inefficiency + auto new_end = begin; + for (blt::size_t i = 0; i < n; i++) + { + if constexpr (check) + { + if (new_end == end) + break; + } + ++new_end; + } + return Derived{get_base(std::move(begin)), get_base(std::move(new_end))}; + } else if constexpr (std::is_same_v) + { + // random access iterators can have math directly applied to them. + if constexpr (check) + { + return Derived{get_base(begin), + get_base(begin + std::min(n, static_cast(std::distance(begin, end))))}; + } else + { + return Derived{get_base(begin), get_base(begin + n)}; + } + } + } + + public: + auto take(blt::size_t n) + { return take_base(n); } + + auto take_or(blt::size_t n) + { return take_base(n); } }; } + template + struct iterator_pair + { + using type = Iter; + + iterator_pair(Iter begin, Iter end): begin(std::move(begin)), end(std::move(end)) + {} + + Iter begin; + Iter end; + }; + + template + class zip_iterator_storage; + + template + class zip_iterator_storage_rev; + + template + class zip_iterator_storage : public iterator::take_impl> + { + public: + using iterator_category = meta::lowest_iterator_category_t; + public: + zip_iterator_storage(iterator_pair... iterator_pairs): + 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): + m_begins(std::move(begins)), m_ends(std::move(ends)) + {} + + auto rev() + { + static_assert((std::is_same_v || + std::is_same_v), + ".rev() must be used with bidirectional (or better) iterators!"); + return zip_iterator_storage_rev{m_ends, m_begins}; + } + + auto skip(blt::size_t n) + { + if constexpr (std::is_same_v) + { + + } + } + + auto begin() const + { + return m_begins; + } + + auto end() const + { + return m_ends; + } + + private: + iterator::zip_wrapper m_begins; + iterator::zip_wrapper m_ends; + }; + + template + class zip_iterator_storage_rev : public iterator::take_impl> + { + public: + using iterator_category = meta::lowest_iterator_category_t; + public: + zip_iterator_storage_rev(iterator_pair... iterator_pairs): m_begins(iterator_pairs.begin...), m_ends(iterator_pairs.end...) + { + static_assert((std::is_same_v || + std::is_same_v), + "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)) + { + static_assert((std::is_same_v || + std::is_same_v), + "reverse iteration is only supported on bidirectional or better iterators!"); + } + + auto rev() + { + return zip_iterator_storage{m_ends.base(), m_begins.base()}; + } + + auto begin() const + { + return m_begins; + } + + auto end() const + { + return m_ends; + } + + private: + std::reverse_iterator> m_begins; + std::reverse_iterator> m_ends; + }; + + /* + * CTAD for the zip containers + */ + + template + zip_iterator_storage(iterator_pair...) -> zip_iterator_storage; + + template + zip_iterator_storage(std::initializer_list...) -> zip_iterator_storage; + + template + zip_iterator_storage_rev(iterator_pair...) -> zip_iterator_storage_rev; + + template + zip_iterator_storage_rev(std::initializer_list...) -> zip_iterator_storage_rev; + + /* + * Helper functions for creating zip containers + */ + + template + auto zip(Container& ... container) + { + return blt::zip_iterator_storage{iterator_pair{container.begin(), container.end()}...}; + } } #endif //BLT_ITERATOR_ZIP diff --git a/include/blt/meta/iterator.h b/include/blt/meta/iterator.h index 77084d0..e7df5a7 100644 --- a/include/blt/meta/iterator.h +++ b/include/blt/meta/iterator.h @@ -114,6 +114,18 @@ namespace blt::meta template using lowest_iterator_category_t = typename lowest_iterator_category::type; + + template + struct is_reverse_iterator : std::false_type + { + }; + + template + struct is_reverse_iterator> : std::true_type + {}; + + template + inline constexpr bool is_reverse_iterator_v = is_reverse_iterator::value; } #endif //BLT_META_ITERATOR_H diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 7ef2e73..93201da 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5 +Subproject commit 93201da2ba5a6aba0a6e57ada64973555629b3e3 diff --git a/tests/iterator_tests.cpp b/tests/iterator_tests.cpp index 5922a7a..e5a4a35 100644 --- a/tests/iterator_tests.cpp +++ b/tests/iterator_tests.cpp @@ -24,13 +24,17 @@ #include #include #include +#include -constexpr auto increasing_reverse_pairs = [](blt::size_t i, blt::size_t index, blt::size_t size) { return i == 0 ? index : (size - 1) - index; }; -constexpr auto increasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t) { return index; }; -constexpr auto decreasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t size) { return size - index; }; +constexpr auto increasing_reverse_pairs = + [](blt::size_t i, blt::size_t index, blt::size_t size) { return i == 0 ? index : (size - 1) - index; }; +constexpr auto increasing_pairs = + [](blt::size_t, blt::size_t index, blt::size_t) { return index; }; +constexpr auto decreasing_pairs = + [](blt::size_t, blt::size_t index, blt::size_t size) { return size - index; }; template -std::array make_array(Func&& func) +std::array make_array(Func func) { std::array array; for (auto&& [index, value] : blt::enumerate(array)) @@ -38,11 +42,22 @@ std::array make_array(Func&& func) return array; } +template +std::forward_list make_list(Func func) +{ + std::forward_list array; + for (auto index : blt::range(0ul, n)) + array.push_front(blt::vec2(func(0, index, n), func(1, index, n))); + return array; +} + constexpr blt::size_t array_size = 10; auto array_1 = make_array(increasing_reverse_pairs); auto array_2 = make_array(increasing_pairs); auto array_3 = make_array(decreasing_pairs); +auto list_1 = make_list(increasing_reverse_pairs); + void test_enumerate() { blt::log_box_t box(std::cout, "Enumerate Tests", 25); @@ -111,6 +126,30 @@ 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)) + { + BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; + } + BLT_TRACE("================================"); + for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).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()) + { + BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; + } + BLT_TRACE("================================"); + for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).take_or(13)) + { + BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; + } + BLT_TRACE("================================"); + for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).rev().take(3)) + { + BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; + } } int main() From 2b375fc8f3b78743dc44fbf906788f9e25f16ed2 Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 29 Sep 2024 23:04:36 -0400 Subject: [PATCH 11/19] skips --- CMakeLists.txt | 2 +- include/blt/iterator/zip.h | 50 +++++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3365ca..5cd6c1f 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.4) +set(BLT_VERSION 1.0.5) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index aa6cf47..a75ff8e 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -72,7 +72,7 @@ namespace blt return tmp; } - auto base() + auto raw_tuple() { return iter; } @@ -205,10 +205,12 @@ namespace blt } }; + BLT_META_MAKE_FUNCTION_CHECK(base); + template auto get_base(Iter iter) { - if constexpr (meta::is_reverse_iterator_v) + if constexpr (has_func_base_v) { return std::move(iter).base(); } else @@ -252,7 +254,7 @@ namespace blt if constexpr (check) { return Derived{get_base(begin), - get_base(begin + std::min(n, static_cast(std::distance(begin, end))))}; + get_base(begin + std::min(static_cast(n), std::distance(begin, end)))}; } else { return Derived{get_base(begin), get_base(begin + n)}; @@ -267,6 +269,48 @@ namespace blt auto take_or(blt::size_t n) { return take_base(n); } }; + + template + class skip_impl + { + private: + template + auto skip_base(blt::size_t n) + { + auto* d = static_cast(this); + auto begin = d->begin(); + auto end = d->end(); + + if constexpr (std::is_same_v) + { + if constexpr (check) + { + return Derived{begin + std::min(static_cast(n), std::distance(begin, end))}; + } else + { + return Derived{begin + n, end}; + } + } else + { + for (blt::size_t i = 0; i < n; i++) + { + if constexpr (check){ + if (begin == end) + break; + } + ++begin; + } + return Derived{begin, end}; + } + } + + public: + void skip(blt::size_t n) + { return skip_base(n); } + + void skip_or(blt::size_t n) + { return skip_base(n); } + }; } template From 1830a3936b12e23cdc1e1e2fe0bf0a7fc951c6be Mon Sep 17 00:00:00 2001 From: Brett Date: Mon, 30 Sep 2024 02:22:33 -0400 Subject: [PATCH 12/19] match ptrdiff_t --- CMakeLists.txt | 2 +- include/blt/iterator/zip.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cd6c1f..6336797 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.5) +set(BLT_VERSION 1.0.6) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index a75ff8e..b4e6efb 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -254,7 +254,7 @@ namespace blt if constexpr (check) { return Derived{get_base(begin), - get_base(begin + std::min(static_cast(n), std::distance(begin, end)))}; + get_base(begin + std::min(static_cast(n), std::distance(begin, end)))}; } else { return Derived{get_base(begin), get_base(begin + n)}; @@ -285,7 +285,7 @@ namespace blt { if constexpr (check) { - return Derived{begin + std::min(static_cast(n), std::distance(begin, end))}; + return Derived{begin + std::min(static_cast(n), std::distance(begin, end))}; } else { return Derived{begin + n, end}; From 0e5d8b604386106bbe52c87e93b32a4a3f775627 Mon Sep 17 00:00:00 2001 From: Brett Date: Mon, 30 Sep 2024 02:38:36 -0400 Subject: [PATCH 13/19] silly --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 130 ++++++++++++++++++++++++ include/blt/iterator/iter_common.h | 30 ------ include/blt/iterator/iterator.h | 2 +- include/blt/iterator/zip.h | 157 +++++------------------------ tests/iterator_tests.cpp | 6 +- 6 files changed, 158 insertions(+), 169 deletions(-) create mode 100644 include/blt/iterator/common.h delete mode 100644 include/blt/iterator/iter_common.h 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"; } From 5745ddba723de1abbe27dadee256647e559c0b89 Mon Sep 17 00:00:00 2001 From: Brett Date: Mon, 30 Sep 2024 03:32:16 -0400 Subject: [PATCH 14/19] probably going to revert all of this. --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 79 +++++++-------- include/blt/iterator/zip.h | 177 ++++++++++++++-------------------- 3 files changed, 109 insertions(+), 149 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a25f735..9da53f2 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.1.1) +set(BLT_VERSION 1.1.2) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 6fa91b8..746af3c 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -25,16 +25,16 @@ namespace blt::iterator { template - struct wrapper_base + struct base_wrapper { - wrapper_base operator++(int) + base_wrapper operator++(int) { auto tmp = *this; ++*this; return tmp; } - wrapper_base operator--(int) + base_wrapper operator--(int) { static_assert(std::is_same_v || std::is_same_v, @@ -51,80 +51,75 @@ namespace blt::iterator return *(*this + n); } - friend wrapper_base operator+(const wrapper_base& a, blt::ptrdiff_t n) + friend base_wrapper operator+(blt::ptrdiff_t n, const base_wrapper& a) { - static_assert(std::is_same_v, - "Iterator must allow random access"); - auto copy = a; - copy += n; - return copy; + return a + n; } - 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) + friend bool operator<(const base_wrapper& a, const base_wrapper& 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) + friend bool operator>(const base_wrapper& a, const base_wrapper& 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) + friend bool operator>=(const base_wrapper& a, base_wrapper& 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) + friend bool operator<=(const base_wrapper& a, const base_wrapper& 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) + friend bool operator==(const base_wrapper& a, const base_wrapper& b) { return a.base() == b.base(); } - friend bool operator!=(const wrapper_base& a, const wrapper_base& b) + friend bool operator!=(const base_wrapper& a, const base_wrapper& b) { return !(a.base() == b.base()); // NOLINT } }; + + template + struct passthrough_wrapper : public base_wrapper + { + public: + explicit passthrough_wrapper(Iter iter): iter(std::move(iter)) + {} + + meta::deref_return_t operator*() const + { + return *iter; + } + + auto base() const + { + return iter; + } + + friend blt::ptrdiff_t operator-(const passthrough_wrapper& a, const passthrough_wrapper& b) + { + return a.base() - b.base(); + } + + protected: + Iter iter; + }; } #endif //BLT_ITERATOR_ITER_COMMON diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index f5fd24b..4efb86a 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -29,7 +29,7 @@ namespace blt namespace iterator { template - class zip_wrapper : public wrapper_base> + struct zip_wrapper : public base_wrapper> { public: using iterator_category = meta::lowest_iterator_category_t; @@ -58,16 +58,18 @@ namespace blt return *this; } - zip_wrapper& operator+=(blt::ptrdiff_t n) + friend zip_wrapper operator+(const zip_wrapper& a, blt::ptrdiff_t n) { - std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter); - return *this; + static_assert(std::is_same_v, + "Iterator must allow random access"); + return std::apply([n](auto& ... i) { return zip_wrapper((i + n)...); }, a.iter); } - zip_wrapper& operator-=(blt::ptrdiff_t n) + friend zip_wrapper operator-(const zip_wrapper& a, blt::ptrdiff_t n) { - std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter); - return *this; + static_assert(std::is_same_v, + "Iterator must allow random access"); + 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) @@ -93,112 +95,78 @@ namespace blt } }; - BLT_META_MAKE_FUNCTION_CHECK(base); - - template - auto get_base(Iter iter) + template + struct skip_wrapper : public passthrough_wrapper> { - if constexpr (has_func_base_v) - { - return std::move(iter).base(); - } else - { - return std::move(iter); - } - } - - template - class take_impl - { - private: - template - auto take_base(blt::size_t n) - { - static_assert(!std::is_same_v, - "Cannot .take() on an input iterator!"); - auto* d = static_cast(this); - auto begin = d->begin(); - auto end = d->end(); - - // take variant for forward and bidirectional iterators - if constexpr (std::is_same_v || - std::is_same_v) - { - // with these guys we have to loop forward to move the iterators. an unfortunate inefficiency - auto new_end = begin; - for (blt::size_t i = 0; i < n; i++) - { - if constexpr (check) - { - if (new_end == end) - break; - } - ++new_end; - } - return Derived{get_base(std::move(begin)), get_base(std::move(new_end))}; - } else if constexpr (std::is_same_v) - { - // random access iterators can have math directly applied to them. - if constexpr (check) - { - return Derived{get_base(begin), - get_base(begin + std::min(static_cast(n), std::distance(begin, end)))}; - } else - { - return Derived{get_base(begin), get_base(begin + n)}; - } - } - } - public: - auto take(blt::size_t n) - { return take_base(n); } + using iterator_category = typename std::iterator_traits::iterator_category; + 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; - auto take_or(blt::size_t n) - { return take_base(n); } - }; - - template - class skip_impl - { - private: - template - auto skip_base(blt::size_t n) + explicit skip_wrapper(Iter iter, blt::size_t n): passthrough_wrapper>(std::move(iter)), skip(n) + {} + + skip_wrapper& operator++() { - auto* d = static_cast(this); - auto begin = d->begin(); - auto end = d->end(); - - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) { - if constexpr (check) + if (skip > 0) { - return Derived{begin + std::min(static_cast(n), std::distance(begin, end))}; - } else - { - return Derived{begin + n, end}; + this->base() += skip; + skip = 0; } } else { - for (blt::size_t i = 0; i < n; i++) + while (skip > 0) { - if constexpr (check) - { - if (begin == end) - break; - } - ++begin; + ++this->base(); + --skip; } - return Derived{begin, end}; } + + ++this->base(); + return *this; + } + + skip_wrapper& operator--() + { + if constexpr (std::is_same_v) + { + if (skip > 0) + { + this->base() -= skip; + skip = 0; + } + } else + { + while (skip > 0) + { + --this->base(); + --skip; + } + } + --this->base(); + return *this; + } + + friend skip_wrapper operator+(const skip_wrapper& a, blt::ptrdiff_t n) + { + static_assert(std::is_same_v, + "Iterator must allow random access"); + return {a.base() + static_cast(a.skip) + n, 0}; + } + + friend skip_wrapper operator-(const skip_wrapper& a, blt::ptrdiff_t n) + { + static_assert(std::is_same_v, + "Iterator must allow random access"); + return {a.base() - static_cast(a.skip) - n, 0}; } - public: - void skip(blt::size_t n) - { return skip_base(n); } - - void skip_or(blt::size_t n) - { return skip_base(n); } + private: + blt::size_t skip; }; } @@ -221,7 +189,7 @@ namespace blt class zip_iterator_storage_rev; template - class zip_iterator_storage : public iterator::take_impl> + class zip_iterator_storage { public: using iterator_category = meta::lowest_iterator_category_t; @@ -244,10 +212,7 @@ namespace blt auto skip(blt::size_t n) { - if constexpr (std::is_same_v) - { - - } + } auto begin() const @@ -266,7 +231,7 @@ namespace blt }; template - class zip_iterator_storage_rev : public iterator::take_impl> + class zip_iterator_storage_rev { public: using iterator_category = meta::lowest_iterator_category_t; @@ -329,7 +294,7 @@ namespace blt template auto zip(Container& ... container) { - return blt::zip_iterator_storage{iterator_pair{container.begin(), container.end()}...}; + return zip_iterator_storage{iterator_pair{container.begin(), container.end()}...}; } } From a66fc586fd679aab7a7f9ffd683af450f30e7c82 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 30 Sep 2024 18:03:44 -0400 Subject: [PATCH 15/19] skip doesnt work --- CMakeLists.txt | 12 +-- include/blt/iterator/common.h | 198 ++++++++++++++++++++++++++++++++-- include/blt/iterator/zip.h | 173 ++--------------------------- libraries/parallel-hashmap | 2 +- tests/iterator_tests.cpp | 7 +- 5 files changed, 211 insertions(+), 181 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9da53f2..d0ebaf1 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.1.2) +set(BLT_VERSION 1.1.3) set(BLT_TARGET BLT) @@ -140,7 +140,7 @@ install(FILES ${CMAKE_BINARY_DIR}/config/blt/config.h DESTINATION ${CMAKE_INSTAL set_target_properties(${BLT_TARGET} PROPERTIES VERSION ${BLT_VERSION}) set_target_properties(${BLT_TARGET} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND) - target_compile_options(${BLT_TARGET} PUBLIC -fuse-ld=mold) + target_link_options(${BLT_TARGET} PUBLIC -fuse-ld=mold) endif () install(TARGETS ${BLT_TARGET} @@ -154,16 +154,16 @@ macro(blt_add_project name source type) add_executable(${name}-${type} ${source}) + if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND) + add_link_options(-fuse-ld=mold) + endif () + target_link_libraries(${name}-${type} PRIVATE BLT) target_compile_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) target_link_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) target_compile_definitions(${name}-${type} PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) - if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND) - target_compile_options(${name}-${type} PUBLIC -fuse-ld=mold) - endif () - if (${TRACK_ALLOCATIONS}) target_compile_definitions(${name}-${type} PRIVATE BLT_TRACK_ALLOCATIONS=1) endif () diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 746af3c..12389dc 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -21,6 +21,7 @@ #include #include +#include namespace blt::iterator { @@ -37,7 +38,8 @@ namespace blt::iterator base_wrapper operator--(int) { static_assert(std::is_same_v || - std::is_same_v, + std::is_same_v, "Iterator must allow random access"); auto tmp = *this; --*this; @@ -86,27 +88,22 @@ namespace blt::iterator friend bool operator==(const base_wrapper& a, const base_wrapper& b) { - return a.base() == b.base(); + return static_cast(a).base() == static_cast(b).base(); } friend bool operator!=(const base_wrapper& a, const base_wrapper& b) { - return !(a.base() == b.base()); // NOLINT + return !(static_cast(a).base() == static_cast(b).base()); // NOLINT } }; - template + template struct passthrough_wrapper : public base_wrapper { public: explicit passthrough_wrapper(Iter iter): iter(std::move(iter)) {} - meta::deref_return_t operator*() const - { - return *iter; - } - auto base() const { return iter; @@ -118,8 +115,189 @@ namespace blt::iterator } protected: - Iter iter; + mutable Iter iter; }; + + template + struct passthrough_wrapper : public passthrough_wrapper + { + using passthrough_wrapper::passthrough_wrapper; + + meta::deref_return_t operator*() const + { + return *this->iter; + } + }; + + namespace impls + { + template + struct skip_wrapper : public passthrough_wrapper> + { + public: + using iterator_category = typename std::iterator_traits::iterator_category; + 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; + + explicit skip_wrapper(Iter iter, blt::size_t n): passthrough_wrapper>(std::move(iter)), skip(n) + {} + + meta::deref_return_t operator*() const + { + BLT_TRACE("Dereference Skip"); + forward_skip(); + return *this->iter; + } + + skip_wrapper& operator++() + { + BLT_TRACE("Forward Skip"); + forward_skip(); + ++this->iter; + return *this; + } + + skip_wrapper& operator--() + { + BLT_TRACE("Backward Skip"); + forward_skip(); + --this->iter; + return *this; + } + + friend skip_wrapper operator+(const skip_wrapper& a, blt::ptrdiff_t n) + { + static_assert(std::is_same_v, + "Iterator must allow random access"); + return {a.base() + static_cast(a.skip) + n, 0}; + } + + friend skip_wrapper operator-(const skip_wrapper& a, blt::ptrdiff_t n) + { + static_assert(std::is_same_v, + "Iterator must allow random access"); + return {a.base() - static_cast(a.skip) - n, 0}; + } + + private: + void forward_skip() const + { + if constexpr (std::is_same_v) + { + if (skip > 0) + { + this->iter = this->iter + skip; + skip = 0; + } + } else + { + while (skip > 0) + { + ++this->iter; + --skip; + } + } + } + + mutable blt::size_t skip; + }; + + template + class take_t + { + private: + template + auto take_base(blt::size_t n) + { + static_assert(!std::is_same_v, + "Cannot .take() on an input iterator!"); + auto* d = static_cast(this); + auto begin = d->begin(); + auto end = d->end(); + + // take variant for forward and bidirectional iterators + if constexpr (std::is_same_v || + std::is_same_v) + { + // with these guys we have to loop forward to move the iterators. an unfortunate inefficiency + auto new_end = begin; + for (blt::size_t i = 0; i < n; i++) + { + if constexpr (check) + { + if (new_end == end) + break; + } + ++new_end; + } + return Derived{std::move(begin), std::move(new_end)}; + } else if constexpr (std::is_same_v) + { + // random access iterators can have math directly applied to them. + if constexpr (check) + { + return Derived{begin, begin + std::min(static_cast(n), std::distance(begin, end))}; + } else + { + return Derived{begin, begin + n}; + } + } + } + + public: + auto take(blt::size_t n) + { return take_base(n); } + + auto take_or(blt::size_t n) + { return take_base(n); } + }; + } + + template + class iterator_container : public impls::take_t> + { + public: + using iterator_category = typename IterBase::iterator_category; + + iterator_container(IterBase begin, IterBase end): m_begin(std::move(begin)), m_end(std::move(end)) + {} + + template + iterator_container(Iter&& begin, Iter&& end): m_begin(std::forward(begin)), m_end(std::forward(end)) + {} + + auto rev() + { + static_assert((std::is_same_v || + std::is_same_v), + ".rev() must be used with bidirectional (or better) iterators!"); + return iterator_container>{std::reverse_iterator{end()}, + std::reverse_iterator{begin()}}; + } + + auto skip(blt::size_t n) + { + return iterator_container>{impls::skip_wrapper{begin(), n}, + impls::skip_wrapper{end(), n}}; + } + + auto begin() const + { + return m_begin; + } + + auto end() const + { + return m_end; + } + + protected: + IterBase m_begin; + IterBase m_end; + }; + } #endif //BLT_ITERATOR_ITER_COMMON diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index 4efb86a..4a04d41 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -38,6 +38,9 @@ namespace blt using pointer = value_type; using reference = value_type; + explicit zip_wrapper(std::tuple iter): iter(std::move(iter)) + {} + explicit zip_wrapper(Iter... iter): iter(std::make_tuple(iter...)) {} @@ -77,7 +80,7 @@ namespace blt return sub(a, b, std::index_sequence_for()); } - auto base() + auto base() const { return iter; } @@ -94,80 +97,6 @@ namespace blt return min; } }; - - template - struct skip_wrapper : public passthrough_wrapper> - { - public: - using iterator_category = typename std::iterator_traits::iterator_category; - 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; - - explicit skip_wrapper(Iter iter, blt::size_t n): passthrough_wrapper>(std::move(iter)), skip(n) - {} - - skip_wrapper& operator++() - { - if constexpr (std::is_same_v) - { - if (skip > 0) - { - this->base() += skip; - skip = 0; - } - } else - { - while (skip > 0) - { - ++this->base(); - --skip; - } - } - - ++this->base(); - return *this; - } - - skip_wrapper& operator--() - { - if constexpr (std::is_same_v) - { - if (skip > 0) - { - this->base() -= skip; - skip = 0; - } - } else - { - while (skip > 0) - { - --this->base(); - --skip; - } - } - --this->base(); - return *this; - } - - friend skip_wrapper operator+(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() + static_cast(a.skip) + n, 0}; - } - - friend skip_wrapper operator-(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() - static_cast(a.skip) - n, 0}; - } - - private: - blt::size_t skip; - }; } template @@ -183,92 +112,15 @@ namespace blt }; template - class zip_iterator_storage; - - template - class zip_iterator_storage_rev; - - template - class zip_iterator_storage + class zip_iterator_storage : public iterator::iterator_container> { public: - using iterator_category = meta::lowest_iterator_category_t; - public: - zip_iterator_storage(iterator_pair... iterator_pairs): - m_begins(std::move(iterator_pairs.begin)...), m_ends(std::move(iterator_pairs.end)...) + using iterator::iterator_container>::iterator_container; + + explicit zip_iterator_storage(iterator_pair... iterator_pairs): + iterator::iterator_container>(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, + iterator::zip_wrapper{std::move(iterator_pairs.end)...}) {} - - zip_iterator_storage(iterator::zip_wrapper begins, iterator::zip_wrapper ends): - m_begins(std::move(begins)), m_ends(std::move(ends)) - {} - - auto rev() - { - static_assert((std::is_same_v || - std::is_same_v), - ".rev() must be used with bidirectional (or better) iterators!"); - return zip_iterator_storage_rev{m_ends, m_begins}; - } - - auto skip(blt::size_t n) - { - - } - - auto begin() const - { - return m_begins; - } - - auto end() const - { - return m_ends; - } - - private: - iterator::zip_wrapper m_begins; - iterator::zip_wrapper m_ends; - }; - - template - class zip_iterator_storage_rev - { - public: - using iterator_category = meta::lowest_iterator_category_t; - public: - zip_iterator_storage_rev(iterator_pair... iterator_pairs): m_begins(iterator_pairs.begin...), m_ends(iterator_pairs.end...) - { - static_assert((std::is_same_v || - std::is_same_v), - "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)) - { - static_assert((std::is_same_v || - std::is_same_v), - "reverse iteration is only supported on bidirectional or better iterators!"); - } - - auto rev() - { - return zip_iterator_storage{m_ends.base(), m_begins.base()}; - } - - auto begin() const - { - return m_begins; - } - - auto end() const - { - return m_ends; - } - - private: - std::reverse_iterator> m_begins; - std::reverse_iterator> m_ends; }; /* @@ -281,11 +133,6 @@ namespace blt template zip_iterator_storage(std::initializer_list...) -> zip_iterator_storage; - template - zip_iterator_storage_rev(iterator_pair...) -> zip_iterator_storage_rev; - - template - zip_iterator_storage_rev(std::initializer_list...) -> zip_iterator_storage_rev; /* * Helper functions for creating zip containers diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 93201da..7ef2e73 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 93201da2ba5a6aba0a6e57ada64973555629b3e3 +Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5 diff --git a/tests/iterator_tests.cpp b/tests/iterator_tests.cpp index 0ee82fc..0fb5198 100644 --- a/tests/iterator_tests.cpp +++ b/tests/iterator_tests.cpp @@ -136,7 +136,7 @@ void test_zip() BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; } BLT_TRACE("================================"); - for (auto [a1, a2, a3] : blt::zip(array_1, array_2, list_1).take(3).rev()) + for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).take(3).rev()) { BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; } @@ -150,6 +150,11 @@ void test_zip() { BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; } + BLT_TRACE("================================"); + for (auto [a1, a2, a3] : blt::zip(array_1, array_2, array_3).skip(2).rev()) + { + BLT_TRACE_STREAM << a1 << " : " << a2 << " : " << a3 << "\n"; + } } int main() From 4bdaa3481b00794429212e01e5bd11999d5aeb12 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 30 Sep 2024 18:15:59 -0400 Subject: [PATCH 16/19] skip working --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 98 ++++++++++++----------------------- 2 files changed, 33 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0ebaf1..014dc94 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.1.3) +set(BLT_VERSION 1.1.4) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 12389dc..a415a78 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -131,77 +131,49 @@ namespace blt::iterator namespace impls { - template - struct skip_wrapper : public passthrough_wrapper> + template + class skip_t { - public: - using iterator_category = typename std::iterator_traits::iterator_category; - 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; - - explicit skip_wrapper(Iter iter, blt::size_t n): passthrough_wrapper>(std::move(iter)), skip(n) - {} - - meta::deref_return_t operator*() const - { - BLT_TRACE("Dereference Skip"); - forward_skip(); - return *this->iter; - } - - skip_wrapper& operator++() - { - BLT_TRACE("Forward Skip"); - forward_skip(); - ++this->iter; - return *this; - } - - skip_wrapper& operator--() - { - BLT_TRACE("Backward Skip"); - forward_skip(); - --this->iter; - return *this; - } - - friend skip_wrapper operator+(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() + static_cast(a.skip) + n, 0}; - } - - friend skip_wrapper operator-(const skip_wrapper& a, blt::ptrdiff_t n) - { - static_assert(std::is_same_v, - "Iterator must allow random access"); - return {a.base() - static_cast(a.skip) - n, 0}; - } - private: - void forward_skip() const + template + auto skip_base(blt::size_t n) { - if constexpr (std::is_same_v) + auto* d = static_cast(this); + auto begin = d->begin(); + auto end = d->end(); + + if constexpr (std::is_same_v || + std::is_same_v) { - if (skip > 0) + for (blt::size_t i = 0; i < n; i++) { - this->iter = this->iter + skip; - skip = 0; + if constexpr (check) + { + if (begin == end) + break; + } + ++begin; } - } else + return Derived{std::move(begin), std::move(end)}; + } else if constexpr (std::is_same_v) { - while (skip > 0) + // random access iterators can have math directly applied to them. + if constexpr (check) { - ++this->iter; - --skip; + return Derived{begin + std::min(static_cast(n), std::distance(begin, end)), end}; + } else + { + return Derived{begin + n, end}; } } } + + public: + auto skip(blt::size_t n) + { return skip_base(n); } - mutable blt::size_t skip; + auto skip_or(blt::size_t n) + { return skip_base(n); } }; template @@ -256,7 +228,7 @@ namespace blt::iterator } template - class iterator_container : public impls::take_t> + class iterator_container : public impls::take_t>, public impls::skip_t> { public: using iterator_category = typename IterBase::iterator_category; @@ -277,12 +249,6 @@ namespace blt::iterator std::reverse_iterator{begin()}}; } - auto skip(blt::size_t n) - { - return iterator_container>{impls::skip_wrapper{begin(), n}, - impls::skip_wrapper{end(), n}}; - } - auto begin() const { return m_begin; From 22c44ca551ecaf4c85278c310a14163d97096fc7 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 30 Sep 2024 18:57:15 -0400 Subject: [PATCH 17/19] trying zip --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 9 +++++---- include/blt/iterator/zip.h | 12 ++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 014dc94..0bf31e4 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.1.4) +set(BLT_VERSION 1.1.5) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index a415a78..1474017 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -227,8 +227,10 @@ namespace blt::iterator }; } - template - class iterator_container : public impls::take_t>, public impls::skip_t> + template + class iterator_container : public impls::take_t>, + public impls::skip_t>, + public Base ... { public: using iterator_category = typename IterBase::iterator_category; @@ -245,8 +247,7 @@ namespace blt::iterator static_assert((std::is_same_v || std::is_same_v), ".rev() must be used with bidirectional (or better) iterators!"); - return iterator_container>{std::reverse_iterator{end()}, - std::reverse_iterator{begin()}}; + return iterator_container < std::reverse_iterator, Base...>{std::reverse_iterator{end()}, std::reverse_iterator{begin()}}; } auto begin() const diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index 4a04d41..bb05bda 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -123,6 +123,18 @@ namespace blt {} }; + template + class zip_t + { + public: + template + auto zip(iterator_pair... iterator_pairs) + { + iterator::iterator_container>(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, + iterator::zip_wrapper{std::move(iterator_pairs.end)...}); + } + }; + /* * CTAD for the zip containers */ From 97b6efb1ff68419f235608cce15df013261049c7 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 30 Sep 2024 19:43:02 -0400 Subject: [PATCH 18/19] zip --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 13 +++++----- include/blt/iterator/zip.h | 46 +++++++++++++++++++++++------------ 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bf31e4..58db704 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.1.5) +set(BLT_VERSION 1.1.6) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 1474017..3918d09 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -129,7 +129,7 @@ namespace blt::iterator } }; - namespace impls + namespace impl { template class skip_t @@ -227,13 +227,13 @@ namespace blt::iterator }; } - template - class iterator_container : public impls::take_t>, - public impls::skip_t>, - public Base ... + template + class iterator_container : public impl::take_t>, + public impl::skip_t> { public: using iterator_category = typename IterBase::iterator_category; + using iterator = IterBase; iterator_container(IterBase begin, IterBase end): m_begin(std::move(begin)), m_end(std::move(end)) {} @@ -247,7 +247,8 @@ namespace blt::iterator static_assert((std::is_same_v || std::is_same_v), ".rev() must be used with bidirectional (or better) iterators!"); - return iterator_container < std::reverse_iterator, Base...>{std::reverse_iterator{end()}, std::reverse_iterator{begin()}}; + return iterator_container>{std::reverse_iterator{end()}, + std::reverse_iterator{begin()}}; } auto begin() const diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index bb05bda..e763f0c 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -97,6 +97,18 @@ namespace blt return min; } }; + +// template +// struct zip_wrapper : public Iter +// { +// using iterator_category = typename std::iterator_traits::iterator_category; +// 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 Iter::Iter; +// }; } template @@ -112,38 +124,42 @@ namespace blt }; template - class zip_iterator_storage : public iterator::iterator_container> + class zip_iterator_container : public iterator::iterator_container> { public: using iterator::iterator_container>::iterator_container; - explicit zip_iterator_storage(iterator_pair... iterator_pairs): + explicit zip_iterator_container(iterator_pair... iterator_pairs): iterator::iterator_container>(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, iterator::zip_wrapper{std::move(iterator_pairs.end)...}) {} + }; - template - class zip_t + namespace impl { - public: - template - auto zip(iterator_pair... iterator_pairs) - { - iterator::iterator_container>(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, - iterator::zip_wrapper{std::move(iterator_pairs.end)...}); - } - }; + template + class zip_t + { + public: + template + auto zip(iterator_pair... iterator_pairs) + { + zip_iterator_container(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, + iterator::zip_wrapper{std::move(iterator_pairs.end)...}); + } + }; + } /* * CTAD for the zip containers */ template - zip_iterator_storage(iterator_pair...) -> zip_iterator_storage; + zip_iterator_container(iterator_pair...) -> zip_iterator_container; template - zip_iterator_storage(std::initializer_list...) -> zip_iterator_storage; + zip_iterator_container(std::initializer_list...) -> zip_iterator_container; /* @@ -153,7 +169,7 @@ namespace blt template auto zip(Container& ... container) { - return zip_iterator_storage{iterator_pair{container.begin(), container.end()}...}; + return zip_iterator_container{iterator_pair{container.begin(), container.end()}...}; } } From 68451b04337199feb65e41bf63bba37b2b6ed8a2 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Tue, 1 Oct 2024 13:27:39 -0400 Subject: [PATCH 19/19] work on enumerate --- CMakeLists.txt | 2 +- include/blt/iterator/common.h | 2 +- include/blt/iterator/enumerate.h | 59 ++++++++++++++++++++++++++++++++ include/blt/iterator/zip.h | 4 +-- tests/iterator_tests.cpp | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 include/blt/iterator/enumerate.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 58db704..29decc6 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.1.6) +set(BLT_VERSION 1.1.7) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index 3918d09..50f3b55 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -115,7 +115,7 @@ namespace blt::iterator } protected: - mutable Iter iter; + Iter iter; }; template diff --git a/include/blt/iterator/enumerate.h b/include/blt/iterator/enumerate.h new file mode 100644 index 0000000..3747a70 --- /dev/null +++ b/include/blt/iterator/enumerate.h @@ -0,0 +1,59 @@ +#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_ENUMERATE_H +#define BLT_ITERATOR_ENUMERATE_H + +#include +#include +#include + +namespace blt +{ + + namespace iterator + { + /** + * struct which is returned by the enumerator. + * @tparam T type to store. + */ + template + struct enumerate_item + { + blt::size_t index; + T value; + }; + + template + class enumerate_wrapper : public passthrough_wrapper> + { + public: + using passthrough_wrapper>::passthrough_wrapper; + + enumerate_item> operator*() const + { + return *this->iter; + } + private: + blt::size_t index; + }; + } + +} + +#endif //BLT_ITERATOR_ENUMERATE_H diff --git a/include/blt/iterator/zip.h b/include/blt/iterator/zip.h index e763f0c..1fec30d 100644 --- a/include/blt/iterator/zip.h +++ b/include/blt/iterator/zip.h @@ -145,8 +145,8 @@ namespace blt template auto zip(iterator_pair... iterator_pairs) { - zip_iterator_container(iterator::zip_wrapper{std::move(iterator_pairs.begin)...}, - iterator::zip_wrapper{std::move(iterator_pairs.end)...}); + auto* d = static_cast(this); + return zip_iterator_container(iterator_pairbegin())>{d->begin(), d->end()}, iterator_pairs...); } }; } diff --git a/tests/iterator_tests.cpp b/tests/iterator_tests.cpp index 0fb5198..2cc275a 100644 --- a/tests/iterator_tests.cpp +++ b/tests/iterator_tests.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include