alloc_rfunction.pass.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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
  10. // REQUIRES-ANY: c++11, c++14
  11. // <functional>
  12. // class function<R(ArgTypes...)>
  13. // template<class A> function(allocator_arg_t, const A&, function&&);
  14. //
  15. // This signature was removed in C++17
  16. #include <functional>
  17. #include <memory>
  18. #include <cassert>
  19. #include "test_macros.h"
  20. #include "min_allocator.h"
  21. #include "count_new.hpp"
  22. class A
  23. {
  24. int data_[10];
  25. public:
  26. static int count;
  27. A()
  28. {
  29. ++count;
  30. for (int i = 0; i < 10; ++i)
  31. data_[i] = i;
  32. }
  33. A(const A&) {++count;}
  34. ~A() {--count;}
  35. int operator()(int i) const
  36. {
  37. for (int j = 0; j < 10; ++j)
  38. i += data_[j];
  39. return i;
  40. }
  41. };
  42. int A::count = 0;
  43. int g(int) { return 0; }
  44. int main()
  45. {
  46. assert(globalMemCounter.checkOutstandingNewEq(0));
  47. {
  48. std::function<int(int)> f = A();
  49. assert(A::count == 1);
  50. assert(globalMemCounter.checkOutstandingNewEq(1));
  51. assert(f.target<A>());
  52. assert(f.target<int(*)(int)>() == 0);
  53. std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f));
  54. assert(A::count == 1);
  55. assert(globalMemCounter.checkOutstandingNewEq(1));
  56. assert(f2.target<A>());
  57. assert(f2.target<int(*)(int)>() == 0);
  58. assert(f.target<A>() == 0);
  59. assert(f.target<int(*)(int)>() == 0);
  60. }
  61. assert(globalMemCounter.checkOutstandingNewEq(0));
  62. {
  63. // Test that moving a function constructed from a reference wrapper
  64. // is done without allocating.
  65. DisableAllocationGuard g;
  66. using Ref = std::reference_wrapper<A>;
  67. A a;
  68. Ref aref(a);
  69. std::function<int(int)> f(aref);
  70. assert(A::count == 1);
  71. assert(f.target<A>() == nullptr);
  72. assert(f.target<Ref>());
  73. std::function<int(int)> f2(std::allocator_arg, std::allocator<void>{},
  74. std::move(f));
  75. assert(A::count == 1);
  76. assert(f2.target<A>() == nullptr);
  77. assert(f2.target<Ref>());
  78. assert(f.target<Ref>()); // f is unchanged because the target is small
  79. }
  80. {
  81. // Test that moving a function constructed from a function pointer
  82. // is done without allocating
  83. DisableAllocationGuard guard;
  84. using Ptr = int(*)(int);
  85. Ptr p = g;
  86. std::function<int(int)> f(p);
  87. assert(f.target<A>() == nullptr);
  88. assert(f.target<Ptr>());
  89. std::function<int(int)> f2(std::allocator_arg, std::allocator<void>(),
  90. std::move(f));
  91. assert(f2.target<A>() == nullptr);
  92. assert(f2.target<Ptr>());
  93. assert(f.target<Ptr>()); // f is unchanged because the target is small
  94. }
  95. }