default_init_test.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
  11. #define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
  12. #include <boost/container/detail/config_begin.hpp>
  13. #include <cstddef>
  14. namespace boost{
  15. namespace container {
  16. namespace test{
  17. //
  18. template<int Dummy = 0>
  19. class default_init_allocator_base
  20. {
  21. protected:
  22. static unsigned char s_pattern;
  23. static bool s_ascending;
  24. public:
  25. static void reset_pattern(unsigned char value)
  26. { s_pattern = value; }
  27. static void set_ascending(bool enable)
  28. { s_ascending = enable; }
  29. };
  30. template<int Dummy>
  31. unsigned char default_init_allocator_base<Dummy>::s_pattern = 0u;
  32. template<int Dummy>
  33. bool default_init_allocator_base<Dummy>::s_ascending = true;
  34. template<class Integral>
  35. class default_init_allocator
  36. : public default_init_allocator_base<0>
  37. {
  38. typedef default_init_allocator_base<0> base_t;
  39. public:
  40. typedef Integral value_type;
  41. default_init_allocator()
  42. {}
  43. template <class U>
  44. default_init_allocator(default_init_allocator<U>)
  45. {}
  46. Integral* allocate(std::size_t n)
  47. {
  48. //Initialize memory to a pattern
  49. const std::size_t max = sizeof(Integral)*n;
  50. unsigned char *puc_raw = ::new unsigned char[max];
  51. if(base_t::s_ascending){
  52. for(std::size_t i = 0; i != max; ++i){
  53. puc_raw[i] = static_cast<unsigned char>(s_pattern++);
  54. }
  55. }
  56. else{
  57. for(std::size_t i = 0; i != max; ++i){
  58. puc_raw[i] = static_cast<unsigned char>(s_pattern--);
  59. }
  60. }
  61. return (Integral*)puc_raw;;
  62. }
  63. void deallocate(Integral *p, std::size_t)
  64. { delete[] (unsigned char*)p; }
  65. };
  66. template<class Integral>
  67. inline bool check_ascending_byte_pattern(const Integral&t)
  68. {
  69. const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
  70. const std::size_t max = sizeof(Integral);
  71. for(std::size_t i = 1; i != max; ++i){
  72. if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. template<class Integral>
  79. inline bool check_descending_byte_pattern(const Integral&t)
  80. {
  81. const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
  82. const std::size_t max = sizeof(Integral);
  83. for(std::size_t i = 1; i != max; ++i){
  84. if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){
  85. return false;
  86. }
  87. }
  88. return true;
  89. }
  90. template<class IntDefaultInitAllocVector>
  91. bool default_init_test()//Test for default initialization
  92. {
  93. const std::size_t Capacity = 100;
  94. {
  95. test::default_init_allocator<int>::reset_pattern(0);
  96. test::default_init_allocator<int>::set_ascending(true);
  97. IntDefaultInitAllocVector v(Capacity, default_init);
  98. typename IntDefaultInitAllocVector::iterator it = v.begin();
  99. //Compare with the pattern
  100. for(std::size_t i = 0; i != Capacity; ++i, ++it){
  101. if(!test::check_ascending_byte_pattern(*it))
  102. return false;
  103. }
  104. }
  105. {
  106. test::default_init_allocator<int>::reset_pattern(0);
  107. test::default_init_allocator<int>::set_ascending(true);
  108. IntDefaultInitAllocVector v(Capacity, default_init, typename IntDefaultInitAllocVector::allocator_type());
  109. typename IntDefaultInitAllocVector::iterator it = v.begin();
  110. //Compare with the pattern
  111. for(std::size_t i = 0; i != Capacity; ++i, ++it){
  112. if(!test::check_ascending_byte_pattern(*it))
  113. return false;
  114. }
  115. }
  116. {
  117. test::default_init_allocator<int>::reset_pattern(100);
  118. test::default_init_allocator<int>::set_ascending(false);
  119. IntDefaultInitAllocVector v;
  120. v.resize(Capacity, default_init);
  121. typename IntDefaultInitAllocVector::iterator it = v.begin();
  122. //Compare with the pattern
  123. for(std::size_t i = 0; i != Capacity; ++i, ++it){
  124. if(!test::check_descending_byte_pattern(*it))
  125. return false;
  126. }
  127. }
  128. return true;
  129. }
  130. } //namespace test{
  131. } //namespace container {
  132. } //namespace boost{
  133. #include <boost/container/detail/config_end.hpp>
  134. #endif //BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER