vector_nocopy_test.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*-
  2. * Copyright 2012-1015 Matthew Endsley
  3. * All rights reserved
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted providing that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  22. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  23. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. * POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "test.h"
  27. #include <tinystl/allocator.h>
  28. #include <tinystl/vector.h>
  29. #include <algorithm>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. struct nocopy {
  33. nocopy() { data = 0; }
  34. explicit nocopy(const char* s) { data = s; }
  35. ~nocopy() { }
  36. void swap(nocopy& other) { std::swap(data, other.data); }
  37. void reset(const char* s) { data = s; }
  38. const char* release() { const char* ret = data; data = 0; return ret; }
  39. const char* data;
  40. private:
  41. nocopy(const nocopy& other);
  42. nocopy& operator=(const nocopy& other);
  43. };
  44. static inline bool operator==(const nocopy& lhs, const char* rhs) {
  45. if (lhs.data == 0 && rhs == 0)
  46. return true;
  47. if (lhs.data != 0 && rhs != 0)
  48. return 0 == strcmp(lhs.data, rhs);
  49. return false;
  50. }
  51. static inline bool operator==(const nocopy& lhs, const nocopy& rhs) {
  52. if (lhs.data == 0 && rhs.data == 0)
  53. return true;
  54. if (lhs.data != 0 && rhs.data != 0)
  55. return 0 == strcmp(lhs.data, rhs.data);
  56. return false;
  57. }
  58. TEST(vector_nocopy_constructor) {
  59. typedef tinystl::vector<nocopy> vector;
  60. {
  61. vector v;
  62. CHECK( v.empty() );
  63. CHECK( v.size() == 0 );
  64. }
  65. {
  66. vector v(10);
  67. CHECK( v.size() == 10 );
  68. for (tinystl::vector<nocopy>::iterator it = v.begin(); it != v.end(); ++it) {
  69. CHECK( it->data == 0 );
  70. }
  71. }
  72. }
  73. TEST(vector_nocopy_pushback) {
  74. tinystl::vector<nocopy> v;
  75. v.emplace_back("42");
  76. v.emplace_back();
  77. v.back().reset("24");
  78. CHECK( v.size() == 2 );
  79. CHECK( v[0] == "42" );
  80. CHECK( v[1] == "24" );
  81. }
  82. TEST(vector_nocopy_vector) {
  83. tinystl::vector< tinystl::vector<nocopy> > v(10);
  84. tinystl::vector< tinystl::vector<nocopy> >::iterator it = v.begin(), end = v.end();
  85. for (; it != end; ++it) {
  86. CHECK( (*it).empty() );
  87. CHECK( (*it).size() == 0 );
  88. CHECK( (*it).begin() == (*it).end() );
  89. }
  90. }
  91. TEST(vector_nocopy_swap) {
  92. tinystl::vector<nocopy> v1;
  93. v1.emplace_back("12");
  94. v1.emplace_back("20");
  95. tinystl::vector<nocopy> v2;
  96. v2.emplace_back("54");
  97. v1.swap(v2);
  98. CHECK(v1.size() == 1);
  99. CHECK(v2.size() == 2);
  100. CHECK(v1[0] == "54");
  101. CHECK(v2[0] == "12");
  102. CHECK(v2[1] == "20");
  103. }
  104. TEST(vector_nocopy_popback) {
  105. tinystl::vector<nocopy> v;
  106. v.emplace_back("12");
  107. v.emplace_back("24");
  108. CHECK(v.back() == "24");
  109. v.pop_back();
  110. CHECK(v.back() == "12");
  111. CHECK(v.size() == 1);
  112. }
  113. TEST(vector_nocopy_erase) {
  114. tinystl::vector<nocopy> v;
  115. v.emplace_back("1");
  116. v.emplace_back("2");
  117. v.emplace_back("3");
  118. v.emplace_back("4");
  119. v.emplace_back("5");
  120. tinystl::vector<nocopy>::iterator it = v.erase(v.begin());
  121. CHECK(*it == "2");
  122. CHECK(v.size() == 4);
  123. it = v.erase(v.end() - 1);
  124. CHECK(it == v.end());
  125. CHECK(v.size() == 3);
  126. v.erase(v.begin() + 1, v.end() - 1);
  127. CHECK(v.size() == 2);
  128. CHECK(v[0] == "2");
  129. CHECK(v[1] == "4");
  130. }
  131. TEST(vector_nocopy_erase_unordered) {
  132. typedef tinystl::vector<nocopy> vector;
  133. vector v;
  134. v.emplace_back("1");
  135. v.emplace_back("2");
  136. v.emplace_back("3");
  137. v.emplace_back("4");
  138. v.emplace_back("5");
  139. const char* first = v.front().release();
  140. vector::iterator it = v.erase_unordered(v.begin());
  141. CHECK( it == v.begin() );
  142. CHECK( v.size() == 4 );
  143. CHECK( std::count(v.begin(), v.end(), first) == 0 );
  144. for (it = v.begin(); it != v.end(); ++it) {
  145. CHECK( std::count(v.begin(), v.end(), *it) == 1 );
  146. }
  147. const char* last = v.back().release();
  148. it = v.erase_unordered(v.end() - 1);
  149. CHECK( it == v.end() );
  150. CHECK( v.size() == 3 );
  151. CHECK( std::count(v.begin(), v.end(), last) == 0 );
  152. for (it = v.begin(); it != v.end(); ++it) {
  153. CHECK( std::count(v.begin(), v.end(), *it) == 1 );
  154. }
  155. first = v.begin()->data;
  156. last = (v.end() - 1)->data;
  157. v.erase_unordered(v.begin() + 1, v.end() - 1);
  158. CHECK( v.size() == 2 );
  159. CHECK( std::count(v.begin(), v.end(), first) == 1 );
  160. CHECK( std::count(v.begin(), v.end(), last) == 1 );
  161. }
  162. TEST(vector_nocopy_insert) {
  163. tinystl::vector<nocopy> v;
  164. v.emplace_back("1");
  165. v.emplace_back("2");
  166. v.emplace_back("3");
  167. v.emplace_back("4");
  168. v.emplace_back("5");
  169. v.emplace(v.begin(), "0");
  170. CHECK( v.size() == 6 );
  171. CHECK( v[0] == "0" );
  172. CHECK( v[1] == "1" );
  173. CHECK( v[5] == "5" );
  174. v.emplace(v.end(), "6");
  175. CHECK( v.size() == 7 );
  176. CHECK( v.front() == "0" );
  177. CHECK( v.back() == "6" );
  178. }
  179. TEST(vector_nocopy_iterator) {
  180. tinystl::vector<nocopy> v(5);
  181. v[0].reset("1");
  182. v[1].reset("2");
  183. v[2].reset("3");
  184. v[3].reset("4");
  185. v[4].reset("5");
  186. const tinystl::vector<nocopy>& cv = v;
  187. //CHECK(v.data() == &*v.begin());
  188. //CHECK(v.data() == &v[0]);
  189. //CHECK(v.data() + v.size() == &*v.end());
  190. CHECK(v.begin() == cv.begin());
  191. CHECK(v.end() == cv.end());
  192. //CHECK(v.data() == cv.data());
  193. }