blob: 2f602006a3cb671b52402ce3426f63275a5ad722 [file] [log] [blame]
// Copyright 2024 The Fuchsia 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 SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ALLOC_CHECKER_CONTAINER_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ALLOC_CHECKER_CONTAINER_H_
#include <string_view>
#include <fbl/alloc_checker.h>
namespace elfldltl {
// Similar to elfldltl::StdContainer (see container.h), except
// AllocCheckerContainer leverages fbl::AllocChecker to check the allocations
// performed by the underlying type method. The string_view error parameter
// should contain a description of the allocation and is included in the
// diagnostics error message. The boolean return value indicates allocation
// success or failure. If allocation fails the Diagnostic's object's OutofMemory
// error is called.
template <template <typename, typename...> class C, typename... P>
struct AllocCheckerContainer {
template <typename T>
class Container : public C<T, P...> {
public:
using Base = C<T, P...>;
using Base::Base;
constexpr Container(Container&&) noexcept = default;
constexpr Container& operator=(Container&&) noexcept = default;
template <class Diagnostics, typename U>
bool push_back(Diagnostics& diagnostics, std::string_view error, U&& value) {
fbl::AllocChecker ac;
Base::push_back(std::forward<U>(value), &ac);
if (!ac.check()) {
diagnostics.OutOfMemory(error, sizeof(U));
return false;
}
return true;
}
template <class Diagnostics, typename U>
bool insert(Diagnostics& diagnostics, std::string_view error, size_t index, U&& value) {
fbl::AllocChecker ac;
Base::insert(index, std::forward<U>(value), &ac);
if (!ac.check()) {
diagnostics.OutOfMemory(error, sizeof(U));
return false;
}
return true;
}
template <class Diagnostics>
bool reserve(Diagnostics& diagnostics, std::string_view error, size_t capacity) {
fbl::AllocChecker ac;
Base::reserve(capacity, &ac);
if (!ac.check()) {
diagnostics.OutOfMemory(error, capacity);
return false;
}
return true;
}
private:
// Make the original methods unavailable.
using Base::insert;
using Base::push_back;
using Base::reserve;
};
};
} // namespace elfldltl
#endif // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ALLOC_CHECKER_CONTAINER_H_