swap_noexcept.pass.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // UNSUPPORTED: c++98, c++03
  9. // <vector>
  10. // void swap(vector& 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>::propagate_on_container_swap::value ||
  16. // allocator_traits<Allocator>::is_always_equal::value);
  17. // This tests a conforming extension
  18. #include <vector>
  19. #include <utility>
  20. #include <cassert>
  21. #include "test_macros.h"
  22. #include "test_allocator.h"
  23. template <class T>
  24. struct some_alloc
  25. {
  26. typedef T value_type;
  27. some_alloc() {}
  28. some_alloc(const some_alloc&);
  29. void deallocate(void*, unsigned) {}
  30. typedef std::true_type propagate_on_container_swap;
  31. };
  32. template <class T>
  33. struct some_alloc2
  34. {
  35. typedef T value_type;
  36. some_alloc2() {}
  37. some_alloc2(const some_alloc2&);
  38. void deallocate(void*, unsigned) {}
  39. typedef std::false_type propagate_on_container_swap;
  40. typedef std::true_type is_always_equal;
  41. };
  42. int main(int, char**)
  43. {
  44. #if defined(_LIBCPP_VERSION)
  45. {
  46. typedef std::vector<bool> C;
  47. static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  48. }
  49. {
  50. typedef std::vector<bool, test_allocator<bool>> C;
  51. static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  52. }
  53. {
  54. typedef std::vector<bool, other_allocator<bool>> C;
  55. static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  56. }
  57. #endif // _LIBCPP_VERSION
  58. {
  59. #if TEST_STD_VER >= 14
  60. #if defined(_LIBCPP_VERSION)
  61. // In C++14, if POCS is set, swapping the allocator is required not to throw
  62. typedef std::vector<bool, some_alloc<bool>> C;
  63. static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  64. #endif // _LIBCPP_VERSION
  65. #else
  66. typedef std::vector<bool, some_alloc<bool>> C;
  67. static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  68. #endif
  69. }
  70. #if TEST_STD_VER >= 14
  71. #if defined(_LIBCPP_VERSION)
  72. {
  73. typedef std::vector<bool, some_alloc2<bool>> C;
  74. // if the allocators are always equal, then the swap can be noexcept
  75. static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
  76. }
  77. #endif // _LIBCPP_VERSION
  78. #endif
  79. return 0;
  80. }