added Mpool and LinkedList
This commit is contained in:
parent
91e4e06318
commit
3b672857aa
@ -71,7 +71,6 @@ protected:
|
|||||||
mutable qse_size_t ref_count;
|
mutable qse_size_t ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_END_NAMESPACE(QSE)
|
QSE_END_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#include <qse/types.h>
|
#include <qse/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
/// \file
|
||||||
|
/// This file defines a class containg aliases to various QSE types.
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -27,12 +27,16 @@
|
|||||||
#ifndef _QSE_UNCOPYABLE_HPP_
|
#ifndef _QSE_UNCOPYABLE_HPP_
|
||||||
#define _QSE_UNCOPYABLE_HPP_
|
#define _QSE_UNCOPYABLE_HPP_
|
||||||
|
|
||||||
#include <qse/Types.hpp>
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
/// The Uncopyable class disallows an inheriting class to be assigned or
|
||||||
|
/// copied.
|
||||||
|
|
||||||
class QSE_EXPORT Uncopyable
|
class QSE_EXPORT Uncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -48,5 +52,4 @@ private:
|
|||||||
QSE_END_NAMESPACE(QSE)
|
QSE_END_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <qse/cmn/Mmged.hpp>
|
#include <qse/cmn/Mmged.hpp>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/// @file
|
/// \file
|
||||||
/// AWK Interpreter
|
/// AWK Interpreter
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
@ -105,24 +105,24 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// @name Error Handling
|
/// \name Error Handling
|
||||||
///
|
///
|
||||||
/// @{
|
/// \{
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getErrorString() function returns a formatting string
|
/// The getErrorString() function returns a formatting string
|
||||||
/// for an error code @a num. You can override this function
|
/// for an error code \a num. You can override this function
|
||||||
/// to customize an error message. You must include the same numbers
|
/// to customize an error message. You must include the same numbers
|
||||||
/// of ${X}'s as the orginal formatting string. Their order may be
|
/// of ${X}'s as the orginal formatting string. Their order may be
|
||||||
/// different. The example below changes the formatting string for
|
/// different. The example below changes the formatting string for
|
||||||
/// #QSE_AWK_ENOENT.
|
/// #QSE_AWK_ENOENT.
|
||||||
/// @code
|
/// \code
|
||||||
/// const MyAwk::char_t* MyAwk::getErrorString (errnum_t num) const
|
/// const MyAwk::char_t* MyAwk::getErrorString (errnum_t num) const
|
||||||
/// {
|
/// {
|
||||||
/// if (num == QSE_AWK_ENOENT) return QSE_T("cannot find '${0}'");
|
/// if (num == QSE_AWK_ENOENT) return QSE_T("cannot find '${0}'");
|
||||||
/// return Awk::getErrorString (num);
|
/// return Awk::getErrorString (num);
|
||||||
/// }
|
/// }
|
||||||
/// @endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
virtual const char_t* getErrorString (
|
virtual const char_t* getErrorString (
|
||||||
errnum_t num
|
errnum_t num
|
||||||
@ -175,7 +175,7 @@ public:
|
|||||||
//protected: can't make it protected for borland
|
//protected: can't make it protected for borland
|
||||||
void retrieveError ();
|
void retrieveError ();
|
||||||
void retrieveError (Run* run);
|
void retrieveError (Run* run);
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class NoSource;
|
class NoSource;
|
||||||
@ -791,14 +791,14 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The isIndexed() function determines if a value is arrayed.
|
/// The isIndexed() function determines if a value is arrayed.
|
||||||
/// @return true if indexed, false if not.
|
/// \return true if indexed, false if not.
|
||||||
///
|
///
|
||||||
bool isIndexed () const;
|
bool isIndexed () const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getIndexed() function gets a value at the given
|
/// The getIndexed() function gets a value at the given
|
||||||
/// index @a idx and sets it to @a val.
|
/// index \a idx and sets it to \a val.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int getIndexed (
|
int getIndexed (
|
||||||
const Index& idx, ///< array index
|
const Index& idx, ///< array index
|
||||||
@ -807,8 +807,8 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The getFirstIndex() function stores the first index of
|
/// The getFirstIndex() function stores the first index of
|
||||||
/// an arrayed value into @a idx.
|
/// an arrayed value into \a idx.
|
||||||
/// @return IndexIterator::END if the arrayed value is empty,
|
/// \return IndexIterator::END if the arrayed value is empty,
|
||||||
/// iterator that can be passed to getNextIndex() if not
|
/// iterator that can be passed to getNextIndex() if not
|
||||||
///
|
///
|
||||||
IndexIterator getFirstIndex (
|
IndexIterator getFirstIndex (
|
||||||
@ -816,10 +816,10 @@ public:
|
|||||||
) const;
|
) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getNextIndex() function stores into @a idx the next
|
/// The getNextIndex() function stores into \a idx the next
|
||||||
/// index of an array value from the position indicated by
|
/// index of an array value from the position indicated by
|
||||||
/// @a iter.
|
/// \a iter.
|
||||||
/// @return IndexIterator::END if the arrayed value is empty,
|
/// \return IndexIterator::END if the arrayed value is empty,
|
||||||
/// iterator that can be passed to getNextIndex() if not
|
/// iterator that can be passed to getNextIndex() if not
|
||||||
///
|
///
|
||||||
IndexIterator getNextIndex (
|
IndexIterator getNextIndex (
|
||||||
@ -882,40 +882,40 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The setGlobal() function sets the value of a global
|
/// The setGlobal() function sets the value of a global
|
||||||
/// variable identified by @a id
|
/// variable identified by \a id
|
||||||
/// to @a v.
|
/// to \a v.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int setGlobal (int id, int_t v);
|
int setGlobal (int id, int_t v);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The setGlobal() function sets the value of a global
|
/// The setGlobal() function sets the value of a global
|
||||||
/// variable identified by @a id
|
/// variable identified by \a id
|
||||||
/// to @a v.
|
/// to \a v.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int setGlobal (int id, flt_t v);
|
int setGlobal (int id, flt_t v);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The setGlobal() function sets the value of a global
|
/// The setGlobal() function sets the value of a global
|
||||||
/// variable identified by @a id
|
/// variable identified by \a id
|
||||||
/// to a string as long as @a len characters pointed to by
|
/// to a string as long as \a len characters pointed to by
|
||||||
/// @a ptr.
|
/// \a ptr.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int setGlobal (int id, const char_t* ptr, size_t len);
|
int setGlobal (int id, const char_t* ptr, size_t len);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The setGlobal() function sets a global variable
|
/// The setGlobal() function sets a global variable
|
||||||
/// identified by @a id to a value @a v.
|
/// identified by \a id to a value \a v.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int setGlobal (int id, const Value& v);
|
int setGlobal (int id, const Value& v);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getGlobal() function gets the value of a global
|
/// The getGlobal() function gets the value of a global
|
||||||
/// variable identified by @a id and stores it in @a v.
|
/// variable identified by \a id and stores it in \a v.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int getGlobal (int id, Value& v) const;
|
int getGlobal (int id, Value& v) const;
|
||||||
|
|
||||||
@ -930,8 +930,8 @@ public:
|
|||||||
operator awk_t* () const;
|
operator awk_t* () const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @name Basic Functions
|
/// \name Basic Functions
|
||||||
/// @{
|
/// \{
|
||||||
///
|
///
|
||||||
|
|
||||||
/// The Awk() function creates an interpreter without fully
|
/// The Awk() function creates an interpreter without fully
|
||||||
@ -946,7 +946,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// The open() function initializes an interpreter.
|
/// The open() function initializes an interpreter.
|
||||||
/// You must call this function before doing anything meaningful.
|
/// You must call this function before doing anything meaningful.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int open ();
|
int open ();
|
||||||
|
|
||||||
@ -957,11 +957,11 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The parse() function parses the source code read from the input
|
/// The parse() function parses the source code read from the input
|
||||||
/// stream @a in and writes the parse tree to the output stream @a out.
|
/// stream \a in and writes the parse tree to the output stream \a out.
|
||||||
/// To disable deparsing, you may set @a out to Awk::Source::NONE.
|
/// To disable deparsing, you may set \a out to Awk::Source::NONE.
|
||||||
/// However, it is not allowed to specify Awk::Source::NONE for @a in.
|
/// However, it is not allowed to specify Awk::Source::NONE for \a in.
|
||||||
///
|
///
|
||||||
/// @return Run object on success, #QSE_NULL on failure
|
/// \return Run object on success, #QSE_NULL on failure
|
||||||
///
|
///
|
||||||
Awk::Run* parse (
|
Awk::Run* parse (
|
||||||
Source& in, ///< script to parse
|
Source& in, ///< script to parse
|
||||||
@ -1002,15 +1002,15 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The loop() function executes the BEGIN block, pattern-action blocks,
|
/// The loop() function executes the BEGIN block, pattern-action blocks,
|
||||||
/// and the END block. The return value is stored into @a ret.
|
/// and the END block. The return value is stored into \a ret.
|
||||||
/// @return 0 on succes, -1 on failure
|
/// \return 0 on succes, -1 on failure
|
||||||
///
|
///
|
||||||
int loop (
|
int loop (
|
||||||
Value* ret ///< return value holder
|
Value* ret ///< return value holder
|
||||||
);
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The call() function invokes a function named @a name.
|
/// The call() function invokes a function named \a name.
|
||||||
///
|
///
|
||||||
int call (
|
int call (
|
||||||
const char_t* name, ///< function name
|
const char_t* name, ///< function name
|
||||||
@ -1023,16 +1023,16 @@ public:
|
|||||||
/// The stop() function makes request to abort execution
|
/// The stop() function makes request to abort execution
|
||||||
///
|
///
|
||||||
void stop ();
|
void stop ();
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @name Configuration
|
/// \name Configuration
|
||||||
/// @{
|
/// \{
|
||||||
///
|
///
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getTrait() function gets the current options.
|
/// The getTrait() function gets the current options.
|
||||||
/// @return current traits
|
/// \return current traits
|
||||||
///
|
///
|
||||||
int getTrait () const;
|
int getTrait () const;
|
||||||
|
|
||||||
@ -1045,7 +1045,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The setMaxDepth() function sets the maximum processing depth
|
/// The setMaxDepth() function sets the maximum processing depth
|
||||||
/// for operations identified by @a ids.
|
/// for operations identified by \a ids.
|
||||||
///
|
///
|
||||||
void setMaxDepth (
|
void setMaxDepth (
|
||||||
depth_t id, ///< depth identifier
|
depth_t id, ///< depth identifier
|
||||||
@ -1054,18 +1054,18 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The getMaxDepth() function gets the maximum depth for an operation
|
/// The getMaxDepth() function gets the maximum depth for an operation
|
||||||
/// type identified by @a id.
|
/// type identified by \a id.
|
||||||
///
|
///
|
||||||
size_t getMaxDepth (
|
size_t getMaxDepth (
|
||||||
depth_t id ///< depth identifier
|
depth_t id ///< depth identifier
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The addArgument() function adds an ARGV string as long as @a len
|
/// The addArgument() function adds an ARGV string as long as \a len
|
||||||
/// characters pointed to
|
/// characters pointed to
|
||||||
/// by @a arg. loop() and call() make a string added available
|
/// by \a arg. loop() and call() make a string added available
|
||||||
/// to a script through ARGV.
|
/// to a script through ARGV.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int addArgument (
|
int addArgument (
|
||||||
const char_t* arg, ///< string pointer
|
const char_t* arg, ///< string pointer
|
||||||
@ -1073,10 +1073,10 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The addArgument() function adds a null-terminated string @a arg.
|
/// The addArgument() function adds a null-terminated string \a arg.
|
||||||
/// loop() and call() make a string added available to a script
|
/// loop() and call() make a string added available to a script
|
||||||
/// through ARGV.
|
/// through ARGV.
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int addArgument (
|
int addArgument (
|
||||||
const char_t* arg ///< string pointer
|
const char_t* arg ///< string pointer
|
||||||
@ -1089,7 +1089,7 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The addGlobal() function registers an intrinsic global variable.
|
/// The addGlobal() function registers an intrinsic global variable.
|
||||||
/// @return integer >= 0 on success, -1 on failure.
|
/// \return integer >= 0 on success, -1 on failure.
|
||||||
///
|
///
|
||||||
int addGlobal (
|
int addGlobal (
|
||||||
const char_t* name ///< variable name
|
const char_t* name ///< variable name
|
||||||
@ -1098,7 +1098,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// The deleteGlobal() function unregisters an intrinsic global
|
/// The deleteGlobal() function unregisters an intrinsic global
|
||||||
/// variable by name.
|
/// variable by name.
|
||||||
/// @return 0 on success, -1 on failure.
|
/// \return 0 on success, -1 on failure.
|
||||||
///
|
///
|
||||||
int deleteGlobal (
|
int deleteGlobal (
|
||||||
const char_t* name ///< variable name
|
const char_t* name ///< variable name
|
||||||
@ -1107,7 +1107,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// The addGlobal() function returns the numeric ID of an intrinsic
|
/// The addGlobal() function returns the numeric ID of an intrinsic
|
||||||
// global variable.
|
// global variable.
|
||||||
/// @return integer >= 0 on success, -1 on failure.
|
/// \return integer >= 0 on success, -1 on failure.
|
||||||
///
|
///
|
||||||
int findGlobal (
|
int findGlobal (
|
||||||
const char_t* name ///> variable name
|
const char_t* name ///> variable name
|
||||||
@ -1115,10 +1115,10 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The setGlobal() function sets the value of a global variable
|
/// The setGlobal() function sets the value of a global variable
|
||||||
/// identified by @a id. The @a id is either a value returned by
|
/// identified by \a id. The \a id is either a value returned by
|
||||||
/// addGlobal() or one of the #gbl_id_t enumerators. It is not allowed
|
/// addGlobal() or one of the #gbl_id_t enumerators. It is not allowed
|
||||||
/// to call this function prior to parse().
|
/// to call this function prior to parse().
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int setGlobal (
|
int setGlobal (
|
||||||
int id, ///< numeric identifier
|
int id, ///< numeric identifier
|
||||||
@ -1127,10 +1127,10 @@ public:
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// The getGlobal() function gets the value of a global variable
|
/// The getGlobal() function gets the value of a global variable
|
||||||
/// identified by @a id. The @a id is either a value returned by
|
/// identified by \a id. The \a id is either a value returned by
|
||||||
/// addGlobal() or one of the #gbl_id_t enumerators. It is not allowed
|
/// addGlobal() or one of the #gbl_id_t enumerators. It is not allowed
|
||||||
/// to call this function before parse().
|
/// to call this function before parse().
|
||||||
/// @return 0 on success, -1 on failure
|
/// \return 0 on success, -1 on failure
|
||||||
///
|
///
|
||||||
int getGlobal (
|
int getGlobal (
|
||||||
int id, ///< numeric identifier
|
int id, ///< numeric identifier
|
||||||
@ -1168,7 +1168,7 @@ public:
|
|||||||
int deleteFunction (
|
int deleteFunction (
|
||||||
const char_t* name ///< function name
|
const char_t* name ///< function name
|
||||||
);
|
);
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
Pipe::Handler* getPipeHandler ()
|
Pipe::Handler* getPipeHandler ()
|
||||||
{
|
{
|
||||||
@ -1238,10 +1238,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// @name Pipe I/O handlers
|
/// \name Pipe I/O handlers
|
||||||
/// Pipe operations are achieved through the following functions
|
/// Pipe operations are achieved through the following functions
|
||||||
/// if no external pipe handler is set with setPipeHandler().
|
/// if no external pipe handler is set with setPipeHandler().
|
||||||
/// @{
|
/// \{
|
||||||
|
|
||||||
/// The openPipe() function is a pure virtual function that must be
|
/// The openPipe() function is a pure virtual function that must be
|
||||||
/// overridden by a child class to open a pipe. It must return 1
|
/// overridden by a child class to open a pipe. It must return 1
|
||||||
@ -1256,26 +1256,26 @@ protected:
|
|||||||
virtual ssize_t readPipe (Pipe& io, char_t* buf, size_t len);
|
virtual ssize_t readPipe (Pipe& io, char_t* buf, size_t len);
|
||||||
virtual ssize_t writePipe (Pipe& io, const char_t* buf, size_t len);
|
virtual ssize_t writePipe (Pipe& io, const char_t* buf, size_t len);
|
||||||
virtual int flushPipe (Pipe& io);
|
virtual int flushPipe (Pipe& io);
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @name File I/O handlers
|
/// \name File I/O handlers
|
||||||
/// File operations are achieved through the following functions
|
/// File operations are achieved through the following functions
|
||||||
/// if no external file handler is set with setFileHandler().
|
/// if no external file handler is set with setFileHandler().
|
||||||
/// @{
|
/// \{
|
||||||
///
|
///
|
||||||
virtual int openFile (File& io);
|
virtual int openFile (File& io);
|
||||||
virtual int closeFile (File& io);
|
virtual int closeFile (File& io);
|
||||||
virtual ssize_t readFile (File& io, char_t* buf, size_t len);
|
virtual ssize_t readFile (File& io, char_t* buf, size_t len);
|
||||||
virtual ssize_t writeFile (File& io, const char_t* buf, size_t len);
|
virtual ssize_t writeFile (File& io, const char_t* buf, size_t len);
|
||||||
virtual int flushFile (File& io);
|
virtual int flushFile (File& io);
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @name Console I/O handlers
|
/// \name Console I/O handlers
|
||||||
/// Console operations are achieved through the following functions.
|
/// Console operations are achieved through the following functions.
|
||||||
/// if no external console handler is set with setConsoleHandler().
|
/// if no external console handler is set with setConsoleHandler().
|
||||||
/// @{
|
/// \{
|
||||||
///
|
///
|
||||||
virtual int openConsole (Console& io);
|
virtual int openConsole (Console& io);
|
||||||
virtual int closeConsole (Console& io);
|
virtual int closeConsole (Console& io);
|
||||||
@ -1283,7 +1283,7 @@ protected:
|
|||||||
virtual ssize_t writeConsole (Console& io, const char_t* buf, size_t len);
|
virtual ssize_t writeConsole (Console& io, const char_t* buf, size_t len);
|
||||||
virtual int flushConsole (Console& io);
|
virtual int flushConsole (Console& io);
|
||||||
virtual int nextConsole (Console& io);
|
virtual int nextConsole (Console& io);
|
||||||
/// @}
|
/// \}
|
||||||
|
|
||||||
// primitive handlers
|
// primitive handlers
|
||||||
virtual flt_t pow (flt_t x, flt_t y) = 0;
|
virtual flt_t pow (flt_t x, flt_t y) = 0;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <qse/cmn/StdMmgr.hpp>
|
#include <qse/cmn/StdMmgr.hpp>
|
||||||
#include <qse/cmn/time.h>
|
#include <qse/cmn/time.h>
|
||||||
|
|
||||||
/// @file
|
/// \file
|
||||||
/// Standard AWK Interpreter
|
/// Standard AWK Interpreter
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
583
qse/include/qse/cmn/LinkedList.hpp
Normal file
583
qse/include/qse/cmn/LinkedList.hpp
Normal file
@ -0,0 +1,583 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_LINKEDLIST_HPP_
|
||||||
|
#define _QSE_CMN_LINKEDLIST_HPP_
|
||||||
|
|
||||||
|
#include <qse/Types.hpp>
|
||||||
|
#include <xp/bas/MemoryPool.hpp>
|
||||||
|
#include <xp/bas/MemoryPoolable.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T> class LinkedList;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LinkedListNode: protected MemoryPoolable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend class LinkedList<T>;
|
||||||
|
|
||||||
|
T value;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LinkedListNode<T>* next;
|
||||||
|
LinkedListNode<T>* prev;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinkedListNode<T>* getNext () { return this->next; }
|
||||||
|
const LinkedListNode<T>* getNext () const { return this->next; }
|
||||||
|
|
||||||
|
LinkedListNode<T>* getPrev () { return this->prev; }
|
||||||
|
const LinkedListNode<T>* getPrev () const { return this->prev; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LinkedListNode () {}
|
||||||
|
LinkedListNode (const T& v): value(v) {}
|
||||||
|
|
||||||
|
void setNext (const LinkedListNode<T>* node)
|
||||||
|
{
|
||||||
|
this->next = node;
|
||||||
|
}
|
||||||
|
void setPrev (const LinkedListNode<T>* node)
|
||||||
|
{
|
||||||
|
this->prev = node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The LinkedList<T> class provides a template for a doubly-linked list.
|
||||||
|
///
|
||||||
|
template <typename T> class LinkedList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef LinkedListNode<T> Node;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
INVALID_INDEX = ~(qse_size_t)0
|
||||||
|
};
|
||||||
|
|
||||||
|
~LinkedList ()
|
||||||
|
{
|
||||||
|
this->clearout ();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList (qse_size_t mpb_size = 0): mp (QSE_SIZEOF(Node), mpb_size)
|
||||||
|
{
|
||||||
|
this->node_count = 0;
|
||||||
|
this->head_node = QSE_NULL;
|
||||||
|
this->tail_node = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList (const LinkedList<T>& ll): mp (ll.mp.datumSize(), ll.mp.blockSize())
|
||||||
|
{
|
||||||
|
this->node_count = 0;
|
||||||
|
this->head_node = QSE_NULL;
|
||||||
|
this->tail_node = QSE_NULL;
|
||||||
|
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
|
||||||
|
this->append (p->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList<T>& operator= (const LinkedList<T>& ll)
|
||||||
|
{
|
||||||
|
this->clear ();
|
||||||
|
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
|
||||||
|
this->append (p->value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[] (qse_size_t index)
|
||||||
|
{
|
||||||
|
// same as getValueAt()
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
Node* np = this->getNodeAt (index);
|
||||||
|
return np->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator[] (qse_size_t index) const
|
||||||
|
{
|
||||||
|
// same as getValueAt()
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
Node* np = this->getNodeAt (index);
|
||||||
|
return np->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t getMPBlockSize() const
|
||||||
|
{
|
||||||
|
return this->mp.blockSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMPEnabled () const
|
||||||
|
{
|
||||||
|
return this->mp.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t getSize () const
|
||||||
|
{
|
||||||
|
return this->node_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty () const
|
||||||
|
{
|
||||||
|
return this->node_count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains (const T& value) const
|
||||||
|
{
|
||||||
|
return this->findFirstNode(value) != QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert an externally created node.
|
||||||
|
// may need to take extra care when using this method.
|
||||||
|
Node* insertNode (Node* pos, Node* node);
|
||||||
|
|
||||||
|
// create a new node to hold the value and insert it.
|
||||||
|
Node* insertValue (Node* pos, const T& value)
|
||||||
|
{
|
||||||
|
Node* n = this->mp.isEnabled()?
|
||||||
|
(new(&mp) Node(value)): (new Node(value));
|
||||||
|
return this->insertNode (pos, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
T& insert (Node* node, const T& value)
|
||||||
|
{
|
||||||
|
return this->insertValue(node, value)->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& insert (qse_size_t index, const T& value)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (index <= node_count);
|
||||||
|
|
||||||
|
if (index >= node_count)
|
||||||
|
{
|
||||||
|
// insert it at the back
|
||||||
|
return this->insert ((Node*)QSE_NULL, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->insert (this->getNodeAt(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
T& prepend (const T& value)
|
||||||
|
{
|
||||||
|
return this->insert (this->head_node, value);
|
||||||
|
}
|
||||||
|
T& append (const T& value)
|
||||||
|
{
|
||||||
|
return this->insert ((Node*)QSE_NULL, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* prependNode (Node* node)
|
||||||
|
{
|
||||||
|
return this->insertNode (head_node, node);
|
||||||
|
}
|
||||||
|
Node* appendNode (Node* node)
|
||||||
|
{
|
||||||
|
return this->insertNode ((Node*)QSE_NULL, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* prependValue (const T& value)
|
||||||
|
{
|
||||||
|
return this->insertValue (this->head_node, value);
|
||||||
|
}
|
||||||
|
Node* appendValue (const T& value)
|
||||||
|
{
|
||||||
|
return this->insertValue ((Node*)QSE_NULL, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prependAll (const LinkedList<T>& list)
|
||||||
|
{
|
||||||
|
Node* n = list.tail_node;
|
||||||
|
|
||||||
|
if (&list == this)
|
||||||
|
{
|
||||||
|
Node* head = list.head_node;
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
this->prepend (n->value);
|
||||||
|
if (n == head) break;
|
||||||
|
n = (Node*)n->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
this->prepend (n->value);
|
||||||
|
n = (Node*)n->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendAll (const LinkedList<T>& list)
|
||||||
|
{
|
||||||
|
Node* n = list.head_node;
|
||||||
|
|
||||||
|
if (&list == this)
|
||||||
|
{
|
||||||
|
Node* tail = list.tail_node;
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
this->append (n->value);
|
||||||
|
if (n == tail) break;
|
||||||
|
n = n->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
this->append (n->value);
|
||||||
|
n = n->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a node from the list without freeing it.
|
||||||
|
// take extra care when using this method as the node
|
||||||
|
// can be freed through the memory pool when the list is
|
||||||
|
// destructed if the memory pool is enabled.
|
||||||
|
Node* yield (Node* node, bool clear_links = true);
|
||||||
|
|
||||||
|
// remove a node from the list and free it.
|
||||||
|
void remove (Node* node)
|
||||||
|
{
|
||||||
|
this->yield (node, false);
|
||||||
|
if (mp.isDisabled()) delete node;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->~Node ();
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
node->operator delete (node, &mp);
|
||||||
|
#else
|
||||||
|
node->dispose (node, &mp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove (qse_size_t index)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (index < node_count);
|
||||||
|
|
||||||
|
Node* np = this->head_node;
|
||||||
|
while (index > 0)
|
||||||
|
{
|
||||||
|
np = np->next;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->remove (np);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* yieldByValue (const T& value, bool clear_links = true)
|
||||||
|
{
|
||||||
|
Node* p = this->findFirstNode (value);
|
||||||
|
Node* p = this->findFirstNode (value);
|
||||||
|
if (p == QSE_NULL) return -1;
|
||||||
|
return this->yield (p, clear_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t removeByValue (const T& value)
|
||||||
|
{
|
||||||
|
Node* p = this->findFirstNode (value);
|
||||||
|
if (!p) return 0;
|
||||||
|
this->remove (p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \return the number of items deleted
|
||||||
|
qse_size_t removeAllByValue (const T& value)
|
||||||
|
{
|
||||||
|
Node* p = this->findFirstNode (value);
|
||||||
|
if (!p) return 0;
|
||||||
|
|
||||||
|
qse_size_t cnt = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Node* tmp = p->next;
|
||||||
|
this->remove (p);
|
||||||
|
cnt++;
|
||||||
|
p = this->findFirstNode (value, tmp);
|
||||||
|
}
|
||||||
|
while (p);
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeHead ()
|
||||||
|
{
|
||||||
|
this->remove (this->head_node);
|
||||||
|
}
|
||||||
|
void removeTail ()
|
||||||
|
{
|
||||||
|
this->remove (this->tail_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* getHeadNode () const
|
||||||
|
{
|
||||||
|
return this->head_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* getTailNode () const
|
||||||
|
{
|
||||||
|
return this->tail_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* getNodeAt (qse_size_t index) const
|
||||||
|
{
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
|
||||||
|
register Node* np;
|
||||||
|
register qse_size_t cnt;
|
||||||
|
|
||||||
|
if (index < (this->node_count >> 1))
|
||||||
|
{
|
||||||
|
for (np = this->head_node, cnt = 0; cnt < index; np = np->next, cnt++)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (np != QSE_NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (np = this->tail_node, cnt = this->node_count - 1; cnt > index; np = np->prev, cnt--)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (np != QSE_NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return np;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& getValueAt (qse_size_t index)
|
||||||
|
{
|
||||||
|
// same as operator[]
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
Node* np = this->getNodeAt (index);
|
||||||
|
return np->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& getValueAt (qse_size_t index) const
|
||||||
|
{
|
||||||
|
// same as operator[]
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
Node* np = this->getNodeAt (index);
|
||||||
|
return np->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAt (qse_size_t index, const T& value)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (index < this->node_count);
|
||||||
|
Node* np = this->getNodeAt (index);
|
||||||
|
np->value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* findFirstNode (const T& value) const
|
||||||
|
{
|
||||||
|
for (Node* p = this->head_node; p; p = p->next)
|
||||||
|
{
|
||||||
|
if (value == p->value) return p;
|
||||||
|
}
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* findLastNode (const T& value) const
|
||||||
|
{
|
||||||
|
for (Node* p = tail_node; p; p = p->prev)
|
||||||
|
{
|
||||||
|
if (value == p->value) return p;
|
||||||
|
}
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* findFirstNode (const T& value, Node* head) const
|
||||||
|
{
|
||||||
|
for (Node* p = head; p; p = p->next)
|
||||||
|
{
|
||||||
|
if (value == p->value) return p;
|
||||||
|
}
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* findLastNode (const T& value, Node* tail) const
|
||||||
|
{
|
||||||
|
for (Node* p = tail; p; p = p->prev)
|
||||||
|
{
|
||||||
|
if (value == p->value) return p;
|
||||||
|
}
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t findFirstIndex (const T& value) const
|
||||||
|
{
|
||||||
|
qse_size_t index = 0;
|
||||||
|
for (Node* p = this->head_node; p; p = p->next)
|
||||||
|
{
|
||||||
|
if (value == p->value) return index;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t findLastIndex (const T& value) const
|
||||||
|
{
|
||||||
|
qse_size_t index = node_count;
|
||||||
|
for (Node* p = tail_node; p; p = p->prev)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
if (value == p->value) return index;
|
||||||
|
}
|
||||||
|
return INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear ()
|
||||||
|
{
|
||||||
|
Node* p, * saved;
|
||||||
|
|
||||||
|
p = this->head_node;
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
saved = p->next;
|
||||||
|
|
||||||
|
if (this->mp.isDisabled()) delete p;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->~Node ();
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
p->operator delete (p, &mp);
|
||||||
|
#else
|
||||||
|
p->dispose (p, &mp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
this->node_count--;
|
||||||
|
p = saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->head_node = this->tail_node = QSE_NULL;
|
||||||
|
QSE_ASSERT (this->node_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearout ()
|
||||||
|
{
|
||||||
|
this->clear ();
|
||||||
|
this->mp.dispose ();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int (LinkedList<T>::*TraverseCallback) (Node* start, Node* cur);
|
||||||
|
|
||||||
|
void traverse (TraverseCallback callback, Node* start)
|
||||||
|
{
|
||||||
|
Node* cur, * prev, * next;
|
||||||
|
|
||||||
|
cur = start;
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
prev = cur->prev;
|
||||||
|
next = cur->next;
|
||||||
|
|
||||||
|
int n = (this->*callback) (start, cur);
|
||||||
|
|
||||||
|
if (n > 0) cur = next;
|
||||||
|
else if (n < 0) cur = prev;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MemoryPool mp;
|
||||||
|
Node* head_node;
|
||||||
|
Node* tail_node;
|
||||||
|
qse_size_t node_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename LinkedList<T>::Node* LinkedList<T>::insertNode (Node* pos, Node* node)
|
||||||
|
{
|
||||||
|
if (pos == QSE_NULL)
|
||||||
|
{
|
||||||
|
if (this->node_count == 0)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (head_node == QSE_NULL);
|
||||||
|
QSE_ASSERT (tail_node == QSE_NULL);
|
||||||
|
this->head_node = this->tail_node = node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->prev = this->tail_node;
|
||||||
|
this->tail_node->next = node;
|
||||||
|
this->tail_node = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->next = pos;
|
||||||
|
node->prev = pos->prev;
|
||||||
|
if (pos->prev) pos->prev->next = node;
|
||||||
|
else this->head_node = node;
|
||||||
|
pos->prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->node_count++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename LinkedList<T>::Node* LinkedList<T>::yield (Node* node, bool clear_links)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (node != QSE_NULL);
|
||||||
|
QSE_ASSERT (this->node_count > 0);
|
||||||
|
|
||||||
|
if (node->next)
|
||||||
|
node->next->prev = node->next;
|
||||||
|
else
|
||||||
|
this->tail_node = node->prev;
|
||||||
|
|
||||||
|
if (node->prev)
|
||||||
|
node->prev->next = node->next;
|
||||||
|
else
|
||||||
|
this->head_node = node->next;
|
||||||
|
|
||||||
|
this->node_count--;
|
||||||
|
|
||||||
|
if (clear_links)
|
||||||
|
{
|
||||||
|
node->next = QSE_NULL;
|
||||||
|
node->prev = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_END_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -50,6 +50,8 @@ pkginclude_HEADERS = \
|
|||||||
xma.h
|
xma.h
|
||||||
|
|
||||||
if ENABLE_CXX
|
if ENABLE_CXX
|
||||||
pkginclude_HEADERS += Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
pkginclude_HEADERS += \
|
||||||
|
Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
|
||||||
|
LinkedList.hpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -50,7 +50,10 @@ PRE_UNINSTALL = :
|
|||||||
POST_UNINSTALL = :
|
POST_UNINSTALL = :
|
||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
@ENABLE_CXX_TRUE@am__append_1 = Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
@ENABLE_CXX_TRUE@am__append_1 = \
|
||||||
|
@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \
|
||||||
|
@ENABLE_CXX_TRUE@ LinkedList.hpp
|
||||||
|
|
||||||
subdir = include/qse/cmn
|
subdir = include/qse/cmn
|
||||||
DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \
|
DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \
|
||||||
$(srcdir)/Makefile.in
|
$(srcdir)/Makefile.in
|
||||||
@ -87,7 +90,8 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \
|
|||||||
lda.h main.h map.h mb8.h mbwc.h mem.h mux.h nwad.h nwif.h \
|
lda.h main.h map.h mb8.h mbwc.h mem.h mux.h nwad.h nwif.h \
|
||||||
nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \
|
nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \
|
||||||
sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \
|
sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \
|
||||||
utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
utf8.h xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp \
|
||||||
|
Mpoolable.hpp LinkedList.hpp
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
am__vpath_adj = case $$p in \
|
am__vpath_adj = case $$p in \
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
|
107
qse/include/qse/cmn/Mpool.hpp
Normal file
107
qse/include/qse/cmn/Mpool.hpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_MPOOL_HPP_
|
||||||
|
#define _QSE_CMN_MPOOL_HPP_
|
||||||
|
|
||||||
|
#include <qse/Uncopyable.hpp>
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocator for fixed-size data
|
||||||
|
//
|
||||||
|
|
||||||
|
class Mpool: public Uncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DEFAULT_BLOCK_SIZE = 128
|
||||||
|
};
|
||||||
|
|
||||||
|
Mpool (
|
||||||
|
qse_size_t datum_size,
|
||||||
|
qse_size_t block_size = DEFAULT_BLOCK_SIZE);
|
||||||
|
~Mpool ();
|
||||||
|
|
||||||
|
void* allocate ();
|
||||||
|
void dispose (void* ptr);
|
||||||
|
void dispose ();
|
||||||
|
|
||||||
|
inline bool isEnabled () const
|
||||||
|
{
|
||||||
|
return this->datum_size > 0 && this->block_size > 0;
|
||||||
|
}
|
||||||
|
inline bool isDisabled () const
|
||||||
|
{
|
||||||
|
return this->datum_size <= 0 || this->block_size <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline qse_size_t datumSize () const
|
||||||
|
{
|
||||||
|
return this->datum_size;
|
||||||
|
}
|
||||||
|
inline qse_size_t blockSize () const
|
||||||
|
{
|
||||||
|
return this->block_size;
|
||||||
|
}
|
||||||
|
inline void setBlockSize (qse_size_t blockSize)
|
||||||
|
{
|
||||||
|
this->block_size = blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
qse_size_t nalloc;
|
||||||
|
qse_size_t navail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct Block
|
||||||
|
{
|
||||||
|
Block* next;
|
||||||
|
//qse_uint8_t data[0];
|
||||||
|
};
|
||||||
|
struct Chain
|
||||||
|
{
|
||||||
|
Chain* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
Block* mp_blocks;
|
||||||
|
Chain* free_list;
|
||||||
|
qse_size_t datum_size;
|
||||||
|
qse_size_t block_size;
|
||||||
|
|
||||||
|
void add_block ();
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_END_NAMESPACE(QSE)
|
||||||
|
////////////////////////////////
|
||||||
|
#endif
|
||||||
|
|
73
qse/include/qse/cmn/Mpoolable.hpp
Normal file
73
qse/include/qse/cmn/Mpoolable.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_MPOOLABLE_HPP_
|
||||||
|
#define _QSE_CMN_MPOOLABLE_HPP_
|
||||||
|
|
||||||
|
#include <qse/cmn/Mpool.hpp>
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
class Mpoolable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef qse_size_t mp_size_t;
|
||||||
|
|
||||||
|
inline void* operator new (mp_size_t size)
|
||||||
|
{
|
||||||
|
return ::operator new (size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete (void* ptr)
|
||||||
|
{
|
||||||
|
::operator delete (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* operator new (mp_size_t /*size*/, Mpool* mp)
|
||||||
|
{
|
||||||
|
return mp->allocate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
void operator delete (void* ptr, Mpool* mp)
|
||||||
|
{
|
||||||
|
mp->dispose (ptr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline void dispose (void* ptr, Mpool* mp)
|
||||||
|
{
|
||||||
|
mp->dispose (ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_END_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
#endif
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef _QSE_HTTP_HTTP_H_
|
#ifndef _QSE_HTTP_HTTP_H_
|
||||||
#define _QSE_HTTP_HTTP_H_
|
#define _QSE_HTTP_HTTP_H_
|
||||||
|
|
||||||
/** @file
|
/** \file
|
||||||
* This file provides basic data types and functions for the http protocol.
|
* This file provides basic data types and functions for the http protocol.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ enum qse_http_range_type_t
|
|||||||
typedef enum qse_http_range_type_t qse_http_range_type_t;
|
typedef enum qse_http_range_type_t qse_http_range_type_t;
|
||||||
/**
|
/**
|
||||||
* The qse_http_range_t type defines a structure that can represent
|
* The qse_http_range_t type defines a structure that can represent
|
||||||
* a value for the @b Range: http header.
|
* a value for the \b Range: http header.
|
||||||
*
|
*
|
||||||
* If type is #QSE_HTTP_RANGE_NONE, this range is not valid.
|
* If type is #QSE_HTTP_RANGE_NONE, this range is not valid.
|
||||||
*
|
*
|
||||||
@ -141,10 +141,10 @@ typedef enum qse_http_range_type_t qse_http_range_type_t;
|
|||||||
*
|
*
|
||||||
* You should adjust a range when the size that this range belongs to is
|
* You should adjust a range when the size that this range belongs to is
|
||||||
* made known. See this code:
|
* made known. See this code:
|
||||||
* @code
|
* \code
|
||||||
* range.from = total_size - range.to;
|
* range.from = total_size - range.to;
|
||||||
* range.to = range.to + range.from - 1;
|
* range.to = range.to + range.from - 1;
|
||||||
* @endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* If type is #QSE_HTTP_RANGE_PROPER, 'from' and 'to' represents a proper range
|
* If type is #QSE_HTTP_RANGE_PROPER, 'from' and 'to' represents a proper range
|
||||||
* where the value of 0 indicates the first byte. This doesn't require any
|
* where the value of 0 indicates the first byte. This doesn't require any
|
||||||
|
@ -141,7 +141,7 @@ if ENABLE_CXX
|
|||||||
|
|
||||||
lib_LTLIBRARIES += libqsecmnxx.la
|
lib_LTLIBRARIES += libqsecmnxx.la
|
||||||
libqsecmnxx_la_SOURCES = \
|
libqsecmnxx_la_SOURCES = \
|
||||||
Mmgr.cpp StdMmgr.cpp
|
Mmgr.cpp StdMmgr.cpp Mpool.cpp
|
||||||
libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||||
libqsecmnxx_la_LIBADD =
|
libqsecmnxx_la_LIBADD =
|
||||||
|
|
||||||
|
@ -149,8 +149,9 @@ libqsecmn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
|||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
$(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@
|
$(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
libqsecmnxx_la_DEPENDENCIES =
|
libqsecmnxx_la_DEPENDENCIES =
|
||||||
am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp
|
am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp Mpool.cpp
|
||||||
@ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo
|
@ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo \
|
||||||
|
@ENABLE_CXX_TRUE@ Mpool.lo
|
||||||
libqsecmnxx_la_OBJECTS = $(am_libqsecmnxx_la_OBJECTS)
|
libqsecmnxx_la_OBJECTS = $(am_libqsecmnxx_la_OBJECTS)
|
||||||
libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
||||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
||||||
@ -433,7 +434,7 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
|
|||||||
libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||||
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
|
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
|
||||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
|
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
|
||||||
@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp
|
@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp Mpool.cpp
|
||||||
|
|
||||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
@ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD =
|
@ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD =
|
||||||
@ -515,6 +516,7 @@ distclean-compile:
|
|||||||
-rm -f *.tab.c
|
-rm -f *.tab.c
|
||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mpool.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-base64.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-base64.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-rand.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-rand.Plo@am__quote@
|
||||||
|
127
qse/lib/cmn/Mpool.cpp
Normal file
127
qse/lib/cmn/Mpool.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/cmn/Mpool.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: can i use QSE_MMGR_XXXXX instead of ::new and ::delete???
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Mpool::Mpool (qse_size_t datum_size, qse_size_t block_size)
|
||||||
|
{
|
||||||
|
if (datum_size > 0 && datum_size < QSE_SIZEOF(void*))
|
||||||
|
datum_size = QSE_SIZEOF(void*);
|
||||||
|
|
||||||
|
this->mp_blocks = QSE_NULL;
|
||||||
|
this->free_list = QSE_NULL;
|
||||||
|
this->datum_size = datum_size;
|
||||||
|
this->block_size = block_size;
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
this->navail = 0;
|
||||||
|
this->nalloc = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Mpool::~Mpool ()
|
||||||
|
{
|
||||||
|
this->dispose ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Mpool::allocate ()
|
||||||
|
{
|
||||||
|
if (this->datum_size <= 0 || this->block_size <= 0) return QSE_NULL;
|
||||||
|
|
||||||
|
void* ptr = this->free_list;
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
this->add_block ();
|
||||||
|
ptr = this->free_list;
|
||||||
|
}
|
||||||
|
this->free_list = this->free_list->next;
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
this->navail--;
|
||||||
|
#endif
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mpool::dispose (void* ptr)
|
||||||
|
{
|
||||||
|
((Chain*)ptr)->next = this->free_list;
|
||||||
|
this->free_list = (Chain*)ptr;
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
this->navail++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mpool::dispose ()
|
||||||
|
{
|
||||||
|
Block* block = this->mp_blocks;
|
||||||
|
while (block)
|
||||||
|
{
|
||||||
|
Block* next = block->next;
|
||||||
|
::delete[] block;
|
||||||
|
block = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->free_list = QSE_NULL;
|
||||||
|
this->mp_blocks = QSE_NULL;
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
this->navail = 0;
|
||||||
|
this->nalloc = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mpool::add_block ()
|
||||||
|
{
|
||||||
|
QSE_ASSERT (this->datum_size > 0 && this->block_size > 0);
|
||||||
|
|
||||||
|
Block* block = (Block*)::new qse_uint8_t[
|
||||||
|
QSE_SIZEOF(Block) + this->block_size * this->datum_size];
|
||||||
|
|
||||||
|
//this->free_list = (Chain*)block->data;
|
||||||
|
this->free_list = (Chain*)(block + 1);
|
||||||
|
Chain* ptr = this->free_list;
|
||||||
|
for (qse_size_t i = 0; i < this->block_size - 1; i++)
|
||||||
|
{
|
||||||
|
Chain* next = (Chain*)((qse_uint8_t*)ptr + this->datum_size);
|
||||||
|
ptr->next = next;
|
||||||
|
ptr = next;
|
||||||
|
}
|
||||||
|
ptr->next = QSE_NULL;
|
||||||
|
|
||||||
|
block->next = this->mp_blocks;
|
||||||
|
this->mp_blocks = block;
|
||||||
|
#if defined(QSE_DEBUG_MPOOL)
|
||||||
|
this->navail += this->block_size;
|
||||||
|
this->nalloc += this->block_size;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
QSE_END_NAMESPACE(QSE)
|
||||||
|
/////////////////////////////////
|
@ -36,7 +36,7 @@ QSE_BEGIN_NAMESPACE(QSE)
|
|||||||
int Sed::open ()
|
int Sed::open ()
|
||||||
{
|
{
|
||||||
sed = qse_sed_open (this->mmgr, QSE_SIZEOF(Sed*));
|
sed = qse_sed_open (this->mmgr, QSE_SIZEOF(Sed*));
|
||||||
if (sed == QSE_NULL) return -1;
|
if (!sed) return -1;
|
||||||
*(Sed**)QSE_XTN(sed) = this;
|
*(Sed**)QSE_XTN(sed) = this;
|
||||||
|
|
||||||
dflerrstr = qse_sed_geterrstr (sed);
|
dflerrstr = qse_sed_geterrstr (sed);
|
||||||
@ -47,7 +47,7 @@ int Sed::open ()
|
|||||||
|
|
||||||
void Sed::close ()
|
void Sed::close ()
|
||||||
{
|
{
|
||||||
if (sed != QSE_NULL)
|
if (sed)
|
||||||
{
|
{
|
||||||
qse_sed_close (sed);
|
qse_sed_close (sed);
|
||||||
sed = QSE_NULL;
|
sed = QSE_NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user