/Src/Dependencies/Boost/libs/unordered/test/objects/test.hpp

http://hadesmem.googlecode.com/ · C++ Header · 311 lines · 249 code · 52 blank · 10 comment · 23 complexity · 86bd892aedabacd0aa95aecba685a68d MD5 · raw file

  1. // Copyright 2006-2009 Daniel James.
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER)
  5. #define BOOST_UNORDERED_TEST_OBJECTS_HEADER
  6. #include <boost/config.hpp>
  7. #include <boost/limits.hpp>
  8. #include <cstddef>
  9. #include <iostream>
  10. #include "../helpers/fwd.hpp"
  11. #include "../helpers/count.hpp"
  12. #include "../helpers/memory.hpp"
  13. #include <map>
  14. namespace test
  15. {
  16. // Note that the default hash function will work for any equal_to (but not
  17. // very well).
  18. class object;
  19. class implicitly_convertible;
  20. class hash;
  21. class less;
  22. class equal_to;
  23. template <class T> class allocator;
  24. object generate(object const*);
  25. implicitly_convertible generate(implicitly_convertible const*);
  26. class object : globally_counted_object
  27. {
  28. friend class hash;
  29. friend class equal_to;
  30. friend class less;
  31. int tag1_, tag2_;
  32. public:
  33. explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
  34. ~object() {
  35. tag1_ = -1;
  36. tag2_ = -1;
  37. }
  38. friend bool operator==(object const& x1, object const& x2) {
  39. return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
  40. }
  41. friend bool operator!=(object const& x1, object const& x2) {
  42. return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
  43. }
  44. friend bool operator<(object const& x1, object const& x2) {
  45. return x1.tag1_ < x2.tag1_ ||
  46. (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
  47. }
  48. friend object generate(object const*) {
  49. int* x = 0;
  50. return object(generate(x), generate(x));
  51. }
  52. friend std::ostream& operator<<(std::ostream& out, object const& o)
  53. {
  54. return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
  55. }
  56. };
  57. class implicitly_convertible : globally_counted_object
  58. {
  59. int tag1_, tag2_;
  60. public:
  61. explicit implicitly_convertible(int t1 = 0, int t2 = 0)
  62. : tag1_(t1), tag2_(t2)
  63. {}
  64. operator object() const
  65. {
  66. return object(tag1_, tag2_);
  67. }
  68. friend implicitly_convertible generate(implicitly_convertible const*) {
  69. int* x = 0;
  70. return implicitly_convertible(generate(x), generate(x));
  71. }
  72. friend std::ostream& operator<<(std::ostream& out, implicitly_convertible const& o)
  73. {
  74. return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
  75. }
  76. };
  77. class hash
  78. {
  79. int type_;
  80. public:
  81. explicit hash(int t = 0) : type_(t) {}
  82. std::size_t operator()(object const& x) const {
  83. switch(type_) {
  84. case 1:
  85. return x.tag1_;
  86. case 2:
  87. return x.tag2_;
  88. default:
  89. return x.tag1_ + x.tag2_;
  90. }
  91. }
  92. std::size_t operator()(int x) const {
  93. return x;
  94. }
  95. friend bool operator==(hash const& x1, hash const& x2) {
  96. return x1.type_ == x2.type_;
  97. }
  98. friend bool operator!=(hash const& x1, hash const& x2) {
  99. return x1.type_ != x2.type_;
  100. }
  101. };
  102. std::size_t hash_value(test::object const& x) {
  103. return hash()(x);
  104. }
  105. class less
  106. {
  107. int type_;
  108. public:
  109. explicit less(int t = 0) : type_(t) {}
  110. bool operator()(object const& x1, object const& x2) const {
  111. switch(type_) {
  112. case 1:
  113. return x1.tag1_ < x2.tag1_;
  114. case 2:
  115. return x1.tag2_ < x2.tag2_;
  116. default:
  117. return x1 < x2;
  118. }
  119. }
  120. std::size_t operator()(int x1, int x2) const {
  121. return x1 < x2;
  122. }
  123. friend bool operator==(less const& x1, less const& x2) {
  124. return x1.type_ == x2.type_;
  125. }
  126. };
  127. class equal_to
  128. {
  129. int type_;
  130. public:
  131. explicit equal_to(int t = 0) : type_(t) {}
  132. bool operator()(object const& x1, object const& x2) const {
  133. switch(type_) {
  134. case 1:
  135. return x1.tag1_ == x2.tag1_;
  136. case 2:
  137. return x1.tag2_ == x2.tag2_;
  138. default:
  139. return x1 == x2;
  140. }
  141. }
  142. std::size_t operator()(int x1, int x2) const {
  143. return x1 == x2;
  144. }
  145. friend bool operator==(equal_to const& x1, equal_to const& x2) {
  146. return x1.type_ == x2.type_;
  147. }
  148. friend bool operator!=(equal_to const& x1, equal_to const& x2) {
  149. return x1.type_ != x2.type_;
  150. }
  151. friend less create_compare(equal_to x) {
  152. return less(x.type_);
  153. }
  154. };
  155. namespace detail
  156. {
  157. // This won't be a problem as I'm only using a single compile unit
  158. // in each test (this is actually require by the minimal test
  159. // framework).
  160. //
  161. // boostinspect:nounnamed
  162. namespace {
  163. test::detail::memory_tracker<std::allocator<int> > tracker;
  164. }
  165. }
  166. template <class T>
  167. class allocator
  168. {
  169. # ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  170. public:
  171. # else
  172. template <class> friend class allocator;
  173. # endif
  174. int tag_;
  175. public:
  176. typedef std::size_t size_type;
  177. typedef std::ptrdiff_t difference_type;
  178. typedef T* pointer;
  179. typedef T const* const_pointer;
  180. typedef T& reference;
  181. typedef T const& const_reference;
  182. typedef T value_type;
  183. template <class U> struct rebind { typedef allocator<U> other; };
  184. explicit allocator(int t = 0) : tag_(t)
  185. {
  186. detail::tracker.allocator_ref();
  187. }
  188. template <class Y> allocator(allocator<Y> const& x)
  189. : tag_(x.tag_)
  190. {
  191. detail::tracker.allocator_ref();
  192. }
  193. allocator(allocator const& x)
  194. : tag_(x.tag_)
  195. {
  196. detail::tracker.allocator_ref();
  197. }
  198. ~allocator()
  199. {
  200. detail::tracker.allocator_unref();
  201. }
  202. pointer address(reference r)
  203. {
  204. return pointer(&r);
  205. }
  206. const_pointer address(const_reference r)
  207. {
  208. return const_pointer(&r);
  209. }
  210. pointer allocate(size_type n) {
  211. pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
  212. detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
  213. return ptr;
  214. }
  215. pointer allocate(size_type n, void const* u)
  216. {
  217. pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
  218. detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
  219. return ptr;
  220. }
  221. void deallocate(pointer p, size_type n)
  222. {
  223. detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
  224. ::operator delete((void*) p);
  225. }
  226. void construct(pointer p, T const& t) {
  227. detail::tracker.track_construct((void*) p, sizeof(T), tag_);
  228. new(p) T(t);
  229. }
  230. #if defined(BOOST_UNORDERED_STD_FORWARD)
  231. template<class... Args> void construct(pointer p, Args&&... args) {
  232. detail::tracker.track_construct((void*) p, sizeof(T), tag_);
  233. new(p) T(std::forward<Args>(args)...);
  234. }
  235. #endif
  236. void destroy(pointer p) {
  237. detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
  238. p->~T();
  239. }
  240. size_type max_size() const {
  241. return (std::numeric_limits<size_type>::max)();
  242. }
  243. bool operator==(allocator const& x) const
  244. {
  245. return tag_ == x.tag_;
  246. }
  247. bool operator!=(allocator const& x) const
  248. {
  249. return tag_ != x.tag_;
  250. }
  251. };
  252. template <class T>
  253. bool equivalent_impl(allocator<T> const& x, allocator<T> const& y,
  254. test::derived_type)
  255. {
  256. return x == y;
  257. }
  258. }
  259. #endif