Brett 2024-09-23 15:51:39 -04:00
parent 96b071e337
commit 209b97079c
2 changed files with 126 additions and 30 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake)
set(BLT_VERSION 0.20.16)
set(BLT_VERSION 0.20.17)
set(BLT_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT)

View File

@ -43,27 +43,16 @@ namespace blt
End end_;
};
template<typename TYPE_ITR>
class iterator_base
{
public:
using value_type = blt::meta::value_type_t<TYPE_ITR, std::remove_pointer_t<TYPE_ITR>>;
using difference_type = blt::meta::difference_t<TYPE_ITR, std::ptrdiff_t>;
using pointer = blt::meta::pointer_t<TYPE_ITR, TYPE_ITR>;
using reference = blt::meta::reference_t<TYPE_ITR, std::remove_pointer_t<TYPE_ITR>&>;
using const_reference = blt::meta::const_reference_t<TYPE_ITR, const std::remove_pointer_t<TYPE_ITR>&>;
};
template<typename TYPE_ITR>
class iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = typename iterator_base<TYPE_ITR>::value_type;
using difference_type = typename iterator_base<TYPE_ITR>::difference_type;
using pointer = typename iterator_base<TYPE_ITR>::pointer;
using reference = typename iterator_base<TYPE_ITR>::reference;
using const_reference = typename iterator_base<TYPE_ITR>::const_reference;
using iterator_category = std::forward_iterator_tag;
using value_type = typename std::iterator_traits<TYPE_ITR>::value_type;
using difference_type = typename std::iterator_traits<TYPE_ITR>::difference_type;
using pointer = typename std::iterator_traits<TYPE_ITR>::pointer;
using reference = typename std::iterator_traits<TYPE_ITR>::reference;
using const_reference = const reference;
private:
blt::size_t index;
TYPE_ITR current;
@ -104,16 +93,65 @@ namespace blt
};
};
template<typename C1_TYPE, typename C2_TYPE>
class pair_iterator
{
public:
using c1_ref = typename std::iterator_traits<C1_TYPE>::reference;
using c2_ref = typename std::iterator_traits<C2_TYPE>::reference;
using iterator_category = std::forward_iterator_tag;
using value_type = std::pair<c1_ref, c2_ref>;
using difference_type = blt::ptrdiff_t;
using pointer = void*;
using reference = value_type&;
using const_reference = const value_type&;
explicit pair_iterator(C1_TYPE c1, C2_TYPE c2): current_c1_iter(c1), current_c2_iter(c2)
{}
pair_iterator& operator++()
{
++current_c1_iter;
++current_c2_iter;
return *this;
}
bool operator==(pair_iterator other) const
{
return current_c1_iter == other.current_c1_iter && current_c2_iter == other.current_c2_iter;
}
bool operator!=(pair_iterator other) const
{
return current_c1_iter != other.current_c1_iter || current_c2_iter != other.current_c2_iter;
}
value_type operator*() const
{
return {*current_c1_iter, *current_c2_iter};
};
value_type operator*()
{
return {*current_c1_iter, *current_c2_iter};
};
private:
C1_TYPE current_c1_iter;
C2_TYPE current_c2_iter;
};
template<typename TYPE_ITR>
class reverse_iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = typename iterator_base<TYPE_ITR>::value_type;
using difference_type = typename iterator_base<TYPE_ITR>::difference_type;
using pointer = typename iterator_base<TYPE_ITR>::pointer;
using reference = typename iterator_base<TYPE_ITR>::reference;
using const_reference = typename iterator_base<TYPE_ITR>::const_reference;
using iterator_category = std::forward_iterator_tag;
using value_type = typename std::iterator_traits<TYPE_ITR>::value_type;
using difference_type = typename std::iterator_traits<TYPE_ITR>::difference_type;
using pointer = typename std::iterator_traits<TYPE_ITR>::pointer;
using reference = typename std::iterator_traits<TYPE_ITR>::reference;
using const_reference = const reference;
private:
blt::size_t index;
TYPE_ITR current;
@ -155,6 +193,18 @@ namespace blt
};
}
template<typename Begin, typename End>
static inline auto iterate(Begin&& begin, End&& end)
{
return itr::itr_container<Begin, End>{std::forward<Begin>(begin), std::forward<End>(end)};
}
template<typename Begin, typename End>
static inline auto reverse_iterate(Begin&& begin, End&& end)
{
return itr::itr_container{std::reverse_iterator(std::forward<Begin>(end)), std::reverse_iterator(std::forward<End>(begin))};
}
template<typename TYPE_ITR, template<typename> typename iterator = itr::iterator>
class enumerator
{
@ -211,16 +261,62 @@ namespace blt
return enumerator{container.begin(), container.end()};
}
template<typename Begin, typename End>
static inline auto iterate(Begin&& begin, End&& end)
template<typename C1_ITER, typename C2_ITER, template<typename, typename> typename iterator = itr::pair_iterator>
class pair_enumerator
{
return itr::itr_container<Begin, End>{std::forward<Begin>(begin), std::forward<End>(end)};
public:
explicit pair_enumerator(C1_ITER c1_begin, C1_ITER c1_end, C2_ITER c2_begin, C2_ITER c2_end):
begin_(std::move(c1_begin), std::move(c2_begin)), end_(std::move(c1_end), std::move(c2_end))
{
auto size_c1 = c1_end - c1_begin;
auto size_c2 = c2_end - c2_begin;
if (size_c1 != size_c2)
throw std::runtime_error("Iterator sizes don't match!");
}
iterator<C1_ITER, C2_ITER> begin()
{
return begin_;
}
iterator<C1_ITER, C2_ITER> end()
{
return end_;
}
private:
iterator<C1_ITER, C2_ITER> begin_;
iterator<C1_ITER, C2_ITER> end_;
};
template<typename T, typename G>
static inline auto in_pairs(const T& container1, const G& container2)
{
return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()};
}
template<typename Begin, typename End>
static inline auto reverse_iterate(Begin&& begin, End&& end)
template<typename T, typename G>
static inline auto in_pairs(T& container1, G& container2)
{
return itr::itr_container{std::reverse_iterator(std::forward<Begin>(end)), std::reverse_iterator(std::forward<End>(begin))};
return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()};
}
template<typename T, typename G, blt::size_t size>
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<typename T, typename G, blt::size_t size>
static inline auto in_pairs(T(& container1)[size], G(& container2)[size])
{
return pair_enumerator{&container1[0], &container1[size], &container2[0], &container2[size]};
}
template<typename T, typename G>
static inline auto in_pairs(T&& container1, G&& container2)
{
return pair_enumerator{container1.begin(), container1.end(), container2.begin(), container2.end()};
}
template<typename T>