| // Copyright 2015 The PDFium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef CORE_FXCRT_STL_UTIL_H_ | 
 | #define CORE_FXCRT_STL_UTIL_H_ | 
 |  | 
 | #include <algorithm> | 
 | #include <array> | 
 | #include <iterator> | 
 | #include <memory> | 
 |  | 
 | #include "core/fxcrt/check_op.h" | 
 | #include "core/fxcrt/compiler_specific.h" | 
 | #include "core/fxcrt/numerics/safe_conversions.h" | 
 |  | 
 | namespace fxcrt { | 
 |  | 
 | // Means of generating a key for searching STL collections of std::unique_ptr | 
 | // that avoids the side effect of deleting the pointer. | 
 | template <class T> | 
 | class FakeUniquePtr : public std::unique_ptr<T> { | 
 |  public: | 
 |   using std::unique_ptr<T>::unique_ptr; | 
 |   ~FakeUniquePtr() { std::unique_ptr<T>::release(); } | 
 | }; | 
 |  | 
 | // Type-deducing wrapper for FakeUniquePtr<T>. | 
 | template <class T> | 
 | FakeUniquePtr<T> MakeFakeUniquePtr(T* arg) { | 
 |   return FakeUniquePtr<T>(arg); | 
 | } | 
 |  | 
 | // Convenience routine for "int-fected" code, so that the stl collection | 
 | // size_t size() method return values will be checked. | 
 | template <typename ResultType, typename Collection> | 
 | ResultType CollectionSize(const Collection& collection) { | 
 |   return pdfium::checked_cast<ResultType>(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 <typename IndexType, typename Collection> | 
 | bool IndexInBounds(const Collection& collection, IndexType index) { | 
 |   return index >= 0 && index < CollectionSize<IndexType>(collection); | 
 | } | 
 |  | 
 | // Equivalent of C++20 std::ranges::fill(). | 
 | template <typename T, typename V> | 
 | void Fill(T&& container, const V& value) { | 
 |   std::fill(std::begin(container), std::end(container), value); | 
 | } | 
 |  | 
 | // Non-flawed version of C++20 std::ranges::copy(), which takes an output | 
 | // range as the second parameter and CHECKS() if it not sufficiently sized. | 
 | template <typename T, typename U> | 
 | void Copy(const T& source_container, U&& dest_container) { | 
 |   static_assert(sizeof(source_container[0]) == sizeof(dest_container[0])); | 
 |   CHECK_GE(std::size(dest_container), std::size(source_container)); | 
 |   std::copy(std::begin(source_container), std::end(source_container), | 
 |             std::begin(dest_container)); | 
 | } | 
 |  | 
 | // ToArray<>() implementation as taken from chromium /base. Replace with | 
 | // std::to_array<>() when C++20 becomes available. | 
 | // | 
 | // Helper inspired by C++20's std::to_array to convert a C-style array to a | 
 | // std::array. As opposed to the C++20 version this implementation does not | 
 | // provide an overload for rvalues and does not strip cv qualifers from the | 
 | // returned std::array::value_type. The returned value_type needs to be | 
 | // specified explicitly, allowing the construction of std::arrays with const | 
 | // elements. | 
 | // | 
 | // Reference: https://en.cppreference.com/w/cpp/container/array/to_array | 
 | template <typename U, typename T, size_t N, size_t... I> | 
 | constexpr std::array<U, N> ToArrayImpl(const T (&data)[N], | 
 |                                        std::index_sequence<I...>) { | 
 |   // SAFETY: compiler-deduced size `N`. | 
 |   return UNSAFE_BUFFERS({{static_cast<U>(data[I])...}}); | 
 | } | 
 |  | 
 | template <typename U, size_t N> | 
 | constexpr std::array<U, N> ToArray(const U (&data)[N]) { | 
 |   return ToArrayImpl<U>(data, std::make_index_sequence<N>()); | 
 | } | 
 |  | 
 | }  // namespace fxcrt | 
 |  | 
 | #endif  // CORE_FXCRT_STL_UTIL_H_ |