// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef THIRD_PARTY_BASE_STL_UTIL_H_ #define THIRD_PARTY_BASE_STL_UTIL_H_ #include #include #include #include #include #include "third_party/base/numerics/safe_conversions.h" #include "third_party/base/numerics/safe_math.h" namespace pdfium { // C++11 implementation of C++17's std::size(): // http://en.cppreference.com/w/cpp/iterator/size template constexpr auto size(const Container& c) -> decltype(c.size()) { return c.size(); } template constexpr size_t size(const T (&array)[N]) noexcept { return N; } // Test to see if a set, map, hash_set or hash_map contains a particular key. // Returns true if the key is in the collection. template bool ContainsKey(const Collection& collection, const Key& key) { return collection.find(key) != collection.end(); } // Test to see if a collection like a vector contains a particular value. // Returns true if the value is in the collection. template bool ContainsValue(const Collection& collection, const Value& value) { return std::find(std::begin(collection), std::end(collection), value) != std::end(collection); } // Means of generating a key for searching STL collections of std::unique_ptr // that avoids the side effect of deleting the pointer. template class FakeUniquePtr : public std::unique_ptr { public: using std::unique_ptr::unique_ptr; ~FakeUniquePtr() { std::unique_ptr::release(); } }; // Convenience routine for "int-fected" code, so that the stl collection // size_t size() method return values will be checked. template ResultType CollectionSize(const Collection& collection) { return pdfium::base::checked_cast(collection.size()); } // Convenience routine for "int-fected" code, to handle signed indicies. The // compiler can deduce the type, making this more convenient than the above. template bool IndexInBounds(const Collection& collection, IndexType index) { return index >= 0 && index < CollectionSize(collection); } // Track the addition of an object to a set, removing it automatically when // the ScopedSetInsertion goes out of scope. template class ScopedSetInsertion { public: ScopedSetInsertion(std::set* org_set, T elem) : m_Set(org_set), m_Entry(elem) { m_Set->insert(m_Entry); } ~ScopedSetInsertion() { m_Set->erase(m_Entry); } private: std::set* const m_Set; const T m_Entry; }; // std::clamp(), some day. template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { return std::min(std::max(v, lo), hi); } // Safely allocate a 1-dim vector big enough for |w| by |h| or die. template std::vector Vector2D(size_t w, size_t h) { pdfium::base::CheckedNumeric safe_size = w; safe_size *= h; return std::vector(safe_size.ValueOrDie()); } } // namespace pdfium #endif // THIRD_PARTY_BASE_STL_UTIL_H_