//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER
#define BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER

#include <boost/interprocess/detail/config_begin.hpp>
#include <vector>
#include <iostream>
#include <new>
#include <utility>
#include <cstring>   //std::memset
#include <boost/interprocess/containers/vector.hpp>

namespace boost { namespace interprocess { namespace test {

enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocation, EndDeallocationType };

//This test allocates until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_allocation(Allocator &a)
{
   for( deallocation_type t = DirectDeallocation
      ; t != EndDeallocationType
      ; t = (deallocation_type)((int)t + 1)){
      std::vector<void*> buffers;
      std::size_t free_memory = a.get_free_memory();

      for(int i = 0; true; ++i){
         void *ptr = a.allocate(i, std::nothrow);
         if(!ptr)
            break;
         std::size_t size = a.size(ptr);
         std::memset(ptr, 0, size);
         buffers.push_back(ptr);
      }

      switch(t){
         case DirectDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case InverseDeallocation:
         {
            for(int j = (int)buffers.size()
               ;j--
               ;){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case MixedDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               int pos = (j%4)*((int)buffers.size())/4;
               a.deallocate(buffers[pos]);
               buffers.erase(buffers.begin()+pos);
            }
         }
         break;
         default:
         break;
      }
      bool ok = free_memory == a.get_free_memory() && 
               a.all_memory_deallocated() && a.check_sanity();
      if(!ok)  return ok;
   }
   return true;
}

//This test allocates until there is no more memory
//and after that tries to shrink all the buffers to the
//half of the original size
template<class Allocator>
bool test_allocation_shrink(Allocator &a)
{
   std::vector<void*> buffers;

   //Allocate buffers with extra memory
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i*2, std::nothrow);
      if(!ptr)
         break;
      std::size_t size = a.size(ptr);
      std::memset(ptr, 0, size);
      buffers.push_back(ptr);
   }

   //Now shrink to half
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ; ++i){
      std::size_t received_size;
      if(a.template allocation_command<char>
         ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, i*2
         , i, received_size, static_cast<char*>(buffers[i])).first){
         if(received_size > std::size_t(i*2)){
            return false;
         }
         if(received_size < std::size_t(i)){
            return false;
         }
         std::memset(buffers[i], 0, a.size(buffers[i]));
      }
   }
   
   //Deallocate it in non sequential order
   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      int pos = (j%4)*((int)buffers.size())/4;
      a.deallocate(buffers[pos]);
      buffers.erase(buffers.begin()+pos);
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates until there is no more memory
//and after that tries to expand all the buffers to
//avoid the wasted internal fragmentation
template<class Allocator>
bool test_allocation_expand(Allocator &a)
{
   std::vector<void*> buffers;

   //Allocate buffers with extra memory
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i, std::nothrow);
      if(!ptr)
         break;
      std::size_t size = a.size(ptr);
      std::memset(ptr, 0, size);
      buffers.push_back(ptr);
   }

   //Now try to expand to the double of the size
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ;++i){
      std::size_t received_size;
      std::size_t min_size = i+1;
      std::size_t preferred_size = i*2;
      preferred_size = min_size > preferred_size ? min_size : preferred_size;

      while(a.template allocation_command<char>
         ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
         , preferred_size, received_size, static_cast<char*>(buffers[i])).first){
         //Check received size is bigger than minimum
         if(received_size < min_size){
            return false;
         }
         //Now, try to expand further
         min_size       = received_size+1;
         preferred_size = min_size*2;
      }
   }
   
   //Deallocate it in non sequential order
   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      int pos = (j%4)*((int)buffers.size())/4;
      a.deallocate(buffers[pos]);
      buffers.erase(buffers.begin()+pos);
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates until there is no more memory
//and after that tries to expand all the buffers to
//avoid the wasted internal fragmentation
template<class Allocator>
bool test_allocation_shrink_and_expand(Allocator &a)
{
   std::vector<void*> buffers;
   std::vector<std::size_t> received_sizes;
   std::vector<bool>        size_reduced;

   //Allocate buffers wand store received sizes
   for(int i = 0; true; ++i){
      std::size_t received_size;
      void *ptr = a.template allocation_command<char>
         ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, i, i*2, received_size).first;
      if(!ptr){
         ptr = a.template allocation_command<char>
            ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, 1, i*2, received_size).first;
         if(!ptr)
            break;
      }
      buffers.push_back(ptr);
      received_sizes.push_back(received_size);
   }

   //Now shrink to half
   for(int i = 0, max = (int)buffers.size()
      ; i < max
      ; ++i){
      std::size_t received_size;
      if(a.template allocation_command<char>
         ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_sizes[i]
         , i, received_size, static_cast<char*>(buffers[i])).first){
         if(received_size > std::size_t(received_sizes[i])){
            return false;
         }
         if(received_size < std::size_t(i)){
            return false;
         }
         size_reduced.push_back(received_size != received_sizes[i]);
      }
   }

   //Now try to expand to the original size
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ;++i){
      std::size_t received_size;
      std::size_t request_size = received_sizes[i];
      if(a.template allocation_command<char>
         ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, request_size
         , request_size, received_size, static_cast<char*>(buffers[i])).first){
         if(received_size != received_sizes[i]){
            return false;
         }
      }
      else{
         return false;
      }
   }
   
   //Deallocate it in non sequential order
   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      int pos = (j%4)*((int)buffers.size())/4;
      a.deallocate(buffers[pos]);
      buffers.erase(buffers.begin()+pos);
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates until there is no more memory
//and after that deallocates the odd buffers to
//make room for expansions. The expansion will probably
//success since the deallocation left room for that.
template<class Allocator>
bool test_allocation_deallocation_expand(Allocator &a)
{
   std::vector<void*> buffers;

   //Allocate buffers with extra memory
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i, std::nothrow);
      if(!ptr)
         break;
      std::size_t size = a.size(ptr);
      std::memset(ptr, 0, size);
      buffers.push_back(ptr);
   }

   //Now deallocate the half of the blocks
   //so expand maybe can merge new free blocks
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ;++i){
      if(i%2){
         a.deallocate(buffers[i]);
         buffers[i] = 0;
      }
   }

   //Now try to expand to the double of the size
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ;++i){
      //
      if(buffers[i]){
         std::size_t received_size;
         std::size_t min_size = i+1;
         std::size_t preferred_size = i*2;
         preferred_size = min_size > preferred_size ? min_size : preferred_size;

         while(a.template allocation_command<char>
            ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
            , preferred_size, received_size, static_cast<char*>(buffers[i])).first){
            //Check received size is bigger than minimum
            if(received_size < min_size){
               return false;
            }
            //Now, try to expand further
            min_size       = received_size+1;
            preferred_size = min_size*2;
         }
      }
   }
   
   //Now erase null values from the vector
   buffers.erase( std::remove(buffers.begin(), buffers.end(), static_cast<void*>(0))
                , buffers.end());

   //Deallocate it in non sequential order
   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      int pos = (j%4)*((int)buffers.size())/4;
      a.deallocate(buffers[pos]);
      buffers.erase(buffers.begin()+pos);
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates until there is no more memory
//and after that deallocates all except the last.
//If the allocation algorithm is a bottom-up algorithm
//the last buffer will be in the end of the segment.
//Then the test will start expanding backwards, until
//the buffer fills all the memory
template<class Allocator>
bool test_allocation_with_reuse(Allocator &a)
{
   //We will repeat this test for different sized elements
   for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
      std::vector<void*> buffers;

      //Allocate buffers with extra memory
      for(int i = 0; true; ++i){
         void *ptr = a.allocate(i*sizeof_object, std::nothrow);
         if(!ptr)
            break;
         std::size_t size = a.size(ptr);
         std::memset(ptr, 0, size);
         buffers.push_back(ptr);
      }
      
      //Now deallocate all except the latest
      //Now try to expand to the double of the sizeof_object
      for(int i = 0, max = (int)buffers.size() - 1
         ;i < max
         ;++i){
         a.deallocate(buffers[i]);
      }

      //Save the unique buffer and clear vector
      void *ptr = buffers.back();
      buffers.clear();

      //Now allocate with reuse
      std::size_t received_size = 0;
      for(int i = 0; true; ++i){
         std::size_t min_size = (received_size + 1);
         std::size_t prf_size = (received_size + (i+1)*2);
         std::pair<void*, bool> ret = a.raw_allocation_command
            ( boost::interprocess::expand_bwd | boost::interprocess::nothrow_allocation, min_size
            , prf_size, received_size, static_cast<char*>(ptr), sizeof_object);
         if(!ret.first)
            break;
         //If we have memory, this must be a buffer reuse
         if(!ret.second)
            return 1;
         if(received_size < min_size)
            return 1;
         ptr = ret.first;
      }
      //There is only a single block so deallocate it
      a.deallocate(ptr);
      
      if(!a.all_memory_deallocated() || !a.check_sanity())
         return false;
   }
   return true;
}


