ETE/ext_includes/lib_buffers.mqh
super.admin 743d6cfc25 convert
2025-05-30 14:53:15 +02:00

363 lines
11 KiB
MQL5

#ifndef LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED
#define LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED
#property version "1.2";
/**********************************************************************************
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
*
* This file is the buffers include file.
*
* MQLplus, including this file may not be copied and/or distributed
* without explecit permit by the author.
* Author Dominik Egert / Freie Netze UG.
**********************************************************************************
*
* Version: 1.2
* State: production
*
* File information
* ================
*
*
*
*
*/
#ifdef DBG_MSG_TRACE_FILE_LOADER
DBG_MSG_TRACE_FILE_LOADER;
#endif
// Include base buffers
#include "lib_base_buffers.mqh"
/*********************************************************************************************************************************************************/
/* */
/* MQLplus data structures */
/* */
/*********************************************************************************************************************************************************/
///////////////////////////////////////
//
// Bitflag Buffer
//
struct buffer_bitflags pack(8)
{
private:
// Local storage
int _arr_size;
ulong bit_flags[];
public:
// Constructor
buffer_bitflags() :
_arr_size (NULL)
{ };
buffer_bitflags(const buffer_bitflags& p_in)
{ operator=(p_in); }
// Assignment operator
void operator=(const buffer_bitflags& p_in)
{
_arr_size = p_in._arr_size;
::ArrayCopy(bit_flags, p_in.bit_flags);
}
void operator=(const int p_in)
{
const int _p_in = p_in * ((p_in < NULL) ? -1 : 1);
const int ptr = _resize(_p_in);
const ulong flag = 1 << (_p_in % 64);
bit_flags[ptr] |= flag;
bit_flags[ptr] &= (p_in < NULL) ? ~flag : bit_flags[ptr];
}
// Access operator
bool operator[](const int p_in)
{ return((bit_flags[_resize(p_in)] & (1 << (p_in % 64))) != NULL); }
// Comparison operators
const bool operator==(const int p_in)
{ return((bit_flags[_resize(p_in)] & (1 << (p_in % 64))) == ((p_in < NULL) ? NULL : (1 << (p_in % 64)))); }
const bool operator!=(const int p_in)
{ return((bit_flags[_resize(p_in)] & (1 << (p_in % 64))) != ((p_in < NULL) ? NULL : (1 << (p_in % 64)))); }
private:
// Auto-Resize function
int _resize(const int p_in)
{
const int ptr = p_in / 64;
_arr_size = (_arr_size <= ptr) ? ::ArrayResize(bit_flags, ptr + 1) : _arr_size;
return(ptr);
}
};
///////////////////////////////////////
//
// First In Last Out Buffer
//
// Derived simple type class object
template <typename T>
class buffer_filo : public _buffer_filo<T>
{
public:
// Constructor / Destructor
// Default constructor
buffer_filo() :
_buffer_filo()
{ };
// Destructor
~buffer_filo()
{ _buffer_filo<T>::reset(); };
// Push functions
// Push new element
bool push(const T& p_in)
{
_ptr = (_ptr == _size - 1) ? ::ArrayResize(buffer, _size + 1) - 1 : (_ptr + 1);
_size += (_ptr == _size);
buffer[_ptr] = p_in;
return(_ptr > -1);
};
// Assignment operator
bool operator+=(const T& p_in)
{ return(push(p_in)); };
};
// Derived complex type class object for pointers
template <typename T>
class ptr_buffer_filo : public _buffer_filo<T*>
{
private:
// Local storage
bool do_not_destroy;
public:
// Constructor / Destructor
// Default constructor
ptr_buffer_filo() :
_buffer_filo(),
do_not_destroy(false)
{ _empty = new T; };
// Specific constructor
ptr_buffer_filo(const bool _do_not_destroy) :
_buffer_filo(),
do_not_destroy(_do_not_destroy)
{ _empty = new T; };
// Destructor
~ptr_buffer_filo()
{
reset();
delete(_empty);
};
// Buffer functions
// Do not destroy
bool dnd(const bool _do_not_destroy = true)
{
do_not_destroy |= _do_not_destroy;
return(do_not_destroy);
};
// Reset
void reset()
{
int cnt = _ptr;
if(!do_not_destroy)
{
while(cnt > -1)
{
if(::CheckPointer(buffer[cnt]) == POINTER_DYNAMIC)
{ delete(buffer[cnt]); }
cnt--;
}
}
_buffer_filo<T*>::reset();
};
// Push functions
// Create and push new element
bool push(const T& _p_in)
{
T* p_in = new T;
*p_in = _p_in;
_ptr = (_ptr == _size - 1) ? ::ArrayResize(buffer, _size + 1) - 1 : (_ptr + 1);
_size += (_ptr == _size);
buffer[_ptr] = p_in;
return(_ptr > -1);
};
// Push new element
bool push(T* p_in)
{
_ptr = (_ptr == _size - 1) ? ::ArrayResize(buffer, _size + 1) - 1 : (_ptr + 1);
_size += (_ptr == _size);
buffer[_ptr] = p_in;
return(_ptr > -1);
};
// Pop functions
// Pop pointer to last element
T* pop()
{ return((_ptr < NULL) ? _empty : buffer[_ptr--]); };
// Pop by decrement
T* operator--(int)
{ return(pop()); };
// Pop by subtraction
void operator-=(const int p_in)
{
int cnt = p_in;
while( (cnt > NULL)
&& (_ptr > -1) )
{ delete(pop()); cnt--; }
};
// Assignment operators
bool operator+=(const T& p_in)
{ return(push(p_in)); };
bool operator+=(T* p_in)
{ return(push(p_in)); };
// Access operator
T* operator[](const int idx) const
{
const int _idx = (idx < NULL) ? (_ptr + idx) + 1 : idx;
return((_ptr == -1) || (_idx < NULL) ? _empty : buffer[_idx]);
}
};
///////////////////////////////////////
//
// First In First Out Buffer
//
///////////////////////////////////////
//
// Circle Buffer
//
template <typename T>
struct buffer_circle : public buffer_fifo<T>
{
private:
// Internal state
uint _max_size;
public:
// Default constructor
buffer_circle() :
buffer_fifo(),
_max_size (NULL)
{ };
// Defined constructor
buffer_circle(const uint size) :
buffer_fifo()
{ _max_size = size; };
// Overwritte size function
int size(const int max_size = -1)
{
switch(max_size)
{
case -1:
return(buffer_fifo<T>::size());
case 0x00:
_max_size = NULL;
buffer_fifo<T>::reset();
return(NULL);
}
while(buffer_fifo<T>::size() > max_size)
{ pop(); }
_max_size = max_size;
return(buffer_fifo<T>::size());
}
// Overwritten push function
void push(const T p_in)
{
if(buffer_fifo<T>::size() >= (int)_max_size)
{ pop(); }
buffer_fifo<T>::push(p_in);
}
// Overwritten push function
void push(const T &p_in)
{
if(buffer_fifo<T>::size() >= (int)_max_size)
{ pop(); }
buffer_fifo<T>::push(p_in);
}
};
//
// END MQL data structures */
//*********************************************************************************************************************************************************/
#endif // LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED