#pragma once #include #include #include #include namespace vcpkg::Util { template using FmapOut = decltype(std::declval()(*begin(std::declval()))); template> std::vector fmap(Cont&& xs, Func&& f) { std::vector ret; ret.reserve(xs.size()); for (auto&& x : xs) ret.push_back(f(x)); return ret; } template using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; template> std::vector fmap_flatten(Cont&& xs, Func&& f) { std::vector ret; for (auto&& x : xs) for (auto&& y : f(x)) ret.push_back(std::move(y)); return ret; } template void unstable_keep_if(Container& cont, Pred pred) { cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); } template void erase_remove_if(Container& cont, Pred pred) { cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); } template auto find(const Container& cont, V&& v) { return std::find(cont.cbegin(), cont.cend(), v); } template auto find_if(const Container& cont, Pred pred) { return std::find_if(cont.cbegin(), cont.cend(), pred); } template auto find_if_not(const Container& cont, Pred pred) { return std::find_if_not(cont.cbegin(), cont.cend(), pred); } template void group_by(const Container& cont, std::map>* output, Func f) { for (const V& element : cont) { K key = f(element); (*output)[key].push_back(&element); } } struct MoveOnlyBase { MoveOnlyBase() = default; MoveOnlyBase(const MoveOnlyBase&) = delete; MoveOnlyBase(MoveOnlyBase&&) = default; MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; MoveOnlyBase& operator=(MoveOnlyBase&&) = default; }; struct ResourceBase { ResourceBase() = default; ResourceBase(const ResourceBase&) = delete; ResourceBase(ResourceBase&&) = delete; ResourceBase& operator=(const ResourceBase&) = delete; ResourceBase& operator=(ResourceBase&&) = delete; }; template struct LockGuardPtr; template struct LockGuarded { friend struct LockGuardPtr; LockGuardPtr lock() { return *this; } private: std::mutex m_mutex; T m_t; }; template struct LockGuardPtr { T& operator*() { return m_ptr; } T* operator->() { return &m_ptr; } T* get() { return &m_ptr; } LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} private: std::unique_lock m_lock; T& m_ptr; }; }