- #include <iostream> 
- #include <iomanip> 
- #include <type_traits> 
-   
- struct move_not_copy { move_not_copy(move_not_copy &&); }; 
-   
- template<typename T> 
- struct has_move_constructor { 
- 	struct helper : public move_not_copy,  public T { 
- 	}; 
- 	constexpr static bool value = std::is_constructible<helper, typename std::add_rvalue_reference<helper>::type> ::value; 
- 	constexpr operator bool () const { return value; } 
- }; 
-   
- struct T0 { 
- 	void operator=(T0&&) {} 
- }; 
- struct Copy { 
-    Copy( const Copy& ); 
- }; 
- struct MoveOnly { 
-    MoveOnly( MoveOnly&& ); 
- }; 
- struct Both { 
-    Both( const Both& ); 
-    Both( Both&& ); 
- }; 
- struct CopyWithDeletedMove { 
-    CopyWithDeletedMove( const CopyWithDeletedMove& ); 
-    CopyWithDeletedMove( CopyWithDeletedMove&& ) = delete; 
- }; 
-   
- template<typename T> 
- void provide_a_report_impl(const char *type_name) { 
- 	std::cout << std::setw(20) << type_name 
- 		<< "  is_copy_constructible " << std::is_constructible<T, typename std::add_lvalue_reference<T>::type>() 
- 		<< "  is_move_constructible " << std::is_constructible<T, typename std::add_rvalue_reference<T>::type>() 
- 		<< "  has_move_constructor " << has_move_constructor<T>::value 
- 		<< std::endl; 
- }; 
- #define REPORT_ON_ISHAS_MOVE_CONSTRUCTOR(T) provide_a_report_impl<T>(#T) 
-   
- int main() 
- { 
-    REPORT_ON_ISHAS_MOVE_CONSTRUCTOR(Copy); 
-    REPORT_ON_ISHAS_MOVE_CONSTRUCTOR(MoveOnly); 
-    REPORT_ON_ISHAS_MOVE_CONSTRUCTOR(Both); 
-    REPORT_ON_ISHAS_MOVE_CONSTRUCTOR(CopyWithDeletedMove); 
- } 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKc3RydWN0IG1vdmVfbm90X2NvcHkgeyBtb3ZlX25vdF9jb3B5KG1vdmVfbm90X2NvcHkgJiYpOyB9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IGhhc19tb3ZlX2NvbnN0cnVjdG9yIHsKCXN0cnVjdCBoZWxwZXIgOiBwdWJsaWMgbW92ZV9ub3RfY29weSwgIHB1YmxpYyBUIHsKCX07Cgljb25zdGV4cHIgc3RhdGljIGJvb2wgdmFsdWUgPSBzdGQ6OmlzX2NvbnN0cnVjdGlibGU8aGVscGVyLCB0eXBlbmFtZSBzdGQ6OmFkZF9ydmFsdWVfcmVmZXJlbmNlPGhlbHBlcj46OnR5cGU+IDo6dmFsdWU7Cgljb25zdGV4cHIgb3BlcmF0b3IgYm9vbCAoKSBjb25zdCB7IHJldHVybiB2YWx1ZTsgfQp9OwoKc3RydWN0IFQwIHsKCXZvaWQgb3BlcmF0b3I9KFQwJiYpIHt9Cn07CnN0cnVjdCBDb3B5IHsKICAgQ29weSggY29uc3QgQ29weSYgKTsKfTsKc3RydWN0IE1vdmVPbmx5IHsKICAgTW92ZU9ubHkoIE1vdmVPbmx5JiYgKTsKfTsKc3RydWN0IEJvdGggewogICBCb3RoKCBjb25zdCBCb3RoJiApOwogICBCb3RoKCBCb3RoJiYgKTsKfTsKc3RydWN0IENvcHlXaXRoRGVsZXRlZE1vdmUgewogICBDb3B5V2l0aERlbGV0ZWRNb3ZlKCBjb25zdCBDb3B5V2l0aERlbGV0ZWRNb3ZlJiApOwogICBDb3B5V2l0aERlbGV0ZWRNb3ZlKCBDb3B5V2l0aERlbGV0ZWRNb3ZlJiYgKSA9IGRlbGV0ZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnZvaWQgcHJvdmlkZV9hX3JlcG9ydF9pbXBsKGNvbnN0IGNoYXIgKnR5cGVfbmFtZSkgewoJc3RkOjpjb3V0IDw8IHN0ZDo6c2V0dygyMCkgPDwgdHlwZV9uYW1lCgkJPDwgIiAgaXNfY29weV9jb25zdHJ1Y3RpYmxlICIgPDwgc3RkOjppc19jb25zdHJ1Y3RpYmxlPFQsIHR5cGVuYW1lIHN0ZDo6YWRkX2x2YWx1ZV9yZWZlcmVuY2U8VD46OnR5cGU+KCkKCQk8PCAiICBpc19tb3ZlX2NvbnN0cnVjdGlibGUgIiA8PCBzdGQ6OmlzX2NvbnN0cnVjdGlibGU8VCwgdHlwZW5hbWUgc3RkOjphZGRfcnZhbHVlX3JlZmVyZW5jZTxUPjo6dHlwZT4oKQoJCTw8ICIgIGhhc19tb3ZlX2NvbnN0cnVjdG9yICIgPDwgaGFzX21vdmVfY29uc3RydWN0b3I8VD46OnZhbHVlCgkJPDwgc3RkOjplbmRsOwp9OwojZGVmaW5lIFJFUE9SVF9PTl9JU0hBU19NT1ZFX0NPTlNUUlVDVE9SKFQpIHByb3ZpZGVfYV9yZXBvcnRfaW1wbDxUPigjVCkKCmludCBtYWluKCkKewogICBSRVBPUlRfT05fSVNIQVNfTU9WRV9DT05TVFJVQ1RPUihDb3B5KTsKICAgUkVQT1JUX09OX0lTSEFTX01PVkVfQ09OU1RSVUNUT1IoTW92ZU9ubHkpOwogICBSRVBPUlRfT05fSVNIQVNfTU9WRV9DT05TVFJVQ1RPUihCb3RoKTsKICAgUkVQT1JUX09OX0lTSEFTX01PVkVfQ09OU1RSVUNUT1IoQ29weVdpdGhEZWxldGVkTW92ZSk7Cn0=