<commit_before>
#pragma once

#include <cassert>
#include <cstddef> // For std::size_t.

	#include <iostream>
#ifdef MEMWA_DEBUGGING_ALLOCATORS
#endif

#include <algorithm>
#include <vector>

namespace memwa
{
//namespace impl
//{
	class LinearBlock;
	class StackBlock;
	class PoolBlock;
	class ListBlock;
	class TinyBlock;
//};

// ----------------------------------------------------------------------------

template < class BlockType >
struct BlockInfo
{

	typedef std::vector< BlockType > Blocks;
	typedef typename Blocks::iterator BlocksIter;
	typedef typename Blocks::const_iterator BlocksCIter;

//	typedef typename BlockInfo< BlockType > MyType;

	BlockInfo( unsigned int initialBlocks, std::size_t blockSize, std::size_t alignment ) :
		blockSize_( blockSize ),
		alignment_( alignment ),
		blocks_(),
		recent_()
	{
		try
		{
			blocks_.reserve( initialBlocks );
			for ( unsigned int ii = 0; ii < initialBlocks; ++ii )
			{
				BlockType block( blockSize_, alignment_ );
				blocks_.push_back( block );
			}
			if ( initialBlocks != 1 )
			{
				std::sort( blocks_.begin(), blocks_.end() );
			}
			recent_ = blocks_.begin();
		}
		catch ( ... )
		{
			Destroy();
			throw std::bad_alloc();
		}
	}

	/// This constructor is used by PoolAllocator and TinyBlockAllocator.
	BlockInfo( unsigned int initialBlocks, std::size_t blockSize, std::size_t objectSize, std::size_t alignment ) :
		blockSize_( blockSize ),
		alignment_( alignment ),
		blocks_(),
		recent_()
	{
//	    std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
		const unsigned int objectsPerPool = blockSize / objectSize;
		try
		{
			blocks_.reserve( initialBlocks );
			for ( unsigned int ii = 0; ii < initialBlocks; ++ii )
			{
				BlockType block( blockSize_, objectSize, alignment, objectsPerPool );
				blocks_.push_back( block );
			}
			if ( initialBlocks != 1 )
			{
				std::sort( blocks_.begin(), blocks_.end() );
			}
			recent_ = blocks_.begin();
//	    	std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
		}
		catch ( ... )
		{
			Destroy();
			throw std::bad_alloc();
		}
//	    std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
	}

	~BlockInfo()
	{
	}

	void Destroy()
	{
		const BlocksIter end( blocks_.end() );
		for ( BlocksIter it( blocks_.begin() ); it != end; ++it )
		{
			BlockType & block = *it;
			block.Destroy();
		}
		blocks_.clear();
	}

	void * Allocate( std::size_t size, const void * hint )
	{
		if ( blockSize_ < size )
		{
			throw std::bad_alloc();
		}

		BlocksIter end( blocks_.end() );
		// Check hint first.
		if ( nullptr != hint )
		{
			BlocksIter it = GetBlock( hint );
			if ( it != end )
			{
				BlockType & block = *it;
				void * p = block.Allocate( size, blockSize_, alignment_ );
				if ( nullptr != p )
				{
					return p;
					recent_ = it;
				}
			}
		}

		// Check most recently used block next.<commit_msg>Fixed bug.<commit_after>
#pragma once

#include <cassert>
#include <cstddef> // For std::size_t.

	#include <iostream>
#ifdef MEMWA_DEBUGGING_ALLOCATORS
#endif

#include <algorithm>
#include <vector>

namespace memwa
{
//namespace impl
//{
	class LinearBlock;
	class StackBlock;
	class PoolBlock;
	class ListBlock;
	class TinyBlock;
//};

// ----------------------------------------------------------------------------

template < class BlockType >
struct BlockInfo
{

	typedef std::vector< BlockType > Blocks;
	typedef typename Blocks::iterator BlocksIter;
	typedef typename Blocks::const_iterator BlocksCIter;

//	typedef typename BlockInfo< BlockType > MyType;

	BlockInfo( unsigned int initialBlocks, std::size_t blockSize, std::size_t alignment ) :
		blockSize_( blockSize ),
		alignment_( alignment ),
		blocks_(),
		recent_()
	{
		try
		{
			blocks_.reserve( initialBlocks );
			for ( unsigned int ii = 0; ii < initialBlocks; ++ii )
			{
				BlockType block( blockSize_, alignment_ );
				blocks_.push_back( block );
			}
			if ( initialBlocks != 1 )
			{
				std::sort( blocks_.begin(), blocks_.end() );
			}
			recent_ = blocks_.begin();
		}
		catch ( ... )
		{
			Destroy();
			throw std::bad_alloc();
		}
	}

	/// This constructor is used by PoolAllocator and TinyBlockAllocator.
	BlockInfo( unsigned int initialBlocks, std::size_t blockSize, std::size_t objectSize, std::size_t alignment ) :
		blockSize_( blockSize ),
		alignment_( alignment ),
		blocks_(),
		recent_()
	{
//	    std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
		const unsigned int objectsPerPool = blockSize / objectSize;
		try
		{
			blocks_.reserve( initialBlocks );
			for ( unsigned int ii = 0; ii < initialBlocks; ++ii )
			{
				BlockType block( blockSize_, objectSize, alignment, objectsPerPool );
				blocks_.push_back( block );
			}
			if ( initialBlocks != 1 )
			{
				std::sort( blocks_.begin(), blocks_.end() );
			}
			recent_ = blocks_.begin();
//	    	std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
		}
		catch ( ... )
		{
			Destroy();
			throw std::bad_alloc();
		}
//	    std::cout << __FUNCTION__ << " : " << __LINE__ << std::endl;
	}

	~BlockInfo()
	{
	}

	void Destroy()
	{
		const BlocksIter end( blocks_.end() );
		for ( BlocksIter it( blocks_.begin() ); it != end; ++it )
		{
			BlockType & block = *it;
			block.Destroy();
		}
		blocks_.clear();
	}

	void * Allocate( std::size_t size, const void * hint )
	{
		if ( blockSize_ < size )
		{
			throw std::bad_alloc();
		}

		BlocksIter end( blocks_.end() );
		// Check hint first.
		if ( nullptr != hint )
		{
			BlocksIter it = GetBlock( hint );
			if ( it != end )
			{
				BlockType & block = *it;
				void * p = block.Allocate( size, blockSize_, alignment_ );
				if ( nullptr != p )
				{
					recent_ = it;
					return p;
				}
			}
		}

		// Check most recently used block next.
{'fraction_non_alphanumeric': 0.16779926816518556, 'fraction_numerical': 0.0013939710751001916, 'mean_word_length': 2.7296946068875894, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7110663', 'n_tokens_mistral': 2205, 'n_tokens_neox': 1876, 'n_words': 478}