1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2007-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 
12 #ifdef _MSC_VER
13 #pragma warning (disable:4702)
14 #endif
15 
16 #include <vector>
17 #include <iostream>
18 #include <cstring>
19 #include <algorithm>    //std::remove
20 #include <boost/container/detail/alloc_lib_auto_link.hpp>
21 
22 namespace boost { namespace container { namespace test {
23 
24 static const int NumIt = 2000;
25 
26 enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocation, EndDeallocationType };
27 
28 //This test allocates until there is no more memory
29 //and after that deallocates all in the inverse order
30 
test_allocation()31 bool test_allocation()
32 {
33    if(!boost_cont_all_deallocated())
34       return false;
35    boost_cont_malloc_check();
36    for( deallocation_type t = DirectDeallocation
37       ; t != EndDeallocationType
38       ; t = (deallocation_type)((int)t + 1)){
39       std::vector<void*> buffers;
40       //std::size_t free_memory = a.get_free_memory();
41 
42       for(int i = 0; i != NumIt; ++i){
43          void *ptr = boost_cont_malloc(i);
44          if(!ptr)
45             break;
46          buffers.push_back(ptr);
47       }
48 
49       switch(t){
50          case DirectDeallocation:
51          {
52             for(int j = 0, max = (int)buffers.size()
53                ;j < max
54                ;++j){
55                boost_cont_free(buffers[j]);
56             }
57          }
58          break;
59          case InverseDeallocation:
60          {
61             for(int j = (int)buffers.size()
62                ;j--
63                ;){
64                boost_cont_free(buffers[j]);
65             }
66          }
67          break;
68          case MixedDeallocation:
69          {
70             for(int j = 0, max = (int)buffers.size()
71                ;j < max
72                ;++j){
73                int pos = (j%4)*((int)buffers.size())/4;
74                boost_cont_free(buffers[pos]);
75                buffers.erase(buffers.begin()+pos);
76             }
77          }
78          break;
79          default:
80          break;
81       }
82       if(!boost_cont_all_deallocated())
83          return false;
84       //bool ok = free_memory == a.get_free_memory() &&
85                //a.all_memory_deallocated() && a.check_sanity();
86       //if(!ok)  return ok;
87    }
88    boost_cont_malloc_check();
89    return 0 != boost_cont_all_deallocated();
90 }
91 
92 //This test allocates until there is no more memory
93 //and after that tries to shrink all the buffers to the
94 //half of the original size
95 
test_allocation_shrink()96 bool test_allocation_shrink()
97 {
98    boost_cont_malloc_check();
99    std::vector<void*> buffers;
100 
101    //Allocate buffers with extra memory
102    for(int i = 0; i != NumIt; ++i){
103       void *ptr = boost_cont_malloc(i*2);
104       if(!ptr)
105          break;
106       buffers.push_back(ptr);
107    }
108 
109    //Now shrink to half
110    for(int i = 0, max = (int)buffers.size()
111       ;i < max
112       ; ++i){
113       std::size_t try_received_size = 0;
114       void* try_result = boost_cont_allocation_command
115                ( BOOST_CONTAINER_TRY_SHRINK_IN_PLACE, 1, i*2
116                , i, &try_received_size, (char*)buffers[i]).first;
117 
118       std::size_t received_size = 0;
119       void* result = boost_cont_allocation_command
120          ( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, i*2
121          , i, &received_size, (char*)buffers[i]).first;
122 
123       if(result != try_result)
124          return false;
125 
126       if(received_size != try_received_size)
127          return false;
128 
129       if(result){
130          if(received_size > std::size_t(i*2)){
131             return false;
132          }
133          if(received_size < std::size_t(i)){
134             return false;
135          }
136       }
137    }
138 
139    //Deallocate it in non sequential order
140    for(int j = 0, max = (int)buffers.size()
141       ;j < max
142       ;++j){
143       int pos = (j%4)*((int)buffers.size())/4;
144       boost_cont_free(buffers[pos]);
145       buffers.erase(buffers.begin()+pos);
146    }
147    boost_cont_malloc_check();
148    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
149 }
150 
151 //This test allocates until there is no more memory
152 //and after that tries to expand all the buffers to
153 //avoid the wasted internal fragmentation
154 
test_allocation_expand()155 bool test_allocation_expand()
156 {
157    boost_cont_malloc_check();
158    std::vector<void*> buffers;
159 
160    //Allocate buffers with extra memory
161    for(int i = 0; i != NumIt; ++i){
162       void *ptr = boost_cont_malloc(i);
163       if(!ptr)
164          break;
165       buffers.push_back(ptr);
166    }
167 
168    //Now try to expand to the double of the size
169    for(int i = 0, max = (int)buffers.size()
170       ;i < max
171       ;++i){
172       std::size_t received_size = 0;
173       std::size_t min_size = i+1;
174       std::size_t preferred_size = i*2;
175       preferred_size = min_size > preferred_size ? min_size : preferred_size;
176       while(boost_cont_allocation_command
177          ( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
178          , preferred_size, &received_size, (char*)buffers[i]).first){
179          //Check received size is bigger than minimum
180          if(received_size < min_size){
181             return false;
182          }
183          //Now, try to expand further
184          min_size       = received_size+1;
185          preferred_size = min_size*2;
186       }
187    }
188 
189    //Deallocate it in non sequential order
190    for(int j = 0, max = (int)buffers.size()
191       ;j < max
192       ;++j){
193       int pos = (j%4)*((int)buffers.size())/4;
194       boost_cont_free(buffers[pos]);
195       buffers.erase(buffers.begin()+pos);
196    }
197    boost_cont_malloc_check();
198    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
199 }
200 
201 //This test allocates until there is no more memory
202 //and after that tries to expand all the buffers to
203 //avoid the wasted internal fragmentation
test_allocation_shrink_and_expand()204 bool test_allocation_shrink_and_expand()
205 {
206    std::vector<void*> buffers;
207    std::vector<std::size_t> received_sizes;
208    std::vector<bool>        size_reduced;
209 
210    //Allocate buffers wand store received sizes
211    for(int i = 0; i != NumIt; ++i){
212       std::size_t received_size = 0;
213       void *ptr = boost_cont_allocation_command
214          (BOOST_CONTAINER_ALLOCATE_NEW, 1, i, i*2, &received_size, 0).first;
215       if(!ptr){
216          ptr = boost_cont_allocation_command
217             ( BOOST_CONTAINER_ALLOCATE_NEW, 1, 1, i*2, &received_size, 0).first;
218          if(!ptr)
219             break;
220       }
221       buffers.push_back(ptr);
222       received_sizes.push_back(received_size);
223    }
224 
225    //Now shrink to half
226    for(int i = 0, max = (int)buffers.size()
227       ; i < max
228       ; ++i){
229       std::size_t received_size = 0;
230       bool size_reduced_flag;
231       if(true == (size_reduced_flag = !!
232          boost_cont_allocation_command
233          ( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, received_sizes[i]
234          , i, &received_size, (char*)buffers[i]).first)){
235          if(received_size > std::size_t(received_sizes[i])){
236             return false;
237          }
238          if(received_size < std::size_t(i)){
239             return false;
240          }
241       }
242       size_reduced.push_back(size_reduced_flag);
243    }
244 
245    //Now try to expand to the original size
246    for(int i = 0, max = (int)buffers.size()
247       ;i < max
248       ;++i){
249       if(!size_reduced[i])  continue;
250       std::size_t received_size = 0;
251       std::size_t request_size =  received_sizes[i];
252       if(boost_cont_allocation_command
253          ( BOOST_CONTAINER_EXPAND_FWD, 1, request_size
254          , request_size, &received_size, (char*)buffers[i]).first){
255          if(received_size != request_size){
256             return false;
257          }
258       }
259       else{
260          return false;
261       }
262    }
263 
264    //Deallocate it in non sequential order
265    for(int j = 0, max = (int)buffers.size()
266       ;j < max
267       ;++j){
268       int pos = (j%4)*((int)buffers.size())/4;
269       boost_cont_free(buffers[pos]);
270       buffers.erase(buffers.begin()+pos);
271    }
272 
273    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
274 }
275 
276 //This test allocates until there is no more memory
277 //and after that deallocates the odd buffers to
278 //make room for expansions. The expansion will probably
279 //success since the deallocation left room for that.
280 
test_allocation_deallocation_expand()281 bool test_allocation_deallocation_expand()
282 {
283    boost_cont_malloc_check();
284    std::vector<void*> buffers;
285 
286    //Allocate buffers with extra memory
287    for(int i = 0; i != NumIt; ++i){
288       void *ptr = boost_cont_malloc(i);
289       if(!ptr)
290          break;
291       buffers.push_back(ptr);
292    }
293 
294    //Now deallocate the half of the blocks
295    //so expand maybe can merge new free blocks
296    for(int i = 0, max = (int)buffers.size()
297       ;i < max
298       ;++i){
299       if(i%2){
300          boost_cont_free(buffers[i]);
301          buffers[i] = 0;
302       }
303    }
304 
305    //Now try to expand to the double of the size
306    for(int i = 0, max = (int)buffers.size()
307       ;i < max
308       ;++i){
309       //
310       if(buffers[i]){
311          std::size_t received_size = 0;
312          std::size_t min_size = i+1;
313          std::size_t preferred_size = i*2;
314          preferred_size = min_size > preferred_size ? min_size : preferred_size;
315 
316          while(boost_cont_allocation_command
317             ( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
318             , preferred_size, &received_size, (char*)buffers[i]).first){
319             //Check received size is bigger than minimum
320             if(received_size < min_size){
321                return false;
322             }
323             //Now, try to expand further
324             min_size       = received_size+1;
325             preferred_size = min_size*2;
326          }
327       }
328    }
329 
330    //Now erase null values from the vector
331    buffers.erase(std::remove(buffers.begin(), buffers.end(), (void*)0)
332                 ,buffers.end());
333 
334    //Deallocate it in non sequential order
335    for(int j = 0, max = (int)buffers.size()
336       ;j < max
337       ;++j){
338       int pos = (j%4)*((int)buffers.size())/4;
339       boost_cont_free(buffers[pos]);
340       buffers.erase(buffers.begin()+pos);
341    }
342    boost_cont_malloc_check();
343    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
344 }
345 
346 //This test allocates until there is no more memory
347 //and after that deallocates all except the last.
348 //If the allocation algorithm is a bottom-up algorithm
349 //the last buffer will be in the end of the segment.
350 //Then the test will start expanding backwards, until
351 //the buffer fills all the memory
352 
test_allocation_with_reuse()353 bool test_allocation_with_reuse()
354 {
355    boost_cont_malloc_check();
356    //We will repeat this test for different sized elements
357    for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
358       std::vector<void*> buffers;
359 
360       //Allocate buffers with extra memory
361       for(int i = 0; i != NumIt; ++i){
362          void *ptr = boost_cont_malloc(i*sizeof_object);
363          if(!ptr)
364             break;
365          buffers.push_back(ptr);
366       }
367 
368       //Now deallocate all except the latest
369       //Now try to expand to the double of the size
370       for(int i = 0, max = (int)buffers.size() - 1
371          ;i < max
372          ;++i){
373          boost_cont_free(buffers[i]);
374       }
375 
376       //Save the unique buffer and clear vector
377       void *ptr = buffers.back();
378       buffers.clear();
379 
380       //Now allocate with reuse
381       std::size_t received_size = 0;
382       for(int i = 0; i != NumIt; ++i){
383          std::size_t min_size = (received_size/sizeof_object + 1)*sizeof_object;
384          std::size_t prf_size = (received_size/sizeof_object + (i+1)*2)*sizeof_object;
385          boost_cont_command_ret_t ret = boost_cont_allocation_command
386             ( BOOST_CONTAINER_EXPAND_BWD, sizeof_object, min_size
387             , prf_size, &received_size, (char*)ptr);
388          //If we have memory, this must be a buffer reuse
389          if(!ret.first)
390             break;
391          //If we have memory, this must be a buffer reuse
392          if(!ret.second)
393             return false;
394          if(received_size < min_size)
395             return false;
396          ptr = ret.first;
397       }
398       //There should be only a single block so deallocate it
399       boost_cont_free(ptr);
400       boost_cont_malloc_check();
401       if(!boost_cont_all_deallocated())
402          return false;
403    }
404    return true;
405 }
406 
407 
408 //This test allocates memory with different alignments
409 //and checks returned memory is aligned.
410 
test_aligned_allocation()411 bool test_aligned_allocation()
412 {
413    boost_cont_malloc_check();
414    //Allocate aligned buffers in a loop
415    //and then deallocate it
416    for(unsigned int i = 1; i != (1 << (sizeof(int)/2)); i <<= 1){
417       for(unsigned int j = 1; j != 512; j <<= 1){
418          void *ptr = boost_cont_memalign(i-1, j);
419          if(!ptr){
420             return false;
421          }
422 
423          if(((std::size_t)ptr & (j - 1)) != 0)
424             return false;
425          boost_cont_free(ptr);
426          //if(!a.all_memory_deallocated() || !a.check_sanity()){
427          //   return false;
428          //}
429       }
430    }
431    boost_cont_malloc_check();
432    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
433 }
434 
435 //This test allocates memory with different alignments
436 //and checks returned memory is aligned.
437 
test_continuous_aligned_allocation()438 bool test_continuous_aligned_allocation()
439 {
440    boost_cont_malloc_check();
441    std::vector<void*> buffers;
442    //Allocate aligned buffers in a loop
443    //and then deallocate it
444    bool continue_loop = true;
445    unsigned int MaxAlign = 4096;
446    unsigned int MaxSize  = 4096;
447    for(unsigned i = 1; i < MaxSize; i <<= 1){
448       for(unsigned int j = 1; j < MaxAlign; j <<= 1){
449          for(int k = 0; k != NumIt; ++k){
450             void *ptr = boost_cont_memalign(i-1, j);
451             buffers.push_back(ptr);
452             if(!ptr){
453                continue_loop = false;
454                break;
455             }
456 
457             if(((std::size_t)ptr & (j - 1)) != 0)
458                return false;
459          }
460          //Deallocate all
461          for(int k = (int)buffers.size(); k--;){
462             boost_cont_free(buffers[k]);
463          }
464          buffers.clear();
465          //if(!a.all_memory_deallocated() && a.check_sanity())
466          //   return false;
467          if(!continue_loop)
468             break;
469       }
470    }
471    boost_cont_malloc_check();
472    return 0 != boost_cont_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
473 }
474 
475 //This test allocates multiple values until there is no more memory
476 //and after that deallocates all in the inverse order
test_many_equal_allocation()477 bool test_many_equal_allocation()
478 {
479    boost_cont_malloc_check();
480    for( deallocation_type t = DirectDeallocation
481       ; t != EndDeallocationType
482       ; t = (deallocation_type)((int)t + 1)){
483       //std::size_t free_memory = a.get_free_memory();
484 
485       std::vector<void*> buffers2;
486 
487       //Allocate buffers with extra memory
488       for(int i = 0; i != NumIt; ++i){
489          void *ptr = boost_cont_malloc(i);
490          if(!ptr)
491             break;
492          //if(!a.check_sanity())
493             //return false;
494          buffers2.push_back(ptr);
495       }
496 
497       //Now deallocate the half of the blocks
498       //so expand maybe can merge new free blocks
499       for(int i = 0, max = (int)buffers2.size()
500          ;i < max
501          ;++i){
502          if(i%2){
503             boost_cont_free(buffers2[i]);
504             buffers2[i] = 0;
505          }
506       }
507 
508       //if(!a.check_sanity())
509          //return false;
510 
511       std::vector<void*> buffers;
512       for(int i = 0; i != NumIt/10; ++i){
513          boost_cont_memchain chain;
514          BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
515          boost_cont_multialloc_nodes((i+1)*2, i+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
516          boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
517          if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
518             break;
519 
520          std::size_t n = 0;
521          for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
522             buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
523             BOOST_CONTAINER_MEMIT_NEXT(it);
524          }
525          if(n != std::size_t((i+1)*2))
526             return false;
527       }
528 
529       //if(!a.check_sanity())
530          //return false;
531 
532       switch(t){
533          case DirectDeallocation:
534          {
535             for(int j = 0, max = (int)buffers.size()
536                ;j < max
537                ;++j){
538                boost_cont_free(buffers[j]);
539             }
540          }
541          break;
542          case InverseDeallocation:
543          {
544             for(int j = (int)buffers.size()
545                ;j--
546                ;){
547                boost_cont_free(buffers[j]);
548             }
549          }
550          break;
551          case MixedDeallocation:
552          {
553             for(int j = 0, max = (int)buffers.size()
554                ;j < max
555                ;++j){
556                int pos = (j%4)*((int)buffers.size())/4;
557                boost_cont_free(buffers[pos]);
558                buffers.erase(buffers.begin()+pos);
559             }
560          }
561          break;
562          default:
563          break;
564       }
565 
566       //Deallocate the rest of the blocks
567 
568       //Deallocate it in non sequential order
569       for(int j = 0, max = (int)buffers2.size()
570          ;j < max
571          ;++j){
572          int pos = (j%4)*((int)buffers2.size())/4;
573          boost_cont_free(buffers2[pos]);
574          buffers2.erase(buffers2.begin()+pos);
575       }
576 
577       //bool ok = free_memory == a.get_free_memory() &&
578                //a.all_memory_deallocated() && a.check_sanity();
579       //if(!ok)  return ok;
580    }
581    boost_cont_malloc_check();
582    return 0 != boost_cont_all_deallocated();
583 }
584 
585 //This test allocates multiple values until there is no more memory
586 //and after that deallocates all in the inverse order
587 
test_many_different_allocation()588 bool test_many_different_allocation()
589 {
590    boost_cont_malloc_check();
591    const std::size_t ArraySize = 11;
592    std::size_t requested_sizes[ArraySize];
593    for(std::size_t i = 0; i < ArraySize; ++i){
594       requested_sizes[i] = 4*i;
595    }
596 
597    for( deallocation_type t = DirectDeallocation
598       ; t != EndDeallocationType
599       ; t = (deallocation_type)((int)t + 1)){
600       //std::size_t free_memory = a.get_free_memory();
601 
602       std::vector<void*> buffers2;
603 
604       //Allocate buffers with extra memory
605       for(int i = 0; i != NumIt; ++i){
606          void *ptr = boost_cont_malloc(i);
607          if(!ptr)
608             break;
609          buffers2.push_back(ptr);
610       }
611 
612       //Now deallocate the half of the blocks
613       //so expand maybe can merge new free blocks
614       for(int i = 0, max = (int)buffers2.size()
615          ;i < max
616          ;++i){
617          if(i%2){
618             boost_cont_free(buffers2[i]);
619             buffers2[i] = 0;
620          }
621       }
622 
623       std::vector<void*> buffers;
624       for(int i = 0; i != NumIt; ++i){
625          boost_cont_memchain chain;
626          BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
627          boost_cont_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
628          boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
629          if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
630             break;
631          std::size_t n = 0;
632          for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
633             buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
634             BOOST_CONTAINER_MEMIT_NEXT(it);
635          }
636          if(n != ArraySize)
637             return false;
638       }
639 
640       switch(t){
641          case DirectDeallocation:
642          {
643             for(int j = 0, max = (int)buffers.size()
644                ;j < max
645                ;++j){
646                boost_cont_free(buffers[j]);
647             }
648          }
649          break;
650          case InverseDeallocation:
651          {
652             for(int j = (int)buffers.size()
653                ;j--
654                ;){
655                boost_cont_free(buffers[j]);
656             }
657          }
658          break;
659          case MixedDeallocation:
660          {
661             for(int j = 0, max = (int)buffers.size()
662                ;j < max
663                ;++j){
664                int pos = (j%4)*((int)buffers.size())/4;
665                boost_cont_free(buffers[pos]);
666                buffers.erase(buffers.begin()+pos);
667             }
668          }
669          break;
670          default:
671          break;
672       }
673 
674       //Deallocate the rest of the blocks
675 
676       //Deallocate it in non sequential order
677       for(int j = 0, max = (int)buffers2.size()
678          ;j < max
679          ;++j){
680          int pos = (j%4)*((int)buffers2.size())/4;
681          boost_cont_free(buffers2[pos]);
682          buffers2.erase(buffers2.begin()+pos);
683       }
684 
685       //bool ok = free_memory == a.get_free_memory() &&
686                //a.all_memory_deallocated() && a.check_sanity();
687       //if(!ok)  return ok;
688    }
689    boost_cont_malloc_check();
690    return 0 != boost_cont_all_deallocated();
691 }
692 
test_many_deallocation()693 bool test_many_deallocation()
694 {
695    const std::size_t ArraySize = 11;
696    std::vector<boost_cont_memchain> buffers;
697    std::size_t requested_sizes[ArraySize];
698    for(std::size_t i = 0; i < ArraySize; ++i){
699       requested_sizes[i] = 4*i;
700    }
701 
702    for(int i = 0; i != NumIt; ++i){
703       boost_cont_memchain chain;
704       BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
705       boost_cont_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
706       boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
707       if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
708          return false;
709       buffers.push_back(chain);
710    }
711    for(int i = 0; i != NumIt; ++i){
712       boost_cont_multidealloc(&buffers[i]);
713    }
714    buffers.clear();
715 
716    boost_cont_malloc_check();
717    if(!boost_cont_all_deallocated())
718       return false;
719 
720    for(int i = 0; i != NumIt; ++i){
721       boost_cont_memchain chain;
722       BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
723       boost_cont_multialloc_nodes(ArraySize, i*4+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
724       boost_cont_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
725       if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
726          return false;
727       buffers.push_back(chain);
728    }
729    for(int i = 0; i != NumIt; ++i){
730       boost_cont_multidealloc(&buffers[i]);
731    }
732    buffers.clear();
733 
734    boost_cont_malloc_check();
735    if(!boost_cont_all_deallocated())
736       return false;
737 
738    return true;
739 }
740 
741 //This function calls all tests
742 
test_all_allocation()743 bool test_all_allocation()
744 {
745    std::cout << "Starting test_allocation"
746              << std::endl;
747 
748    if(!test_allocation()){
749       std::cout << "test_allocation_direct_deallocation failed"
750                 << std::endl;
751       return false;
752    }
753 
754    std::cout << "Starting test_many_equal_allocation"
755              << std::endl;
756 
757    if(!test_many_equal_allocation()){
758       std::cout << "test_many_equal_allocation failed"
759                 << std::endl;
760       return false;
761    }
762 
763    std::cout << "Starting test_many_different_allocation"
764              << std::endl;
765 
766    if(!test_many_different_allocation()){
767       std::cout << "test_many_different_allocation failed"
768                 << std::endl;
769       return false;
770    }
771 
772    std::cout << "Starting test_allocation_shrink"
773              << std::endl;
774 
775    if(!test_allocation_shrink()){
776       std::cout << "test_allocation_shrink failed"
777                 << std::endl;
778       return false;
779    }
780 
781    if(!test_allocation_shrink_and_expand()){
782       std::cout << "test_allocation_shrink_and_expand failed"
783                 << std::endl;
784       return false;
785    }
786 
787    std::cout << "Starting test_allocation_expand"
788              << std::endl;
789 
790    if(!test_allocation_expand()){
791       std::cout << "test_allocation_expand failed"
792                 << std::endl;
793       return false;
794    }
795 
796    std::cout << "Starting test_allocation_deallocation_expand"
797              << std::endl;
798 
799    if(!test_allocation_deallocation_expand()){
800       std::cout << "test_allocation_deallocation_expand failed"
801                 << std::endl;
802       return false;
803    }
804 
805    std::cout << "Starting test_allocation_with_reuse"
806              << std::endl;
807 
808    if(!test_allocation_with_reuse()){
809       std::cout << "test_allocation_with_reuse failed"
810                 << std::endl;
811       return false;
812    }
813 
814    std::cout << "Starting test_aligned_allocation"
815              << std::endl;
816 
817    if(!test_aligned_allocation()){
818       std::cout << "test_aligned_allocation failed"
819                 << std::endl;
820       return false;
821    }
822 
823    std::cout << "Starting test_continuous_aligned_allocation"
824              << std::endl;
825 
826    if(!test_continuous_aligned_allocation()){
827       std::cout << "test_continuous_aligned_allocation failed"
828                 << std::endl;
829       return false;
830    }
831 
832    if(!test_many_deallocation()){
833       std::cout << "test_many_deallocation failed"
834                 << std::endl;
835       return false;
836    }
837 
838    return 0 != boost_cont_all_deallocated();
839 }
840 
841 }}}   //namespace boost { namespace container { namespace test {
842 
843 
main()844 int main()
845 {
846    if(!boost::container::test::test_all_allocation())
847       return 1;
848    return 0;
849 }
850