enhanced qse_fma_h to have more consistency with qse_xma_h
This commit is contained in:
parent
530ab74909
commit
810134f0ea
@ -22,20 +22,21 @@
|
||||
#define _QSE_CMN_FMA_H_
|
||||
|
||||
/** @file
|
||||
* This file defines a fixed-size block memory allocator. As the block size
|
||||
* is known in advance, it achieves block allocation with little overhead.
|
||||
* This file defines a fixed-size block memory allocator.
|
||||
* As the block size is known in advance, it achieves block allocation
|
||||
* with little overhead.
|
||||
*
|
||||
* <pre>
|
||||
* chunk head(cnkhead)
|
||||
* | chunk
|
||||
* |
|
||||
* | +---------------------------------------------+
|
||||
* +--> | | f1 | f2 | | |
|
||||
* +--> | | f1 | f2 | | | chunk #2
|
||||
* +--|---------^------|----^--------------------+
|
||||
* | | | |
|
||||
* | +------+ +---+ +--------------+ chunk
|
||||
* | +------+ +---+ +--------------+
|
||||
* | | | |
|
||||
* | +-----------------|----V--------------|-------+
|
||||
* +---> | | | f3 | | f4 |
|
||||
* +---> | | | f3 | | f4 | chunk #1
|
||||
* +---------------------------------------^-----+
|
||||
* |
|
||||
* free block head (freeblk)
|
||||
@ -44,8 +45,122 @@
|
||||
* The diagram above assumes that f1, f2, f3, and f4 are free blocks.
|
||||
* The chaining order depends on the allocation and deallocation order.
|
||||
*
|
||||
* See #qse_fma_t for more information. Use #qse_xma_t for variable-size block
|
||||
* allocation.
|
||||
* See an example below. Note that it omits error handling.
|
||||
*
|
||||
* @code
|
||||
* #include <qse/cmn/fma.h>
|
||||
* int main ()
|
||||
* {
|
||||
* qse_fma_t* fma;
|
||||
* int* ptr1, * ptr2;
|
||||
*
|
||||
* // create a memory allocator for integer blocks up to 50.
|
||||
* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
|
||||
*
|
||||
* // allocate two integer blocks
|
||||
* ptr1 = (int*) qse_fma_alloc (fma, sizeof(int));
|
||||
* ptr2 = (int*) qse_fma_alloc (fma, sizeof(int));
|
||||
*
|
||||
* *ptr1 = 20; *ptr2 = 99;
|
||||
*
|
||||
* // free the two blocks.
|
||||
* qse_fma_free (fma, ptr1);
|
||||
* qse_fma_free (fma, ptr2);
|
||||
*
|
||||
* // destroy the memory allocator
|
||||
* qse_fma_close (fma);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* The following example shows how to use the fixed-size block
|
||||
* allocator for a dynamic data structure allocating fixed-size nodes.
|
||||
*
|
||||
* @code
|
||||
* #include <qse/cmn/fma.h>
|
||||
* #include <qse/cmn/rbt.h>
|
||||
* #include <qse/cmn/mem.h>
|
||||
* #include <qse/cmn/stdio.h>
|
||||
*
|
||||
* static qse_rbt_walk_t walk (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx)
|
||||
* {
|
||||
* qse_printf (QSE_T("key = %lld, value = %lld\n"),
|
||||
* *(long*)QSE_RBT_KPTR(pair), *(long*)QSE_RBT_VPTR(pair));
|
||||
* return QSE_RBT_WALK_FORWARD;
|
||||
* }
|
||||
*
|
||||
* int main ()
|
||||
* {
|
||||
* qse_fma_t* fma;
|
||||
* qse_rbt_t rbt;
|
||||
* qse_size_t blksize;
|
||||
* long x;
|
||||
*
|
||||
* // prepare the fixed-size block allocator into the qse_mmgr_t interface
|
||||
* qse_mmgr_t mmgr =
|
||||
* {
|
||||
* (qse_mmgr_alloc_t) qse_fma_alloc,
|
||||
* (qse_mmgr_realloc_t) qse_fma_realloc,
|
||||
* (qse_mmgr_free_t) qse_fma_free,
|
||||
* QSE_NULL
|
||||
* };
|
||||
*
|
||||
* // the block size of a red-black tree is fixed to be:
|
||||
* // key size + value size + internal node size.
|
||||
* blksize = sizeof(long) + sizeof(long) + sizeof(qse_rbt_pair_t);
|
||||
*
|
||||
* // create a fixed-size block allocator which is created
|
||||
* // with the default memory allocator.
|
||||
* fma = qse_fma_open (QSE_MMGR_GETDFL(), 0, blksize, 10, 0);
|
||||
* if (fma == QSE_NULL)
|
||||
* {
|
||||
* qse_printf (QSE_T("cannot open a memory allocator\n"));
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* // complete the qse_mmgr_t interface by providing the allocator.
|
||||
* mmgr.udd = fma;
|
||||
*
|
||||
* // initializes the statically declared red-black tree.
|
||||
* // can not call qse_rbt_open() which allocates the qse_rbt_t object.
|
||||
* // as its size differs from the block size calculated above.
|
||||
* if (qse_rbt_init (&rbt, &mmgr) == QSE_NULL)
|
||||
* {
|
||||
* qse_printf (QSE_T("cannot initialize a tree\n"));
|
||||
* qse_fma_close (fma);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* // perform more initializations for keys and values.
|
||||
* qse_rbt_setcopier (&rbt, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE);
|
||||
* qse_rbt_setcopier (&rbt, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE);
|
||||
* qse_rbt_setscale (&rbt, QSE_RBT_KEY, QSE_SIZEOF(long));
|
||||
* qse_rbt_setscale (&rbt, QSE_RBT_VAL, QSE_SIZEOF(long));
|
||||
*
|
||||
* // insert numbers into the red-black tree
|
||||
* for (x = 10; x < 100; x++)
|
||||
* {
|
||||
* long y = x * x;
|
||||
* if (qse_rbt_insert (&rbt, &x, 1, &y, 1) == QSE_NULL)
|
||||
* {
|
||||
* qse_printf (QSE_T("failed to insert. out of memory\n"));
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // print the tree contents
|
||||
* qse_rbt_walk (&rbt, walk, QSE_NULL);
|
||||
*
|
||||
* // finalize the tree.
|
||||
* qse_rbt_fini (&rbt);
|
||||
*
|
||||
* // destroy the memory allocator.
|
||||
* qse_fma_close (fma);
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Use #qse_xma_t for variable-size block allocation.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
@ -73,27 +188,6 @@ struct qse_fma_blk_t
|
||||
|
||||
/** @struct qse_fma_t
|
||||
* The qse_fma_t type defines a fixed-size block memory allocator.
|
||||
* See the example below. Note that it omits error handling.
|
||||
* @code
|
||||
* qse_fma_t* fma;
|
||||
* int* ptr1, * ptr2;
|
||||
*
|
||||
* // create a memory allocator for integer blocks up to 50.
|
||||
* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
|
||||
*
|
||||
* // allocate two integer blocks
|
||||
* ptr1 = (int*) qse_fma_alloc (fma);
|
||||
* ptr2 = (int*) qse_fma_alloc (fma);
|
||||
*
|
||||
* *ptr1 = 20; *ptr2 = 99;
|
||||
*
|
||||
* // free the two blocks.
|
||||
* qse_fma_free (fma, ptr1);
|
||||
* qse_fma_free (fma, ptr2);
|
||||
*
|
||||
* // destroy the memory allocator
|
||||
* qse_fma_close (fma);
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct qse_fma_t qse_fma_t;
|
||||
struct qse_fma_t
|
||||
@ -122,9 +216,9 @@ QSE_DEFINE_COMMON_FUNCTIONS (fma)
|
||||
qse_fma_t* qse_fma_open (
|
||||
qse_mmgr_t* mmgr, /**< outer memory manager */
|
||||
qse_size_t xtnsize, /**< extension size in bytes */
|
||||
qse_size_t blksize, /**< block size in bytes */
|
||||
qse_size_t blksize, /**< fixed block size in bytes */
|
||||
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
|
||||
qse_size_t maxcnks /**< maximum numbers of chunks */
|
||||
qse_size_t maxcnks /**< maximum numbers of chunks. 0 for no limit */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -135,14 +229,15 @@ void qse_fma_close (
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_fma_init() function initializes an memory allocator.
|
||||
* The qse_fma_init() function initializes an memory allocator statically
|
||||
* declared.
|
||||
*/
|
||||
qse_fma_t* qse_fma_init (
|
||||
qse_fma_t* fma, /**< memory allocator */
|
||||
qse_mmgr_t* mmgr, /**< outer memory manager */
|
||||
qse_size_t blksize, /**< block size in bytes */
|
||||
qse_size_t blksize, /**< fixed block size in bytes */
|
||||
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
|
||||
qse_size_t maxcnks /**< maximum numbers of chunks */
|
||||
qse_size_t maxcnks /**< maximum numbers of chunks. 0 for no limit */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -153,15 +248,41 @@ void qse_fma_fini (
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_fma_alloc() function allocates a block.
|
||||
* @return block pointer on success, QSE_NULL on failure
|
||||
* The qse_fma_alloc() function allocates a block of the fixed block size
|
||||
* specified during initialization regardless of the block size @a size
|
||||
* requested so long as it is not greater than the fixed size. The function
|
||||
* fails if it is greater.
|
||||
*
|
||||
* @return block pointer on success, #QSE_NULL on failure
|
||||
*/
|
||||
void* qse_fma_alloc (
|
||||
qse_fma_t* fma /**< memory allocator */
|
||||
qse_fma_t* fma, /**< memory allocator */
|
||||
qse_size_t size /**< block size in bytes*/
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_fma_alloc() function deallocates a block.
|
||||
* The qse_fma_realloc() function is provided for consistency with other
|
||||
* generic memory allocator which provides a reallocation function.
|
||||
* Block resizing is meaningless for #qse_fma_t as it deals with fixed-size
|
||||
* blocks.
|
||||
*
|
||||
* If the @a size requested is greater than the fixed block size of the memory
|
||||
* allocator @a fma, the function fails; If the block @a blk is #QSE_NULL and
|
||||
* the @a size requested is not greater than the fixed block size of the memory
|
||||
* allocator @a fma, it allocates a block of the fixed size; If the block
|
||||
* @a blk is not #QSE_NULL and the @a size requested is not greater than the
|
||||
* fixed block size of the memory allocator @a fma, it returns the block @blk.
|
||||
*
|
||||
* @return block pointer on success, #QSE_NULL on failure
|
||||
*/
|
||||
void* qse_fma_realloc (
|
||||
qse_fma_t* fma, /**< memory allocator */
|
||||
void* blk, /**< memory block */
|
||||
qse_size_t size /**< block size in bytes*/
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_fma_free() function deallocates a block.
|
||||
*/
|
||||
void qse_fma_free (
|
||||
qse_fma_t* fma, /**< memory allocator */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: mem.h 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: mem.h 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -21,13 +21,21 @@
|
||||
#ifndef _QSE_CMN_MEM_H_
|
||||
#define _QSE_CMN_MEM_H_
|
||||
|
||||
/** @file
|
||||
* This file defines functions and macros for memory manipulation.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/* gets a pointer to the default memory manager */
|
||||
/**
|
||||
* The QSE_MMGR_GETDFL() macro returns the default memory manager.
|
||||
*/
|
||||
#define QSE_MMGR_GETDFL() (qse_mmgr)
|
||||
|
||||
/* sets a pointer to the default memory manager */
|
||||
/**
|
||||
* The QSE_MMGR_SETDFL() macro changes the default memory manager.
|
||||
*/
|
||||
#define QSE_MMGR_SETDFL(m) ((qse_mmgr)=(m))
|
||||
|
||||
/* allocate a memory block */
|
||||
@ -46,163 +54,128 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NAME: holds a pointer to the default memory manager
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The QSE_MMGR_GETDFL() macro returns the default memory manager.
|
||||
* You may use QSE_MMGR_SETDFL() to change the default memory manager.
|
||||
/**
|
||||
* The qse_mmgr global variable holds a pointer to the default memory
|
||||
* manager. Use QSE_MMGR_GETDFL() and QSE_MMGR_SETDFL() to manipulate it.
|
||||
*/
|
||||
extern qse_mmgr_t* qse_mmgr;
|
||||
|
||||
/*
|
||||
* NAME: copy a memory block
|
||||
/**
|
||||
* The qse_memcpy() functions copies @a n bytes from the source memory block
|
||||
* @a src to the destinaion memory block @a dst. The memory blocks must not
|
||||
* overlap. Use qse_memmove() if they overlap.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memcpy() functions copies n bytes from the source memory block src
|
||||
* to the destinaion memory block dst.
|
||||
*
|
||||
* RETURNS: the destination memory block dst.
|
||||
*
|
||||
* WARNING:
|
||||
* The memory blocks should not overlap. Use the qse_memmove() function if
|
||||
* they overlap.
|
||||
* @return destination memory block @a dst.
|
||||
*/
|
||||
|
||||
void* qse_memcpy (
|
||||
void* dst /* a pointer to the destination memory block */ ,
|
||||
const void* src /* a pointer to the source memory block */ ,
|
||||
qse_size_t n /* the number of bytes to copy */
|
||||
void* dst, /**< destination memory block */
|
||||
const void* src, /**< source memory block */
|
||||
qse_size_t n /**< number of bytes to copy */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: copy a memory block with more care
|
||||
/**
|
||||
* The qse_memmove() functions copies @a n bytes from the source memory block
|
||||
* @a src to the destinaion memory block @a dst without corrupting overlapping
|
||||
* zone.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memmove() functions copies n bytes from the source memory block src
|
||||
* to the destinaion memory block dst without corrupting overlapping zone.
|
||||
*
|
||||
* RETURNS: the destination memory block dst.
|
||||
* @return destination memory block @a dst.
|
||||
*/
|
||||
void* qse_memmove (
|
||||
void* dst /* a pointer to the destination memory block */,
|
||||
const void* src /* a pointer to the source memory block */,
|
||||
qse_size_t n /* the number of bytes to copy */
|
||||
void* dst, /**< destination memory block */
|
||||
const void* src, /**< source memory block */
|
||||
qse_size_t n /**< number of bytes to copy */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: fill a memory block
|
||||
* The qse_memset() function fills leading @a n bytes of the destination
|
||||
* memory block @a dst with the byte @a val.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memset() function fills leading n bytes of the destination
|
||||
* memory block dst with the byte val.
|
||||
*
|
||||
* RETURNS: the destination memory block dst
|
||||
* @return destination memory block @a dst.
|
||||
*/
|
||||
void* qse_memset (
|
||||
void* dst /* a pointer to the destination memory block */,
|
||||
int val /* the byte to fill the memory block with */,
|
||||
qse_size_t n /* the number of bytes to fill */
|
||||
void* dst, /**< destination memory block */
|
||||
int val, /**< value fill the memory block with */
|
||||
qse_size_t n /**< number of bytes to fill */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: compare memory blocks
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memcmp() function compares leading n bytes of two memory blocks
|
||||
* s1 and s2.
|
||||
/**
|
||||
* The qse_memcmp() function compares leading *a n bytes of two memory blocks
|
||||
* @a s1 and @a s2.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 if two memory ares have the same leadning n bytes.
|
||||
* a positive number if the first different byte of s1 is greater than that
|
||||
* of s2.
|
||||
* a negative number if the first different byte of s1 is less than that of s2.
|
||||
* @return
|
||||
* 0 if two memory ares have the same leadning @a n bytes.
|
||||
* positive number if the first different byte of s1 is greater than that of s2.
|
||||
* negative number if the first different byte of s1 is less than that of s2.
|
||||
*/
|
||||
int qse_memcmp (
|
||||
const void* s1 /* a pointer to the first memory block to compare */,
|
||||
const void* s2 /* a pointer to the second memory block to compare */,
|
||||
qse_size_t n /* the number of bytes to compare */
|
||||
const void* s1, /**< first memory block to compare */
|
||||
const void* s2, /**< second memory block to compare */
|
||||
qse_size_t n /**< the number of bytes to compare */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: find a byte forward in a memory block
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_membyte() function scans the memory block s from the first byte
|
||||
* up to the nth byte in search of the byte val. If it finds a match,
|
||||
* it aborts scanning the memory block and returns the pointer to the matching
|
||||
* location.
|
||||
/**
|
||||
* The qse_membyte() function scans the memory block @a s from the first byte
|
||||
* up to the nth byte in search of the byte @a val. If it finds a match,
|
||||
* it aborts scanning the memory block and returns the pointer to the matching
|
||||
* location.
|
||||
*
|
||||
* RETURNS:
|
||||
* QSE_NULL if the byte val is not found.
|
||||
* The pointer to the location in the memory block s matching the byte val
|
||||
* @return
|
||||
* #QSE_NULL if the byte @a val is not found.
|
||||
* pointer to the location in the memory block @a s matching the byte @a val
|
||||
* if a match is found.
|
||||
*/
|
||||
void* qse_membyte (
|
||||
const void* s /* a pointer to the memory block to scan */,
|
||||
int val /* a byte to find */,
|
||||
qse_size_t n /* the number of bytes to scan */
|
||||
const void* s, /**< memory block to scan */
|
||||
int val, /**< byte to find */
|
||||
qse_size_t n /**< number of bytes to scan */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: find a byte backward in a memory block
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memrbyte() function scans the memory block s from the nth byte
|
||||
* backward to the first byte in search of the byte val. If it finds a match,
|
||||
* it aborts scanning the memory block and returns the pointer to the matching
|
||||
* location.
|
||||
* The qse_memrbyte() function scans the memory block @a s from the nth byte
|
||||
* backward to the first byte in search of the byte @a val. If it finds a match,
|
||||
* it aborts scanning the memory block and returns the pointer to the matching
|
||||
* location.
|
||||
*
|
||||
* RETURNS:
|
||||
* QSE_NULL if the byte val is not found.
|
||||
* The pointer to the location in the memory block s matching the byte val
|
||||
* @return
|
||||
* #QSE_NULL if the byte val is not found.
|
||||
* pointer to the location in the memory block s matching the byte val
|
||||
* if a match is found.
|
||||
*/
|
||||
void* qse_memrbyte (
|
||||
const void* s /* a pointer to the memory block to scan */,
|
||||
int val /* a byte to find */,
|
||||
qse_size_t n /* the number of bytes to scan */
|
||||
const void* s, /**< memory block to scan */
|
||||
int val, /**< byte to find */
|
||||
qse_size_t n /**< number of bytes to scan */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: find a block of bytes forward in a memory block
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memmem() functions scans the first hl bytes of the memory block hs
|
||||
* in search of the byte block nd of the length nl bytes.
|
||||
/**
|
||||
* The qse_memmem() functions scans the first @a hl bytes of the memory
|
||||
* block @a hs in search of the byte block @a nd of the length @a nl bytes.
|
||||
*
|
||||
* RETURNS:
|
||||
* QSE_NULL if the byte val is not found.
|
||||
* The pointer to the location in the memory block s matching the byte val
|
||||
* if a match is found.
|
||||
*
|
||||
* RETURNS:
|
||||
* QSE_NULL if no match is found.
|
||||
* The pointer to the start of the matching location if a match is found.
|
||||
* @return
|
||||
* #QSE_NULL if no match is found.
|
||||
* pointer to the start of the matching location if a match is found.
|
||||
*/
|
||||
void* qse_memmem (
|
||||
const void* hs /* a pointer to the memory block to scan */,
|
||||
qse_size_t hl /* the number of bytes to scan */,
|
||||
const void* nd /* a pointer to the byte block to find */,
|
||||
qse_size_t nl /* the number of bytes in the block */
|
||||
const void* hs, /**< memory block to scan */
|
||||
qse_size_t hl, /**< number of bytes to scan */
|
||||
const void* nd, /**< byte block to find */
|
||||
qse_size_t nl /**< number of bytes in the block */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: find a block of bytes backward in a memory block
|
||||
* The qse_memrmem() functions scans the first @a hl bytes of the memory
|
||||
* block @a hs backward in search of the byte block @a nd of the length
|
||||
* @a nl bytes.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The qse_memrmem() functions scans the first hl bytes of the memory block hs
|
||||
* backward in search of the byte block nd of the length nl bytes.
|
||||
*
|
||||
* RETURNS:
|
||||
* QSE_NULL if no match is found.
|
||||
* The pointer to the start of the matching location if a match is found.
|
||||
* @return
|
||||
* #QSE_NULL if no match is found.
|
||||
* pointer to the start of the matching location if a match is found.
|
||||
*/
|
||||
void* qse_memrmem (
|
||||
const void* hs /* a pointer to the memory block to scan */,
|
||||
qse_size_t hl /* the number of bytes to scan */,
|
||||
const void* nd /* a pointer to the byte block to find */,
|
||||
qse_size_t nl /* the number of bytes in the block */
|
||||
const void* hs, /**< memory block to scan */
|
||||
qse_size_t hl, /**< number of bytes to scan */
|
||||
const void* nd, /**< byte block to find */
|
||||
qse_size_t nl /**< number of bytes in the block */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: opt.h 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: opt.h 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -25,7 +25,7 @@
|
||||
#include <qse/macros.h>
|
||||
|
||||
/** @file
|
||||
* <qse/cmn/opt.h> defines functions and data structures to process
|
||||
* This file defines functions and data structures to process
|
||||
* command-line arguments.
|
||||
*/
|
||||
|
||||
|
@ -22,8 +22,7 @@
|
||||
#define _QSE_CMN_STDIO_H_
|
||||
|
||||
/** @file
|
||||
* #qse_char_t friendly stdio wrapper functions are defined in this file.
|
||||
*
|
||||
* This file defines stdio wrapper functions for #qse_char_t.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
@ -89,6 +88,9 @@ QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode);
|
||||
QSE_FILE* qse_popen (const qse_char_t* cmd, const qse_char_t* mode);
|
||||
|
||||
/**
|
||||
* The qse_getline() function read a line from a file pointer @a fp
|
||||
* until a new line character is met.
|
||||
*
|
||||
* @return -2 on error, -1 on eof, length of data read on success
|
||||
*/
|
||||
qse_ssize_t qse_getline (qse_char_t **buf, qse_size_t *n, QSE_FILE *fp);
|
||||
|
@ -27,7 +27,36 @@
|
||||
* larger memory chunk allocated with an outer memory allocator.
|
||||
* Typically, an outer memory allocator is a standard memory allocator
|
||||
* like malloc(). You can isolate memory blocks into a particular chunk.
|
||||
* See #qse_xma_t for an example.
|
||||
*
|
||||
* See the example below. Note it omits error handling.
|
||||
*
|
||||
* @code
|
||||
* #include <qse/cmn/xma.h>
|
||||
* #include <qse/cmn/stdio.h>
|
||||
* int main ()
|
||||
* {
|
||||
* qse_xma_t* xma;
|
||||
* void* ptr1, * ptr2;
|
||||
*
|
||||
* // create a new memory allocator obtaining a 100K byte zone
|
||||
* // with the default memory allocator
|
||||
* xma = qse_xma_open (QSE_NULL, 0, 100000L);
|
||||
*
|
||||
* ptr1 = qse_xma_alloc (xma, 5000); // allocate a 5K block from the zone
|
||||
* ptr2 = qse_xma_alloc (xma, 1000); // allocate a 1K block from the zone
|
||||
* ptr1 = qse_xma_realloc (xma, ptr1, 6000); // resize the 5K block to 6K.
|
||||
*
|
||||
* qse_xma_dump (xma, qse_printf); // dump memory blocks
|
||||
*
|
||||
* // the following two lines are not actually needed as the allocator
|
||||
* // is closed after them.
|
||||
* qse_xma_free (xma, ptr2); // dispose of the 1K block
|
||||
* qse_xma_free (xma, ptr1); // dispose of the 6K block
|
||||
*
|
||||
* qse_xma_close (xma); // destroy the memory allocator
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
@ -39,28 +68,6 @@
|
||||
/** @struct qse_xma_t
|
||||
* The qse_xma_t type defines a simple memory allocator over a memory zone.
|
||||
* It can obtain a relatively large zone of memory and manage it.
|
||||
*
|
||||
* @code
|
||||
* qse_xma_t* xma;
|
||||
* void* ptr1, * ptr2;
|
||||
*
|
||||
* // create a new memory allocator obtaining a 100K byte zone
|
||||
* // with the default memory allocator
|
||||
* xma = qse_xma_open (QSE_NULL, 0, 100000L);
|
||||
*
|
||||
* ptr1 = qse_xma_alloc (xma, 5000); // allocate a 5K block from the zone
|
||||
* ptr2 = qse_xma_alloc (xma, 1000); // allocate a 1K block from the zone
|
||||
* ptr1 = qse_xma_realloc (xma, ptr1, 6000); // resize the 5K block to 6K.
|
||||
*
|
||||
* qse_xma_dump (xma, qse_printf); // dump memory blocks
|
||||
*
|
||||
* // the following two lines are not actually needed as the allocator
|
||||
* // is closed after them.
|
||||
* qse_xma_free (xma, ptr2); // dispose of the 1K block
|
||||
* qse_xma_free (xma, ptr1); // dispose of the 6K block
|
||||
*
|
||||
* qse_xma_close (xma); // destroy the memory allocator
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct qse_xma_t qse_xma_t;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: macros.h 338 2010-07-30 13:24:19Z hyunghwan.chung $
|
||||
* $Id: macros.h 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -24,7 +24,7 @@
|
||||
#include <qse/types.h>
|
||||
|
||||
/** @file
|
||||
* <qse/macros.h> contains various useful macro definitions.
|
||||
* This file contains various useful macro definitions.
|
||||
*/
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: types.h 338 2010-07-30 13:24:19Z hyunghwan.chung $
|
||||
* $Id: types.h 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -22,7 +22,7 @@
|
||||
#define _QSE_TYPES_H_
|
||||
|
||||
/**@file
|
||||
* <qse/types.h> defines various common basic types designed to be
|
||||
* This file defines various common basic types designed to be
|
||||
* cross-platform. These types are preferred over native data types.
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fio.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
* $Id: fio.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -81,6 +81,8 @@ qse_fio_t* qse_fio_init (
|
||||
{
|
||||
qse_fio_hnd_t handle;
|
||||
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (fio, 0, QSE_SIZEOF(*fio));
|
||||
fio->mmgr = mmgr;
|
||||
|
||||
|
@ -29,7 +29,7 @@ qse_fma_t* qse_fma_open (
|
||||
{
|
||||
qse_fma_t* fma;
|
||||
|
||||
if (mmgr == QSE_NULL)
|
||||
if (mmgr == QSE_NULL)
|
||||
{
|
||||
mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
@ -61,13 +61,14 @@ qse_fma_t* qse_fma_init (
|
||||
qse_fma_t* fma, qse_mmgr_t* mmgr,
|
||||
qse_size_t blksize, qse_size_t maxblks, qse_size_t maxcnks)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (fma, 0, QSE_SIZEOF(*fma));
|
||||
fma->mmgr = mmgr;
|
||||
|
||||
if (blksize <= QSE_SIZEOF(qse_fma_blk_t))
|
||||
if (blksize < QSE_SIZEOF(qse_fma_blk_t))
|
||||
blksize = QSE_SIZEOF(qse_fma_blk_t);
|
||||
if (maxblks <= 0) maxblks = 1;
|
||||
if (maxcnks <= 0) maxcnks = 1;
|
||||
|
||||
fma->blksize = blksize;
|
||||
fma->maxblks = maxblks;
|
||||
@ -78,6 +79,7 @@ qse_fma_t* qse_fma_init (
|
||||
|
||||
void qse_fma_fini (qse_fma_t* fma)
|
||||
{
|
||||
/* destroys the chunks allocated */
|
||||
while (fma->cnkhead)
|
||||
{
|
||||
qse_fma_cnk_t* next = fma->cnkhead->next;
|
||||
@ -93,7 +95,7 @@ static QSE_INLINE qse_fma_cnk_t* add_chunk (qse_fma_t* fma)
|
||||
qse_size_t i;
|
||||
|
||||
/* check if there are too many chunks */
|
||||
if (fma->numcnks >= fma->maxcnks) return QSE_NULL;
|
||||
if (fma->maxcnks && fma->numcnks >= fma->maxcnks) return QSE_NULL;
|
||||
|
||||
/* allocate a chunk */
|
||||
cnk = (qse_fma_cnk_t*) QSE_MMGR_ALLOC (fma->mmgr,
|
||||
@ -118,10 +120,16 @@ static QSE_INLINE qse_fma_cnk_t* add_chunk (qse_fma_t* fma)
|
||||
return cnk;
|
||||
}
|
||||
|
||||
void* qse_fma_alloc (qse_fma_t* fma)
|
||||
void* qse_fma_alloc (qse_fma_t* fma, qse_size_t size)
|
||||
{
|
||||
void* blk;
|
||||
|
||||
QSE_ASSERTX (size <= fma->blksize,
|
||||
"You must not request a block larger than the fixed size set in the allocator. Use a generic allocator instead"
|
||||
);
|
||||
|
||||
if (size > fma->blksize) return QSE_NULL;
|
||||
|
||||
if ((blk = fma->freeblk) == QSE_NULL)
|
||||
{
|
||||
if (add_chunk (fma) == QSE_NULL) return QSE_NULL;
|
||||
@ -131,9 +139,23 @@ void* qse_fma_alloc (qse_fma_t* fma)
|
||||
return blk;
|
||||
}
|
||||
|
||||
void* qse_fma_realloc (qse_fma_t* fma, void* blk, qse_size_t size)
|
||||
{
|
||||
if (blk)
|
||||
{
|
||||
QSE_ASSERTX (size <= fma->blksize,
|
||||
"A block can be enlarged with a fixed-size block allocator. Use a generic allocator instead"
|
||||
);
|
||||
|
||||
if (size > fma->blksize) return QSE_NULL;
|
||||
return blk;
|
||||
}
|
||||
|
||||
return qse_fma_alloc (fma, size);
|
||||
}
|
||||
|
||||
void qse_fma_free (qse_fma_t* fma, void* blk)
|
||||
{
|
||||
((qse_fma_blk_t*)blk)->next = fma->freeblk;
|
||||
fma->freeblk = blk;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: htb.c 332 2010-07-13 11:25:24Z hyunghwan.chung $
|
||||
* $Id: htb.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -248,11 +248,14 @@ void qse_htb_close (htb_t* htb)
|
||||
|
||||
htb_t* qse_htb_init (htb_t* htb, mmgr_t* mmgr, size_t capa, int factor)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_ASSERTX (capa > 0,
|
||||
"The initial capacity should be greater than 0. Otherwise, it is adjusted to 1 in the release mode");
|
||||
QSE_ASSERTX (factor >= 0 && factor <= 100,
|
||||
"The load factor should be between 0 and 100 inclusive. In the release mode, a value out of the range is adjusted to 100");
|
||||
|
||||
|
||||
/* some initial adjustment */
|
||||
if (capa <= 0) capa = 1;
|
||||
if (factor > 100) factor = 100;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lda.c 327 2010-05-10 13:15:55Z hyunghwan.chung $
|
||||
* $Id: lda.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -108,10 +108,10 @@ lda_t* qse_lda_open (mmgr_t* mmgr, size_t ext, size_t capa)
|
||||
if (mmgr == QSE_NULL) return QSE_NULL;
|
||||
}
|
||||
|
||||
lda = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(lda_t) + ext);
|
||||
if (lda == QSE_NULL) return QSE_NULL;
|
||||
lda = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(lda_t) + ext);
|
||||
if (lda == QSE_NULL) return QSE_NULL;
|
||||
|
||||
if (qse_lda_init (lda, mmgr, capa) == QSE_NULL)
|
||||
if (qse_lda_init (lda, mmgr, capa) == QSE_NULL)
|
||||
{
|
||||
QSE_MMGR_FREE (mmgr, lda);
|
||||
return QSE_NULL;
|
||||
@ -128,6 +128,8 @@ void qse_lda_close (lda_t* lda)
|
||||
|
||||
lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (lda, 0, QSE_SIZEOF(*lda));
|
||||
|
||||
lda->mmgr = mmgr;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: pio.c 316 2009-12-14 12:50:11Z hyunghwan.chung $
|
||||
* $Id: pio.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -72,7 +72,6 @@ void qse_pio_close (qse_pio_t* pio)
|
||||
qse_pio_t* qse_pio_init (
|
||||
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd, int oflags)
|
||||
{
|
||||
|
||||
qse_pio_hnd_t handle[6] =
|
||||
{
|
||||
QSE_PIO_HND_NIL,
|
||||
@ -92,6 +91,8 @@ qse_pio_t* qse_pio_init (
|
||||
|
||||
int i, minidx = -1, maxidx = -1;
|
||||
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
#ifdef _WIN32
|
||||
SECURITY_ATTRIBUTES secattr;
|
||||
PROCESS_INFORMATION procinfo;
|
||||
|
@ -192,6 +192,8 @@ void qse_rbt_close (rbt_t* rbt)
|
||||
|
||||
rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
/* do not zero out the extension */
|
||||
QSE_MEMSET (rbt, 0, SIZEOF(*rbt));
|
||||
rbt->mmgr = mmgr;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rex.c 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
* $Id: rex.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -118,6 +118,8 @@ struct cand_t
|
||||
|
||||
qse_rex_t* qse_rex_init (qse_rex_t* rex, qse_mmgr_t* mmgr, qse_rex_node_t* code)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (rex, 0, QSE_SIZEOF(*rex));
|
||||
rex->mmgr = mmgr;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sio.c 340 2010-08-01 13:13:38Z hyunghwan.chung $
|
||||
* $Id: sio.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -178,6 +178,8 @@ qse_sio_t* qse_sio_init (
|
||||
{
|
||||
int mode;
|
||||
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (sio, 0, QSE_SIZEOF(*sio));
|
||||
sio->mmgr = mmgr;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sll.c 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
* $Id: sll.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -124,6 +124,8 @@ void qse_sll_close (sll_t* sll)
|
||||
|
||||
sll_t* qse_sll_init (sll_t* sll, mmgr_t* mmgr)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
/* do not zero out the extension */
|
||||
QSE_MEMSET (sll, 0, SIZEOF(*sll));
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str_dyn.c 297 2009-10-08 13:09:19Z hyunghwan.chung $
|
||||
* $Id: str_dyn.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -57,6 +57,8 @@ void qse_str_close (qse_str_t* str)
|
||||
|
||||
qse_str_t* qse_str_init (qse_str_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (str, 0, QSE_SIZEOF(qse_str_t));
|
||||
|
||||
str->mmgr = mmgr;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tio.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: tio.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -58,6 +58,8 @@ int qse_tio_close (qse_tio_t* tio)
|
||||
|
||||
qse_tio_t* qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (tio, 0, QSE_SIZEOF(*tio));
|
||||
|
||||
tio->mmgr = mmgr;
|
||||
|
@ -142,6 +142,8 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
|
||||
qse_xma_blk_t* free;
|
||||
qse_size_t xfi;
|
||||
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
/* round 'zonesize' to be the multiples of ALIGN */
|
||||
zonesize = ((zonesize + ALIGN - 1) / ALIGN) * ALIGN;
|
||||
|
||||
|
@ -109,6 +109,8 @@ void qse_cut_close (qse_cut_t* cut)
|
||||
|
||||
static qse_cut_t* qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (cut, 0, QSE_SIZEOF(*cut));
|
||||
|
||||
cut->mmgr = mmgr;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sed.c 344 2010-08-17 13:15:14Z hyunghwan.chung $
|
||||
* $Id: sed.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -75,6 +75,8 @@ void qse_sed_close (qse_sed_t* sed)
|
||||
|
||||
static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||
{
|
||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_MEMSET (sed, 0, QSE_SIZEOF(*sed));
|
||||
sed->mmgr = mmgr;
|
||||
sed->errstr = qse_sed_dflerrstr;
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <qse/cmn/fma.h>
|
||||
#include <qse/cmn/rbt.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
|
||||
#define R(f) \
|
||||
@ -12,7 +14,7 @@ static int test1 ()
|
||||
int i;
|
||||
int* ptr[100];
|
||||
|
||||
qse_fma_t* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
|
||||
qse_fma_t* fma = qse_fma_open (QSE_MMGR_GETDFL(), 0, sizeof(int), 10, 5);
|
||||
if (fma == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cannot open fma\n"));
|
||||
@ -21,7 +23,7 @@ static int test1 ()
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ptr[i] = qse_fma_alloc (fma);
|
||||
ptr[i] = qse_fma_alloc (fma, sizeof(int));
|
||||
if (ptr[i])
|
||||
{
|
||||
qse_printf (QSE_T("%d %p\n"), i, ptr[i]);
|
||||
@ -50,7 +52,7 @@ static int test1 ()
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ptr[i] = qse_fma_alloc (fma);
|
||||
ptr[i] = qse_fma_alloc (fma, sizeof(int));
|
||||
if (ptr[i])
|
||||
{
|
||||
qse_printf (QSE_T("%d %p\n"), i, ptr[i]);
|
||||
@ -63,8 +65,71 @@ static int test1 ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_rbt_walk_t walk (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx)
|
||||
{
|
||||
qse_printf (QSE_T("key = %lld, value = %lld\n"),
|
||||
*(long*)QSE_RBT_KPTR(pair), *(long*)QSE_RBT_VPTR(pair));
|
||||
return QSE_RBT_WALK_FORWARD;
|
||||
}
|
||||
|
||||
static int test2 ()
|
||||
{
|
||||
qse_mmgr_t mmgr =
|
||||
{
|
||||
(qse_mmgr_alloc_t) qse_fma_alloc,
|
||||
(qse_mmgr_realloc_t) qse_fma_realloc,
|
||||
(qse_mmgr_free_t) qse_fma_free,
|
||||
QSE_NULL
|
||||
};
|
||||
qse_fma_t* fma;
|
||||
qse_rbt_t rbt;
|
||||
qse_size_t blksize;
|
||||
long x;
|
||||
|
||||
/* key */ /* value */ /* internal node */
|
||||
blksize = sizeof(long) + sizeof(long) + sizeof(qse_rbt_pair_t);
|
||||
|
||||
fma = qse_fma_open (QSE_MMGR_GETDFL(), 0, blksize, 10, 0);
|
||||
if (fma == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cannot open a memory allocator\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmgr.udd = fma;
|
||||
if (qse_rbt_init (&rbt, &mmgr) == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cannot initialize a tree\n"));
|
||||
qse_fma_close (fma);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qse_rbt_setcopier (&rbt, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE);
|
||||
qse_rbt_setcopier (&rbt, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE);
|
||||
qse_rbt_setscale (&rbt, QSE_RBT_KEY, QSE_SIZEOF(long));
|
||||
qse_rbt_setscale (&rbt, QSE_RBT_VAL, QSE_SIZEOF(long));
|
||||
|
||||
for (x = 10; x < 100; x++)
|
||||
{
|
||||
long y = x * x;
|
||||
if (qse_rbt_insert (&rbt, &x, 1, &y, 1) == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("failed to insert. out of memory\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qse_rbt_walk (&rbt, walk, QSE_NULL);
|
||||
|
||||
qse_rbt_fini (&rbt);
|
||||
qse_fma_close (fma);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
R (test1);
|
||||
R (test2);
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,7 +102,6 @@ qse_printf (QSE_T("deleting %d\n"), i);
|
||||
static int test2 ()
|
||||
{
|
||||
qse_rbt_t* s1;
|
||||
int i;
|
||||
|
||||
s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0);
|
||||
if (s1 == QSE_NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user