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)
include(cmake/color.cmake)
set(BLT_VERSION 4.0.31)
set(BLT_VERSION 4.0.32)
set(BLT_TARGET BLT)

View File

@ -42,19 +42,21 @@ namespace blt::iterator
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;
--*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<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);
}
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 <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))
{
}
@ -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 <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;
@ -382,6 +383,14 @@ namespace blt::iterator
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>
auto map(Func func) const
{

View File

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

View File

@ -114,7 +114,7 @@ namespace blt::meta
template<typename T>
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>

View File

@ -20,11 +20,44 @@
#define BLT_META_TYPE_TRAITS_H
#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>
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/fs/path_helper.h>
#include <blt/std/string.h>
#include <blt/iterator/flatten.h>
namespace blt::argparse
{
@ -415,7 +416,7 @@ namespace blt::argparse
if (i != strings.size() - 1)
help += ", ";
}
help += parser.he
// help += parser.he
help.newline();
}
}