65 lines
2.4 KiB
C++
65 lines
2.4 KiB
C++
//
|
|
// Created by Patrick Maschek on 24.12.2023.
|
|
//
|
|
|
|
#ifndef CONST_CONTAINER_HELPER_H_
|
|
#define CONST_CONTAINER_HELPER_H_
|
|
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
|
|
namespace cc::helper {
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr std::size_t array_size(const T(&)[N]) { return N; }
|
|
|
|
template<std::input_or_output_iterator InputIt1, std::input_or_output_iterator InputIt2, typename T = InputIt1::value_type>
|
|
requires ((InputIt1::value_type == InputIt2::value_type)
|
|
&& std::indirectly_writable<typename InputIt1::value_type, InputIt1> && std::indirectly_readable<InputIt1>
|
|
&& std::indirectly_writable<typename InputIt2::value_type, InputIt1> && std::indirectly_readable<InputIt2>)
|
|
constexpr void swap_iter_range(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
|
|
{
|
|
auto dist1 = std::distance(first1, last1);
|
|
auto dist2 = std::distance(first2, last2);
|
|
|
|
if (dist1 == dist2) {
|
|
std::swap_ranges(first1, last1, first2);
|
|
return;
|
|
}
|
|
|
|
auto swap_dist = std::min(dist1, dist2);
|
|
|
|
std::swap_ranges(first1, std::next(first1, swap_dist), first2, std::next(first2, swap_dist));
|
|
|
|
std::advance(first1, swap_dist);
|
|
std::advance(first2, swap_dist);
|
|
|
|
if (dist1 < dist2) {
|
|
std::move(first2, last2, last1);
|
|
} else {
|
|
std::move(first1, last1, last2);
|
|
}
|
|
}
|
|
|
|
template<std::input_or_output_iterator InputIt1, std::input_or_output_iterator InputIt2, typename T = InputIt1::value_type>
|
|
requires ((InputIt1::value_type == InputIt2::value_type)
|
|
&& std::indirectly_writable<typename InputIt1::value_type, InputIt1> && std::indirectly_readable<InputIt1>
|
|
&& std::indirectly_writable<typename InputIt2::value_type, InputIt1> && std::indirectly_readable<InputIt2>)
|
|
constexpr void swap(InputIt1 first1, InputIt1 last1, InputIt1 end1, InputIt2 first2, InputIt2 last2, InputIt2 end2)
|
|
{
|
|
auto max_dist = std::min(std::distance(first1, end1), std::distance(first2, end2));
|
|
|
|
auto dist1 = std::distance(first1, last1);
|
|
auto dist2 = std::distance(first2, last2);
|
|
|
|
if (max_dist < dist1 || max_dist < dist2) throw std::invalid_argument("Distance between iterators does not fit inbetween other "
|
|
"(Range 1: " + std::to_string(dist1) + "/" + std::to_string(std::distance(first1, end1)) + ", " +
|
|
"Range 2: " + std::to_string(dist2) + "/" + std::to_string(std::distance(first2, end2)) + ")");
|
|
|
|
swap_iter_range(first1, last1, first2, last2);
|
|
}
|
|
|
|
}; // cc
|
|
|
|
#endif //CONST_CONTAINER_HELPER_H_
|