//This test allocates memory with different alignments
//and checks returned memory is aligned.
template<class Allocator>
bool test_aligned_allocation(Allocator &a)
{
   //Allocate aligned buffers in a loop
   //and then deallocate it
   bool continue_loop = true;
   for(unsigned int i = 1; continue_loop; i <<= 1){
      for(unsigned int j = 1; true; j <<= 1){
         void *ptr = a.allocate_aligned(i-1, j, std::nothrow);
         if(!ptr){
            if(j == 1)
               continue_loop = false;
            break;
         }
         
         if(((std::size_t)ptr & (j - 1)) != 0)
            return false;
         a.deallocate(ptr);
         if(!a.all_memory_deallocated() || !a.check_sanity()){
            return false;
         }
      }
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates memory with different alignments
//and checks returned memory is aligned.
template<class Allocator>
bool test_continuous_aligned_allocation(Allocator &a)
{
   std::vector<void*> buffers;
   //Allocate aligned buffers in a loop
   //and then deallocate it
   bool continue_loop = true;
   for(unsigned i = 1; continue_loop && i; i <<= 1){
      for(unsigned int j = 1; j; j <<= 1){
         for(bool any_allocated = false; 1;){
            void *ptr = a.allocate_aligned(i-1, j, std::nothrow);
            buffers.push_back(ptr);
            if(!ptr){
               if(j == 1 && !any_allocated){
                  continue_loop = false;
               }
               break;
            }
            else{
               any_allocated = true;
            }
            
            if(((std::size_t)ptr & (j - 1)) != 0)
               return false;
         }
         //Deallocate all
         for(unsigned int k = (int)buffers.size(); k--;){
            a.deallocate(buffers[k]);
         }
         buffers.clear();
         if(!a.all_memory_deallocated() && a.check_sanity())
            return false;
         if(!continue_loop)
            break;
      }
   }

   return a.all_memory_deallocated() && a.check_sanity();
}

//This test allocates memory, writes it with a non-zero value and
//tests zero_free_memory initializes to zero for the next allocation
template<class Allocator>
bool test_clear_free_memory(Allocator &a)
{
   std::vector<void*> buffers;

   //Allocate memory
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i, std::nothrow);
      if(!ptr)
         break;
      std::size_t size = a.size(ptr);
      std::memset(ptr, 1, size);
      buffers.push_back(ptr);
   }

   //Mark it
   for(int i = 0, max = buffers.size(); i < max; ++i){
      std::memset(buffers[i], 1, i);
   }

   //Deallocate all
   for(int j = (int)buffers.size()
      ;j--
      ;){
      a.deallocate(buffers[j]);
   }
   buffers.clear();

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   //Now clear all free memory
   a.zero_free_memory();

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   //Now test all allocated memory is zero
   //Allocate memory
   const char *first_addr = 0;
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i, std::nothrow);
      if(!ptr)
         break;
      if(i == 0){
         first_addr = (char*)ptr;
      }
      std::size_t memsize = a.size(ptr);
      buffers.push_back(ptr);

      for(int j = 0; j < (int)memsize; ++j){
         if(static_cast<char*>((char*)ptr)[j]){
            std::cout << "Zero memory test failed. in buffer " << i
                      << " byte " << j << " first address " << (void*) first_addr << " offset " << ((char*)ptr+j) - (char*)first_addr << " memsize: " << memsize << std::endl;
            return false;
         }
      }
   }

   //Deallocate all
   for(int j = (int)buffers.size()
      ;j--
      ;){
      a.deallocate(buffers[j]);
   }
   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   return true;
}


