• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CORE_FXCRT_STL_UTIL_H_
6 #define CORE_FXCRT_STL_UTIL_H_
7 
8 #include <algorithm>
9 #include <array>
10 #include <iterator>
11 #include <memory>
12 
13 #include "core/fxcrt/check_op.h"
14 #include "core/fxcrt/compiler_specific.h"
15 #include "core/fxcrt/numerics/safe_conversions.h"
16 
17 namespace fxcrt {
18 
19 // Means of generating a key for searching STL collections of std::unique_ptr
20 // that avoids the side effect of deleting the pointer.
21 template <class T>
22 class FakeUniquePtr : public std::unique_ptr<T> {
23  public:
24   using std::unique_ptr<T>::unique_ptr;
~FakeUniquePtr()25   ~FakeUniquePtr() { std::unique_ptr<T>::release(); }
26 };
27 
28 // Type-deducing wrapper for FakeUniquePtr<T>.
29 template <class T>
MakeFakeUniquePtr(T * arg)30 FakeUniquePtr<T> MakeFakeUniquePtr(T* arg) {
31   return FakeUniquePtr<T>(arg);
32 }
33 
34 // Convenience routine for "int-fected" code, so that the stl collection
35 // size_t size() method return values will be checked.
36 template <typename ResultType, typename Collection>
CollectionSize(const Collection & collection)37 ResultType CollectionSize(const Collection& collection) {
38   return pdfium::checked_cast<ResultType>(collection.size());
39 }
40 
41 // Convenience routine for "int-fected" code, to handle signed indicies. The
42 // compiler can deduce the type, making this more convenient than the above.
43 template <typename IndexType, typename Collection>
IndexInBounds(const Collection & collection,IndexType index)44 bool IndexInBounds(const Collection& collection, IndexType index) {
45   return index >= 0 && index < CollectionSize<IndexType>(collection);
46 }
47 
48 // Equivalent of C++20 std::ranges::fill().
49 template <typename T, typename V>
Fill(T && container,const V & value)50 void Fill(T&& container, const V& value) {
51   std::fill(std::begin(container), std::end(container), value);
52 }
53 
54 // Non-flawed version of C++20 std::ranges::copy(), which takes an output
55 // range as the second parameter and CHECKS() if it not sufficiently sized.
56 template <typename T, typename U>
Copy(const T & source_container,U && dest_container)57 void Copy(const T& source_container, U&& dest_container) {
58   static_assert(sizeof(source_container[0]) == sizeof(dest_container[0]));
59   CHECK_GE(std::size(dest_container), std::size(source_container));
60   std::copy(std::begin(source_container), std::end(source_container),
61             std::begin(dest_container));
62 }
63 
64 // ToArray<>() implementation as taken from chromium /base. Replace with
65 // std::to_array<>() when C++20 becomes available.
66 //
67 // Helper inspired by C++20's std::to_array to convert a C-style array to a
68 // std::array. As opposed to the C++20 version this implementation does not
69 // provide an overload for rvalues and does not strip cv qualifers from the
70 // returned std::array::value_type. The returned value_type needs to be
71 // specified explicitly, allowing the construction of std::arrays with const
72 // elements.
73 //
74 // Reference: https://en.cppreference.com/w/cpp/container/array/to_array
75 template <typename U, typename T, size_t N, size_t... I>
ToArrayImpl(const T (& data)[N],std::index_sequence<I...>)76 constexpr std::array<U, N> ToArrayImpl(const T (&data)[N],
77                                        std::index_sequence<I...>) {
78   // SAFETY: compiler-deduced size `N`.
79   return UNSAFE_BUFFERS({{static_cast<U>(data[I])...}});
80 }
81 
82 template <typename U, size_t N>
ToArray(const U (& data)[N])83 constexpr std::array<U, N> ToArray(const U (&data)[N]) {
84   return ToArrayImpl<U>(data, std::make_index_sequence<N>());
85 }
86 
87 }  // namespace fxcrt
88 
89 #endif  // CORE_FXCRT_STL_UTIL_H_
90