#include <cstdint>
#include <type_traits>
#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature) \
template <typename U> \
class traitsName \
{ \
private: \
template<typename T, T> struct helper; \
template<typename T> \
static std::uint8_t check(helper<signature, &funcName>*); \
template<typename T> static std::uint16_t check(...); \
public: \
static \
constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
}
DEFINE_HAS_SIGNATURE( has_ref_swap, T:: swap , void ( T:: * ) ( T& ) ) ;
DEFINE_HAS_SIGNATURE( has_value_swap, T:: swap , void ( T:: * ) ( T) ) ;
template < typename T>
struct MetaHelperType_impl
{
static_assert( ! has_value_swap< T> :: value ,
"Incorrect implementation of T::swap, "
"signature should be void T::swap(T&) instead of T::swap(T)" ) ;
using type = std:: conditional_t < has_ref_swap< T> :: value ,
std:: true_type ,
std:: false_type > ;
} ;
template < typename T>
using MetaHelperType = typename MetaHelperType_impl< T> :: type ;
struct NonReferenceSwap
{
void swap( NonReferenceSwap) { }
} ;
struct ReferenceSwap
{
void swap( ReferenceSwap & ) { }
} ;
struct NoSwapFunction { } ;
int main( ) {
static_assert( MetaHelperType< ReferenceSwap> :: value , "unexpected result" ) ;
static_assert( ! MetaHelperType< NoSwapFunction> :: value , "unexpected result" ) ;
static_assert( ! MetaHelperType< NonReferenceSwap> :: value , "unexpected result" ) ; // Doesn't compile as expected
}
I2luY2x1ZGUgPGNzdGRpbnQ+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCiNkZWZpbmUgREVGSU5FX0hBU19TSUdOQVRVUkUodHJhaXRzTmFtZSwgZnVuY05hbWUsIHNpZ25hdHVyZSkgICAgICAgICAgICAgICBcCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBjbGFzcyB0cmFpdHNOYW1lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBwcml2YXRlOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVCwgVD4gc3RydWN0IGhlbHBlcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGljIHN0ZDo6dWludDhfdCBjaGVjayhoZWxwZXI8c2lnbmF0dXJlLCAmZnVuY05hbWU+Kik7ICAgICAgICAgICBcCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RhdGljIHN0ZDo6dWludDE2X3QgY2hlY2soLi4uKTsgICAgICAgICAgICAgICBcCiAgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGljICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgY29uc3RleHByIGJvb2wgdmFsdWUgPSBzaXplb2YoY2hlY2s8VT4oMCkpID09IHNpemVvZihzdGQ6OnVpbnQ4X3QpOyBcCiAgICB9CgpERUZJTkVfSEFTX1NJR05BVFVSRShoYXNfcmVmX3N3YXAsIFQ6OnN3YXAsIHZvaWQgKFQ6OiopKFQmKSk7CkRFRklORV9IQVNfU0lHTkFUVVJFKGhhc192YWx1ZV9zd2FwLCBUOjpzd2FwLCB2b2lkIChUOjoqKShUKSk7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IE1ldGFIZWxwZXJUeXBlX2ltcGwKewogICAgc3RhdGljX2Fzc2VydCghaGFzX3ZhbHVlX3N3YXA8VD46OnZhbHVlLAogICAgICAgICAgICAgICAgICAiSW5jb3JyZWN0IGltcGxlbWVudGF0aW9uIG9mIFQ6OnN3YXAsICIKICAgICAgICAgICAgICAgICAgInNpZ25hdHVyZSBzaG91bGQgYmUgdm9pZCBUOjpzd2FwKFQmKSBpbnN0ZWFkIG9mIFQ6OnN3YXAoVCkiKTsKCiAgICB1c2luZyB0eXBlID0gc3RkOjpjb25kaXRpb25hbF90PGhhc19yZWZfc3dhcDxUPjo6dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dHJ1ZV90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZhbHNlX3R5cGU+Owp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnVzaW5nIE1ldGFIZWxwZXJUeXBlID0gdHlwZW5hbWUgTWV0YUhlbHBlclR5cGVfaW1wbDxUPjo6dHlwZTsKCnN0cnVjdCBOb25SZWZlcmVuY2VTd2FwCnsKICAgIHZvaWQgc3dhcChOb25SZWZlcmVuY2VTd2FwKSB7fQp9OwoKc3RydWN0IFJlZmVyZW5jZVN3YXAKewogICAgdm9pZCBzd2FwKFJlZmVyZW5jZVN3YXAgJikge30KfTsKCnN0cnVjdCBOb1N3YXBGdW5jdGlvbiB7fTsKCmludCBtYWluKCkgewoJc3RhdGljX2Fzc2VydChNZXRhSGVscGVyVHlwZTxSZWZlcmVuY2VTd2FwPjo6dmFsdWUsICJ1bmV4cGVjdGVkIHJlc3VsdCIpOwoJc3RhdGljX2Fzc2VydCghTWV0YUhlbHBlclR5cGU8Tm9Td2FwRnVuY3Rpb24+Ojp2YWx1ZSwgInVuZXhwZWN0ZWQgcmVzdWx0Iik7CQoJc3RhdGljX2Fzc2VydCghTWV0YUhlbHBlclR5cGU8Tm9uUmVmZXJlbmNlU3dhcD46OnZhbHVlLCAidW5leHBlY3RlZCByZXN1bHQiKTsgLy8gRG9lc24ndCBjb21waWxlIGFzIGV4cGVjdGVkCQp9
compilation info
prog.cpp: In instantiation of 'struct MetaHelperType_impl<NonReferenceSwap>':
prog.cpp:34:61: required by substitution of 'template<class T> using MetaHelperType = typename MetaHelperType_impl::type [with T = NonReferenceSwap]'
prog.cpp:51:48: required from here
prog.cpp:24:5: error: static assertion failed: Incorrect implementation of T::swap, signature should be void T::swap(T&) instead of T::swap(T)
static_assert(!has_value_swap<T>::value,
^
stdout