//This test uses tests grow and shrink_to_fit functions
template<class Allocator>
bool test_grow_shrink_to_fit(Allocator &a)
{
   std::vector<void*> buffers;

   std::size_t original_size = a.get_size();
   std::size_t original_free = a.get_free_memory();

   a.shrink_to_fit();

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   std::size_t shrunk_size          = a.get_size();
   std::size_t shrunk_free_memory   = a.get_free_memory();
   if(shrunk_size != a.get_min_size())
      return 1;

   a.grow(original_size - shrunk_size);

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   if(original_size != a.get_size())
      return false;
   if(original_free != a.get_free_memory())
      return false;

   //Allocate memory
   for(int i = 0; true; ++i){
      void *ptr = a.allocate(i, std::nothrow);
      if(!ptr)
         break;
      std::size_t size = a.size(ptr);
      std::memset(ptr, 0, size);
      buffers.push_back(ptr);
   }

   //Now deallocate the half of the blocks
   //so expand maybe can merge new free blocks
   for(int i = 0, max = (int)buffers.size()
      ;i < max
      ;++i){
      if(i%2){
         a.deallocate(buffers[i]);
         buffers[i] = 0;
      }
   }

   //Deallocate the rest of the blocks

   //Deallocate it in non sequential order
   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      int pos = (j%5)*((int)buffers.size())/4;
      if(pos == int(buffers.size()))
         --pos;
      a.deallocate(buffers[pos]);
      buffers.erase(buffers.begin()+pos);
      std::size_t old_free = a.get_free_memory();
      a.shrink_to_fit();
      if(!a.check_sanity())   return false;
      if(original_size < a.get_size())    return false;
      if(old_free < a.get_free_memory())  return false;

      a.grow(original_size - a.get_size());

      if(!a.check_sanity())   return false;
      if(original_size != a.get_size())         return false;
      if(old_free      != a.get_free_memory())  return false;
   }

   //Now shrink it to the maximum
   a.shrink_to_fit();

   if(a.get_size() != a.get_min_size())
      return 1;

   if(shrunk_free_memory != a.get_free_memory())
      return 1;

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;

   a.grow(original_size - shrunk_size);

   if(original_size != a.get_size())
      return false;
   if(original_free != a.get_free_memory())
      return false;

   if(!a.all_memory_deallocated() && a.check_sanity())
      return false;
   return true;
}

//This test allocates multiple values until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_many_equal_allocation(Allocator &a)
{
   for( deallocation_type t = DirectDeallocation
      ; t != EndDeallocationType
      ; t = (deallocation_type)((int)t + 1)){
      std::size_t free_memory = a.get_free_memory();

      std::vector<void*> buffers2;

      //Allocate buffers with extra memory
      for(int i = 0; true; ++i){
         void *ptr = a.allocate(i, std::nothrow);
         if(!ptr)
            break;
         std::size_t size = a.size(ptr);
         std::memset(ptr, 0, size);
         if(!a.check_sanity())
            return false;
         buffers2.push_back(ptr);
      }

      //Now deallocate the half of the blocks
      //so expand maybe can merge new free blocks
      for(int i = 0, max = (int)buffers2.size()
         ;i < max
         ;++i){
         if(i%2){
            a.deallocate(buffers2[i]);
            buffers2[i] = 0;
         }
      }

      if(!a.check_sanity())
         return false;

      typedef typename Allocator::multiallocation_chain multiallocation_chain;
      std::vector<void*> buffers;
      for(int i = 0; true; ++i){
         multiallocation_chain chain(a.allocate_many(i+1, (i+1)*2, std::nothrow));
         if(chain.empty())
            break;

         std::size_t n = chain.size();
         while(!chain.empty()){
            buffers.push_back(detail::get_pointer(chain.front()));
            chain.pop_front();
         }
         if(n != std::size_t((i+1)*2))
            return false;
      }

      if(!a.check_sanity())
         return false;

      switch(t){
         case DirectDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case InverseDeallocation:
         {
            for(int j = (int)buffers.size()
               ;j--
               ;){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case MixedDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               int pos = (j%4)*((int)buffers.size())/4;
               a.deallocate(buffers[pos]);
               buffers.erase(buffers.begin()+pos);
            }
         }
         break;
         default:
         break;
      }

      //Deallocate the rest of the blocks

      //Deallocate it in non sequential order
      for(int j = 0, max = (int)buffers2.size()
         ;j < max
         ;++j){
         int pos = (j%4)*((int)buffers2.size())/4;
         a.deallocate(buffers2[pos]);
         buffers2.erase(buffers2.begin()+pos);
      }

      bool ok = free_memory == a.get_free_memory() && 
               a.all_memory_deallocated() && a.check_sanity();
      if(!ok)  return ok;
   }
   return true;
}

//This test allocates multiple values until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_many_different_allocation(Allocator &a)
{
   typedef typename Allocator::multiallocation_chain multiallocation_chain;
   const std::size_t ArraySize = 11;
   std::size_t requested_sizes[ArraySize];
   for(std::size_t i = 0; i < ArraySize; ++i){
      requested_sizes[i] = 4*i;
   }

   for( deallocation_type t = DirectDeallocation
      ; t != EndDeallocationType
      ; t = (deallocation_type)((int)t + 1)){
      std::size_t free_memory = a.get_free_memory();

      std::vector<void*> buffers2;

      //Allocate buffers with extra memory
      for(int i = 0; true; ++i){
         void *ptr = a.allocate(i, std::nothrow);
         if(!ptr)
            break;
         std::size_t size = a.size(ptr);
         std::memset(ptr, 0, size);
         buffers2.push_back(ptr);
      }

      //Now deallocate the half of the blocks
      //so expand maybe can merge new free blocks
      for(int i = 0, max = (int)buffers2.size()
         ;i < max
         ;++i){
         if(i%2){
            a.deallocate(buffers2[i]);
            buffers2[i] = 0;
         }
      }

      std::vector<void*> buffers;
      for(int i = 0; true; ++i){
         multiallocation_chain chain(a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow));
         if(chain.empty())
            break;
         std::size_t n = chain.size();
         while(!chain.empty()){
            buffers.push_back(detail::get_pointer(chain.front()));
            chain.pop_front();
         }
         if(n != ArraySize)
            return false;
      }

      switch(t){
         case DirectDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case InverseDeallocation:
         {
            for(int j = (int)buffers.size()
               ;j--
               ;){
               a.deallocate(buffers[j]);
            }
         }
         break;
         case MixedDeallocation:
         {
            for(int j = 0, max = (int)buffers.size()
               ;j < max
               ;++j){
               int pos = (j%4)*((int)buffers.size())/4;
               a.deallocate(buffers[pos]);
               buffers.erase(buffers.begin()+pos);
            }
         }
         break;
         default:
         break;
      }

      //Deallocate the rest of the blocks

      //Deallocate it in non sequential order
      for(int j = 0, max = (int)buffers2.size()
         ;j < max
         ;++j){
         int pos = (j%4)*((int)buffers2.size())/4;
         a.deallocate(buffers2[pos]);
         buffers2.erase(buffers2.begin()+pos);
      }

      bool ok = free_memory == a.get_free_memory() && 
               a.all_memory_deallocated() && a.check_sanity();
      if(!ok)  return ok;
   }
   return true;
}

//This test allocates multiple values until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_many_deallocation(Allocator &a)
{
   typedef typename Allocator::multiallocation_chain multiallocation_chain;
   const std::size_t ArraySize = 11;
   vector<multiallocation_chain> buffers;
   std::size_t requested_sizes[ArraySize];
   for(std::size_t i = 0; i < ArraySize; ++i){
      requested_sizes[i] = 4*i;
   }
   std::size_t free_memory = a.get_free_memory();

   {
      for(int i = 0; true; ++i){
         multiallocation_chain chain = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
         if(chain.empty())
            break;
         buffers.push_back(boost::interprocess::move(chain));
      }
      for(int i = 0, max = (int)buffers.size(); i != max; ++i){
         a.deallocate_many(boost::interprocess::move(buffers[i]));
      }
      buffers.clear();
      bool ok = free_memory == a.get_free_memory() && 
               a.all_memory_deallocated() && a.check_sanity();
      if(!ok)  return ok;
   }

   {
      for(int i = 0; true; ++i){
         multiallocation_chain chain(a.allocate_many(i*4, ArraySize, std::nothrow));
         if(chain.empty())
            break;
         buffers.push_back(boost::interprocess::move(chain));
      }
      for(int i = 0, max = (int)buffers.size(); i != max; ++i){
         a.deallocate_many(boost::interprocess::move(buffers[i]));
      }
      buffers.clear();

      bool ok = free_memory == a.get_free_memory() && 
               a.all_memory_deallocated() && a.check_sanity();
      if(!ok)  return ok;
   }

   return true;
}


//This function calls all tests
template<class Allocator>
bool test_all_allocation(Allocator &a)
{
   std::cout << "Starting test_allocation. Class: "
             << typeid(a).name() << std::endl;

   if(!test_allocation(a)){
      std::cout << "test_allocation_direct_deallocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_many_equal_allocation. Class: "
             << typeid(a).name() << std::endl;

   if(!test_many_equal_allocation(a)){
      std::cout << "test_many_equal_allocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_many_different_allocation. Class: "
             << typeid(a).name() << std::endl;

   if(!test_many_different_allocation(a)){
      std::cout << "test_many_different_allocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   if(!test_many_deallocation(a)){
      std::cout << "test_many_deallocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_allocation_shrink. Class: "
             << typeid(a).name() << std::endl;

   if(!test_allocation_shrink(a)){
      std::cout << "test_allocation_shrink failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   if(!test_allocation_shrink_and_expand(a)){
      std::cout << "test_allocation_shrink_and_expand failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_allocation_expand. Class: "
             << typeid(a).name() << std::endl;

   if(!test_allocation_expand(a)){
      std::cout << "test_allocation_expand failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_allocation_deallocation_expand. Class: "
             << typeid(a).name() << std::endl;

   if(!test_allocation_deallocation_expand(a)){
      std::cout << "test_allocation_deallocation_expand failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_allocation_with_reuse. Class: "
             << typeid(a).name() << std::endl;

   if(!test_allocation_with_reuse(a)){
      std::cout << "test_allocation_with_reuse failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_aligned_allocation. Class: "
             << typeid(a).name() << std::endl;

   if(!test_aligned_allocation(a)){
      std::cout << "test_aligned_allocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_continuous_aligned_allocation. Class: "
             << typeid(a).name() << std::endl;

   if(!test_continuous_aligned_allocation(a)){
      std::cout << "test_continuous_aligned_allocation failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_clear_free_memory. Class: "
             << typeid(a).name() << std::endl;

   if(!test_clear_free_memory(a)){
      std::cout << "test_clear_free_memory failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   std::cout << "Starting test_grow_shrink_to_fit. Class: "
             << typeid(a).name() << std::endl;

   if(!test_grow_shrink_to_fit(a)){
      std::cout << "test_grow_shrink_to_fit failed. Class: "
                << typeid(a).name() << std::endl;
      return false;
   }

   return true;
}

}}}   //namespace boost { namespace interprocess { namespace test {

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

#endif   //BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER

