Unfortunately, the standard does not define what it means to be a "placement" allocation or deallocation function.
This is CWG 2592. I think the intended meaning is probably something similar to what is in the proposed resolution.
So the usual allocation functions would be the ones with the following signatures:
void* operator new(std::size_t);
void* operator new(std::size_t, std::align_val_t);
void* operator new[](std::size_t);
void* operator new[](std::size_t, std::align_val_t);
including any replacements declared by the user, and any functions with such signatures at class scope. And the placement ones would be ones with any other signature, including the following from the standard library:
void* operator new(std::size_t, const std::nothrow_t&) noexcept;
void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&) noexcept;
void* operator new(std::size_t, void*) noexcept;
void* operator new[](std::size_t, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t, void*) noexcept;
"Usual deallocation function" was given an actual definition in the standard at some point. In N4944 it reads:
A usual deallocation function is a deallocation
function whose parameters after the first are
- optionally, a parameter of type
std::destroying_delete_t
, then
- optionally, a parameter of type
std::size_t
, then
- optionally, a parameter of type
std::align_val_t
.
[...] A template instance is never a usual deallocation function, regardless of its signature.
A placement deallocation function is obviously a deallocation function that's not a usual deallocation function; CWG 2592 seeks to clarify this normatively.
So there are 8 possible signatures for a usual deallocation function. A usual deallocation function can have class scope. The following deallocation functions from the standard library are usual deallocation functions:
void operator delete(void*) noexcept;
void operator delete(void*, std::size_t) noexcept;
void operator delete(void*, std::align_val_t) noexcept;
void operator delete(void*, std::size_t, std::align_val_t) noexcept;
void operator delete[](void*) noexcept;
void operator delete[](void*, std::size_t) noexcept;
void operator delete[](void*, std::align_val_t) noexcept;
void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
and the following are placement deallocation functions:
void operator delete(void*, const std::nothrow_t&) noexcept;
void operator delete(void*, std::align_val_t, const std::nothrow_t&) noexcept;
void operator delete(void*, void*);
void operator delete[](void*, const std::nothrow_t&) noexcept;
void operator delete[](void*, std::align_val_t, const std::nothrow_t&) noexcept;
void operator delete[](void*, void*);