mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
63 lines
2.2 KiB
C++
63 lines
2.2 KiB
C++
|
/*
|
||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*/
|
||
|
|
||
|
#include <cstdlib>
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
/**
|
||
|
* @brief Type that is only usable with new (std::nothrow) to avoid exceptions.
|
||
|
*
|
||
|
* This struct shall be inherited by all types in NVS that may be allocated dynamically (with new).
|
||
|
*
|
||
|
* NVS allocates memory at runtime. Because we use C++, we need to avoid the global ``operator new`` from libstdc++,
|
||
|
* since it throws exceptions and we compile NVS with ``-fno-exceptions``. We also need to avoid the global
|
||
|
* non-throwing version of that operator from libstdc++, since it is merely a wrapper around the original operator
|
||
|
* catching all exceptions.
|
||
|
*
|
||
|
* This struct removes the normal operator new from this and all types inheriting from it. It furthermore provides
|
||
|
* a custom version of operator new (..., const std::nothrow_t&) noexcept that will not use C++ exceptions.
|
||
|
*
|
||
|
* E.g., if you have a type MyType inheriting from ExceptionlessAllocatable, you want to use it as follows:
|
||
|
* @code{c++}
|
||
|
* MyType : public ExceptionlessAllocatable {
|
||
|
* ExceptionlessAllocatable();
|
||
|
* ExceptionlessAllocatable(int param);
|
||
|
* };
|
||
|
* // ...
|
||
|
* MyType *m0 = new (std::nothrow) MyType;
|
||
|
* MyType *m1 = new (std::nothrow) MyType(47);
|
||
|
* // ...
|
||
|
* delete m1;
|
||
|
* delete m0;
|
||
|
* @endcode
|
||
|
*/
|
||
|
struct ExceptionlessAllocatable {
|
||
|
/**
|
||
|
* Disallow use of the default new operator, all of NVS is currently tailored to not throw exceptions
|
||
|
*/
|
||
|
static void *operator new( std::size_t ) = delete;
|
||
|
|
||
|
/**
|
||
|
* Simple implementation with malloc(). No exceptions are thrown if the allocation fails.
|
||
|
* To use this operator, your type must inherit from this class and then allocate with:
|
||
|
* @code{c}
|
||
|
* new (std::nothrow) <YourType>; // default constructor
|
||
|
* new (std::nothrow) <YourType>(<constructor parameters>); // non-default constructor
|
||
|
* @endcode
|
||
|
*/
|
||
|
void *operator new (size_t size, const std::nothrow_t&) noexcept {
|
||
|
return std::malloc(size);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use \c delete as normal. This operator will be called automatically instead of the global one from libstdc++.
|
||
|
*/
|
||
|
void operator delete (void *obj) noexcept {
|
||
|
free(obj);
|
||
|
}
|
||
|
};
|