i am now working on flatten

v2
Brett 2025-02-27 15:17:59 -05:00
parent 6935ae4785
commit 58ea39be08
8 changed files with 223 additions and 94 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) include(cmake/color.cmake)
set(BLT_VERSION 4.0.31) set(BLT_VERSION 4.0.32)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -42,19 +42,21 @@ namespace blt::iterator
base_wrapper operator--(int) base_wrapper operator--(int)
{ {
static_assert(meta::is_bidirectional_or_better_category_v<typename Derived::iterator_category>, "Iterator must allow random access"); static_assert(meta::is_bidirectional_or_better_category_v<typename Derived::iterator_category>,
"Iterator must allow bidirectional access");
auto tmp = *this; auto tmp = *this;
--*this; --*this;
return tmp; return tmp;
} }
auto operator[](blt::ptrdiff_t n) const auto operator[](ptrdiff_t n) const
{ {
static_assert(meta::is_random_access_iterator_category_v<typename Derived::iterator_category>, "Iterator must allow random access"); static_assert(meta::is_random_access_iterator_category_v<typename Derived::iterator_category>,
"Iterator must allow bidirectional access");
return *(*this + n); 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; return a + n;
} }
@ -95,9 +97,8 @@ namespace blt::iterator
}; };
template <typename Iter, typename Derived, bool dereference = false> template <typename Iter, typename Derived, bool dereference = false>
struct passthrough_wrapper : public base_wrapper<Derived> struct passthrough_wrapper : base_wrapper<Derived>
{ {
public:
explicit passthrough_wrapper(Iter iter): iter(std::move(iter)) explicit passthrough_wrapper(Iter iter): iter(std::move(iter))
{ {
} }
@ -107,7 +108,7 @@ namespace blt::iterator
return iter; 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(); return a.base() - b.base();
} }
@ -117,7 +118,7 @@ namespace blt::iterator
}; };
template <typename Iter, typename Derived> template <typename Iter, typename Derived>
struct passthrough_wrapper<Iter, Derived, true> : public passthrough_wrapper<Iter, Derived> struct passthrough_wrapper<Iter, Derived, true> : passthrough_wrapper<Iter, Derived>
{ {
using passthrough_wrapper<Iter, Derived>::passthrough_wrapper; using passthrough_wrapper<Iter, Derived>::passthrough_wrapper;
@ -382,6 +383,14 @@ namespace blt::iterator
return enumerate_iterator_container{begin(), end(), static_cast<blt::size_t>(std::distance(begin(), end()))}; return enumerate_iterator_container{begin(), end(), static_cast<blt::size_t>(std::distance(begin(), end()))};
} }
auto flatten() const
{
return iterator_container<flatten_wrapper<IterBase>>{
blt::iterator::flatten_wrapper<IterBase>{m_begin},
blt::iterator::flatten_wrapper<IterBase>{m_end}
};
}
template <typename Func> template <typename Func>
auto map(Func func) const auto map(Func func) const
{ {

View File

@ -20,120 +20,123 @@
#define BLT_ITERATOR_ENUMERATE_H #define BLT_ITERATOR_ENUMERATE_H
#include <blt/iterator/common.h> #include <blt/iterator/common.h>
#include <tuple>
namespace blt namespace blt
{ {
namespace iterator namespace iterator
{ {
/** /**
* struct which is returned by the enumerator. * struct which is returned by the enumerator.
* @tparam T type to store. * @tparam T type to store.
*/ */
template<typename T> template <typename T>
struct enumerate_item struct enumerate_item
{ {
blt::size_t index; const size_t index;
T value; T value;
}; };
template<typename Iter> template <typename Iter>
class enumerate_wrapper : public passthrough_wrapper<Iter, enumerate_wrapper<Iter>> class enumerate_wrapper : public passthrough_wrapper<Iter, enumerate_wrapper<Iter>>
{ {
public: public:
enumerate_wrapper(blt::size_t index, Iter iter): passthrough_wrapper<Iter, enumerate_wrapper<Iter>>(std::move(iter)), index(index) enumerate_wrapper(const size_t index, Iter iter): passthrough_wrapper<Iter, enumerate_wrapper<Iter>>(std::move(iter)), index(index)
{} {
}
using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
using value_type = enumerate_item<meta::deref_return_t<Iter>>; using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
using difference_type = blt::ptrdiff_t; using value_type = enumerate_item<Iter>;
using pointer = value_type; using difference_type = blt::ptrdiff_t;
using reference = value_type; using pointer = value_type;
using reference = value_type;
enumerate_item<meta::deref_return_t<Iter>> operator*() const
{ enumerate_item<meta::deref_return_t<Iter>> operator*() const
return {index, *this->iter}; {
} return {index, *this->iter};
}
enumerate_wrapper& operator++()
{ enumerate_wrapper& operator++()
++index; {
++this->iter; ++index;
return *this; ++this->iter;
} return *this;
}
enumerate_wrapper& operator--()
{ enumerate_wrapper& operator--()
--index; {
--this->iter; --index;
return *this; --this->iter;
} return *this;
}
friend enumerate_wrapper operator+(const enumerate_wrapper& a, blt::ptrdiff_t n)
{ friend enumerate_wrapper operator+(const enumerate_wrapper& a, blt::ptrdiff_t n)
static_assert(meta::is_random_access_iterator_v<Iter>, "Iterator must allow random access"); {
auto copy = a; static_assert(meta::is_random_access_iterator_v<Iter>, "Iterator must allow random access");
copy.index += n; auto copy = a;
copy.iter = copy.iter + n; copy.index += n;
return copy; copy.iter = copy.iter + n;
} return copy;
}
friend enumerate_wrapper operator-(const enumerate_wrapper& a, blt::ptrdiff_t n)
{ friend enumerate_wrapper operator-(const enumerate_wrapper& a, blt::ptrdiff_t n)
static_assert(meta::is_random_access_iterator_v<Iter>, "Iterator must allow random access"); {
auto copy = a; static_assert(meta::is_random_access_iterator_v<Iter>, "Iterator must allow random access");
copy.index -= n; auto copy = a;
copy.iter = copy.iter - n; copy.index -= n;
return copy; copy.iter = copy.iter - n;
} return copy;
}
private:
blt::size_t index; private:
blt::size_t index;
}; };
} }
template<typename Iter> template <typename Iter>
class enumerate_iterator_container : public iterator::iterator_container<iterator::enumerate_wrapper<Iter>> class enumerate_iterator_container : public iterator::iterator_container<iterator::enumerate_wrapper<Iter>>
{ {
public: public:
using iterator::iterator_container<iterator::enumerate_wrapper<Iter>>::iterator_container; using iterator::iterator_container<iterator::enumerate_wrapper<Iter>>::iterator_container;
enumerate_iterator_container(Iter begin, Iter end, blt::size_t size): enumerate_iterator_container(Iter begin, Iter end, blt::size_t size):
iterator::iterator_container<iterator::enumerate_wrapper<Iter>>( iterator::iterator_container<iterator::enumerate_wrapper<Iter>>(
iterator::enumerate_wrapper<Iter>{0, std::move(begin)}, iterator::enumerate_wrapper<Iter>{size, std::move(end)}) iterator::enumerate_wrapper<Iter>{0, std::move(begin)}, iterator::enumerate_wrapper<Iter>{size, std::move(end)})
{} {
}
}; };
template<typename Iter> template <typename Iter>
enumerate_iterator_container(Iter, Iter, blt::size_t) -> enumerate_iterator_container<Iter>; enumerate_iterator_container(Iter, Iter, blt::size_t) -> enumerate_iterator_container<Iter>;
template<typename T> template <typename T>
static inline auto enumerate(T& container) static inline auto enumerate(T& container)
{ {
return enumerate_iterator_container{container.begin(), container.end(), return enumerate_iterator_container{
static_cast<blt::size_t>(std::distance(container.begin(), container.end()))}; container.begin(), container.end(),
static_cast<blt::size_t>(std::distance(container.begin(), container.end()))
};
} }
template<typename T> template <typename T>
static inline auto enumerate(const T& container) static inline auto enumerate(const T& container)
{ {
return enumerate_iterator_container{container.begin(), container.end(), return enumerate_iterator_container{
static_cast<blt::size_t>(std::distance(container.begin(), container.end()))}; container.begin(), container.end(),
static_cast<blt::size_t>(std::distance(container.begin(), container.end()))
};
} }
template<typename T, blt::size_t size> template <typename T, blt::size_t size>
static inline auto enumerate(const T(& container)[size]) static inline auto enumerate(const T (&container)[size])
{ {
return enumerate_iterator_container{&container[0], &container[size], size}; return enumerate_iterator_container{&container[0], &container[size], size};
} }
template<typename T, blt::size_t size> template <typename T, blt::size_t size>
static inline auto enumerate(T(& container)[size]) static inline auto enumerate(T (&container)[size])
{ {
return enumerate_iterator_container{&container[0], &container[size], size}; return enumerate_iterator_container{&container[0], &container[size], size};
} }
} }
#endif //BLT_ITERATOR_ENUMERATE_H #endif //BLT_ITERATOR_ENUMERATE_H

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_ITERATOR_FLATTEN_H
#define BLT_ITERATOR_FLATTEN_H
#include <blt/iterator/common.h>
#include <tuple>
namespace blt::iterator
{
namespace detail
{
template<typename T>
struct make_tuple
{
using type = std::tuple<T>;
static auto convert(T&& f)
{
return std::forward_as_tuple(std::forward<T>(f));
}
};
template<typename... Args>
struct make_tuple<std::tuple<Args...>>
{
using type = std::tuple<Args...>;
static std::tuple<Args...>& convert(std::tuple<Args...>& lvalue)
{
return lvalue;
}
static std::tuple<Args...>&& convert(std::tuple<Args...>&& rvalue)
{
return rvalue;
}
};
}
template <typename Iter>
class flatten_wrapper : public deref_only_wrapper<Iter, flatten_wrapper<Iter>>
{
public:
using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
// using value_type = std::invoke_result_t<Func, meta::deref_return_t<Iter>>;
using difference_type = ptrdiff_t;
// using pointer = value_type;
// using reference = value_type;
explicit flatten_wrapper(Iter iter):
deref_only_wrapper<Iter, flatten_wrapper<Iter>>(std::move(iter))
{
}
reference operator*() const
{
return func(*this->iter);
}
};
}
#endif //BLT_ITERATOR_FLATTEN_H

View File

@ -46,6 +46,9 @@ namespace blt
template<typename Iter, typename Pred> template<typename Iter, typename Pred>
class filter_wrapper; class filter_wrapper;
template<typename Iter>
class flatten_wrapper;
namespace impl namespace impl
{ {

View File

@ -114,7 +114,7 @@ namespace blt::meta
template<typename T> template<typename T>
struct deref_return struct deref_return
{ {
using type = typename std::invoke_result_t<decltype(&T::operator*), T&>; using type = std::invoke_result_t<decltype(&T::operator*), T&>;
}; };
template<typename T> template<typename T>

View File

@ -20,11 +20,44 @@
#define BLT_META_TYPE_TRAITS_H #define BLT_META_TYPE_TRAITS_H
#include <type_traits> #include <type_traits>
#include <tuple>
namespace blt::meta { namespace blt::meta
{
template <typename T>
using remove_cvref_t = std::remove_volatile_t<std::remove_const_t<std::remove_reference_t<T>>>;
template <typename U>
using add_const_ref_t = std::conditional_t<std::is_reference_v<U>, const std::remove_reference_t<U>&, const U>;
template <typename>
struct is_tuple : std::false_type
{
};
template <typename... T>
struct is_tuple<std::tuple<T...>> : std::true_type
{
};
template <typename>
struct is_pair : std::false_type
{
};
template <typename T, typename G>
struct is_pair<std::pair<T, G>> : std::true_type
{
};
template<typename T> template<typename T>
using remove_cvref_t = std::remove_volatile_t<std::remove_const_t<std::remove_reference_t<T>>>; static constexpr bool is_tuple_v = is_tuple<T>::value;
template<typename T>
static constexpr bool is_pair_v = is_pair<T>::value;
template<typename T>
static constexpr bool is_tuple_like_v = is_tuple_v<T> || is_pair_v<T>;
} }

View File

@ -24,6 +24,7 @@
#include <blt/iterator/enumerate.h> #include <blt/iterator/enumerate.h>
#include <blt/fs/path_helper.h> #include <blt/fs/path_helper.h>
#include <blt/std/string.h> #include <blt/std/string.h>
#include <blt/iterator/flatten.h>
namespace blt::argparse namespace blt::argparse
{ {
@ -415,7 +416,7 @@ namespace blt::argparse
if (i != strings.size() - 1) if (i != strings.size() - 1)
help += ", "; help += ", ";
} }
help += parser.he // help += parser.he
help.newline(); help.newline();
} }
} }