• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #ifndef BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
12 #define BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
13 
14 #include <boost/container/detail/config_begin.hpp>
15 #include <cstddef>
16 
17 namespace boost{
18 namespace container {
19 namespace test{
20 
21 //
22 template<int Dummy = 0>
23 class default_init_allocator_base
24 {
25    protected:
26    static unsigned char s_pattern;
27    static bool          s_ascending;
28 
29    public:
reset_pattern(unsigned char value)30    static void reset_pattern(unsigned char value)
31    {  s_pattern = value;   }
32 
set_ascending(bool enable)33    static void set_ascending(bool enable)
34    {  s_ascending = enable;   }
35 };
36 
37 template<int Dummy>
38 unsigned char default_init_allocator_base<Dummy>::s_pattern = 0u;
39 
40 template<int Dummy>
41 bool default_init_allocator_base<Dummy>::s_ascending = true;
42 
43 template<class Integral>
44 class default_init_allocator
45    : public default_init_allocator_base<0>
46 {
47    typedef default_init_allocator_base<0> base_t;
48    public:
49    typedef Integral value_type;
50 
default_init_allocator()51    default_init_allocator()
52    {}
53 
54    template <class U>
default_init_allocator(default_init_allocator<U>)55    default_init_allocator(default_init_allocator<U>)
56    {}
57 
allocate(std::size_t n)58    Integral* allocate(std::size_t n)
59    {
60       //Initialize memory to a pattern
61       const std::size_t max = sizeof(Integral)*n;
62       unsigned char *puc_raw = ::new unsigned char[max];
63 
64       if(base_t::s_ascending){
65          for(std::size_t i = 0; i != max; ++i){
66             puc_raw[i] = static_cast<unsigned char>(s_pattern++);
67          }
68       }
69       else{
70          for(std::size_t i = 0; i != max; ++i){
71             puc_raw[i] = static_cast<unsigned char>(s_pattern--);
72          }
73       }
74       return (Integral*)puc_raw;;
75    }
76 
deallocate(Integral * p,std::size_t)77    void deallocate(Integral *p, std::size_t)
78    {  delete[] (unsigned char*)p;  }
79 };
80 
81 template<class Integral>
check_ascending_byte_pattern(const Integral & t)82 inline bool check_ascending_byte_pattern(const Integral&t)
83 {
84    const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
85    const std::size_t max = sizeof(Integral);
86    for(std::size_t i = 1; i != max; ++i){
87       if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){
88          return false;
89       }
90    }
91    return true;
92 }
93 
94 template<class Integral>
check_descending_byte_pattern(const Integral & t)95 inline bool check_descending_byte_pattern(const Integral&t)
96 {
97    const unsigned char *pch = &reinterpret_cast<const unsigned char &>(t);
98    const std::size_t max = sizeof(Integral);
99    for(std::size_t i = 1; i != max; ++i){
100       if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){
101          return false;
102       }
103    }
104    return true;
105 }
106 
107 template<class IntDefaultInitAllocVector>
default_init_test()108 bool default_init_test()//Test for default initialization
109 {
110    const std::size_t Capacity = 100;
111 
112    {
113       test::default_init_allocator<int>::reset_pattern(0);
114       test::default_init_allocator<int>::set_ascending(true);
115       IntDefaultInitAllocVector v(Capacity, default_init);
116       typename IntDefaultInitAllocVector::iterator it = v.begin();
117       //Compare with the pattern
118       for(std::size_t i = 0; i != Capacity; ++i, ++it){
119          if(!test::check_ascending_byte_pattern(*it))
120             return false;
121       }
122    }
123    {
124       test::default_init_allocator<int>::reset_pattern(0);
125       test::default_init_allocator<int>::set_ascending(true);
126       IntDefaultInitAllocVector v(Capacity, default_init, typename IntDefaultInitAllocVector::allocator_type());
127       typename IntDefaultInitAllocVector::iterator it = v.begin();
128       //Compare with the pattern
129       for(std::size_t i = 0; i != Capacity; ++i, ++it){
130          if(!test::check_ascending_byte_pattern(*it))
131             return false;
132       }
133    }
134    {
135       test::default_init_allocator<int>::reset_pattern(100);
136       test::default_init_allocator<int>::set_ascending(false);
137       IntDefaultInitAllocVector v;
138       v.resize(Capacity, default_init);
139       typename IntDefaultInitAllocVector::iterator it = v.begin();
140       //Compare with the pattern
141       for(std::size_t i = 0; i != Capacity; ++i, ++it){
142          if(!test::check_descending_byte_pattern(*it))
143             return false;
144       }
145    }
146    return true;
147 }
148 
149 }  //namespace test{
150 }  //namespace container {
151 }  //namespace boost{
152 
153 #include <boost/container/detail/config_end.hpp>
154 
155 #endif //BOOST_CONTAINER_TEST_DEFAULT_INIT_TEST_HEADER
156