xref: /aosp_15_r20/external/pdfium/core/fxcrt/fixed_size_data_vector.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2022 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_FIXED_SIZE_DATA_VECTOR_H_
6 #define CORE_FXCRT_FIXED_SIZE_DATA_VECTOR_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 #include <utility>
12 
13 #include "core/fxcrt/fx_memory_wrappers.h"
14 #include "third_party/base/containers/span.h"
15 
16 namespace fxcrt {
17 
18 enum class DataVectorAllocOption {
19   kInitialized,
20   kUninitialized,
21   kTryInitialized,
22 };
23 
24 // A simple data container that has a fixed size.
25 // Unlike std::vector, it cannot be implicitly copied and its data is only
26 // accessible using spans.
27 // It can either initialize its data with zeros, or leave its data
28 // uninitialized.
29 template <typename T, DataVectorAllocOption OPTION>
30 class FixedSizeDataVector {
31  public:
FixedSizeDataVector()32   FixedSizeDataVector() : FixedSizeDataVector(0) {}
FixedSizeDataVector(size_t size)33   explicit FixedSizeDataVector(size_t size)
34       : data_(MaybeInit(size, OPTION)), size_(CalculateSize(size, OPTION)) {}
35   FixedSizeDataVector(const FixedSizeDataVector&) = delete;
36   FixedSizeDataVector& operator=(const FixedSizeDataVector&) = delete;
37   template <DataVectorAllocOption OTHER_OPTION>
FixedSizeDataVector(FixedSizeDataVector<T,OTHER_OPTION> && that)38   FixedSizeDataVector(FixedSizeDataVector<T, OTHER_OPTION>&& that) noexcept {
39     data_ = std::move(that.data_);
40     size_ = that.size_;
41     that.size_ = 0;
42   }
43   template <DataVectorAllocOption OTHER_OPTION>
44   FixedSizeDataVector& operator=(
45       FixedSizeDataVector<T, OTHER_OPTION>&& that) noexcept {
46     data_ = std::move(that.data_);
47     size_ = that.size_;
48     that.size_ = 0;
49     return *this;
50   }
51   ~FixedSizeDataVector() = default;
52 
53   operator pdfium::span<const T>() const { return span(); }
54 
writable_span()55   pdfium::span<T> writable_span() {
56     return pdfium::make_span(data_.get(), size_);
57   }
58 
span()59   pdfium::span<const T> span() const {
60     return pdfium::make_span(data_.get(), size_);
61   }
62 
size()63   size_t size() const { return size_; }
empty()64   bool empty() const { return size_ == 0; }
65 
66  private:
67   friend class FixedSizeDataVector<T, DataVectorAllocOption::kInitialized>;
68   friend class FixedSizeDataVector<T, DataVectorAllocOption::kUninitialized>;
69   friend class FixedSizeDataVector<T, DataVectorAllocOption::kTryInitialized>;
70 
MaybeInit(size_t size,DataVectorAllocOption alloc_option)71   static T* MaybeInit(size_t size, DataVectorAllocOption alloc_option) {
72     if (size == 0)
73       return nullptr;
74     switch (alloc_option) {
75       case DataVectorAllocOption::kInitialized:
76         return FX_Alloc(T, size);
77       case DataVectorAllocOption::kUninitialized:
78         return FX_AllocUninit(T, size);
79       case DataVectorAllocOption::kTryInitialized:
80         return FX_TryAlloc(T, size);
81     }
82   }
83 
CalculateSize(size_t size,DataVectorAllocOption alloc_option)84   size_t CalculateSize(size_t size, DataVectorAllocOption alloc_option) const {
85     switch (alloc_option) {
86       case DataVectorAllocOption::kInitialized:
87       case DataVectorAllocOption::kUninitialized:
88         return size;
89       case DataVectorAllocOption::kTryInitialized:
90         return data_ ? size : 0;
91     }
92   }
93 
94   std::unique_ptr<T, FxFreeDeleter> data_;
95   size_t size_;
96 };
97 
98 }  // namespace fxcrt
99 
100 #endif  // CORE_FXCRT_FIXED_SIZE_DATA_VECTOR_H_
101