Revert "Update aosp/master libcxx rebase to r263688"
The world is burning. This reverts commitc004fd909c, reversing changes made to1418e4163d.
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
|
||||
// <functional>
|
||||
|
||||
// template<CopyConstructible Fn, CopyConstructible... Types>
|
||||
// unspecified bind(Fn, Types...);
|
||||
// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
|
||||
// unspecified bind(Fn, Types...);
|
||||
|
||||
// https://llvm.org/bugs/show_bug.cgi?id=23141
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
struct Fun
|
||||
{
|
||||
template<typename T, typename U>
|
||||
void operator()(T &&, U &&) const
|
||||
{
|
||||
static_assert(std::is_same<U, int &>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::bind(Fun{}, std::placeholders::_1, 42)("hello");
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
struct DummyUnaryFunction
|
||||
{
|
||||
template <typename S>
|
||||
int operator()(S const &) const { return 0; }
|
||||
int operator()(S const & s) const { return 0; }
|
||||
};
|
||||
|
||||
struct BadUnaryFunction
|
||||
@@ -39,7 +39,7 @@ struct BadUnaryFunction
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Check that BadUnaryFunction::operator()(S const &) is not
|
||||
// instantiated when checking if BadUnaryFunction is a nested bind
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility> // for std::move
|
||||
#include <cassert>
|
||||
|
||||
struct NonCopyable {
|
||||
@@ -172,32 +171,6 @@ void bullet_one_two_tests() {
|
||||
test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
|
||||
test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
|
||||
}
|
||||
{
|
||||
TestClass cl_obj(42);
|
||||
std::reference_wrapper<TestClass> cl(cl_obj);
|
||||
test_b12<int&(NonCopyable&&) &, int&>(cl);
|
||||
test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
|
||||
test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
|
||||
test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
|
||||
|
||||
test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
|
||||
test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
|
||||
test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
|
||||
test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
|
||||
}
|
||||
{
|
||||
DerivedFromTestClass cl_obj(42);
|
||||
std::reference_wrapper<DerivedFromTestClass> cl(cl_obj);
|
||||
test_b12<int&(NonCopyable&&) &, int&>(cl);
|
||||
test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
|
||||
test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
|
||||
test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
|
||||
|
||||
test_b12<int&(NonCopyable&&) &, int&>(std::move(cl));
|
||||
test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl));
|
||||
test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl));
|
||||
test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl));
|
||||
}
|
||||
{
|
||||
TestClass cl_obj(42);
|
||||
TestClass *cl = &cl_obj;
|
||||
@@ -243,22 +216,6 @@ void bullet_three_four_tests() {
|
||||
test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
|
||||
test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
|
||||
}
|
||||
{
|
||||
typedef TestClass Fn;
|
||||
Fn cl(42);
|
||||
test_b34<int&>(std::reference_wrapper<Fn>(cl));
|
||||
test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
|
||||
test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
|
||||
test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
|
||||
}
|
||||
{
|
||||
typedef DerivedFromTestClass Fn;
|
||||
Fn cl(42);
|
||||
test_b34<int&>(std::reference_wrapper<Fn>(cl));
|
||||
test_b34<int const&>(std::reference_wrapper<Fn const>(cl));
|
||||
test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl));
|
||||
test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl));
|
||||
}
|
||||
{
|
||||
typedef TestClass Fn;
|
||||
Fn cl_obj(42);
|
||||
|
||||
@@ -69,7 +69,4 @@ int main()
|
||||
test0(std::mem_fn(&A::test0));
|
||||
test1(std::mem_fn(&A::test1));
|
||||
test2(std::mem_fn(&A::test2));
|
||||
#if __has_feature(cxx_noexcept)
|
||||
static_assert((noexcept(std::mem_fn(&A::test0))), ""); // LWG#2489
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// INVOKE (f, t1, t2, ..., tN)
|
||||
|
||||
// The tests for INVOKE (f, t1, t2, ..., tN) live in the "test/libcxx" tree
|
||||
// since they require calling the implementation specific "__invoke" and
|
||||
// "__invoke_constexpr" functions.
|
||||
|
||||
int main() {}
|
||||
@@ -0,0 +1,318 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// INVOKE (f, t1, t2, ..., tN)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TESTING INVOKE(f, t1, t2, ..., tN)
|
||||
// - Bullet 1 -- (t1.*f)(t2, ..., tN)
|
||||
// - Bullet 2 -- ((*t1).*f)(t2, ..., tN)
|
||||
//
|
||||
// Overview:
|
||||
// Bullets 1 and 2 handle the case where 'f' is a pointer to member function.
|
||||
// Bullet 1 only handles the cases where t1 is an object of type T or a
|
||||
// type derived from 'T'. Bullet 2 handles all other cases.
|
||||
//
|
||||
// Concerns:
|
||||
// 1) cv-qualified member function signatures are accepted.
|
||||
// 2) reference qualified member function signatures are accepted.
|
||||
// 3) member functions with varargs at the end are accepted.
|
||||
// 4) The arguments are perfect forwarded to the member function call.
|
||||
// 5) Classes that are publicly derived from 'T' are accepted as the call object
|
||||
// 6) All types that dereference to T or a type derived from T can be used
|
||||
// as the call object.
|
||||
// 7) Pointers to T or a type derived from T can be used as the call object.
|
||||
// 8) Reference return types are properly deduced.
|
||||
//
|
||||
//
|
||||
// Plan:
|
||||
// 1) Create a class that contains a set, 'S', of non-static functions.
|
||||
// 'S' should include functions that cover every single combination
|
||||
// of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
|
||||
// The argument types used in the functions should be non-copyable (C-4).
|
||||
// The functions should return 'MethodID::setUncheckedCall()'.
|
||||
//
|
||||
// 2) Create a set of supported call object, 'Objs', of different types
|
||||
// and behaviors. (C-5,6,7)
|
||||
//
|
||||
// 3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
|
||||
// in 'Objs'. After every attempted call to 'f' check that 'f' was
|
||||
// actually called using 'MethodID::checkCalled(<return-value>)'
|
||||
//
|
||||
// 3b) If 'f' is reference qualified call 'f' with the properly qualified
|
||||
// call object. Otherwise call 'f' with lvalue call objects.
|
||||
//
|
||||
// 3a) If 'f' is const, volatile, or cv qualified then call it with call
|
||||
// objects that are equally or less cv-qualified.
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "invoke_helpers.h"
|
||||
|
||||
//==============================================================================
|
||||
// MemFun03 - C++03 compatible set of test member functions.
|
||||
struct MemFun03 {
|
||||
typedef void*& R;
|
||||
#define F(...) \
|
||||
R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
|
||||
#
|
||||
F()
|
||||
F(...)
|
||||
F(ArgType&)
|
||||
F(ArgType&, ...)
|
||||
F(ArgType&, ArgType&)
|
||||
F(ArgType&, ArgType&, ...)
|
||||
F(ArgType&, ArgType&, ArgType&)
|
||||
F(ArgType&, ArgType&, ArgType&, ...)
|
||||
#undef F
|
||||
public:
|
||||
MemFun03() {}
|
||||
private:
|
||||
MemFun03(MemFun03 const&);
|
||||
MemFun03& operator=(MemFun03 const&);
|
||||
};
|
||||
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
|
||||
//==============================================================================
|
||||
// MemFun11 - C++11 reference qualified test member functions.
|
||||
struct MemFun11 {
|
||||
typedef void*& R;
|
||||
typedef MemFun11 C;
|
||||
#define F(...) \
|
||||
R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
|
||||
R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
|
||||
#
|
||||
F()
|
||||
F(...)
|
||||
F(ArgType&&)
|
||||
F(ArgType&&, ...)
|
||||
F(ArgType&&, ArgType&&)
|
||||
F(ArgType&&, ArgType&&, ...)
|
||||
F(ArgType&&, ArgType&&, ArgType&&)
|
||||
F(ArgType&&, ArgType&&, ArgType&&, ...)
|
||||
#undef F
|
||||
public:
|
||||
MemFun11() {}
|
||||
private:
|
||||
MemFun11(MemFun11 const&);
|
||||
MemFun11& operator=(MemFun11 const&);
|
||||
};
|
||||
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// TestCase - A test case for a single member function.
|
||||
// ClassType - The type of the class being tested.
|
||||
// CallSig - The function signature of the method being tested.
|
||||
// Arity - the arity of 'CallSig'
|
||||
// CV - the cv qualifiers of 'CallSig' represented as a type tag.
|
||||
// RValue - The method is RValue qualified.
|
||||
// ArgRValue - Call the method with RValue arguments.
|
||||
template <class ClassType, class CallSig, int Arity, class CV,
|
||||
bool RValue = false, bool ArgRValue = false>
|
||||
struct TestCaseImp {
|
||||
public:
|
||||
|
||||
static void run() { TestCaseImp().doTest(); }
|
||||
|
||||
private:
|
||||
//==========================================================================
|
||||
// TEST DISPATCH
|
||||
void doTest() {
|
||||
// (Plan-2) Create test call objects.
|
||||
typedef ClassType T;
|
||||
typedef DerivedFromType<T> D;
|
||||
T obj;
|
||||
T* obj_ptr = &obj;
|
||||
D der;
|
||||
D* der_ptr = &der;
|
||||
DerefToType<T> dref;
|
||||
DerefPropType<T> dref2;
|
||||
|
||||
// (Plan-3) Dispatch based on the CV tags.
|
||||
CV tag;
|
||||
Bool<!RValue> NotRValue;
|
||||
runTestDispatch(tag, obj);
|
||||
runTestDispatch(tag, der);
|
||||
runTestDispatch(tag, dref2);
|
||||
runTestDispatchIf(NotRValue, tag, dref);
|
||||
runTestDispatchIf(NotRValue, tag, obj_ptr);
|
||||
runTestDispatchIf(NotRValue, tag, der_ptr);
|
||||
}
|
||||
|
||||
template <class QT, class Tp>
|
||||
void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
|
||||
runTestDispatch(q, v);
|
||||
}
|
||||
|
||||
template <class QT, class Tp>
|
||||
void runTestDispatchIf(Bool<false>, QT, Tp&) {
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
void runTestDispatch(Q_None, Tp& v) {
|
||||
runTest(v);
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
void runTestDispatch(Q_Const, Tp& v) {
|
||||
Tp const& cv = v;
|
||||
runTest(v);
|
||||
runTest(cv);
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
void runTestDispatch(Q_Volatile, Tp& v) {
|
||||
Tp volatile& vv = v;
|
||||
runTest(v);
|
||||
runTest(vv);
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
void runTestDispatch(Q_CV, Tp& v) {
|
||||
Tp const& cv = v;
|
||||
Tp volatile& vv = v;
|
||||
Tp const volatile& cvv = v;
|
||||
runTest(v);
|
||||
runTest(cv);
|
||||
runTest(vv);
|
||||
runTest(cvv);
|
||||
}
|
||||
|
||||
template <class Obj>
|
||||
void runTest(Obj& obj) {
|
||||
typedef Caster<Q_None, RValue> SCast;
|
||||
typedef Caster<Q_None, ArgRValue> ACast;
|
||||
typedef CallSig (ClassType::*MemPtr);
|
||||
// Delegate test to logic in invoke_helpers.h
|
||||
BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
|
||||
b.runTest( (MemPtr)&ClassType::f, obj);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Sig, int Arity, class CV>
|
||||
struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
template <class Sig, int Arity, class CV, bool RValue = false>
|
||||
struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
typedef void*& R;
|
||||
typedef ArgType A;
|
||||
TestCase<R(), 0, Q_None>::run();
|
||||
TestCase<R() const, 0, Q_Const>::run();
|
||||
TestCase<R() volatile, 0, Q_Volatile>::run();
|
||||
TestCase<R() const volatile, 0, Q_CV>::run();
|
||||
TestCase<R(...), 0, Q_None>::run();
|
||||
TestCase<R(...) const, 0, Q_Const>::run();
|
||||
TestCase<R(...) volatile, 0, Q_Volatile>::run();
|
||||
TestCase<R(...) const volatile, 0, Q_CV>::run();
|
||||
TestCase<R(A&), 1, Q_None>::run();
|
||||
TestCase<R(A&) const, 1, Q_Const>::run();
|
||||
TestCase<R(A&) volatile, 1, Q_Volatile>::run();
|
||||
TestCase<R(A&) const volatile, 1, Q_CV>::run();
|
||||
TestCase<R(A&, ...), 1, Q_None>::run();
|
||||
TestCase<R(A&, ...) const, 1, Q_Const>::run();
|
||||
TestCase<R(A&, ...) volatile, 1, Q_Volatile>::run();
|
||||
TestCase<R(A&, ...) const volatile, 1, Q_CV>::run();
|
||||
TestCase<R(A&, A&), 2, Q_None>::run();
|
||||
TestCase<R(A&, A&) const, 2, Q_Const>::run();
|
||||
TestCase<R(A&, A&) volatile, 2, Q_Volatile>::run();
|
||||
TestCase<R(A&, A&) const volatile, 2, Q_CV>::run();
|
||||
TestCase<R(A&, A&, ...), 2, Q_None>::run();
|
||||
TestCase<R(A&, A&, ...) const, 2, Q_Const>::run();
|
||||
TestCase<R(A&, A&, ...) volatile, 2, Q_Volatile>::run();
|
||||
TestCase<R(A&, A&, ...) const volatile, 2, Q_CV>::run();
|
||||
TestCase<R(A&, A&, A&), 3, Q_None>::run();
|
||||
TestCase<R(A&, A&, A&) const, 3, Q_Const>::run();
|
||||
TestCase<R(A&, A&, A&) volatile, 3, Q_Volatile>::run();
|
||||
TestCase<R(A&, A&, A&) const volatile, 3, Q_CV>::run();
|
||||
TestCase<R(A&, A&, A&, ...), 3, Q_None>::run();
|
||||
TestCase<R(A&, A&, A&, ...) const, 3, Q_Const>::run();
|
||||
TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run();
|
||||
TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run();
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
TestCase11<R() &, 0, Q_None>::run();
|
||||
TestCase11<R() const &, 0, Q_Const>::run();
|
||||
TestCase11<R() volatile &, 0, Q_Volatile>::run();
|
||||
TestCase11<R() const volatile &, 0, Q_CV>::run();
|
||||
TestCase11<R(...) &, 0, Q_None>::run();
|
||||
TestCase11<R(...) const &, 0, Q_Const>::run();
|
||||
TestCase11<R(...) volatile &, 0, Q_Volatile>::run();
|
||||
TestCase11<R(...) const volatile &, 0, Q_CV>::run();
|
||||
TestCase11<R(A&&) &, 1, Q_None>::run();
|
||||
TestCase11<R(A&&) const &, 1, Q_Const>::run();
|
||||
TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run();
|
||||
TestCase11<R(A&&) const volatile &, 1, Q_CV>::run();
|
||||
TestCase11<R(A&&, ...) &, 1, Q_None>::run();
|
||||
TestCase11<R(A&&, ...) const &, 1, Q_Const>::run();
|
||||
TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run();
|
||||
TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run();
|
||||
TestCase11<R(A&&, A&&) &, 2, Q_None>::run();
|
||||
TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run();
|
||||
TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run();
|
||||
TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run();
|
||||
TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run();
|
||||
TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run();
|
||||
TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run();
|
||||
TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run();
|
||||
TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
|
||||
TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// INVOKE (f, t1, t2, ..., tN)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TESTING INVOKE(f, t1, t2, ..., tN)
|
||||
// - Bullet 3 -- t1.*f
|
||||
// - Bullet 4 -- (*t1).*f
|
||||
//
|
||||
// Overview:
|
||||
// Bullets 3 and 4 handle the case where 'f' is a pointer to member object.
|
||||
// Bullet 3 only handles the cases where t1 is an object of type T or a
|
||||
// type derived from 'T'. Bullet 4 handles all other cases.
|
||||
//
|
||||
// Concerns:
|
||||
// 1) The return type is always an lvalue reference.
|
||||
// 2) The return type is not less cv-qualified that the object that contains it.
|
||||
// 3) The return type is not less cv-qualified than object type.
|
||||
// 4) The call object is perfectly forwarded.
|
||||
// 5) Classes that are publicly derived from 'T' are accepted as the call object
|
||||
// 6) All types that dereference to T or a type derived from T can be used
|
||||
// as the call object.
|
||||
// 7) Pointers to T or a type derived from T can be used as the call object.
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "invoke_helpers.h"
|
||||
|
||||
template <class Tp>
|
||||
struct TestMemberObject {
|
||||
TestMemberObject() : object() {}
|
||||
Tp object;
|
||||
private:
|
||||
TestMemberObject(TestMemberObject const&);
|
||||
TestMemberObject& operator=(TestMemberObject const&);
|
||||
};
|
||||
|
||||
template <class ObjectType>
|
||||
struct TestCase {
|
||||
public:
|
||||
|
||||
static void run() { TestCase().doTest(); }
|
||||
|
||||
private:
|
||||
typedef TestMemberObject<ObjectType> TestType;
|
||||
|
||||
//==========================================================================
|
||||
// TEST DISPATCH
|
||||
void doTest() {
|
||||
typedef DerivedFromType<TestType> Derived;
|
||||
TestType obj;
|
||||
TestType* obj_ptr = &obj;
|
||||
Derived der;
|
||||
Derived* der_ptr = &der;
|
||||
DerefToType<TestType> dref;
|
||||
DerefPropType<TestType> dref2;
|
||||
|
||||
{
|
||||
typedef ObjectType (TestType::*MemPtr);
|
||||
typedef ObjectType E;
|
||||
MemPtr M = &TestType::object;
|
||||
runTestDispatch<E>(M, obj, &obj.object);
|
||||
runTestDispatch<E>(M, der, &der.object);
|
||||
runTestDispatch<E>(M, dref2, &dref2.object.object);
|
||||
runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
|
||||
runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
|
||||
runTestPointerDispatch<E>(M, dref, &dref.object.object);
|
||||
}
|
||||
{
|
||||
typedef ObjectType const (TestType::*CMemPtr);
|
||||
typedef ObjectType const E;
|
||||
CMemPtr M = &TestType::object;
|
||||
runTestDispatch<E>(M, obj, &obj.object);
|
||||
runTestDispatch<E>(M, der, &der.object);
|
||||
runTestDispatch<E>(M, dref2, &dref2.object.object);
|
||||
runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
|
||||
runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
|
||||
runTestPointerDispatch<E>(M, dref, &dref.object.object);
|
||||
}
|
||||
{
|
||||
typedef ObjectType volatile (TestType::*VMemPtr);
|
||||
typedef ObjectType volatile E;
|
||||
VMemPtr M = &TestType::object;
|
||||
runTestDispatch<E>(M, obj, &obj.object);
|
||||
runTestDispatch<E>(M, der, &der.object);
|
||||
runTestDispatch<E>(M, dref2, &dref2.object.object);
|
||||
runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
|
||||
runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
|
||||
runTestPointerDispatch<E>(M, dref, &dref.object.object);
|
||||
}
|
||||
{
|
||||
typedef ObjectType const volatile (TestType::*CVMemPtr);
|
||||
typedef ObjectType const volatile E;
|
||||
CVMemPtr M = &TestType::object;
|
||||
runTestDispatch<E>(M, obj, &obj.object);
|
||||
runTestDispatch<E>(M, der, &der.object);
|
||||
runTestDispatch<E>(M, dref2, &dref2.object.object);
|
||||
runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
|
||||
runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
|
||||
runTestPointerDispatch<E>(M, dref, &dref.object.object);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Expect, class Fn, class T>
|
||||
void runTestDispatch(Fn M, T& obj, ObjectType* expect) {
|
||||
runTest<Expect &> (M, C_<T&>(obj), expect);
|
||||
runTest<Expect const&> (M, C_<T const&>(obj), expect);
|
||||
runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect);
|
||||
runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect);
|
||||
#if TEST_STD_VER >= 11
|
||||
runTest<Expect&&> (M, C_<T&&>(obj), expect);
|
||||
runTest<Expect const&&> (M, C_<T const&&>(obj), expect);
|
||||
runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect);
|
||||
runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Expect, class Fn, class T>
|
||||
void runTestPointerDispatch(Fn M, T& obj, ObjectType* expect) {
|
||||
runTest<Expect&>(M, C_<T &>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T const&>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T volatile&>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T const volatile&>(obj), expect);
|
||||
#if TEST_STD_VER >= 11
|
||||
runTest<Expect&>(M, C_<T&&>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T const&&>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T volatile&&>(obj), expect);
|
||||
runTest<Expect&>(M, C_<T const volatile&&>(obj), expect);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Expect, class Fn, class T>
|
||||
#if TEST_STD_VER >= 11
|
||||
void runTest(Fn M, T&& obj, ObjectType* expect) {
|
||||
#else
|
||||
void runTest(Fn M, T& obj, ObjectType* expect ) {
|
||||
#endif
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(M, std::forward<T>(obj))), Expect
|
||||
>::value), "");
|
||||
Expect e = std::__invoke(M, std::forward<T>(obj));
|
||||
assert(&e == expect);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
TestCase<ArgType>::run();
|
||||
TestCase<ArgType const>::run();
|
||||
TestCase<ArgType volatile>::run();
|
||||
TestCase<ArgType const volatile>::run();
|
||||
TestCase<ArgType*>::run();
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// INVOKE (f, t1, t2, ..., tN)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TESTING INVOKE(f, t1, t2, ..., tN)
|
||||
// - Bullet 5 -- f(t2, ..., tN)
|
||||
//
|
||||
// Overview:
|
||||
// Bullet 5 handles the cases where the first argument is not a member
|
||||
// function.
|
||||
//
|
||||
// Concerns:
|
||||
// 1) Different types of callable objects are supported. Including
|
||||
// 1a) Free Function pointers and references.
|
||||
// 1b) Classes which provide a call operator
|
||||
// 1c) lambdas
|
||||
// 2) The callable objects are perfect forwarded.
|
||||
// 3) The arguments are perfect forwarded.
|
||||
// 4) Signatures which include varargs are supported.
|
||||
// 5) In C++03 3 extra arguments should be allowed.
|
||||
//
|
||||
// Plan:
|
||||
// 1) Define a set of free functions, 'SF', and class types with call
|
||||
// operators, 'SC', that address concerns 4 and 5. The free functions should
|
||||
// return 'FunctionID::setUncheckedCall()' and the call operators should
|
||||
// return 'MethodID::setUncheckedCall()'.
|
||||
//
|
||||
// 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'
|
||||
// using the correct number of arguments and cv-ref qualifiers. Check that
|
||||
// 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free
|
||||
// function and 'MethodID::checkCall()' otherwise.
|
||||
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "invoke_helpers.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// freeFunction03 - A C++03 free function.
|
||||
void*& freeFunction03() {
|
||||
return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
void*& freeFunction03(...) {
|
||||
return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
template <class A0>
|
||||
void*& freeFunction03(A0&) {
|
||||
return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
|
||||
template <class A0>
|
||||
void*& freeFunction03(A0&, ...) {
|
||||
return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
template <class A0, class A1>
|
||||
void*& freeFunction03(A0&, A1&) {
|
||||
return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
|
||||
template <class A0, class A1>
|
||||
void*& freeFunction03(A0&, A1&, ...) {
|
||||
return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2>
|
||||
void*& freeFunction03(A0&, A1&, A2&) {
|
||||
return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2>
|
||||
void*& freeFunction03(A0&, A1&, A2&, ...) {
|
||||
return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Functor03 - C++03 compatible functor object
|
||||
struct Functor03 {
|
||||
typedef void*& R;
|
||||
typedef Functor03 C;
|
||||
#define F(Args, ...) \
|
||||
__VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \
|
||||
__VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \
|
||||
__VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \
|
||||
__VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }
|
||||
#
|
||||
F(())
|
||||
F((A0&), template <class A0>)
|
||||
F((A0&, A1&), template <class A0, class A1>)
|
||||
F((A0&, A1&, A2&), template <class A0, class A1, class A2>)
|
||||
#undef F
|
||||
public:
|
||||
Functor03() {}
|
||||
private:
|
||||
Functor03(Functor03 const&);
|
||||
Functor03& operator=(Functor03 const&);
|
||||
};
|
||||
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
|
||||
//==============================================================================
|
||||
// freeFunction11 - A C++11 free function.
|
||||
template <class ...Args>
|
||||
void*& freeFunction11(Args&&...) {
|
||||
return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
|
||||
}
|
||||
|
||||
template <class ...Args>
|
||||
void*& freeFunction11(Args&&...,...) {
|
||||
return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Functor11 - C++11 reference qualified test member functions.
|
||||
struct Functor11 {
|
||||
typedef void*& R;
|
||||
typedef Functor11 C;
|
||||
|
||||
#define F(CV) \
|
||||
template <class ...Args> \
|
||||
R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
|
||||
#
|
||||
F(&)
|
||||
F(const &)
|
||||
F(volatile &)
|
||||
F(const volatile &)
|
||||
F(&&)
|
||||
F(const &&)
|
||||
F(volatile &&)
|
||||
F(const volatile &&)
|
||||
#undef F
|
||||
public:
|
||||
Functor11() {}
|
||||
private:
|
||||
Functor11(Functor11 const&);
|
||||
Functor11& operator=(Functor11 const&);
|
||||
};
|
||||
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// TestCaseFunctorImp - A test case for an operator() class method.
|
||||
// ClassType - The type of the call object.
|
||||
// CallSig - The function signature of the call operator being tested.
|
||||
// Arity - the arity of 'CallSig'
|
||||
// ObjCaster - Transformation function applied to call object.
|
||||
// ArgCaster - Transformation function applied to the extra arguments.
|
||||
template <class ClassType, class CallSig, int Arity,
|
||||
class ObjCaster, class ArgCaster = LValueCaster>
|
||||
struct TestCaseFunctorImp {
|
||||
public:
|
||||
static void run() {
|
||||
typedef MethodID<CallSig ClassType::*> MID;
|
||||
BasicTest<MID, Arity, ObjCaster, ArgCaster> t;
|
||||
typedef ClassType T;
|
||||
typedef DerivedFromType<T> D;
|
||||
T obj;
|
||||
D der;
|
||||
t.runTest(obj);
|
||||
t.runTest(der);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// TestCaseFreeFunction - A test case for a free function.
|
||||
// CallSig - The function signature of the free function being tested.
|
||||
// FnPtr - The function being tested.
|
||||
// Arity - the arity of 'CallSig'
|
||||
// ArgCaster - Transformation function to be applied to the extra arguments.
|
||||
template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>
|
||||
struct TestCaseFreeFunction {
|
||||
public:
|
||||
static void run() {
|
||||
typedef FunctionPtrID<CallSig, FnPtr> FID;
|
||||
BasicTest<FID, Arity, LValueCaster, ArgCaster> t;
|
||||
|
||||
DerefToType<CallSig*> deref_to(FnPtr);
|
||||
DerefToType<CallSig&> deref_to_ref(*FnPtr);
|
||||
|
||||
t.runTest(FnPtr);
|
||||
t.runTest(*FnPtr);
|
||||
t.runTest(deref_to);
|
||||
t.runTest(deref_to_ref);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// runTest Helpers
|
||||
//==============================================================================
|
||||
#if TEST_STD_VER >= 11
|
||||
template <class Sig, int Arity, class ArgCaster>
|
||||
void runFunctionTestCase11() {
|
||||
TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Sig, int Arity, class ArgCaster>
|
||||
void runFunctionTestCase() {
|
||||
TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
|
||||
#if TEST_STD_VER >= 11
|
||||
runFunctionTestCase11<Sig, Arity, ArgCaster>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Sig, int Arity, class ObjCaster, class ArgCaster>
|
||||
void runFunctorTestCase() {
|
||||
TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();
|
||||
}
|
||||
|
||||
template <class Sig, int Arity, class ObjCaster>
|
||||
void runFunctorTestCase() {
|
||||
TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
// runTestCase - Run a test case for C++11 class functor types
|
||||
template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
|
||||
void runFunctorTestCase11() {
|
||||
TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
|
||||
}
|
||||
#endif
|
||||
|
||||
// runTestCase - Run a test case for both function and functor types.
|
||||
template <class Sig, int Arity, class ArgCaster>
|
||||
void runTestCase() {
|
||||
runFunctionTestCase<Sig, Arity, ArgCaster>();
|
||||
runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();
|
||||
};
|
||||
|
||||
int main() {
|
||||
typedef void*& R;
|
||||
typedef ArgType A;
|
||||
typedef A const CA;
|
||||
|
||||
runTestCase< R(), 0, LValueCaster >();
|
||||
runTestCase< R(A&), 1, LValueCaster >();
|
||||
runTestCase< R(A&, A&), 2, LValueCaster >();
|
||||
runTestCase< R(A&, A&, A&), 3, LValueCaster >();
|
||||
runTestCase< R(CA&), 1, ConstCaster >();
|
||||
runTestCase< R(CA&, CA&), 2, ConstCaster >();
|
||||
runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >();
|
||||
|
||||
runFunctionTestCase<R(...), 0, LValueCaster >();
|
||||
runFunctionTestCase<R(A&, ...), 1, LValueCaster >();
|
||||
runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
|
||||
runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
runFunctionTestCase11<R(A&&), 1, MoveCaster >();
|
||||
runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
|
||||
#endif
|
||||
|
||||
runFunctorTestCase<R(), 0, LValueCaster >();
|
||||
runFunctorTestCase<R() const, 0, ConstCaster >();
|
||||
runFunctorTestCase<R() volatile, 0, VolatileCaster >();
|
||||
runFunctorTestCase<R() const volatile, 0, CVCaster >();
|
||||
runFunctorTestCase<R(A&), 1, LValueCaster >();
|
||||
runFunctorTestCase<R(A&) const, 1, ConstCaster >();
|
||||
runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >();
|
||||
runFunctorTestCase<R(A&) const volatile, 1, CVCaster >();
|
||||
runFunctorTestCase<R(A&, A&), 2, LValueCaster >();
|
||||
runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >();
|
||||
runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >();
|
||||
runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >();
|
||||
runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >();
|
||||
runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >();
|
||||
runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >();
|
||||
runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >();
|
||||
{
|
||||
typedef ConstCaster CC;
|
||||
runFunctorTestCase<R(CA&), 1, LValueCaster, CC>();
|
||||
runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>();
|
||||
runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>();
|
||||
runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>();
|
||||
runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
runFunctorTestCase11<R() &, 0, LValueCaster >();
|
||||
runFunctorTestCase11<R() const &, 0, ConstCaster >();
|
||||
runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
|
||||
runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
|
||||
runFunctorTestCase11<R() &&, 0, MoveCaster >();
|
||||
runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
|
||||
runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
|
||||
runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
|
||||
{
|
||||
typedef MoveCaster MC;
|
||||
runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
|
||||
runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// [func.require]
|
||||
|
||||
// INVOKE
|
||||
#if __cplusplus < 201103L
|
||||
int main () {} // no __invoke in C++03
|
||||
#else
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T, int N>
|
||||
struct Array
|
||||
{
|
||||
typedef T type[N];
|
||||
};
|
||||
|
||||
struct Type
|
||||
{
|
||||
Array<char, 1>::type& f1();
|
||||
Array<char, 2>::type& f2() const;
|
||||
|
||||
Array<char, 1>::type& g1() &;
|
||||
Array<char, 2>::type& g2() const &;
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Array<char, 3>::type& g3() &&;
|
||||
Array<char, 4>::type& g4() const &&;
|
||||
#endif
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, "");
|
||||
static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, "");
|
||||
|
||||
static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, "");
|
||||
static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, "");
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, "");
|
||||
static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,317 @@
|
||||
#ifndef INVOKE_HELPERS_H
|
||||
#define INVOKE_HELPERS_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <int I>
|
||||
struct Int : public std::integral_constant<int, I> {};
|
||||
|
||||
template <bool P>
|
||||
struct Bool : public std::integral_constant<bool, P> {};
|
||||
|
||||
struct Q_None {
|
||||
template <class T>
|
||||
struct apply { typedef T type; };
|
||||
};
|
||||
|
||||
struct Q_Const {
|
||||
template <class T>
|
||||
struct apply { typedef T const type; };
|
||||
};
|
||||
|
||||
struct Q_Volatile {
|
||||
template <class T>
|
||||
struct apply { typedef T volatile type; };
|
||||
};
|
||||
|
||||
struct Q_CV {
|
||||
template <class T>
|
||||
struct apply { typedef T const volatile type; };
|
||||
};
|
||||
|
||||
// Caster - A functor object that performs cv-qualifier and value category
|
||||
// conversions.
|
||||
// QualTag - A metafunction type that applies cv-qualifiers to its argument.
|
||||
// RValue - True if the resulting object should be an RValue reference.
|
||||
// False otherwise.
|
||||
template <class QualTag, bool RValue = false>
|
||||
struct Caster {
|
||||
template <class T>
|
||||
struct apply {
|
||||
typedef typename std::remove_reference<T>::type RawType;
|
||||
typedef typename QualTag::template apply<RawType>::type CVType;
|
||||
#if TEST_STD_VER >= 11
|
||||
typedef typename std::conditional<RValue,
|
||||
CVType&&, CVType&
|
||||
>::type type;
|
||||
#else
|
||||
typedef CVType& type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
typename apply<T>::type
|
||||
operator()(T& obj) const {
|
||||
typedef typename apply<T>::type OutType;
|
||||
return static_cast<OutType>(obj);
|
||||
}
|
||||
};
|
||||
|
||||
typedef Caster<Q_None> LValueCaster;
|
||||
typedef Caster<Q_Const> ConstCaster;
|
||||
typedef Caster<Q_Volatile> VolatileCaster;
|
||||
typedef Caster<Q_CV> CVCaster;
|
||||
typedef Caster<Q_None, true> MoveCaster;
|
||||
typedef Caster<Q_Const, true> MoveConstCaster;
|
||||
typedef Caster<Q_Volatile, true> MoveVolatileCaster;
|
||||
typedef Caster<Q_CV, true> MoveCVCaster;
|
||||
|
||||
// A shorter name for 'static_cast'
|
||||
template <class QualType, class Tp>
|
||||
QualType C_(Tp& v) { return static_cast<QualType>(v); };
|
||||
|
||||
//==============================================================================
|
||||
// ArgType - A non-copyable type intended to be used as a dummy argument type
|
||||
// to test functions.
|
||||
struct ArgType {
|
||||
int value;
|
||||
explicit ArgType(int val = 0) : value(val) {}
|
||||
private:
|
||||
ArgType(ArgType const&);
|
||||
ArgType& operator=(ArgType const&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// DerivedFromBase - A type that derives from it's template argument 'Base'
|
||||
template <class Base>
|
||||
struct DerivedFromType : public Base {
|
||||
DerivedFromType() : Base() {}
|
||||
template <class Tp>
|
||||
explicit DerivedFromType(Tp const& t) : Base(t) {}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// DerefToType - A type that dereferences to it's template argument 'To'.
|
||||
// The cv-ref qualifiers of the 'DerefToType' object do not propagate
|
||||
// to the resulting 'To' object.
|
||||
template <class To>
|
||||
struct DerefToType {
|
||||
To object;
|
||||
|
||||
DerefToType() {}
|
||||
|
||||
template <class Up>
|
||||
explicit DerefToType(Up const& val) : object(val) {}
|
||||
|
||||
To& operator*() const volatile { return const_cast<To&>(object); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// DerefPropToType - A type that dereferences to it's template argument 'To'.
|
||||
// The cv-ref qualifiers of the 'DerefPropToType' object propagate
|
||||
// to the resulting 'To' object.
|
||||
template <class To>
|
||||
struct DerefPropType {
|
||||
To object;
|
||||
|
||||
DerefPropType() {}
|
||||
|
||||
template <class Up>
|
||||
explicit DerefPropType(Up const& val) : object(val) {}
|
||||
|
||||
#if TEST_STD_VER < 11
|
||||
To& operator*() { return object; }
|
||||
To const& operator*() const { return object; }
|
||||
To volatile& operator*() volatile { return object; }
|
||||
To const volatile& operator*() const volatile { return object; }
|
||||
#else
|
||||
To& operator*() & { return object; }
|
||||
To const& operator*() const & { return object; }
|
||||
To volatile& operator*() volatile & { return object; }
|
||||
To const volatile& operator*() const volatile & { return object; }
|
||||
To&& operator*() && { return static_cast<To &&>(object); }
|
||||
To const&& operator*() const && { return static_cast<To const&&>(object); }
|
||||
To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); }
|
||||
To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// MethodID - A type that uniquely identifies a member function for a class.
|
||||
// This type is used to communicate between the member functions being tested
|
||||
// and the tests invoking them.
|
||||
// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
|
||||
// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
|
||||
// that the method has been called and that the return value of `__invoke`
|
||||
// matches what the method actually returned.
|
||||
template <class T>
|
||||
struct MethodID {
|
||||
typedef void* IDType;
|
||||
|
||||
static int dummy; // A dummy memory location.
|
||||
static void* id; // The "ID" is the value of this pointer.
|
||||
static bool unchecked_call; // Has a call happened that has not been checked.
|
||||
|
||||
static void*& setUncheckedCall() {
|
||||
assert(unchecked_call == false);
|
||||
unchecked_call = true;
|
||||
return id;
|
||||
}
|
||||
|
||||
static bool checkCalled(void*& return_value) {
|
||||
bool old = unchecked_call;
|
||||
unchecked_call = false;
|
||||
return old && id == return_value && &id == &return_value;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> int MethodID<T>::dummy = 0;
|
||||
template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
|
||||
template <class T> bool MethodID<T>::unchecked_call = false;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// FunctionPtrID - Like MethodID but for free function pointers.
|
||||
template <class T, T*>
|
||||
struct FunctionPtrID {
|
||||
static int dummy; // A dummy memory location.
|
||||
static void* id; // The "ID" is the value of this pointer.
|
||||
static bool unchecked_call; // Has a call happened that has not been checked.
|
||||
|
||||
static void*& setUncheckedCall() {
|
||||
assert(unchecked_call == false);
|
||||
unchecked_call = true;
|
||||
return id;
|
||||
}
|
||||
|
||||
static bool checkCalled(void*& return_value) {
|
||||
bool old = unchecked_call;
|
||||
unchecked_call = false;
|
||||
return old && id == return_value && &id == &return_value;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0;
|
||||
template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
|
||||
template <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false;
|
||||
|
||||
//==============================================================================
|
||||
// BasicTest - The basic test structure for everything except
|
||||
// member object pointers.
|
||||
// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
|
||||
// Arity - The Arity of the call signature.
|
||||
// ObjectCaster - The object transformation functor type.
|
||||
// ArgCaster - The extra argument transformation functor type.
|
||||
template <class ID, int Arity, class ObjectCaster = LValueCaster,
|
||||
class ArgCaster = LValueCaster>
|
||||
struct BasicTest {
|
||||
template <class ObjectT>
|
||||
void runTest(ObjectT& object) {
|
||||
Int<Arity> A;
|
||||
runTestImp(A, object);
|
||||
}
|
||||
|
||||
template <class MethodPtr, class ObjectT>
|
||||
void runTest(MethodPtr ptr, ObjectT& object) {
|
||||
Int<Arity> A;
|
||||
runTestImp(A, ptr, object);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef void*& CallRet;
|
||||
ObjectCaster object_cast;
|
||||
ArgCaster arg_cast;
|
||||
ArgType a0, a1, a2;
|
||||
|
||||
//==========================================================================
|
||||
// BULLET 1 AND 2 TEST METHODS
|
||||
//==========================================================================
|
||||
template <class MethodPtr, class ObjectT>
|
||||
void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(ptr, object_cast(object)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(ptr, object_cast(object));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class MethodPtr, class ObjectT>
|
||||
void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class MethodPtr, class ObjectT>
|
||||
void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class MethodPtr, class ObjectT>
|
||||
void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
// BULLET 5 TEST METHODS
|
||||
//==========================================================================
|
||||
template <class ObjectT>
|
||||
void runTestImp(Int<0>, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(object_cast(object)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(object_cast(object));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class ObjectT>
|
||||
void runTestImp(Int<1>, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(object_cast(object), arg_cast(a0)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class ObjectT>
|
||||
void runTestImp(Int<2>, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
|
||||
template <class ObjectT>
|
||||
void runTestImp(Int<3>, ObjectT& object) {
|
||||
static_assert((std::is_same<
|
||||
decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
|
||||
, CallRet>::value), "");
|
||||
assert(ID::unchecked_call == false);
|
||||
CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
|
||||
assert(ID::checkCalled(ret));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // INVOKE_HELPERS_H
|
||||
@@ -1,247 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function(Fp);
|
||||
|
||||
// Ensure that __not_null works for all function types.
|
||||
// See https://llvm.org/bugs/show_bug.cgi?id=23589
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TESTING std::function<...>::__not_null(Callable)
|
||||
//
|
||||
// Concerns:
|
||||
// 1) The call __not_null(Callable) is well formed and correct for each
|
||||
// possible 'Callable' type category. These categories include:
|
||||
// 1a) function pointers
|
||||
// 1b) member function pointer
|
||||
// 1c) member data pointer
|
||||
// 1d) callable class type
|
||||
// 1e) lambdas
|
||||
// Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
|
||||
// types can be null. The other categories are not tested here.
|
||||
// 3) '__not_null(Callable)' is well formed when the call signature includes
|
||||
// varargs.
|
||||
// 4) '__not_null(Callable)' works for Callable types with all aritys less
|
||||
// than or equal to 3 in C++03.
|
||||
// 5) '__not_null(Callable)' works when 'Callable' is a member function
|
||||
// pointer to a cv or ref qualified function type.
|
||||
//
|
||||
// Plan:
|
||||
// 1 For categories 1a, 1b and 1c define a set of
|
||||
// 'Callable' objects for this category. This set should include examples
|
||||
// of arity 0, 1, 2 and possible 3 including versions with varargs as the
|
||||
// last parameter.
|
||||
//
|
||||
// 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
|
||||
//
|
||||
// 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
|
||||
// the signature of the 'Callable' object.
|
||||
//
|
||||
// 2 Create an object of type 'F' using a null pointer of type 'Callable'.
|
||||
// Check that 'F.target<Callable>()' is null.
|
||||
//
|
||||
// 3 Create an object of type 'F' that is not null. Check that
|
||||
// 'F.target<Callable>()' is not null and is equal to the original
|
||||
// argument.
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int foo() { return 42; }
|
||||
int foo(int) { return 42; }
|
||||
int foo(int, int) { return 42; }
|
||||
int foo(int, int, int) { return 42; }
|
||||
|
||||
int foo(...) { return 42; }
|
||||
int foo(int, ...) { return 42; }
|
||||
int foo(int, int, ...) { return 42; }
|
||||
int foo(int, int, int, ...) { return 42; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct MemFun03 {
|
||||
int foo() { return 42; }
|
||||
int foo() const { return 42; }
|
||||
int foo() volatile { return 42; }
|
||||
int foo() const volatile { return 42; }
|
||||
|
||||
int foo(int) { return 42; }
|
||||
int foo(int) const { return 42; }
|
||||
int foo(int) volatile { return 42; }
|
||||
int foo(int) const volatile { return 42; }
|
||||
|
||||
int foo(int, int) { return 42; }
|
||||
int foo(int, int) const { return 42; }
|
||||
int foo(int, int) volatile { return 42; }
|
||||
int foo(int, int) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, int) { return 42; }
|
||||
int foo(int, int, int) const { return 42; }
|
||||
int foo(int, int, int) volatile { return 42; }
|
||||
int foo(int, int, int) const volatile { return 42; }
|
||||
|
||||
int foo(...) { return 42; }
|
||||
int foo(...) const { return 42; }
|
||||
int foo(...) volatile { return 42; }
|
||||
int foo(...) const volatile { return 42; }
|
||||
|
||||
int foo(int, ...) { return 42; }
|
||||
int foo(int, ...) const { return 42; }
|
||||
int foo(int, ...) volatile { return 42; }
|
||||
int foo(int, ...) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, ...) { return 42; }
|
||||
int foo(int, int, ...) const { return 42; }
|
||||
int foo(int, int, ...) volatile { return 42; }
|
||||
int foo(int, int, ...) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, int, ...) { return 42; }
|
||||
int foo(int, int, int, ...) const { return 42; }
|
||||
int foo(int, int, int, ...) volatile { return 42; }
|
||||
int foo(int, int, int, ...) const volatile { return 42; }
|
||||
};
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct MemFun11 {
|
||||
int foo() & { return 42; }
|
||||
int foo() const & { return 42; }
|
||||
int foo() volatile & { return 42; }
|
||||
int foo() const volatile & { return 42; }
|
||||
|
||||
int foo(...) & { return 42; }
|
||||
int foo(...) const & { return 42; }
|
||||
int foo(...) volatile & { return 42; }
|
||||
int foo(...) const volatile & { return 42; }
|
||||
|
||||
int foo() && { return 42; }
|
||||
int foo() const && { return 42; }
|
||||
int foo() volatile && { return 42; }
|
||||
int foo() const volatile && { return 42; }
|
||||
|
||||
int foo(...) && { return 42; }
|
||||
int foo(...) const && { return 42; }
|
||||
int foo(...) volatile && { return 42; }
|
||||
int foo(...) const volatile && { return 42; }
|
||||
};
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
struct MemData {
|
||||
int foo;
|
||||
};
|
||||
|
||||
// Create a non-null free function by taking the address of
|
||||
// &static_cast<Tp&>(foo);
|
||||
template <class Tp>
|
||||
struct Creator {
|
||||
static Tp create() {
|
||||
return &foo;
|
||||
}
|
||||
};
|
||||
|
||||
// Create a non-null member pointer.
|
||||
template <class Ret, class Class>
|
||||
struct Creator<Ret Class::*> {
|
||||
typedef Ret Class::*ReturnType;
|
||||
static ReturnType create() {
|
||||
return &Class::foo;
|
||||
}
|
||||
};
|
||||
|
||||
template <class TestFn, class Fn>
|
||||
void test_imp() {
|
||||
{ // Check that the null value is detected
|
||||
TestFn tf = nullptr;
|
||||
std::function<Fn> f = tf;
|
||||
assert(f.template target<TestFn>() == nullptr);
|
||||
}
|
||||
{ // Check that the non-null value is detected.
|
||||
TestFn tf = Creator<TestFn>::create();
|
||||
assert(tf != nullptr);
|
||||
std::function<Fn> f = tf;
|
||||
assert(f.template target<TestFn>() != nullptr);
|
||||
assert(*f.template target<TestFn>() == tf);
|
||||
}
|
||||
}
|
||||
|
||||
void test_func() {
|
||||
test_imp<int(*)(), int()>();
|
||||
test_imp<int(*)(...), int()>();
|
||||
test_imp<int(*)(int), int(int)>();
|
||||
test_imp<int(*)(int, ...), int(int)>();
|
||||
test_imp<int(*)(int, int), int(int, int)>();
|
||||
test_imp<int(*)(int, int, ...), int(int, int)>();
|
||||
test_imp<int(*)(int, int, int), int(int, int, int)>();
|
||||
test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
|
||||
}
|
||||
|
||||
void test_mf() {
|
||||
test_imp<int(MemFun03::*)(), int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
|
||||
|
||||
test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
|
||||
|
||||
test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
|
||||
|
||||
test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_md() {
|
||||
test_imp<int MemData::*, int(MemData&)>();
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_func();
|
||||
test_mf();
|
||||
test_md();
|
||||
}
|
||||
@@ -12,12 +12,10 @@
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F, class A> void assign(F&&, const A&);
|
||||
// This call was removed post-C++14
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
class A
|
||||
@@ -51,7 +49,6 @@ int A::count = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
#if TEST_STD_VER <= 14
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
f.assign(A(), test_allocator<A>());
|
||||
@@ -60,5 +57,4 @@ int main()
|
||||
assert(f.target<int(*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FUNCTION_TYPES_H
|
||||
#define FUNCTION_TYPES_H
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
// reference_wrapper(T&&) = delete;
|
||||
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
// Don't allow binding to a temp
|
||||
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct A {};
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
// Test that reference wrapper meets the requirements of TriviallyCopyable,
|
||||
// CopyConstructible and CopyAssignable.
|
||||
|
||||
// Test fails due to use of is_trivially_* trait.
|
||||
// XFAIL: gcc-4.9
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
template <class T>
|
||||
@@ -58,49 +57,4 @@ int main()
|
||||
test<unsigned long>();
|
||||
test<long long>();
|
||||
test<unsigned long long>();
|
||||
|
||||
// LWG #2119
|
||||
test<std::ptrdiff_t>();
|
||||
test<size_t>();
|
||||
|
||||
test<int8_t>();
|
||||
test<int16_t>();
|
||||
test<int32_t>();
|
||||
test<int64_t>();
|
||||
|
||||
test<int_fast8_t>();
|
||||
test<int_fast16_t>();
|
||||
test<int_fast32_t>();
|
||||
test<int_fast64_t>();
|
||||
|
||||
test<int_least8_t>();
|
||||
test<int_least16_t>();
|
||||
test<int_least32_t>();
|
||||
test<int_least64_t>();
|
||||
|
||||
test<intmax_t>();
|
||||
test<intptr_t>();
|
||||
|
||||
test<uint8_t>();
|
||||
test<uint16_t>();
|
||||
test<uint32_t>();
|
||||
test<uint64_t>();
|
||||
|
||||
test<uint_fast8_t>();
|
||||
test<uint_fast16_t>();
|
||||
test<uint_fast32_t>();
|
||||
test<uint_fast64_t>();
|
||||
|
||||
test<uint_least8_t>();
|
||||
test<uint_least16_t>();
|
||||
test<uint_least32_t>();
|
||||
test<uint_least64_t>();
|
||||
|
||||
test<uintmax_t>();
|
||||
test<uintptr_t>();
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_INT128
|
||||
test<__int128_t>();
|
||||
test<__uint128_t>();
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user