i am now working on flatten
parent
6935ae4785
commit
58ea39be08
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue