////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER #define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER #include #include namespace boost{ namespace container { namespace test{ // template class default_init_allocator_base { protected: static unsigned char s_pattern; static bool s_ascending; public: static void reset_pattern(unsigned char value) { s_pattern = value; } static void set_ascending(bool enable) { s_ascending = enable; } }; template unsigned char default_init_allocator_base::s_pattern = 0u; template bool default_init_allocator_base::s_ascending = true; template class default_init_allocator : public default_init_allocator_base<0> { typedef default_init_allocator_base<0> base_t; public: typedef Integral value_type; default_init_allocator() {} template default_init_allocator(default_init_allocator) {} Integral* allocate(std::size_t n) { //Initialize memory to a pattern const std::size_t max = sizeof(Integral)*n; unsigned char *puc_raw = ::new unsigned char[max]; if(base_t::s_ascending){ for(std::size_t i = 0; i != max; ++i){ puc_raw[i] = static_cast(s_pattern++); } } else{ for(std::size_t i = 0; i != max; ++i){ puc_raw[i] = static_cast(s_pattern--); } } return (Integral*)puc_raw;; } void deallocate(Integral *p, std::size_t) { delete[] (unsigned char*)p; } }; template inline bool check_ascending_byte_pattern(const Integral&t) { const unsigned char *pch = &reinterpret_cast(t); const std::size_t max = sizeof(Integral); for(std::size_t i = 1; i != max; ++i){ if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){ return false; } } return true; } template inline bool check_descending_byte_pattern(const Integral&t) { const unsigned char *pch = &reinterpret_cast(t); const std::size_t max = sizeof(Integral); for(std::size_t i = 1; i != max; ++i){ if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){ return false; } } return true; } template bool default_init_test()//Test for default initialization { const std::size_t Capacity = 100; { test::default_init_allocator::reset_pattern(0); test::default_init_allocator::set_ascending(true); IntDefaultInitAllocVector v(Capacity, default_init); typename IntDefaultInitAllocVector::iterator it = v.begin(); //Compare with the pattern for(std::size_t i = 0; i != Capacity; ++i, ++it){ if(!test::check_ascending_byte_pattern(*it)) return false; } } { test::default_init_allocator::reset_pattern(0); test::default_init_allocator::set_ascending(true); IntDefaultInitAllocVector v(Capacity, default_init, typename IntDefaultInitAllocVector::allocator_type()); typename IntDefaultInitAllocVector::iterator it = v.begin(); //Compare with the pattern for(std::size_t i = 0; i != Capacity; ++i, ++it){ if(!test::check_ascending_byte_pattern(*it)) return false; } } { test::default_init_allocator::reset_pattern(100); test::default_init_allocator::set_ascending(false); IntDefaultInitAllocVector v; v.resize(Capacity, default_init); typename IntDefaultInitAllocVector::iterator it = v.begin(); //Compare with the pattern for(std::size_t i = 0; i != Capacity; ++i, ++it){ if(!test::check_descending_byte_pattern(*it)) return false; } } return true; } } //namespace test{ } //namespace container { } //namespace boost{ #include #endif //BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER