#pragma once #include "../concepts/container.hpp" #include #include #include #include namespace util { namespace rg = std::ranges; namespace detail { template constexpr auto collect_range(R &&r) -> Collection { Collection c; if constexpr (rg::sized_range && util::reservable) { c.reserve(r.size()); } if constexpr (util::back_insertible) { rg::move(r, std::back_inserter(c)); } else if constexpr (util::back_emplaceable) { for (auto &&e : r) { c.emplace_back(std::move(e)); } } else if constexpr (util::emplaceable) { for (auto &&e : r) { c.emplace(std::move(e)); } } return c; } template struct collect_range_adaptor { template constexpr auto operator()(R &&r) const { return collect_range(std::forward(r)); } }; template constexpr auto operator|(R &&r, const collect_range_adaptor &adaptor) { return adaptor(std::forward(r)); } } // namespace detail namespace views { template inline detail::collect_range_adaptor collect; } template constexpr auto collect(R &&r) -> Collection { return r | views::collect; } template constexpr auto to_vector(Range r) -> std::vector> { std::vector> v; if constexpr (rg::sized_range) { v.reserve(rg::size(r)); } std::ranges::copy(r, std::back_inserter(v)); return v; } template constexpr auto to_unordered_set(Range r) -> std::unordered_set> { std::unordered_set> v(r.begin(), r.end()); return v; } } // namespace util