swap_noexcept.pass.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. // <map>
  10. // void swap(multimap& c)
  11. // noexcept(!allocator_type::propagate_on_container_swap::value ||
  12. // __is_nothrow_swappable<allocator_type>::value);
  13. //
  14. // In C++17, the standard says that swap shall have:
  15. // noexcept(allocator_traits<Allocator>::is_always_equal::value &&
  16. // noexcept(swap(declval<Compare&>(), declval<Compare&>())));
  17. // This tests a conforming extension
  18. #include <map>
  19. #include <cassert>
  20. #include "MoveOnly.h"
  21. #include "test_allocator.h"
  22. template <class T>
  23. struct some_comp
  24. {
  25. typedef T value_type;
  26. some_comp() {}
  27. some_comp(const some_comp&) {}
  28. void deallocate(void*, unsigned) {}
  29. typedef std::true_type propagate_on_container_swap;
  30. };
  31. template <class T>
  32. struct some_comp2
  33. {
  34. typedef T value_type;
  35. some_comp2() {}
  36. some_comp2(const some_comp2&) {}
  37. void deallocate(void*, unsigned) {}
  38. typedef std::true_type propagate_on_container_swap;
  39. };
  40. #if TEST_STD_VER >= 14
  41. template <typename T>
  42. void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
  43. #endif
  44. template <class T>
  45. struct some_alloc
  46. {
  47. typedef T value_type;
  48. some_alloc() {}
  49. some_alloc(const some_alloc&);
  50. void deallocate(void*, unsigned) {}
  51. typedef std::true_type propagate_on_container_swap;
  52. };
  53. template <class T>
  54. struct some_alloc2
  55. {
  56. typedef T value_type;
  57. some_alloc2() {}
  58. some_alloc2(const some_alloc2&);
  59. void deallocate(void*, unsigned) {}
  60. typedef std::false_type propagate_on_container_swap;
  61. typedef std::true_type is_always_equal;
  62. };
  63. template <class T>
  64. struct some_alloc3
  65. {
  66. typedef T value_type;
  67. some_alloc3() {}
  68. some_alloc3(const some_alloc3&);
  69. void deallocate(void*, unsigned) {}
  70. typedef std::false_type propagate_on_container_swap;
  71. typedef std::false_type is_always_equal;
  72. };
  73. int main()
  74. {
  75. #if __has_feature(cxx_noexcept)
  76. {
  77. typedef std::multimap<MoveOnly, MoveOnly> C;
  78. C c1, c2;
  79. static_assert(noexcept(swap(c1, c2)), "");
  80. }
  81. {
  82. typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
  83. C c1, c2;
  84. static_assert(noexcept(swap(c1, c2)), "");
  85. }
  86. {
  87. typedef std::multimap<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
  88. C c1, c2;
  89. static_assert(noexcept(swap(c1, c2)), "");
  90. }
  91. {
  92. typedef std::multimap<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
  93. C c1, c2;
  94. static_assert(!noexcept(swap(c1, c2)), "");
  95. }
  96. #if TEST_STD_VER >= 14
  97. { // POCS allocator, throwable swap for comp
  98. typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
  99. C c1, c2;
  100. static_assert(!noexcept(swap(c1, c2)), "");
  101. }
  102. { // always equal allocator, throwable swap for comp
  103. typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
  104. C c1, c2;
  105. static_assert(!noexcept(swap(c1, c2)), "");
  106. }
  107. { // POCS allocator, nothrow swap for comp
  108. typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
  109. C c1, c2;
  110. static_assert( noexcept(swap(c1, c2)), "");
  111. }
  112. { // always equal allocator, nothrow swap for comp
  113. typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
  114. C c1, c2;
  115. static_assert( noexcept(swap(c1, c2)), "");
  116. }
  117. { // NOT always equal allocator, nothrow swap for comp
  118. typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
  119. C c1, c2;
  120. static_assert( noexcept(swap(c1, c2)), "");
  121. }
  122. #endif
  123. #endif
  124. }