const_container/include/helper.h

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_