#include <new> 
#include <utility> 
#include <type_traits> 
 
struct  A
{ 
 
} ; 
 
struct  B
{ 
	int  i; 
} ; 
 
template < typename  T, typename  U, typename ... Args > 
T*  construct( U ptr, Args&& ... args ) 
{ 
	static_assert( std:: is_same < U, void * > :: value  or std:: is_same < U, char * > :: value , "must be void* or char*" ) ; 
	return  :: new ( ptr)  T( std:: forward < Args> ( args) ...) ; 
} 
 
int  main( ) 
{ 
	A a; 
	alignas( B)  char  area[ sizeof ( B) ] ; 
	void *  ptr =  area; 
	construct< B> ( & a) ;  // fails at compile time 
	construct< B> ( & area[ 0 ] ) ; 
	construct< B> ( ptr) ; 
} 
 
				I2luY2x1ZGUgPG5ldz4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnN0cnVjdCBBCnsKCn07CgpzdHJ1Y3QgQgp7CglpbnQgaTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFUsIHR5cGVuYW1lLi4uIEFyZ3M+ClQqIGNvbnN0cnVjdChVIHB0ciwgQXJncyYmLi4uIGFyZ3MpCnsKCXN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPFUsIHZvaWQqPjo6dmFsdWUgb3Igc3RkOjppc19zYW1lPFUsIGNoYXIqPjo6dmFsdWUsICJtdXN0IGJlIHZvaWQqIG9yIGNoYXIqIik7CglyZXR1cm4gOjpuZXcocHRyKSBUKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7Cn0KCmludCBtYWluKCkKewoJQSBhOwoJYWxpZ25hcyhCKSBjaGFyIGFyZWFbc2l6ZW9mKEIpXTsKCXZvaWQqIHB0ciA9IGFyZWE7Cgljb25zdHJ1Y3Q8Qj4oJmEpOyAvLyBmYWlscyBhdCBjb21waWxlIHRpbWUKCWNvbnN0cnVjdDxCPigmYXJlYVswXSk7Cgljb25zdHJ1Y3Q8Qj4ocHRyKTsKfQ==
				
				 
				 
				 
				 
			 
			
				
			
			
				
	
		
	 
	
		  compilation info 
		 
	 
	prog.cpp: In instantiation of 'T* construct(U, Args&& ...) [with T = B; U = A*; Args = {}]':
prog.cpp:27:17:   required from here
prog.cpp:18:2: error: static assertion failed: must be void* or char*
  static_assert(std::is_same<U, void*>::value or std::is_same<U, char*>::value, "must be void* or char*");
  ^
 
		
		 
	
		
		  stdout