// // Created by Patrick Maschek on 24.12.2023. // #ifndef CONST_CONTAINER_HELPER_H_ #define CONST_CONTAINER_HELPER_H_ #include #include #include #include namespace cc::helper { template constexpr std::size_t array_size(const T(&)[N]) { return N; } template requires ((InputIt1::value_type == InputIt2::value_type) && std::indirectly_writable && std::indirectly_readable && std::indirectly_writable && std::indirectly_readable) 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 requires ((InputIt1::value_type == InputIt2::value_type) && std::indirectly_writable && std::indirectly_readable && std::indirectly_writable && std::indirectly_readable) 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_