I'm not an expert in placement new but there are a couple of issues with how you are defining the macro.
Issue 1
The most obvious problem is the use of the cast (TYPE*)STORAGE
for the storage location. This is incorrect. Placement new is just another C++ function and it participates in operations like overload resolution. Arbitrarily casting the memory to a specific type could cause the placement new to bind to a different operator new that the user expected.
For example, it's valid to have the following two definitions of placement new. Your macro would potentially cause the wrong one to be called.
void * _cdecl operator new(size_t cbSize, void* pv);
void * _cdecl operator new(size_t cbSize, SomeType* pv)-
...
// These two call different overloads
void* p = malloc(sizeof(SomeType));
SomeType* f1 = CONSTRUCT_INPLACE(SomeType, p,())
SomeType* f2 = new (p) SomeType();
I wrote a blog post awhile back on how you can use this type of overload resolution to implement custom allocators.
Issue 2
The expression STORAGE in the macro should be wrapped in parens to prevent evil macro expansion bugs.
::new((TYPE*)(STORAGE)) TYPE INIT