bool test_names_and_types(ManagedMemory &m)
{
   typedef typename ManagedMemory::char_type char_type;
   typedef std::char_traits<char_type> char_traits_type;
   std::vector<char*> buffers;
   const int BufferLen = 100;
   char_type name[BufferLen];

   basic_bufferstream<char_type> formatter(name, BufferLen);

   for(int i = 0; true; ++i){
      formatter.seekp(0);
      formatter << get_prefix(char_type()) << i << std::ends;

      char *ptr = m.template construct<char>(name, std::nothrow)(i);

      if(!ptr)
         break;

      std::size_t namelen = char_traits_type::length(m.get_instance_name(ptr));
      if(namelen != char_traits_type::length(name)){
         return 1;
      }

      if(char_traits_type::compare(m.get_instance_name(ptr), name, namelen) != 0){
         return 1;
      }

      if(m.template find<char>(name).first == 0)
         return false;

      if(m.get_instance_type(ptr) != named_type)
         return false;

      buffers.push_back(ptr);
   }

   if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
      return false;

   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      m.destroy_ptr(buffers[j]);
   }

   if(m.get_num_named_objects() != 0 || !m.check_sanity())
      return false;
   m.shrink_to_fit_indexes();
   if(!m.all_memory_deallocated())
      return false;
   return true;
}
bool test_inverse_named_allocation_destruction(ManagedMemory &m)
{
   typedef typename ManagedMemory::char_type char_type;

   std::vector<char*> buffers;
   const int BufferLen = 100;
   char_type name[BufferLen];

   basic_bufferstream<char_type> formatter(name, BufferLen);

   for(unsigned int i = 0; true; ++i){
      formatter.seekp(0);
      formatter << get_prefix(char_type()) << i << std::ends;
      char *ptr = m.template construct<char>(name, std::nothrow)(i);
      if(!ptr)
         break;
      buffers.push_back(ptr);
   }

   if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
      return false;

   for(unsigned int j = 0, max = (unsigned int)buffers.size()
      ;j < max
      ;++j){
      m.destroy_ptr(buffers[j]);
   }

   if(m.get_num_named_objects() != 0 || !m.check_sanity())
      return false;
   m.shrink_to_fit_indexes();
   if(!m.all_memory_deallocated())
      return false;
   return true;
}
bool test_shrink_to_fit(ManagedMemory &m)
{
   typedef typename ManagedMemory::char_type char_type;
   typedef std::char_traits<char_type> char_traits_type;
   std::vector<char*> buffers;
   const int BufferLen = 100;
   char_type name[BufferLen];

   basic_bufferstream<char_type> formatter(name, BufferLen);

   std::size_t free_memory_before = m.get_free_memory();

   for(int i = 0; true; ++i){
      formatter.seekp(0);
      formatter << get_prefix(char_type()) << i << std::ends;

      char *ptr = m.template construct<char>(name, std::nothrow)(i);

      if(!ptr)
         break;
      buffers.push_back(ptr);
   }

   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      m.destroy_ptr(buffers[j]);
   }

   std::size_t free_memory_after = m.get_free_memory();

   if(free_memory_before != free_memory_after){
      m.shrink_to_fit_indexes();
      if(free_memory_before != free_memory_after)
         return false;
   }
   return true;
}
bool test_named_iterators(ManagedMemory &m)
{
   typedef typename ManagedMemory::char_type char_type;
   std::vector<char*> buffers;
   const int BufferLen = 100;
   char_type name[BufferLen];
   typedef std::basic_string<char_type> string_type;
   std::set<string_type> names;

   basic_bufferstream<char_type> formatter(name, BufferLen);

   string_type aux_str;

   for(int i = 0; true; ++i){
      formatter.seekp(0);
      formatter << get_prefix(char_type()) << i << std::ends;
      char *ptr = m.template construct<char>(name, std::nothrow)(i);
      if(!ptr)
         break;
      aux_str = name;
      names.insert(aux_str);
      buffers.push_back(ptr);
   }

   if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
      return false;

   typedef typename ManagedMemory::const_named_iterator const_named_iterator;
   const_named_iterator named_beg = m.named_begin();
   const_named_iterator named_end = m.named_end();

   if((std::size_t)boost::container::iterator_distance(named_beg, named_end) != (std::size_t)buffers.size()){
      return 1;
   }

   for(; named_beg != named_end; ++named_beg){
      const char_type *name_str = named_beg->name();
      aux_str = name_str;
      if(names.find(aux_str) == names.end()){
         return 1;
      }

      if(aux_str.size() != named_beg->name_length()){
         return 1;
      }

      const void *found_value = m.template find<char>(name_str).first;

      if(found_value == 0)
         return false;
      if(found_value != named_beg->value())
         return false;
   }

   for(int j = 0, max = (int)buffers.size()
      ;j < max
      ;++j){
      m.destroy_ptr(buffers[j]);
   }

   if(m.get_num_named_objects() != 0 || !m.check_sanity())
      return false;
   m.shrink_to_fit_indexes();
   if(!m.all_memory_deallocated())
      return false;
   return true;
}