#pragma once #include <concepts> #include <ranges> namespace util { template <typename C> concept reservable = requires(C &c, typename C::size_type i) { {c.reserve(i)}; }; template <typename C> concept back_insertible = requires(C &c, const std::ranges::range_value_t<C> &t) { { std::back_inserter(c) } -> std::same_as<std::back_insert_iterator<C>>; {c.push_back(t)}; }; template <typename C> concept front_insertible = requires(C &c, const std::ranges::range_value_t<C> &t) { { std::front_inserter(c) } -> std::same_as<std::front_insert_iterator<C>>; {c.push_front(t)}; }; template <typename C> concept insertible = requires(C &c, std::ranges::iterator_t<C> i, const std::ranges::range_value_t<C> &t) { { std::inserter(c, i) } -> std::same_as<std::insert_iterator<C>>; {c.insert(i, t)}; }; template <typename C, typename... Ts> concept emplaceable = requires(C &c, Ts... t) { {c.emplace(std::move(t...))}; }; template <typename C, typename... Ts> concept back_emplaceable = requires(C &c, Ts... t) { {c.emplace_back(std::move(t...))}; }; } // namespace util