summaryrefslogtreecommitdiff
path: root/libs/container/test/propagate_allocator_test.hpp
blob: 67138892b8b4de626ca2e99586217db63446cb39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008. 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_PROPAGATE_ALLOCATOR_TEST_HPP
#define BOOST_CONTAINER_PROPAGATE_ALLOCATOR_TEST_HPP

#include <boost/container/detail/config_begin.hpp>
#include <boost/core/lightweight_test.hpp>
#include "dummy_test_allocator.hpp"

#include <iostream>

namespace boost{
namespace container {
namespace test{

template<template<class, class> class ContainerWrapper>
bool test_propagate_allocator()
{
   {
      typedef propagation_test_allocator<char, true, true, true, true>  AlwaysPropagate;
      typedef ContainerWrapper<char, AlwaysPropagate>                   PropagateCont;

      //////////////////////////////////////////
      //Test AlwaysPropagate allocator propagation
      //////////////////////////////////////////
      AlwaysPropagate::reset_unique_id();

      //default constructor
      PropagateCont c;
      BOOST_TEST (c.get_stored_allocator().id_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0);
      BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c.get_stored_allocator().swaps_ == 0);

      //copy constructor
      PropagateCont c2(c);
      //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler).
      //For allocators that copy in select_on_container_copy_construction, at least we must have a copy
      unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_;
      unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_;
      BOOST_TEST (c2.get_stored_allocator().id_ == 0);
      BOOST_TEST (ctr_copies > 0);
      BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0);
      BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);

      //move constructor
      PropagateCont c3(boost::move(c2));
      BOOST_TEST (c3.get_stored_allocator().id_ == 0);
      BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies);
      BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves);
      ctr_moves = c3.get_stored_allocator().ctr_moves_;
      BOOST_TEST (ctr_moves > 0);
      BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c3.get_stored_allocator().swaps_ == 0);

      //copy assign
      c2 = c3;
      unsigned int assign_copies = c2.get_stored_allocator().assign_copies_;
      BOOST_TEST (c2.get_stored_allocator().id_ == 0);
      BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
      BOOST_TEST (c2.get_stored_allocator().ctr_moves_  == ctr_moves);
      BOOST_TEST (assign_copies == 1);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);

      //move assign
      c = boost::move(c2);
      unsigned int assign_moves = c.get_stored_allocator().assign_moves_;
      BOOST_TEST (c.get_stored_allocator().id_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_copies_    == ctr_copies);
      BOOST_TEST (c.get_stored_allocator().ctr_moves_     == ctr_moves);
      BOOST_TEST (c.get_stored_allocator().assign_copies_ == assign_copies);
      BOOST_TEST (assign_moves == 1);
      BOOST_TEST (c.get_stored_allocator().swaps_ == 0);

      //swap
      c.get_stored_allocator().id_ = 999;
      c.swap(c2);
      unsigned int swaps = c2.get_stored_allocator().swaps_;
      BOOST_TEST (c2.get_stored_allocator().id_ == 999);
      BOOST_TEST (c2.get_stored_allocator().ctr_copies_    == ctr_copies);
      BOOST_TEST (c2.get_stored_allocator().ctr_moves_     == ctr_moves);
      BOOST_TEST (c2.get_stored_allocator().assign_copies_ == assign_copies);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_  == assign_moves);
      BOOST_TEST (swaps == 1);
   }

   //////////////////////////////////////////
   //Test NeverPropagate allocator propagation
   //////////////////////////////////////////
   {
      typedef propagation_test_allocator<char, false, false, false, false> NeverPropagate;
      typedef ContainerWrapper<char, NeverPropagate>                       NoPropagateCont;
      NeverPropagate::reset_unique_id();

      //default constructor
      NoPropagateCont c;
      BOOST_TEST (c.get_stored_allocator().id_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0);
      BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c.get_stored_allocator().swaps_ == 0);

      //copy constructor
      //propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler)
      //For allocators that don't copy in select_on_container_copy_construction we must have a default
      //construction
      NoPropagateCont c2(c);
      unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_;
      unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_;
      BOOST_TEST (c2.get_stored_allocator().id_ == 1);
      BOOST_TEST (ctr_copies >= 0);
      BOOST_TEST (ctr_moves >= 0);
      BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);

      //move constructor
      NoPropagateCont c3(boost::move(c2));
      BOOST_TEST (c3.get_stored_allocator().id_ == 1);
      BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies);
      BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves);
      unsigned int ctr_moves2 = ctr_moves;
      ctr_moves = c3.get_stored_allocator().ctr_moves_;
      BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c3.get_stored_allocator().swaps_ == 0);

      //copy assign
      c2 = c3;
      BOOST_TEST (c2.get_stored_allocator().id_ == 1);
      BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
      BOOST_TEST (c2.get_stored_allocator().ctr_moves_  == ctr_moves2);
      BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);

      //move assign
      c = boost::move(c2);
      BOOST_TEST (c.get_stored_allocator().id_ == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_copies_    == 0);
      BOOST_TEST (c.get_stored_allocator().ctr_moves_     == 0);
      BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c.get_stored_allocator().swaps_ == 0);

      //swap
      c.get_stored_allocator().id_ = 999;
      c2.swap(c);
      BOOST_TEST (c2.get_stored_allocator().id_ == 1);
      BOOST_TEST (c.get_stored_allocator().id_ == 999);
      BOOST_TEST (c2.get_stored_allocator().ctr_copies_    == ctr_copies);
      BOOST_TEST (c2.get_stored_allocator().ctr_moves_  == ctr_moves2);
      BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
      BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
      BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
   }

   return report_errors() == 0;
}

}  //namespace test{
}  //namespace container {
}  //namespace boost{

#include <boost/container/detail/config_end.hpp>

#endif   //#ifndef BOOST_CONTAINER_PROPAGATE_ALLOCATOR_TEST_HPP