67 lines
2.6 KiB
C++
67 lines
2.6 KiB
C++
//
|
|
// Created by Patrick Maschek on 24.12.2023.
|
|
//
|
|
|
|
#ifndef CONST_CONTAINER_HELPER_H_
|
|
#define CONST_CONTAINER_HELPER_H_
|
|
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
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>
|
|
requires std::is_same_v<typename std::iterator_traits<InputIt1>::value_type, typename std::iterator_traits<InputIt2>::value_type>
|
|
&& std::indirectly_writable<InputIt1, typename std::iterator_traits<InputIt2>::value_type> && std::indirectly_readable<InputIt1>
|
|
&& std::indirectly_writable<InputIt2, typename std::iterator_traits<InputIt1>::value_type> && 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::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>
|
|
requires std::is_same_v<typename std::iterator_traits<InputIt1>::value_type, typename std::iterator_traits<InputIt2>::value_type>
|
|
&& std::indirectly_writable<InputIt1, typename std::iterator_traits<InputIt2>::value_type> && std::indirectly_readable<InputIt1>
|
|
&& std::indirectly_writable<InputIt2, typename std::iterator_traits<InputIt1>::value_type> && 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 in between 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_
|