forked from crosspoint-reader/crosspoint-reader
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemory.h
More file actions
54 lines (48 loc) · 1.65 KB
/
Copy pathMemory.h
File metadata and controls
54 lines (48 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#pragma once
#include <cstddef>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>
// Nothrow versions of std::make_unique. Return nullptr on allocation failure
// instead of calling abort() (the default when exceptions are disabled on ESP32).
//
// Single object:
// auto obj = makeUniqueNoThrow<PNG>();
// if (!obj) { LOG_ERR("TAG", "OOM"); return false; }
//
// Array:
// auto buf = makeUniqueNoThrow<uint8_t[]>(size);
// if (!buf) { LOG_ERR("TAG", "OOM"); return false; }
// buf[0] = 0xFF;
// someApi(buf.get(), size);
//
template <typename T, typename... Args>
requires(!std::is_array_v<T>)
std::unique_ptr<T> makeUniqueNoThrow(Args&&... args) {
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}
template <typename T>
requires std::is_unbounded_array_v<T>
std::unique_ptr<T> makeUniqueNoThrow(size_t count) {
using Elem = std::remove_extent_t<T>;
return std::unique_ptr<T>(new (std::nothrow) Elem[count]());
}
// Helper struct to call a cleanup function on exit from any scope.
// Use with a lambda to avoid unnecessary allocations from std::function/std::bind:
// Example:
// auto jpeg = makeUniqueNoThrow<JPEGDEC>();
// ScopedCleanup cleanup{[&jpeg]{ jpeg->close(); }};
//
template <typename F>
struct [[nodiscard]] ScopedCleanup final {
const F fn;
explicit ScopedCleanup(F f) : fn{std::move(f)} {}
ScopedCleanup(const ScopedCleanup&) = delete;
ScopedCleanup& operator=(const ScopedCleanup&) = delete;
ScopedCleanup(ScopedCleanup&&) = delete;
ScopedCleanup& operator=(ScopedCleanup&&) = delete;
~ScopedCleanup() { fn(); }
};
template <typename F>
ScopedCleanup(F) -> ScopedCleanup<F>;