copy_alloc.pass.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. // <string>
  10. // basic_string(const basic_string& str, const Allocator& alloc);
  11. #include <string>
  12. #include <cassert>
  13. #include "test_macros.h"
  14. #include "test_allocator.h"
  15. #include "min_allocator.h"
  16. #ifndef TEST_HAS_NO_EXCEPTIONS
  17. template <class T>
  18. struct alloc_imp {
  19. bool active;
  20. alloc_imp() : active(true) {}
  21. T* allocate(std::size_t n)
  22. {
  23. if (active)
  24. return static_cast<T*>(std::malloc(n * sizeof(T)));
  25. else
  26. throw std::bad_alloc();
  27. }
  28. void deallocate(T* p, std::size_t) { std::free(p); }
  29. void activate () { active = true; }
  30. void deactivate() { active = false; }
  31. };
  32. template <class T>
  33. struct poca_alloc {
  34. typedef T value_type;
  35. typedef std::true_type propagate_on_container_copy_assignment;
  36. alloc_imp<T> *imp;
  37. poca_alloc(alloc_imp<T> *imp_) : imp (imp_) {}
  38. template <class U>
  39. poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}
  40. T* allocate (std::size_t n) { return imp->allocate(n);}
  41. void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }
  42. };
  43. template <typename T, typename U>
  44. bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
  45. {
  46. return lhs.imp == rhs.imp;
  47. }
  48. template <typename T, typename U>
  49. bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
  50. {
  51. return lhs.imp != rhs.imp;
  52. }
  53. template <class S>
  54. void test_assign(S &s1, const S& s2)
  55. {
  56. try { s1 = s2; }
  57. catch ( std::bad_alloc &) { return; }
  58. assert(false);
  59. }
  60. #endif
  61. template <class S>
  62. void
  63. test(S s1, const typename S::allocator_type& a)
  64. {
  65. S s2(s1, a);
  66. LIBCPP_ASSERT(s2.__invariants());
  67. assert(s2 == s1);
  68. assert(s2.capacity() >= s2.size());
  69. assert(s2.get_allocator() == a);
  70. }
  71. int main()
  72. {
  73. {
  74. typedef test_allocator<char> A;
  75. typedef std::basic_string<char, std::char_traits<char>, A> S;
  76. test(S(), A(3));
  77. test(S("1"), A(5));
  78. test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
  79. }
  80. #if TEST_STD_VER >= 11
  81. {
  82. typedef min_allocator<char> A;
  83. typedef std::basic_string<char, std::char_traits<char>, A> S;
  84. test(S(), A());
  85. test(S("1"), A());
  86. test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
  87. }
  88. #ifndef TEST_HAS_NO_EXCEPTIONS
  89. {
  90. typedef poca_alloc<char> A;
  91. typedef std::basic_string<char, std::char_traits<char>, A> S;
  92. const char * p1 = "This is my first string";
  93. const char * p2 = "This is my second string";
  94. alloc_imp<char> imp1;
  95. alloc_imp<char> imp2;
  96. S s1(p1, A(&imp1));
  97. S s2(p2, A(&imp2));
  98. assert(s1 == p1);
  99. assert(s2 == p2);
  100. imp2.deactivate();
  101. test_assign(s1, s2);
  102. assert(s1 == p1);
  103. assert(s2 == p2);
  104. }
  105. #endif
  106. #endif
  107. }