diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fea85e..73252bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 4.0.31) +set(BLT_VERSION 4.0.32) set(BLT_TARGET BLT) diff --git a/include/blt/iterator/common.h b/include/blt/iterator/common.h index d98ddeb..92a5b29 100644 --- a/include/blt/iterator/common.h +++ b/include/blt/iterator/common.h @@ -42,19 +42,21 @@ namespace blt::iterator base_wrapper operator--(int) { - static_assert(meta::is_bidirectional_or_better_category_v, "Iterator must allow random access"); + static_assert(meta::is_bidirectional_or_better_category_v, + "Iterator must allow bidirectional access"); auto tmp = *this; --*this; return tmp; } - auto operator[](blt::ptrdiff_t n) const + auto operator[](ptrdiff_t n) const { - static_assert(meta::is_random_access_iterator_category_v, "Iterator must allow random access"); + static_assert(meta::is_random_access_iterator_category_v, + "Iterator must allow bidirectional access"); return *(*this + n); } - friend base_wrapper operator+(blt::ptrdiff_t n, const base_wrapper& a) + friend base_wrapper operator+(ptrdiff_t n, const base_wrapper& a) { return a + n; } @@ -95,9 +97,8 @@ namespace blt::iterator }; template - struct passthrough_wrapper : public base_wrapper + struct passthrough_wrapper : base_wrapper { - public: explicit passthrough_wrapper(Iter iter): iter(std::move(iter)) { } @@ -107,7 +108,7 @@ namespace blt::iterator return iter; } - friend blt::ptrdiff_t operator-(const passthrough_wrapper& a, const passthrough_wrapper& b) + friend ptrdiff_t operator-(const passthrough_wrapper& a, const passthrough_wrapper& b) { return a.base() - b.base(); } @@ -117,7 +118,7 @@ namespace blt::iterator }; template - struct passthrough_wrapper : public passthrough_wrapper + struct passthrough_wrapper : passthrough_wrapper { using passthrough_wrapper::passthrough_wrapper; @@ -382,6 +383,14 @@ namespace blt::iterator return enumerate_iterator_container{begin(), end(), static_cast(std::distance(begin(), end()))}; } + auto flatten() const + { + return iterator_container>{ + blt::iterator::flatten_wrapper{m_begin}, + blt::iterator::flatten_wrapper{m_end} + }; + } + template auto map(Func func) const { diff --git a/include/blt/iterator/enumerate.h b/include/blt/iterator/enumerate.h index 0a3ea12..3dbc9af 100644 --- a/include/blt/iterator/enumerate.h +++ b/include/blt/iterator/enumerate.h @@ -20,120 +20,123 @@ #define BLT_ITERATOR_ENUMERATE_H #include -#include namespace blt { - namespace iterator { /** * struct which is returned by the enumerator. * @tparam T type to store. */ - template + template struct enumerate_item { - blt::size_t index; + const size_t index; T value; }; - - template + + template class enumerate_wrapper : public passthrough_wrapper> { - public: - enumerate_wrapper(blt::size_t index, Iter iter): passthrough_wrapper>(std::move(iter)), index(index) - {} - - using iterator_category = typename std::iterator_traits::iterator_category; - using value_type = enumerate_item>; - using difference_type = blt::ptrdiff_t; - using pointer = value_type; - using reference = value_type; - - enumerate_item> operator*() const - { - return {index, *this->iter}; - } - - enumerate_wrapper& operator++() - { - ++index; - ++this->iter; - return *this; - } - - enumerate_wrapper& operator--() - { - --index; - --this->iter; - return *this; - } - - friend enumerate_wrapper operator+(const enumerate_wrapper& a, blt::ptrdiff_t n) - { - static_assert(meta::is_random_access_iterator_v, "Iterator must allow random access"); - auto copy = a; - copy.index += n; - copy.iter = copy.iter + n; - return copy; - } - - friend enumerate_wrapper operator-(const enumerate_wrapper& a, blt::ptrdiff_t n) - { - static_assert(meta::is_random_access_iterator_v, "Iterator must allow random access"); - auto copy = a; - copy.index -= n; - copy.iter = copy.iter - n; - return copy; - } - - private: - blt::size_t index; + public: + enumerate_wrapper(const size_t index, Iter iter): passthrough_wrapper>(std::move(iter)), index(index) + { + } + + using iterator_category = typename std::iterator_traits::iterator_category; + using value_type = enumerate_item; + using difference_type = blt::ptrdiff_t; + using pointer = value_type; + using reference = value_type; + + enumerate_item> operator*() const + { + return {index, *this->iter}; + } + + enumerate_wrapper& operator++() + { + ++index; + ++this->iter; + return *this; + } + + enumerate_wrapper& operator--() + { + --index; + --this->iter; + return *this; + } + + friend enumerate_wrapper operator+(const enumerate_wrapper& a, blt::ptrdiff_t n) + { + static_assert(meta::is_random_access_iterator_v, "Iterator must allow random access"); + auto copy = a; + copy.index += n; + copy.iter = copy.iter + n; + return copy; + } + + friend enumerate_wrapper operator-(const enumerate_wrapper& a, blt::ptrdiff_t n) + { + static_assert(meta::is_random_access_iterator_v, "Iterator must allow random access"); + auto copy = a; + copy.index -= n; + copy.iter = copy.iter - n; + return copy; + } + + private: + blt::size_t index; }; } - - template + + template class enumerate_iterator_container : public iterator::iterator_container> { - public: - using iterator::iterator_container>::iterator_container; - - enumerate_iterator_container(Iter begin, Iter end, blt::size_t size): - iterator::iterator_container>( - iterator::enumerate_wrapper{0, std::move(begin)}, iterator::enumerate_wrapper{size, std::move(end)}) - {} + public: + using iterator::iterator_container>::iterator_container; + + enumerate_iterator_container(Iter begin, Iter end, blt::size_t size): + iterator::iterator_container>( + iterator::enumerate_wrapper{0, std::move(begin)}, iterator::enumerate_wrapper{size, std::move(end)}) + { + } }; - - template + + template enumerate_iterator_container(Iter, Iter, blt::size_t) -> enumerate_iterator_container; - - template + + template static inline auto enumerate(T& container) { - return enumerate_iterator_container{container.begin(), container.end(), - static_cast(std::distance(container.begin(), container.end()))}; + return enumerate_iterator_container{ + container.begin(), container.end(), + static_cast(std::distance(container.begin(), container.end())) + }; } - - template + + template static inline auto enumerate(const T& container) { - return enumerate_iterator_container{container.begin(), container.end(), - static_cast(std::distance(container.begin(), container.end()))}; + return enumerate_iterator_container{ + container.begin(), container.end(), + static_cast(std::distance(container.begin(), container.end())) + }; } - - template - static inline auto enumerate(const T(& container)[size]) + + template + static inline auto enumerate(const T (&container)[size]) { return enumerate_iterator_container{&container[0], &container[size], size}; } - - template - static inline auto enumerate(T(& container)[size]) + + template + static inline auto enumerate(T (&container)[size]) { return enumerate_iterator_container{&container[0], &container[size], size}; } - } #endif //BLT_ITERATOR_ENUMERATE_H diff --git a/include/blt/iterator/flatten.h b/include/blt/iterator/flatten.h new file mode 100644 index 0000000..e6b22f9 --- /dev/null +++ b/include/blt/iterator/flatten.h @@ -0,0 +1,80 @@ +#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_FLATTEN_H +#define BLT_ITERATOR_FLATTEN_H + +#include +#include + +namespace blt::iterator +{ + namespace detail + { + template + struct make_tuple + { + using type = std::tuple; + + static auto convert(T&& f) + { + return std::forward_as_tuple(std::forward(f)); + } + }; + + template + struct make_tuple> + { + using type = std::tuple; + + static std::tuple& convert(std::tuple& lvalue) + { + return lvalue; + } + + static std::tuple&& convert(std::tuple&& rvalue) + { + return rvalue; + } + }; + } + + template + class flatten_wrapper : public deref_only_wrapper> + { + public: + using iterator_category = typename std::iterator_traits::iterator_category; + // using value_type = std::invoke_result_t>; + using difference_type = ptrdiff_t; + // using pointer = value_type; + // using reference = value_type; + + explicit flatten_wrapper(Iter iter): + deref_only_wrapper>(std::move(iter)) + { + } + + reference operator*() const + { + return func(*this->iter); + } + }; +} + + +#endif //BLT_ITERATOR_FLATTEN_H diff --git a/include/blt/iterator/fwddecl.h b/include/blt/iterator/fwddecl.h index f0e80ea..612ce36 100644 --- a/include/blt/iterator/fwddecl.h +++ b/include/blt/iterator/fwddecl.h @@ -46,6 +46,9 @@ namespace blt template class filter_wrapper; + + template + class flatten_wrapper; namespace impl { diff --git a/include/blt/meta/meta.h b/include/blt/meta/meta.h index fe502ca..97b2d55 100644 --- a/include/blt/meta/meta.h +++ b/include/blt/meta/meta.h @@ -114,7 +114,7 @@ namespace blt::meta template struct deref_return { - using type = typename std::invoke_result_t; + using type = std::invoke_result_t; }; template diff --git a/include/blt/meta/type_traits.h b/include/blt/meta/type_traits.h index d811aa5..5be8c28 100644 --- a/include/blt/meta/type_traits.h +++ b/include/blt/meta/type_traits.h @@ -20,11 +20,44 @@ #define BLT_META_TYPE_TRAITS_H #include +#include -namespace blt::meta { +namespace blt::meta +{ + template + using remove_cvref_t = std::remove_volatile_t>>; + + template + using add_const_ref_t = std::conditional_t, const std::remove_reference_t&, const U>; + + template + struct is_tuple : std::false_type + { + }; + + template + struct is_tuple> : std::true_type + { + }; + + template + struct is_pair : std::false_type + { + }; + + template + struct is_pair> : std::true_type + { + }; template - using remove_cvref_t = std::remove_volatile_t>>; + static constexpr bool is_tuple_v = is_tuple::value; + + template + static constexpr bool is_pair_v = is_pair::value; + + template + static constexpr bool is_tuple_like_v = is_tuple_v || is_pair_v; } diff --git a/src/blt/parse/argparse_v2.cpp b/src/blt/parse/argparse_v2.cpp index 86e282b..33ef63d 100644 --- a/src/blt/parse/argparse_v2.cpp +++ b/src/blt/parse/argparse_v2.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace blt::argparse { @@ -415,7 +416,7 @@ namespace blt::argparse if (i != strings.size() - 1) help += ", "; } - help += parser.he + // help += parser.he help.newline(); } }