not_fn.pass.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // UNSUPPORTED: c++98, c++03, c++11, c++14
  10. // template <class F> unspecified not_fn(F&& f);
  11. #include <functional>
  12. #include <type_traits>
  13. #include <string>
  14. #include <cassert>
  15. #include "test_macros.h"
  16. #include "type_id.h"
  17. ///////////////////////////////////////////////////////////////////////////////
  18. // CALLABLE TEST TYPES
  19. ///////////////////////////////////////////////////////////////////////////////
  20. bool returns_true() { return true; }
  21. template <class Ret = bool>
  22. struct MoveOnlyCallable {
  23. MoveOnlyCallable(MoveOnlyCallable const&) = delete;
  24. MoveOnlyCallable(MoveOnlyCallable&& other)
  25. : value(other.value)
  26. { other.value = !other.value; }
  27. template <class ...Args>
  28. Ret operator()(Args&&...) { return Ret{value}; }
  29. explicit MoveOnlyCallable(bool x) : value(x) {}
  30. Ret value;
  31. };
  32. template <class Ret = bool>
  33. struct CopyCallable {
  34. CopyCallable(CopyCallable const& other)
  35. : value(other.value) {}
  36. CopyCallable(CopyCallable&& other)
  37. : value(other.value) { other.value = !other.value; }
  38. template <class ...Args>
  39. Ret operator()(Args&&...) { return Ret{value}; }
  40. explicit CopyCallable(bool x) : value(x) {}
  41. Ret value;
  42. };
  43. template <class Ret = bool>
  44. struct ConstCallable {
  45. ConstCallable(ConstCallable const& other)
  46. : value(other.value) {}
  47. ConstCallable(ConstCallable&& other)
  48. : value(other.value) { other.value = !other.value; }
  49. template <class ...Args>
  50. Ret operator()(Args&&...) const { return Ret{value}; }
  51. explicit ConstCallable(bool x) : value(x) {}
  52. Ret value;
  53. };
  54. template <class Ret = bool>
  55. struct NoExceptCallable {
  56. NoExceptCallable(NoExceptCallable const& other)
  57. : value(other.value) {}
  58. template <class ...Args>
  59. Ret operator()(Args&&...) noexcept { return Ret{value}; }
  60. template <class ...Args>
  61. Ret operator()(Args&&...) const noexcept { return Ret{value}; }
  62. explicit NoExceptCallable(bool x) : value(x) {}
  63. Ret value;
  64. };
  65. struct CopyAssignableWrapper {
  66. CopyAssignableWrapper(CopyAssignableWrapper const&) = default;
  67. CopyAssignableWrapper(CopyAssignableWrapper&&) = default;
  68. CopyAssignableWrapper& operator=(CopyAssignableWrapper const&) = default;
  69. CopyAssignableWrapper& operator=(CopyAssignableWrapper &&) = default;
  70. template <class ...Args>
  71. bool operator()(Args&&...) { return value; }
  72. explicit CopyAssignableWrapper(bool x) : value(x) {}
  73. bool value;
  74. };
  75. struct MoveAssignableWrapper {
  76. MoveAssignableWrapper(MoveAssignableWrapper const&) = delete;
  77. MoveAssignableWrapper(MoveAssignableWrapper&&) = default;
  78. MoveAssignableWrapper& operator=(MoveAssignableWrapper const&) = delete;
  79. MoveAssignableWrapper& operator=(MoveAssignableWrapper &&) = default;
  80. template <class ...Args>
  81. bool operator()(Args&&...) { return value; }
  82. explicit MoveAssignableWrapper(bool x) : value(x) {}
  83. bool value;
  84. };
  85. struct MemFunCallable {
  86. explicit MemFunCallable(bool x) : value(x) {}
  87. bool return_value() const { return value; }
  88. bool return_value_nc() { return value; }
  89. bool value;
  90. };
  91. enum CallType : unsigned {
  92. CT_None,
  93. CT_NonConst = 1,
  94. CT_Const = 2,
  95. CT_LValue = 4,
  96. CT_RValue = 8
  97. };
  98. inline constexpr CallType operator|(CallType LHS, CallType RHS) {
  99. return static_cast<CallType>(static_cast<unsigned>(LHS) | static_cast<unsigned>(RHS));
  100. }
  101. struct ForwardingCallObject {
  102. template <class ...Args>
  103. bool operator()(Args&&...) & {
  104. set_call<Args&&...>(CT_NonConst | CT_LValue);
  105. return true;
  106. }
  107. template <class ...Args>
  108. bool operator()(Args&&...) const & {
  109. set_call<Args&&...>(CT_Const | CT_LValue);
  110. return true;
  111. }
  112. // Don't allow the call operator to be invoked as an rvalue.
  113. template <class ...Args>
  114. bool operator()(Args&&...) && {
  115. set_call<Args&&...>(CT_NonConst | CT_RValue);
  116. return true;
  117. }
  118. template <class ...Args>
  119. bool operator()(Args&&...) const && {
  120. set_call<Args&&...>(CT_Const | CT_RValue);
  121. return true;
  122. }
  123. template <class ...Args>
  124. static void set_call(CallType type) {
  125. assert(last_call_type == CT_None);
  126. assert(last_call_args == nullptr);
  127. last_call_type = type;
  128. last_call_args = &makeArgumentID<Args...>();
  129. }
  130. template <class ...Args>
  131. static bool check_call(CallType type) {
  132. bool result =
  133. last_call_type == type
  134. && last_call_args
  135. && *last_call_args == makeArgumentID<Args...>();
  136. last_call_type = CT_None;
  137. last_call_args = nullptr;
  138. return result;
  139. }
  140. static CallType last_call_type;
  141. static TypeID const* last_call_args;
  142. };
  143. CallType ForwardingCallObject::last_call_type = CT_None;
  144. TypeID const* ForwardingCallObject::last_call_args = nullptr;
  145. ///////////////////////////////////////////////////////////////////////////////
  146. // BOOL TEST TYPES
  147. ///////////////////////////////////////////////////////////////////////////////
  148. struct EvilBool {
  149. static int bang_called;
  150. EvilBool(EvilBool const&) = default;
  151. EvilBool(EvilBool&&) = default;
  152. friend EvilBool operator!(EvilBool const& other) {
  153. ++bang_called;
  154. return EvilBool{!other.value};
  155. }
  156. private:
  157. friend struct MoveOnlyCallable<EvilBool>;
  158. friend struct CopyCallable<EvilBool>;
  159. friend struct NoExceptCallable<EvilBool>;
  160. explicit EvilBool(bool x) : value(x) {}
  161. EvilBool& operator=(EvilBool const& other) = default;
  162. public:
  163. bool value;
  164. };
  165. int EvilBool::bang_called = 0;
  166. struct ExplicitBool {
  167. ExplicitBool(ExplicitBool const&) = default;
  168. ExplicitBool(ExplicitBool&&) = default;
  169. explicit operator bool() const { return value; }
  170. private:
  171. friend struct MoveOnlyCallable<ExplicitBool>;
  172. friend struct CopyCallable<ExplicitBool>;
  173. explicit ExplicitBool(bool x) : value(x) {}
  174. ExplicitBool& operator=(bool x) {
  175. value = x;
  176. return *this;
  177. }
  178. bool value;
  179. };
  180. struct NoExceptEvilBool {
  181. NoExceptEvilBool(NoExceptEvilBool const&) = default;
  182. NoExceptEvilBool(NoExceptEvilBool&&) = default;
  183. NoExceptEvilBool& operator=(NoExceptEvilBool const& other) = default;
  184. explicit NoExceptEvilBool(bool x) : value(x) {}
  185. friend NoExceptEvilBool operator!(NoExceptEvilBool const& other) noexcept {
  186. return NoExceptEvilBool{!other.value};
  187. }
  188. bool value;
  189. };
  190. void constructor_tests()
  191. {
  192. {
  193. using T = MoveOnlyCallable<bool>;
  194. T value(true);
  195. using RetT = decltype(std::not_fn(std::move(value)));
  196. static_assert(std::is_move_constructible<RetT>::value, "");
  197. static_assert(!std::is_copy_constructible<RetT>::value, "");
  198. static_assert(!std::is_move_assignable<RetT>::value, "");
  199. static_assert(!std::is_copy_assignable<RetT>::value, "");
  200. auto ret = std::not_fn(std::move(value));
  201. // test it was moved from
  202. assert(value.value == false);
  203. // test that ret() negates the original value 'true'
  204. assert(ret() == false);
  205. assert(ret(0, 0.0, "blah") == false);
  206. // Move ret and test that it was moved from and that ret2 got the
  207. // original value.
  208. auto ret2 = std::move(ret);
  209. assert(ret() == true);
  210. assert(ret2() == false);
  211. assert(ret2(42) == false);
  212. }
  213. {
  214. using T = CopyCallable<bool>;
  215. T value(false);
  216. using RetT = decltype(std::not_fn(value));
  217. static_assert(std::is_move_constructible<RetT>::value, "");
  218. static_assert(std::is_copy_constructible<RetT>::value, "");
  219. static_assert(!std::is_move_assignable<RetT>::value, "");
  220. static_assert(!std::is_copy_assignable<RetT>::value, "");
  221. auto ret = std::not_fn(value);
  222. // test that value is unchanged (copied not moved)
  223. assert(value.value == false);
  224. // test 'ret' has the original value
  225. assert(ret() == true);
  226. assert(ret(42, 100) == true);
  227. // move from 'ret' and check that 'ret2' has the original value.
  228. auto ret2 = std::move(ret);
  229. assert(ret() == false);
  230. assert(ret2() == true);
  231. assert(ret2("abc") == true);
  232. }
  233. {
  234. using T = CopyAssignableWrapper;
  235. T value(true);
  236. T value2(false);
  237. using RetT = decltype(std::not_fn(value));
  238. static_assert(std::is_move_constructible<RetT>::value, "");
  239. static_assert(std::is_copy_constructible<RetT>::value, "");
  240. static_assert(std::is_move_assignable<RetT>::value, "");
  241. static_assert(std::is_copy_assignable<RetT>::value, "");
  242. auto ret = std::not_fn(value);
  243. assert(ret() == false);
  244. auto ret2 = std::not_fn(value2);
  245. assert(ret2() == true);
  246. ret = ret2;
  247. assert(ret() == true);
  248. assert(ret2() == true);
  249. }
  250. {
  251. using T = MoveAssignableWrapper;
  252. T value(true);
  253. T value2(false);
  254. using RetT = decltype(std::not_fn(std::move(value)));
  255. static_assert(std::is_move_constructible<RetT>::value, "");
  256. static_assert(!std::is_copy_constructible<RetT>::value, "");
  257. static_assert(std::is_move_assignable<RetT>::value, "");
  258. static_assert(!std::is_copy_assignable<RetT>::value, "");
  259. auto ret = std::not_fn(std::move(value));
  260. assert(ret() == false);
  261. auto ret2 = std::not_fn(std::move(value2));
  262. assert(ret2() == true);
  263. ret = std::move(ret2);
  264. assert(ret() == true);
  265. }
  266. }
  267. void return_type_tests()
  268. {
  269. using std::is_same;
  270. {
  271. using T = CopyCallable<bool>;
  272. auto ret = std::not_fn(T{false});
  273. static_assert(is_same<decltype(ret()), bool>::value, "");
  274. static_assert(is_same<decltype(ret("abc")), bool>::value, "");
  275. assert(ret() == true);
  276. }
  277. {
  278. using T = CopyCallable<ExplicitBool>;
  279. auto ret = std::not_fn(T{true});
  280. static_assert(is_same<decltype(ret()), bool>::value, "");
  281. static_assert(is_same<decltype(ret(std::string("abc"))), bool>::value, "");
  282. assert(ret() == false);
  283. }
  284. {
  285. using T = CopyCallable<EvilBool>;
  286. auto ret = std::not_fn(T{false});
  287. static_assert(is_same<decltype(ret()), EvilBool>::value, "");
  288. EvilBool::bang_called = 0;
  289. auto value_ret = ret();
  290. assert(EvilBool::bang_called == 1);
  291. assert(value_ret.value == true);
  292. ret();
  293. assert(EvilBool::bang_called == 2);
  294. }
  295. }
  296. // Other tests only test using objects with call operators. Test various
  297. // other callable types here.
  298. void other_callable_types_test()
  299. {
  300. { // test with function pointer
  301. auto ret = std::not_fn(returns_true);
  302. assert(ret() == false);
  303. }
  304. { // test with lambda
  305. auto returns_value = [](bool value) { return value; };
  306. auto ret = std::not_fn(returns_value);
  307. assert(ret(true) == false);
  308. assert(ret(false) == true);
  309. }
  310. { // test with pointer to member function
  311. MemFunCallable mt(true);
  312. const MemFunCallable mf(false);
  313. auto ret = std::not_fn(&MemFunCallable::return_value);
  314. assert(ret(mt) == false);
  315. assert(ret(mf) == true);
  316. assert(ret(&mt) == false);
  317. assert(ret(&mf) == true);
  318. }
  319. { // test with pointer to member function
  320. MemFunCallable mt(true);
  321. MemFunCallable mf(false);
  322. auto ret = std::not_fn(&MemFunCallable::return_value_nc);
  323. assert(ret(mt) == false);
  324. assert(ret(mf) == true);
  325. assert(ret(&mt) == false);
  326. assert(ret(&mf) == true);
  327. }
  328. { // test with pointer to member data
  329. MemFunCallable mt(true);
  330. const MemFunCallable mf(false);
  331. auto ret = std::not_fn(&MemFunCallable::value);
  332. assert(ret(mt) == false);
  333. assert(ret(mf) == true);
  334. assert(ret(&mt) == false);
  335. assert(ret(&mf) == true);
  336. }
  337. }
  338. void throws_in_constructor_test()
  339. {
  340. #ifndef TEST_HAS_NO_EXCEPTIONS
  341. struct ThrowsOnCopy {
  342. ThrowsOnCopy(ThrowsOnCopy const&) {
  343. throw 42;
  344. }
  345. ThrowsOnCopy() = default;
  346. bool operator()() const {
  347. assert(false);
  348. #if defined(TEST_COMPILER_C1XX)
  349. __assume(0);
  350. #else
  351. __builtin_unreachable();
  352. #endif
  353. }
  354. };
  355. {
  356. ThrowsOnCopy cp;
  357. try {
  358. std::not_fn(cp);
  359. assert(false);
  360. } catch (int const& value) {
  361. assert(value == 42);
  362. }
  363. }
  364. #endif
  365. }
  366. void call_operator_sfinae_test() {
  367. { // wrong number of arguments
  368. using T = decltype(std::not_fn(returns_true));
  369. static_assert(std::is_callable<T()>::value, ""); // callable only with no args
  370. static_assert(!std::is_callable<T(bool)>::value, "");
  371. }
  372. { // violates const correctness (member function pointer)
  373. using T = decltype(std::not_fn(&MemFunCallable::return_value_nc));
  374. static_assert(std::is_callable<T(MemFunCallable&)>::value, "");
  375. static_assert(!std::is_callable<T(const MemFunCallable&)>::value, "");
  376. }
  377. { // violates const correctness (call object)
  378. using Obj = CopyCallable<bool>;
  379. using NCT = decltype(std::not_fn(Obj{true}));
  380. using CT = const NCT;
  381. static_assert(std::is_callable<NCT()>::value, "");
  382. static_assert(!std::is_callable<CT()>::value, "");
  383. }
  384. { // returns bad type with no operator!
  385. auto fn = [](auto x) { return x; };
  386. using T = decltype(std::not_fn(fn));
  387. static_assert(std::is_callable<T(bool)>::value, "");
  388. static_assert(!std::is_callable<T(std::string)>::value, "");
  389. }
  390. }
  391. void call_operator_forwarding_test()
  392. {
  393. using Fn = ForwardingCallObject;
  394. auto obj = std::not_fn(Fn{});
  395. const auto& c_obj = obj;
  396. { // test zero args
  397. obj();
  398. assert(Fn::check_call<>(CT_NonConst | CT_LValue));
  399. std::move(obj)();
  400. assert(Fn::check_call<>(CT_NonConst | CT_RValue));
  401. c_obj();
  402. assert(Fn::check_call<>(CT_Const | CT_LValue));
  403. std::move(c_obj)();
  404. assert(Fn::check_call<>(CT_Const | CT_RValue));
  405. }
  406. { // test value categories
  407. int x = 42;
  408. const int cx = 42;
  409. obj(x);
  410. assert(Fn::check_call<int&>(CT_NonConst | CT_LValue));
  411. obj(cx);
  412. assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue));
  413. obj(std::move(x));
  414. assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue));
  415. obj(std::move(cx));
  416. assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue));
  417. obj(42);
  418. assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue));
  419. }
  420. { // test value categories - rvalue
  421. int x = 42;
  422. const int cx = 42;
  423. std::move(obj)(x);
  424. assert(Fn::check_call<int&>(CT_NonConst | CT_RValue));
  425. std::move(obj)(cx);
  426. assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue));
  427. std::move(obj)(std::move(x));
  428. assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue));
  429. std::move(obj)(std::move(cx));
  430. assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue));
  431. std::move(obj)(42);
  432. assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue));
  433. }
  434. { // test value categories - const call
  435. int x = 42;
  436. const int cx = 42;
  437. c_obj(x);
  438. assert(Fn::check_call<int&>(CT_Const | CT_LValue));
  439. c_obj(cx);
  440. assert(Fn::check_call<const int&>(CT_Const | CT_LValue));
  441. c_obj(std::move(x));
  442. assert(Fn::check_call<int&&>(CT_Const | CT_LValue));
  443. c_obj(std::move(cx));
  444. assert(Fn::check_call<const int&&>(CT_Const | CT_LValue));
  445. c_obj(42);
  446. assert(Fn::check_call<int&&>(CT_Const | CT_LValue));
  447. }
  448. { // test value categories - const call rvalue
  449. int x = 42;
  450. const int cx = 42;
  451. std::move(c_obj)(x);
  452. assert(Fn::check_call<int&>(CT_Const | CT_RValue));
  453. std::move(c_obj)(cx);
  454. assert(Fn::check_call<const int&>(CT_Const | CT_RValue));
  455. std::move(c_obj)(std::move(x));
  456. assert(Fn::check_call<int&&>(CT_Const | CT_RValue));
  457. std::move(c_obj)(std::move(cx));
  458. assert(Fn::check_call<const int&&>(CT_Const | CT_RValue));
  459. std::move(c_obj)(42);
  460. assert(Fn::check_call<int&&>(CT_Const | CT_RValue));
  461. }
  462. { // test multi arg
  463. const double y = 3.14;
  464. std::string s = "abc";
  465. obj(42, std::move(y), s, std::string{"foo"});
  466. Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_LValue);
  467. std::move(obj)(42, std::move(y), s, std::string{"foo"});
  468. Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_RValue);
  469. c_obj(42, std::move(y), s, std::string{"foo"});
  470. Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_LValue);
  471. std::move(c_obj)(42, std::move(y), s, std::string{"foo"});
  472. Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue);
  473. }
  474. }
  475. void call_operator_noexcept_test()
  476. {
  477. {
  478. using T = ConstCallable<bool>;
  479. T value(true);
  480. auto ret = std::not_fn(value);
  481. static_assert(!noexcept(ret()), "call should not be noexcept");
  482. auto const& cret = ret;
  483. static_assert(!noexcept(cret()), "call should not be noexcept");
  484. }
  485. {
  486. using T = NoExceptCallable<bool>;
  487. T value(true);
  488. auto ret = std::not_fn(value);
  489. LIBCPP_STATIC_ASSERT(noexcept(!_VSTD::__invoke(value)), "");
  490. #if TEST_STD_VER > 14
  491. static_assert(noexcept(!std::invoke(value)), "");
  492. #endif
  493. static_assert(noexcept(ret()), "call should be noexcept");
  494. auto const& cret = ret;
  495. static_assert(noexcept(cret()), "call should be noexcept");
  496. }
  497. {
  498. using T = NoExceptCallable<NoExceptEvilBool>;
  499. T value(true);
  500. auto ret = std::not_fn(value);
  501. static_assert(noexcept(ret()), "call should not be noexcept");
  502. auto const& cret = ret;
  503. static_assert(noexcept(cret()), "call should not be noexcept");
  504. }
  505. {
  506. using T = NoExceptCallable<EvilBool>;
  507. T value(true);
  508. auto ret = std::not_fn(value);
  509. static_assert(!noexcept(ret()), "call should not be noexcept");
  510. auto const& cret = ret;
  511. static_assert(!noexcept(cret()), "call should not be noexcept");
  512. }
  513. }
  514. void test_lwg2767() {
  515. // See https://cplusplus.github.io/LWG/lwg-defects.html#2767
  516. struct Abstract { virtual void f() const = 0; };
  517. struct Derived : public Abstract { void f() const {} };
  518. struct F { bool operator()(Abstract&&) { return false; } };
  519. {
  520. Derived d;
  521. Abstract &a = d;
  522. bool b = std::not_fn(F{})(std::move(a));
  523. assert(b);
  524. }
  525. }
  526. int main()
  527. {
  528. constructor_tests();
  529. return_type_tests();
  530. other_callable_types_test();
  531. throws_in_constructor_test();
  532. call_operator_sfinae_test(); // somewhat of an extension
  533. call_operator_forwarding_test();
  534. call_operator_noexcept_test();
  535. test_lwg2767();
  536. }