zip iterator, random access
parent
fb3ed3aa5e
commit
7580fa544a
|
@ -1,7 +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 1.0.1)
|
set(BLT_VERSION 1.0.2)
|
||||||
set(BLT_TEST_VERSION 0.0.1)
|
|
||||||
|
|
||||||
set(BLT_TARGET BLT)
|
set(BLT_TARGET BLT)
|
||||||
|
|
||||||
|
@ -34,6 +33,8 @@ if(${BLT_DISABLE_STATS})
|
||||||
add_compile_definitions(BLT_DISABLE_STATS)
|
add_compile_definitions(BLT_DISABLE_STATS)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
find_program(MOLD "mold")
|
||||||
|
|
||||||
configure_file(include/blt/config.h.in config/blt/config.h @ONLY)
|
configure_file(include/blt/config.h.in config/blt/config.h @ONLY)
|
||||||
|
|
||||||
message("Enabling library compilation")
|
message("Enabling library compilation")
|
||||||
|
@ -138,28 +139,62 @@ install(FILES ${CMAKE_BINARY_DIR}/config/blt/config.h DESTINATION ${CMAKE_INSTAL
|
||||||
|
|
||||||
set_target_properties(${BLT_TARGET} PROPERTIES VERSION ${BLT_VERSION})
|
set_target_properties(${BLT_TARGET} PROPERTIES VERSION ${BLT_VERSION})
|
||||||
set_target_properties(${BLT_TARGET} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
|
set_target_properties(${BLT_TARGET} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||||
|
if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND)
|
||||||
|
target_compile_options(${BLT_TARGET} PUBLIC -fuse-ld=mold)
|
||||||
|
endif ()
|
||||||
|
|
||||||
install(TARGETS ${BLT_TARGET}
|
install(TARGETS ${BLT_TARGET}
|
||||||
CONFIGURATIONS RelWithDebInfo
|
CONFIGURATIONS RelWithDebInfo
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
macro(blt_add_project name source type)
|
||||||
|
|
||||||
|
project(${name}-${type})
|
||||||
|
|
||||||
|
add_executable(${name}-${type} ${source})
|
||||||
|
|
||||||
|
target_link_libraries(${name}-${type} PRIVATE BLT)
|
||||||
|
|
||||||
|
target_compile_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
|
||||||
|
target_link_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
|
||||||
|
target_compile_definitions(${name}-${type} PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL})
|
||||||
|
|
||||||
|
if (NOT ${MOLD} STREQUAL MOLD-NOTFOUND)
|
||||||
|
target_compile_options(${name}-${type} PUBLIC -fuse-ld=mold)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (${TRACK_ALLOCATIONS})
|
||||||
|
target_compile_definitions(${name}-${type} PRIVATE BLT_TRACK_ALLOCATIONS=1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (${ENABLE_ADDRSAN} MATCHES ON)
|
||||||
|
target_compile_options(${name}-${type} PRIVATE -fsanitize=address)
|
||||||
|
target_link_options(${name}-${type} PRIVATE -fsanitize=address)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (${ENABLE_UBSAN} MATCHES ON)
|
||||||
|
target_compile_options(${name}-${type} PRIVATE -fsanitize=undefined)
|
||||||
|
target_link_options(${name}-${type} PRIVATE -fsanitize=undefined)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (${ENABLE_TSAN} MATCHES ON)
|
||||||
|
target_compile_options(${name}-${type} PRIVATE -fsanitize=thread)
|
||||||
|
target_link_options(${name}-${type} PRIVATE -fsanitize=thread)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_test(NAME ${name} COMMAND ${name}-${type})
|
||||||
|
|
||||||
|
set(failRegex "\\[WARN\\]" "FAIL" "ERROR" "FATAL" "exception")
|
||||||
|
set_property(TEST ${name} PROPERTY FAIL_REGULAR_EXPRESSION "${failRegex}")
|
||||||
|
|
||||||
|
project(${BLT_TARGET})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
if (${BUILD_TESTS})
|
if (${BUILD_TESTS})
|
||||||
message("Building test version ${BLT_TEST_VERSION}")
|
message("Building tests for version ${BLT_VERSION}")
|
||||||
project(BLT_TESTS VERSION ${BLT_TEST_VERSION})
|
|
||||||
|
|
||||||
include_directories(tests/include)
|
blt_add_project(blt-iterator tests/iterator_tests.cpp test)
|
||||||
|
|
||||||
file(GLOB_RECURSE TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.cpp")
|
|
||||||
|
|
||||||
message("Using files ${TEST_FILES}")
|
|
||||||
|
|
||||||
add_executable(BLT_TESTS ${TEST_FILES})
|
|
||||||
|
|
||||||
target_link_libraries(BLT_TESTS PRIVATE BLT)
|
|
||||||
|
|
||||||
include(cmake/warnings.cmake)
|
|
||||||
include(cmake/sanitizers.cmake)
|
|
||||||
|
|
||||||
message("Built tests")
|
message("Built tests")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -59,118 +59,6 @@ namespace blt
|
||||||
template<typename Iter1, typename Iter2, typename = std::void_t<>>
|
template<typename Iter1, typename Iter2, typename = std::void_t<>>
|
||||||
class pair_wrapper;
|
class pair_wrapper;
|
||||||
|
|
||||||
template<typename Tag, typename... Iter>
|
|
||||||
class zip_wrapper;
|
|
||||||
|
|
||||||
template<typename Tag, typename... Iter>
|
|
||||||
class zip_iterator_storage;
|
|
||||||
|
|
||||||
template<typename Tag, typename... Iter>
|
|
||||||
class zip_iterator_storage_rev;
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_forward_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit zip_forward_iterator(Iter... iter): iter(std::make_tuple(iter...))
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::tuple<blt::meta::deref_return_t<Iter>...> operator*() const
|
|
||||||
{
|
|
||||||
return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(const zip_forward_iterator& a, const zip_forward_iterator& b)
|
|
||||||
{
|
|
||||||
return a.iter == b.iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator!=(const zip_forward_iterator& a, const zip_forward_iterator& b)
|
|
||||||
{
|
|
||||||
return !(a.iter == b.iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_forward_iterator& operator++()
|
|
||||||
{
|
|
||||||
std::apply([](auto& ... i) { ((++i), ...); }, iter);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_forward_iterator operator++(int)
|
|
||||||
{
|
|
||||||
auto tmp = *this;
|
|
||||||
++*this;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto base()
|
|
||||||
{
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::tuple<Iter...> iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_bidirectional_iterator : public zip_forward_iterator<Iter...>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using zip_forward_iterator<Iter...>::zip_forward_iterator;
|
|
||||||
|
|
||||||
zip_bidirectional_iterator& operator--()
|
|
||||||
{
|
|
||||||
std::apply([](auto& ... i) { ((--i), ...); }, this->iter);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_bidirectional_iterator operator--(int)
|
|
||||||
{
|
|
||||||
auto tmp = *this;
|
|
||||||
--*this;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_wrapper<std::forward_iterator_tag, Iter...> : public zip_forward_iterator<Iter...>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using zip_forward_iterator<Iter...>::zip_forward_iterator;
|
|
||||||
|
|
||||||
using iterator_category = std::forward_iterator_tag;
|
|
||||||
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
|
||||||
using difference_type = blt::ptrdiff_t;
|
|
||||||
using pointer = value_type;
|
|
||||||
using reference = value_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_wrapper<std::bidirectional_iterator_tag, Iter...> : public zip_bidirectional_iterator<Iter...>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
|
|
||||||
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
|
||||||
using difference_type = blt::ptrdiff_t;
|
|
||||||
using pointer = value_type;
|
|
||||||
using reference = value_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_wrapper<std::random_access_iterator_tag, Iter...> : public zip_bidirectional_iterator<Iter...>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
|
|
||||||
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
|
||||||
using difference_type = blt::ptrdiff_t;
|
|
||||||
using pointer = value_type;
|
|
||||||
using reference = value_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct which is returned by the enumerator.
|
* struct which is returned by the enumerator.
|
||||||
* @tparam T type to store.
|
* @tparam T type to store.
|
||||||
|
@ -590,25 +478,6 @@ namespace blt
|
||||||
return CompleteEnumerator{b->begin(), b->end(), static_cast<blt::size_t>(std::distance(b->begin(), b->end()))};
|
return CompleteEnumerator{b->begin(), b->end(), static_cast<blt::size_t>(std::distance(b->begin(), b->end()))};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_iterator_storage<std::forward_iterator_tag, Iter...>
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_iterator_storage<std::bidirectional_iterator_tag, Iter...>
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Iter>
|
|
||||||
class zip_iterator_storage<std::random_access_iterator_tag, Iter...>
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,6 +25,356 @@
|
||||||
namespace blt
|
namespace blt
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace iterator
|
||||||
|
{
|
||||||
|
template<typename Tag, typename... Iter>
|
||||||
|
class zip_wrapper;
|
||||||
|
|
||||||
|
template<typename Tag, typename... Iter>
|
||||||
|
class zip_iterator_storage;
|
||||||
|
|
||||||
|
template<typename Tag, typename... Iter>
|
||||||
|
class zip_iterator_storage_rev;
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_forward_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit zip_forward_iterator(Iter... iter): iter(std::make_tuple(iter...))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::tuple<blt::meta::deref_return_t<Iter>...> operator*() const
|
||||||
|
{
|
||||||
|
return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const zip_forward_iterator& a, const zip_forward_iterator& b)
|
||||||
|
{
|
||||||
|
return a.iter == b.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const zip_forward_iterator& a, const zip_forward_iterator& b)
|
||||||
|
{
|
||||||
|
return !(a.iter == b.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_forward_iterator& operator++()
|
||||||
|
{
|
||||||
|
std::apply([](auto& ... i) { ((++i), ...); }, iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_forward_iterator operator++(int)
|
||||||
|
{
|
||||||
|
auto tmp = *this;
|
||||||
|
++*this;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto base()
|
||||||
|
{
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::tuple<Iter...> iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_bidirectional_iterator : public zip_forward_iterator<Iter...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using zip_forward_iterator<Iter...>::zip_forward_iterator;
|
||||||
|
|
||||||
|
zip_bidirectional_iterator& operator--()
|
||||||
|
{
|
||||||
|
std::apply([](auto& ... i) { ((--i), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_bidirectional_iterator operator--(int)
|
||||||
|
{
|
||||||
|
auto tmp = *this;
|
||||||
|
--*this;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_random_access_iterator : public zip_bidirectional_iterator<Iter...>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template<typename T, T... n>
|
||||||
|
static blt::ptrdiff_t sub(const zip_random_access_iterator& a, const zip_random_access_iterator& b,
|
||||||
|
std::integer_sequence<T, n...>)
|
||||||
|
{
|
||||||
|
auto min = std::min(std::get<n>(a.iter) - std::get<n>(b.iter)...);
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
|
||||||
|
|
||||||
|
zip_random_access_iterator& operator+=(blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_random_access_iterator& operator-=(blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_random_access_iterator operator+(const zip_random_access_iterator& a, blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_random_access_iterator operator+(blt::ptrdiff_t n, const zip_random_access_iterator& a)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_random_access_iterator operator-(const zip_random_access_iterator& a, blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_random_access_iterator operator-(blt::ptrdiff_t n, const zip_random_access_iterator& a)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend blt::ptrdiff_t operator-(const zip_random_access_iterator& a, const zip_random_access_iterator& b)
|
||||||
|
{
|
||||||
|
return sub(a, b, std::index_sequence_for<Iter...>());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator[](blt::ptrdiff_t n) const
|
||||||
|
{
|
||||||
|
return *(*this + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(const zip_random_access_iterator& a, const zip_random_access_iterator& b)
|
||||||
|
{
|
||||||
|
return b - a > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>(const zip_random_access_iterator& a, const zip_random_access_iterator& b)
|
||||||
|
{
|
||||||
|
return b < a;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>=(const zip_random_access_iterator& a, const zip_random_access_iterator& b)
|
||||||
|
{
|
||||||
|
return !(a < b); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<=(const zip_random_access_iterator& a, const zip_random_access_iterator& b)
|
||||||
|
{
|
||||||
|
return !(a > b); // NOLINT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_wrapper<std::forward_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
||||||
|
using difference_type = blt::ptrdiff_t;
|
||||||
|
using pointer = value_type;
|
||||||
|
using reference = value_type;
|
||||||
|
|
||||||
|
explicit zip_wrapper(Iter... iter): iter(std::make_tuple(iter...))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::tuple<blt::meta::deref_return_t<Iter>...> operator*() const
|
||||||
|
{
|
||||||
|
return std::apply([](auto& ... i) { return std::make_tuple(*i...); }, iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return a.iter == b.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return !(a.iter == b.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_wrapper& operator++()
|
||||||
|
{
|
||||||
|
std::apply([](auto& ... i) { ((++i), ...); }, iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_wrapper operator++(int)
|
||||||
|
{
|
||||||
|
auto tmp = *this;
|
||||||
|
++*this;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto base()
|
||||||
|
{
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::tuple<Iter...> iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_wrapper<std::bidirectional_iterator_tag, Iter...> : public zip_wrapper<std::forward_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using zip_wrapper<std::forward_iterator_tag, Iter...>::zip_wrapper;
|
||||||
|
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
||||||
|
using difference_type = blt::ptrdiff_t;
|
||||||
|
using pointer = value_type;
|
||||||
|
using reference = value_type;
|
||||||
|
|
||||||
|
zip_wrapper& operator--()
|
||||||
|
{
|
||||||
|
std::apply([](auto& ... i) { ((--i), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_wrapper operator--(int)
|
||||||
|
{
|
||||||
|
auto tmp = *this;
|
||||||
|
--*this;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_wrapper<std::random_access_iterator_tag, Iter...> : public zip_wrapper<std::bidirectional_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template<typename T, T... n>
|
||||||
|
static blt::ptrdiff_t sub(const zip_wrapper& a, const zip_wrapper& b,
|
||||||
|
std::integer_sequence<T, n...>)
|
||||||
|
{
|
||||||
|
auto min = std::min(std::get<n>(a.iter) - std::get<n>(b.iter)...);
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
using zip_wrapper<std::bidirectional_iterator_tag, Iter...>::zip_wrapper;
|
||||||
|
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = std::tuple<blt::meta::deref_return_t<Iter>...>;
|
||||||
|
using difference_type = blt::ptrdiff_t;
|
||||||
|
using pointer = value_type;
|
||||||
|
using reference = value_type;
|
||||||
|
|
||||||
|
using zip_bidirectional_iterator<Iter...>::zip_bidirectional_iterator;
|
||||||
|
|
||||||
|
zip_wrapper& operator+=(blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
std::apply([n](auto& ... i) { ((i += n), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
zip_wrapper& operator-=(blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
std::apply([n](auto& ... i) { ((i -= n), ...); }, this->iter);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_wrapper operator+(const zip_wrapper& a, blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_wrapper operator+(blt::ptrdiff_t n, const zip_wrapper& a)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i + n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_wrapper operator-(const zip_wrapper& a, blt::ptrdiff_t n)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend zip_wrapper operator-(blt::ptrdiff_t n, const zip_wrapper& a)
|
||||||
|
{
|
||||||
|
return std::apply([n](auto& ... i) { return zip_random_access_iterator{(i - n)...}; }, a.iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend blt::ptrdiff_t operator-(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return sub(a, b, std::index_sequence_for<Iter...>());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator[](blt::ptrdiff_t n) const
|
||||||
|
{
|
||||||
|
return *(*this + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return b - a > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return b < a;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>=(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return !(a < b); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<=(const zip_wrapper& a, const zip_wrapper& b)
|
||||||
|
{
|
||||||
|
return !(a > b); // NOLINT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage<std::forward_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage<std::bidirectional_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage<std::random_access_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage_rev<std::forward_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage_rev<std::bidirectional_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Iter>
|
||||||
|
class zip_iterator_storage_rev<std::random_access_iterator_tag, Iter...>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_ITERATOR_ZIP
|
#endif //BLT_ITERATOR_ZIP
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <blt/std/ranges.h>
|
#include <blt/std/ranges.h>
|
||||||
#include <blt/std/iterator.h>
|
#include <blt/iterator/iterator.h>
|
||||||
#include <blt/std/utility.h>
|
#include <blt/std/utility.h>
|
||||||
#include <blt/std/types.h>
|
#include <blt/std/types.h>
|
||||||
#include <blt/std/assert.h>
|
#include <blt/std/assert.h>
|
||||||
|
@ -159,10 +159,10 @@ namespace blt
|
||||||
*/
|
*/
|
||||||
inline std::optional<block_view> search_for_block(block_storage* blk, size_t n)
|
inline std::optional<block_view> search_for_block(block_storage* blk, size_t n)
|
||||||
{
|
{
|
||||||
for (auto kv : blt::enumerate(blk->unallocated_blocks))
|
for (auto [index, item] : blt::enumerate(blk->unallocated_blocks))
|
||||||
{
|
{
|
||||||
if (kv.second.n >= n)
|
if (item.n >= n)
|
||||||
return block_view{blk, kv.first, kv.second.n - n};
|
return block_view{blk, index, item.n - n};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,6 +174,12 @@ namespace blt::random
|
||||||
return BLT_RANDOM_FUNCTION(seed, min, max);
|
return BLT_RANDOM_FUNCTION(seed, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr T get(T min, T max)
|
||||||
|
{
|
||||||
|
return BLT_RANDOM_FUNCTION(seed, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool choice()
|
constexpr bool choice()
|
||||||
{
|
{
|
||||||
return BLT_RANDOM_DOUBLE(seed) < 0.5;
|
return BLT_RANDOM_DOUBLE(seed) < 0.5;
|
||||||
|
|
|
@ -42,8 +42,8 @@ namespace blt
|
||||||
using pointer = T*;
|
using pointer = T*;
|
||||||
using const_reference = const T&;
|
using const_reference = const T&;
|
||||||
using const_pointer = const T*;
|
using const_pointer = const T*;
|
||||||
using iterator = blt::ptr_iterator<T>;
|
using iterator = T*;
|
||||||
using const_iterator = blt::ptr_iterator<const T>;
|
using const_iterator = const T*;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
public:
|
public:
|
||||||
|
@ -131,24 +131,24 @@ namespace blt
|
||||||
return buffer_[index];
|
return buffer_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline pointer operator*()
|
constexpr inline reference operator*()
|
||||||
{
|
{
|
||||||
return buffer_;
|
return *buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline const_pointer operator*() const
|
constexpr inline const_reference operator*() const
|
||||||
{
|
{
|
||||||
return buffer_;
|
return *buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline pointer data()
|
constexpr inline pointer data()
|
||||||
{
|
{
|
||||||
return buffer_;
|
return buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline const_pointer data() const
|
constexpr inline const_pointer data() const
|
||||||
{
|
{
|
||||||
return buffer_;
|
return buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline reference front()
|
constexpr inline reference front()
|
||||||
|
@ -290,8 +290,8 @@ namespace blt
|
||||||
using const_reference = const value_type&;
|
using const_reference = const value_type&;
|
||||||
using pointer = value_type*;
|
using pointer = value_type*;
|
||||||
using const_pointer = const pointer;
|
using const_pointer = const pointer;
|
||||||
using iterator = blt::ptr_iterator<T>;
|
using iterator = T*;
|
||||||
using const_iterator = blt::ptr_iterator<const T>;
|
using const_iterator = const T*;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 63acc3336f941c6f324c88eb9ee4ce623a460cd5
|
Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5
|
|
@ -6,7 +6,7 @@
|
||||||
#include <blt/parse/argparse.h>
|
#include <blt/parse/argparse.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <blt/std/string.h>
|
#include <blt/std/string.h>
|
||||||
#include <blt/std/iterator.h>
|
#include <blt/iterator/iterator.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "blt/std/utility.h"
|
#include "blt/std/utility.h"
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <blt/parse/obj_loader.h>
|
#include <blt/parse/obj_loader.h>
|
||||||
#include <blt/fs/loader.h>
|
#include <blt/fs/loader.h>
|
||||||
#include <blt/std/string.h>
|
#include <blt/std/string.h>
|
||||||
#include <blt/std/iterator.h>
|
#include <blt/iterator/iterator.h>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include "blt/std/assert.h"
|
#include "blt/std/assert.h"
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* <Short Description>
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include <blt/std/logging.h>
|
||||||
|
#include <blt/std/types.h>
|
||||||
|
#include <blt/std/assert.h>
|
||||||
|
#include <blt/math/vectors.h>
|
||||||
|
#include <blt/math/log_util.h>
|
||||||
|
#include <blt/iterator/zip.h>
|
||||||
|
#include <blt/iterator/iterator.h>
|
||||||
|
#include <blt/format/boxing.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
constexpr auto increasing_reverse_pairs = [](blt::size_t i, blt::size_t index, blt::size_t size) { return i == 0 ? index : (size - 1) - index; };
|
||||||
|
constexpr auto increasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t) { return index; };
|
||||||
|
constexpr auto decreasing_pairs = [](blt::size_t, blt::size_t index, blt::size_t size) { return size - index; };
|
||||||
|
|
||||||
|
template<blt::size_t n, typename Func>
|
||||||
|
std::array<blt::vec2, n> make_array(Func&& func)
|
||||||
|
{
|
||||||
|
std::array<blt::vec2, n> array;
|
||||||
|
for (auto&& [index, value] : blt::enumerate(array))
|
||||||
|
value = blt::vec2(func(0, index, n), func(1, index, n));
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr blt::size_t array_size = 10;
|
||||||
|
auto array_1 = make_array<array_size>(increasing_reverse_pairs);
|
||||||
|
auto array_2 = make_array<array_size>(increasing_pairs);
|
||||||
|
auto array_3 = make_array<array_size>(decreasing_pairs);
|
||||||
|
|
||||||
|
void test_enumerate()
|
||||||
|
{
|
||||||
|
blt::log_box_t box(std::cout, "Enumerate Tests", 25);
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1))
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).rev())
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).take(3))
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index < 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).take(3).rev())
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index < 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).skip(3))
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).skip(3).rev())
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).skip(3).take(5))
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index >= 3 && index < (array_1.size() - 5) + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("");
|
||||||
|
|
||||||
|
for (const auto& [index, item] : blt::enumerate(array_1).skip(3).rev().take(5))
|
||||||
|
{
|
||||||
|
BLT_TRACE_STREAM << index << " : " << item << "\n";
|
||||||
|
BLT_ASSERT(index >= 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_pairs()
|
||||||
|
{
|
||||||
|
blt::log_box_t box(std::cout, "Pairs Tests", 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_zip()
|
||||||
|
{
|
||||||
|
blt::log_box_t box(std::cout, "Zip Tests", 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_enumerate();
|
||||||
|
std::cout << std::endl;
|
||||||
|
test_pairs();
|
||||||
|
std::cout << std::endl;
|
||||||
|
test_zip();
|
||||||
|
}
|
|
@ -28,8 +28,8 @@ namespace blt::test
|
||||||
void print(const T& ref)
|
void print(const T& ref)
|
||||||
{
|
{
|
||||||
BLT_TRACE_STREAM << "(" << ref.size() << ") [";
|
BLT_TRACE_STREAM << "(" << ref.size() << ") [";
|
||||||
for (auto v : blt::enumerate(ref))
|
for (auto [index, item] : blt::enumerate(ref))
|
||||||
BLT_TRACE_STREAM << v.second << ((v.first != ref.size()-1) ? ", " : "]\n");
|
BLT_TRACE_STREAM << item << ((index != ref.size()-1) ? ", " : "]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vector_run()
|
void vector_run()
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <blt/fs/nbt.h>
|
#include <blt/fs/nbt.h>
|
||||||
#include <blt/profiling/profiler.h>
|
#include <blt/profiling/profiler.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
#include <blt/std/format.h>
|
#include <blt/format/format.h>
|
||||||
#include <blt/fs/filesystem.h>
|
#include <blt/fs/filesystem.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace blt::tests {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* generateRandomData(T* arr, size_t size, uint32_t seed = 0) {
|
T* generateRandomData(T* arr, size_t size, uint32_t seed = 0) {
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
arr[i] = blt::random::randomInt_c(i * size + seed, std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
|
arr[i] = blt::random::random_t(i * size + seed).get(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "blt/profiling/profiler_v2.h"
|
#include "blt/profiling/profiler_v2.h"
|
||||||
#include "blt/std/logging.h"
|
#include "blt/std/logging.h"
|
||||||
#include "blt/std/time.h"
|
#include "blt/std/time.h"
|
||||||
#include "blt/std/format.h"
|
#include "blt/format/format.h"
|
||||||
|
|
||||||
void print(const std::vector<std::string>& vtr) {
|
void print(const std::vector<std::string>& vtr) {
|
||||||
for (const auto& line : vtr)
|
for (const auto& line : vtr)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <blt/std/utility.h>
|
#include <blt/std/utility.h>
|
||||||
#include <blt/std/string.h>
|
#include <blt/std/string.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
|
#include <blt/iterator/iterator.h>
|
||||||
|
|
||||||
namespace blt::test
|
namespace blt::test
|
||||||
{
|
{
|
||||||
|
@ -32,27 +33,27 @@ namespace blt::test
|
||||||
auto sv_splits_c = blt::string::split_sv(str, ' ');
|
auto sv_splits_c = blt::string::split_sv(str, ' ');
|
||||||
auto sv_splits_s = blt::string::split_sv(str, "LOT");
|
auto sv_splits_s = blt::string::split_sv(str, "LOT");
|
||||||
|
|
||||||
for (auto v : blt::enumerate(s_splits_c))
|
for (auto [index, item] : blt::enumerate(s_splits_c))
|
||||||
{
|
{
|
||||||
if (v.second != sv_splits_c[v.first])
|
if (item != sv_splits_c[index])
|
||||||
{
|
{
|
||||||
BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_c[v.first]).c_str());
|
BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", item.c_str(), std::string(sv_splits_c[index]).c_str());
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
BLT_DEBUG(v.second);
|
BLT_DEBUG(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BLT_INFO("");
|
BLT_INFO("");
|
||||||
|
|
||||||
for (auto v : blt::enumerate(s_splits_s))
|
for (auto [index, item] : blt::enumerate(s_splits_s))
|
||||||
{
|
{
|
||||||
if (v.second != sv_splits_s[v.first])
|
if (item != sv_splits_s[index])
|
||||||
{
|
{
|
||||||
BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_s[v.first]).c_str());
|
BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", item.c_str(), std::string(sv_splits_s[index]).c_str());
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
BLT_DEBUG(v.second);
|
BLT_DEBUG(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <blt/std/utility.h>
|
#include <blt/std/utility.h>
|
||||||
#include <blt/std/format.h>
|
#include <blt/format/format.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
#include <blt/profiling/profiler_v2.h>
|
#include <blt/profiling/profiler_v2.h>
|
||||||
#include <utility_test.h>
|
#include <utility_test.h>
|
||||||
|
|
Loading…
Reference in New Issue