111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The LLVM Compiler Infrastructure 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Source Licenses. See LICENSE.TXT for details. 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef INVOKE_HELPERS_H 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define INVOKE_HELPERS_H 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <type_traits> 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cassert> 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <functional> 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "test_macros.h" 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <int I> 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Int : public std::integral_constant<int, I> {}; 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <bool P> 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Bool : public std::integral_constant<bool, P> {}; 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Q_None { 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct apply { typedef T type; }; 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Q_Const { 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct apply { typedef T const type; }; 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Q_Volatile { 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct apply { typedef T volatile type; }; 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Q_CV { 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct apply { typedef T const volatile type; }; 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Caster - A functor object that performs cv-qualifier and value category 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// conversions. 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// QualTag - A metafunction type that applies cv-qualifiers to its argument. 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// RValue - True if the resulting object should be an RValue reference. 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// False otherwise. 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class QualTag, bool RValue = false> 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Caster { 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct apply { 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename std::remove_reference<T>::type RawType; 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename QualTag::template apply<RawType>::type CVType; 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename std::conditional<RValue, 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CVType&&, CVType& 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert >::type type; 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef CVType& type; 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class T> 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename apply<T>::type 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(T& obj) const { 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename apply<T>::type OutType; 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return static_cast<OutType>(obj); 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_None> LValueCaster; 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_Const> ConstCaster; 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_Volatile> VolatileCaster; 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_CV> CVCaster; 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_None, true> MoveCaster; 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_Const, true> MoveConstCaster; 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_Volatile, true> MoveVolatileCaster; 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef Caster<Q_CV, true> MoveCVCaster; 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 8411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp const& makeConst(Tp& ref) { return ref; } 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 8711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp const* makeConst(Tp* ptr) { return ptr; } 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::reference_wrapper<const Tp> makeConst(std::reference_wrapper<Tp>& ref) { 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::reference_wrapper<const Tp>(ref.get()); 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 9511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp volatile& makeVolatile(Tp& ref) { return ref; } 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 9811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp volatile* makeVolatile(Tp* ptr) { return ptr; } 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::reference_wrapper<volatile Tp> makeVolatile(std::reference_wrapper<Tp>& ref) { 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::reference_wrapper<volatile Tp>(ref.get()); 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 10611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp const volatile& makeCV(Tp& ref) { return ref; } 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 10911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertTp const volatile* makeCV(Tp* ptr) { return ptr; } 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Tp> 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::reference_wrapper<const volatile Tp> makeCV(std::reference_wrapper<Tp>& ref) { 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::reference_wrapper<const volatile Tp>(ref.get()); 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// A shorter name for 'static_cast' 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class QualType, class Tp> 11811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertQualType C_(Tp& v) { return static_cast<QualType>(v); }; 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// ArgType - A non-copyable type intended to be used as a dummy argument type 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// to test functions. 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct ArgType { 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int value; 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit ArgType(int val = 0) : value(val) {} 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate: 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ArgType(ArgType const&); 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ArgType& operator=(ArgType const&); 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// DerivedFromBase - A type that derives from it's template argument 'Base' 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class Base> 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct DerivedFromType : public Base { 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DerivedFromType() : Base() {} 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class Tp> 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit DerivedFromType(Tp const& t) : Base(t) {} 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// DerefToType - A type that dereferences to it's template argument 'To'. 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The cv-ref qualifiers of the 'DerefToType' object do not propagate 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// to the resulting 'To' object. 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class To> 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct DerefToType { 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To object; 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DerefToType() {} 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class Up> 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit DerefToType(Up const& val) : object(val) {} 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To& operator*() const volatile { return const_cast<To&>(object); } 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// DerefPropToType - A type that dereferences to it's template argument 'To'. 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The cv-ref qualifiers of the 'DerefPropToType' object propagate 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// to the resulting 'To' object. 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class To> 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct DerefPropType { 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To object; 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert DerefPropType() {} 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class Up> 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit DerefPropType(Up const& val) : object(val) {} 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER < 11 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To& operator*() { return object; } 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const& operator*() const { return object; } 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To volatile& operator*() volatile { return object; } 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const volatile& operator*() const volatile { return object; } 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To& operator*() & { return object; } 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const& operator*() const & { return object; } 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To volatile& operator*() volatile & { return object; } 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const volatile& operator*() const volatile & { return object; } 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To&& operator*() && { return static_cast<To &&>(object); } 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const&& operator*() const && { return static_cast<To const&&>(object); } 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); } 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); } 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MethodID - A type that uniquely identifies a member function for a class. 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This type is used to communicate between the member functions being tested 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// and the tests invoking them. 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// - Test methods should call 'setUncheckedCall()' whenever they are invoked. 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// - Tests consume the unchecked call using checkCall(<return-value>)` to assert 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// that the method has been called and that the return value of `__invoke` 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// matches what the method actually returned. 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T> 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct MethodID { 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef void* IDType; 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int dummy; // A dummy memory location. 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void* id; // The "ID" is the value of this pointer. 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static bool unchecked_call; // Has a call happened that has not been checked. 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void*& setUncheckedCall() { 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(unchecked_call == false); 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unchecked_call = true; 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return id; 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static bool checkCalled(void*& return_value) { 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool old = unchecked_call; 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unchecked_call = false; 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return old && id == return_value && &id == &return_value; 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T> int MethodID<T>::dummy = 0; 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy; 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T> bool MethodID<T>::unchecked_call = false; 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// FunctionPtrID - Like MethodID but for free function pointers. 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T, T*> 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct FunctionPtrID { 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static int dummy; // A dummy memory location. 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void* id; // The "ID" is the value of this pointer. 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static bool unchecked_call; // Has a call happened that has not been checked. 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static void*& setUncheckedCall() { 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(unchecked_call == false); 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unchecked_call = true; 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return id; 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static bool checkCalled(void*& return_value) { 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool old = unchecked_call; 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unchecked_call = false; 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return old && id == return_value && &id == &return_value; 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0; 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy; 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false; 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//============================================================================== 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// BasicTest - The basic test structure for everything except 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// member object pointers. 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// ID - The "Function Identifier" type used either MethodID or FunctionPtrID. 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Arity - The Arity of the call signature. 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// ObjectCaster - The object transformation functor type. 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// ArgCaster - The extra argument transformation functor type. 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class ID, int Arity, class ObjectCaster = LValueCaster, 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class ArgCaster = LValueCaster> 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct BasicTest { 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class ObjectT> 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTest(ObjectT& object) { 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Int<Arity> A; 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert runTestImp(A, object); 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class MethodPtr, class ObjectT> 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTest(MethodPtr ptr, ObjectT& object) { 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Int<Arity> A; 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert runTestImp(A, ptr, object); 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate: 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef void*& CallRet; 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ObjectCaster object_cast; 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ArgCaster arg_cast; 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ArgType a0, a1, a2; 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //========================================================================== 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // BULLET 1, 2 AND 3 TEST METHODS 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //========================================================================== 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class MethodPtr, class ObjectT> 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) { 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(ptr, object_cast(object))) 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(ptr, object_cast(object)); 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(ptr, object_cast(object))) 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(ptr, object_cast(object)); 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class MethodPtr, class ObjectT> 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) { 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0))) 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0)); 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0))) 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0)); 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class MethodPtr, class ObjectT> 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) { 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1))) 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1))) 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class MethodPtr, class ObjectT> 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) { 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //========================================================================== 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // BULLET 7 TEST METHODS 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //========================================================================== 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class ObjectT> 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<0>, ObjectT& object) { 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(object_cast(object))) 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(object_cast(object)); 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(object_cast(object))) 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(object_cast(object)); 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class ObjectT> 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<1>, ObjectT& object) { 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(object_cast(object), arg_cast(a0))) 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(object_cast(object), arg_cast(a0)); 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0))) 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0)); 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class ObjectT> 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<2>, ObjectT& object) { 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1))) 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)); 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1))) 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1)); 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <class ObjectT> 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void runTestImp(Int<3>, ObjectT& object) { 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if TEST_STD_VER >= 11 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same< 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert , CallRet>::value), ""); 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::unchecked_call == false); 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(ID::checkCalled(ret)); 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // INVOKE_HELPERS_H 457