Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: // Chris@102: // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // See http://www.boost.org/libs/container for documentation. Chris@102: // Chris@102: ////////////////////////////////////////////////////////////////////////////// Chris@102: #ifndef BOOST_CONTAINER_ALLOC_LIB_EXT_H Chris@102: #define BOOST_CONTAINER_ALLOC_LIB_EXT_H Chris@102: Chris@102: #include Chris@102: Chris@102: #ifdef _MSC_VER Chris@102: #pragma warning (push) Chris@102: #pragma warning (disable : 4127) Chris@102: Chris@102: /* Chris@102: we need to import/export our code only if the user has specifically Chris@102: asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost Chris@102: libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK Chris@102: if they want just this one to be dynamically liked: Chris@102: */ Chris@102: #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK) Chris@102: Chris@102: /* export if this is our own source, otherwise import: */ Chris@102: #ifdef BOOST_CONTAINER_SOURCE Chris@102: # define BOOST_CONTAINER_DECL __declspec(dllexport) Chris@102: #else Chris@102: # define BOOST_CONTAINER_DECL __declspec(dllimport) Chris@102: #endif /* BOOST_CONTAINER_SOURCE */ Chris@102: #endif /* DYN_LINK */ Chris@102: #endif /* _MSC_VER */ Chris@102: Chris@102: /* if BOOST_CONTAINER_DECL isn't defined yet define it now: */ Chris@102: #ifndef BOOST_CONTAINER_DECL Chris@102: #define BOOST_CONTAINER_DECL Chris@102: #endif Chris@102: Chris@102: #ifdef __cplusplus Chris@102: extern "C" { Chris@102: #endif Chris@102: Chris@102: /*!An forward iterator to traverse the elements of a memory chain container.*/ Chris@102: typedef struct multialloc_node_impl Chris@102: { Chris@102: struct multialloc_node_impl *next_node_ptr; Chris@102: } boost_cont_memchain_node; Chris@102: Chris@102: Chris@102: /*!An forward iterator to traverse the elements of a memory chain container.*/ Chris@102: typedef struct multialloc_it_impl Chris@102: { Chris@102: boost_cont_memchain_node *node_ptr; Chris@102: } boost_cont_memchain_it; Chris@102: Chris@102: /*!Memory chain: A container holding memory portions allocated by boost_cont_multialloc_nodes Chris@102: and boost_cont_multialloc_arrays functions.*/ Chris@102: typedef struct boost_cont_memchain_impl Chris@102: { Chris@102: size_t num_mem; Chris@102: boost_cont_memchain_node root_node; Chris@102: boost_cont_memchain_node *last_node_ptr; Chris@102: } boost_cont_memchain; Chris@102: Chris@102: /*!Advances the iterator one position so that it points to the next element in the memory chain*/ Chris@102: #define BOOST_CONTAINER_MEMIT_NEXT(IT) (IT.node_ptr = IT.node_ptr->next_node_ptr) Chris@102: Chris@102: /*!Returns the address of the memory chain currently pointed by the iterator*/ Chris@102: #define BOOST_CONTAINER_MEMIT_ADDR(IT) ((void*)IT.node_ptr) Chris@102: Chris@102: /*!Initializer for an iterator pointing to the position before the first element*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_BEFORE_BEGIN_IT(PMEMCHAIN) { &((PMEMCHAIN)->root_node) } Chris@102: Chris@102: /*!Initializer for an iterator pointing to the first element*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(PMEMCHAIN) {(PMEMCHAIN)->root_node.next_node_ptr } Chris@102: Chris@102: /*!Initializer for an iterator pointing to the last element*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_LAST_IT(PMEMCHAIN) {(PMEMCHAIN)->last_node_ptr } Chris@102: Chris@102: /*!Initializer for an iterator pointing to one past the last element (end iterator)*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_END_IT(PMEMCHAIN) {(boost_cont_memchain_node *)0 } Chris@102: Chris@102: /*!True if IT is the end iterator, false otherwise*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_IS_END_IT(PMEMCHAIN, IT) (!(IT).node_ptr) Chris@102: Chris@102: /*!The address of the first memory portion hold by the memory chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(PMEMCHAIN)((void*)((PMEMCHAIN)->root_node.next_node_ptr)) Chris@102: Chris@102: /*!The address of the last memory portion hold by the memory chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_LASTMEM(PMEMCHAIN) ((void*)((PMEMCHAIN)->last_node_ptr)) Chris@102: Chris@102: /*!The number of memory portions hold by the memory chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_SIZE(PMEMCHAIN) ((PMEMCHAIN)->num_mem) Chris@102: Chris@102: /*!Initializes the memory chain from the first memory portion, the last memory Chris@102: portion and number of portions obtained from another memory chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_INIT_FROM(PMEMCHAIN, FIRST, LAST, NUM)\ Chris@102: (PMEMCHAIN)->last_node_ptr = (boost_cont_memchain_node *)(LAST), \ Chris@102: (PMEMCHAIN)->root_node.next_node_ptr = (boost_cont_memchain_node *)(FIRST), \ Chris@102: (PMEMCHAIN)->num_mem = (NUM);\ Chris@102: /**/ Chris@102: Chris@102: /*!Default initializes a memory chain. Postconditions: begin iterator is end iterator, Chris@102: the number of portions is zero.*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_INIT(PMEMCHAIN)\ Chris@102: ((PMEMCHAIN)->root_node.next_node_ptr = 0, (PMEMCHAIN)->last_node_ptr = &((PMEMCHAIN)->root_node), (PMEMCHAIN)->num_mem = 0)\ Chris@102: /**/ Chris@102: Chris@102: /*!True if the memory chain is empty (holds no memory portions*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_EMPTY(PMEMCHAIN)\ Chris@102: ((PMEMCHAIN)->num_mem == 0)\ Chris@102: /**/ Chris@102: Chris@102: /*!Inserts a new memory portions in the front of the chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(PMEMCHAIN, MEM)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\ Chris@102: ____chain____->last_node_ptr->next_node_ptr = ____tmp_mem____;\ Chris@102: ____tmp_mem____->next_node_ptr = 0;\ Chris@102: ____chain____->last_node_ptr = ____tmp_mem____;\ Chris@102: ++____chain____->num_mem;\ Chris@102: }while(0)\ Chris@102: /**/ Chris@102: Chris@102: /*!Inserts a new memory portions in the back of the chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_PUSH_FRONT(PMEMCHAIN, MEM)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\ Chris@102: boost_cont_memchain *____root____ = &((PMEMCHAIN)->root_node);\ Chris@102: if(!____chain____->root_node.next_node_ptr){\ Chris@102: ____chain____->last_node_ptr = ____tmp_mem____;\ Chris@102: }\ Chris@102: boost_cont_memchain_node *____old_first____ = ____root____->next_node_ptr;\ Chris@102: ____tmp_mem____->next_node_ptr = ____old_first____;\ Chris@102: ____root____->next_node_ptr = ____tmp_mem____;\ Chris@102: ++____chain____->num_mem;\ Chris@102: }while(0)\ Chris@102: /**/ Chris@102: Chris@102: /*!Erases the memory portion after the portion pointed by BEFORE_IT from the memory chain*/ Chris@102: /*!Precondition: BEFORE_IT must be a valid iterator of the memory chain and it can't be the end iterator*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_ERASE_AFTER(PMEMCHAIN, BEFORE_IT)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain_node *____prev_node____ = (BEFORE_IT).node_ptr;\ Chris@102: boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\ Chris@102: if(____chain____->last_node_ptr == ____erase_node____){\ Chris@102: ____chain____->last_node_ptr = &____chain____->root_node;\ Chris@102: }\ Chris@102: ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\ Chris@102: --____chain____->num_mem;\ Chris@102: }while(0)\ Chris@102: /**/ Chris@102: Chris@102: /*!Erases the first portion from the memory chain. Chris@102: Precondition: the memory chain must not be empty*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_POP_FRONT(PMEMCHAIN)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain_node *____prev_node____ = &____chain____->root_node;\ Chris@102: boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\ Chris@102: if(____chain____->last_node_ptr == ____erase_node____){\ Chris@102: ____chain____->last_node_ptr = &____chain____->root_node;\ Chris@102: }\ Chris@102: ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\ Chris@102: --____chain____->num_mem;\ Chris@102: }while(0)\ Chris@102: /**/ Chris@102: Chris@102: /*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/ Chris@102: /* Chris@102: #define BOOST_CONTAINER_MEMCHAIN_SPLICE_BACK(PMEMCHAIN, PMEMCHAIN2)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain *____chain2____ = (PMEMCHAIN2);\ Chris@102: if(!____chain2____->root_node.next_node_ptr){\ Chris@102: break;\ Chris@102: }\ Chris@102: else if(!____chain____->first_mem){\ Chris@102: ____chain____->first_mem = ____chain2____->first_mem;\ Chris@102: ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\ Chris@102: ____chain____->num_mem = ____chain2____->num_mem;\ Chris@102: BOOST_CONTAINER_MEMCHAIN_INIT(*____chain2____);\ Chris@102: }\ Chris@102: else{\ Chris@102: ____chain____->last_node_ptr->next_node_ptr = ____chain2____->first_mem;\ Chris@102: ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\ Chris@102: ____chain____->num_mem += ____chain2____->num_mem;\ Chris@102: }\ Chris@102: }while(0)\*/ Chris@102: /**/ Chris@102: Chris@102: /*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/ Chris@102: #define BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(PMEMCHAIN, BEFORE_IT, FIRST, BEFORELAST, NUM)\ Chris@102: do{\ Chris@102: boost_cont_memchain *____chain____ = (PMEMCHAIN);\ Chris@102: boost_cont_memchain_node *____pnode____ = (BEFORE_IT).node_ptr;\ Chris@102: boost_cont_memchain_node *____next____ = ____pnode____->next_node_ptr;\ Chris@102: boost_cont_memchain_node *____first____ = (boost_cont_memchain_node *)(FIRST);\ Chris@102: boost_cont_memchain_node *____blast____ = (boost_cont_memchain_node *)(BEFORELAST);\ Chris@102: size_t ____num____ = (NUM);\ Chris@102: if(!____num____){\ Chris@102: break;\ Chris@102: }\ Chris@102: if(____pnode____ == ____chain____->last_node_ptr){\ Chris@102: ____chain____->last_node_ptr = ____blast____;\ Chris@102: }\ Chris@102: ____pnode____->next_node_ptr = ____first____;\ Chris@102: ____blast____->next_node_ptr = ____next____;\ Chris@102: ____chain____->num_mem += ____num____;\ Chris@102: }while(0)\ Chris@102: /**/ Chris@102: Chris@102: BOOST_CONTAINER_DECL size_t boost_cont_size(const void *p); Chris@102: Chris@102: BOOST_CONTAINER_DECL void* boost_cont_malloc(size_t bytes); Chris@102: Chris@102: BOOST_CONTAINER_DECL void boost_cont_free(void* mem); Chris@102: Chris@102: BOOST_CONTAINER_DECL void* boost_cont_memalign(size_t bytes, size_t alignment); Chris@102: Chris@102: /*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays Chris@102: must be contiguous.*/ Chris@102: #define DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1)) Chris@102: Chris@102: /*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays Chris@102: should be selected by those functions.*/ Chris@102: #define DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0)) Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_multialloc_nodes Chris@102: (size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_multialloc_arrays Chris@102: (size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain); Chris@102: Chris@102: BOOST_CONTAINER_DECL void boost_cont_multidealloc(boost_cont_memchain *pchain); Chris@102: Chris@102: BOOST_CONTAINER_DECL size_t boost_cont_footprint(); Chris@102: Chris@102: BOOST_CONTAINER_DECL size_t boost_cont_allocated_memory(); Chris@102: Chris@102: BOOST_CONTAINER_DECL size_t boost_cont_chunksize(const void *p); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_all_deallocated(); Chris@102: Chris@102: typedef struct boost_cont_malloc_stats_impl Chris@102: { Chris@102: size_t max_system_bytes; Chris@102: size_t system_bytes; Chris@102: size_t in_use_bytes; Chris@102: } boost_cont_malloc_stats_t; Chris@102: Chris@102: BOOST_CONTAINER_DECL boost_cont_malloc_stats_t boost_cont_malloc_stats(); Chris@102: Chris@102: BOOST_CONTAINER_DECL size_t boost_cont_in_use_memory(); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_trim(size_t pad); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_mallopt Chris@102: (int parameter_number, int parameter_value); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_grow Chris@102: (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_shrink Chris@102: (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit); Chris@102: Chris@102: BOOST_CONTAINER_DECL void* boost_cont_alloc Chris@102: (size_t minbytes, size_t preferred_bytes, size_t *received_bytes); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_malloc_check(); Chris@102: Chris@102: typedef unsigned int allocation_type; Chris@102: Chris@102: enum Chris@102: { Chris@102: // constants for allocation commands Chris@102: BOOST_CONTAINER_ALLOCATE_NEW = 0X01, Chris@102: BOOST_CONTAINER_EXPAND_FWD = 0X02, Chris@102: BOOST_CONTAINER_EXPAND_BWD = 0X04, Chris@102: BOOST_CONTAINER_SHRINK_IN_PLACE = 0X08, Chris@102: BOOST_CONTAINER_NOTHROW_ALLOCATION = 0X10, Chris@102: // BOOST_CONTAINER_ZERO_MEMORY = 0X20, Chris@102: BOOST_CONTAINER_TRY_SHRINK_IN_PLACE = 0X40, Chris@102: BOOST_CONTAINER_EXPAND_BOTH = BOOST_CONTAINER_EXPAND_FWD | BOOST_CONTAINER_EXPAND_BWD, Chris@102: BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH Chris@102: }; Chris@102: Chris@102: //#define BOOST_CONTAINERDLMALLOC__FOOTERS Chris@102: #ifndef BOOST_CONTAINERDLMALLOC__FOOTERS Chris@102: enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) }; Chris@102: #else Chris@102: enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 }; Chris@102: #endif Chris@102: Chris@102: typedef struct boost_cont_command_ret_impl Chris@102: { Chris@102: void *first; Chris@102: int second; Chris@102: }boost_cont_command_ret_t; Chris@102: Chris@102: BOOST_CONTAINER_DECL boost_cont_command_ret_t boost_cont_allocation_command Chris@102: ( allocation_type command Chris@102: , size_t sizeof_object Chris@102: , size_t limit_objects Chris@102: , size_t preferred_objects Chris@102: , size_t *received_objects Chris@102: , void *reuse_ptr Chris@102: ); Chris@102: Chris@102: BOOST_CONTAINER_DECL int boost_cont_mallopt(int param_number, int value); Chris@102: Chris@102: #ifdef __cplusplus Chris@102: } //extern "C" { Chris@102: #endif Chris@102: Chris@102: #ifdef _MSC_VER Chris@102: #pragma warning (pop) Chris@102: #endif Chris@102: Chris@102: Chris@102: #endif //#define BOOST_CONTAINERDLMALLOC__EXT_H