MQLplus/lib_structures/base/lib_base_buffers.mqh
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

306 lines
10 KiB
MQL5

#ifndef LIB_MQLPLUS_BASE_BUFFERS_TEMPLATES_MQH_INCLUDED
#define LIB_MQLPLUS_BASE_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 mt5api Array
//
//#include <MQLplus/lib_mqlplus/mt5api/lib_mt5api_Array_tpl.mqh>
#ifndef LIB_MQLPLUS
#define mqp_ArrayResize ArrayResize
#endif
/*********************************************************************************************************************************************************/
/* */
/* MQLplus data structures */
/* */
/*********************************************************************************************************************************************************/
///////////////////////////////////////
//
// First In Last Out Buffer
//
// Base class object
template <typename T>
class _buffer_filo
{
protected:
// Internal state
int _size;
int _ptr;
// Buffer
T buffer[];
T _empty;
public:
// Constructor / Destructor
// Default constructor
_buffer_filo() :
_size(NULL),
_ptr(-1)
{ mqp_ArrayResize(buffer, NULL); };
// Buffer functions
// Reset
void reset()
{
::ArrayFree(buffer);
_size = NULL;
_ptr = -1;
};
// Size
int size() const
{ return(_ptr + 1); };
// Pop functions
// Pop 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) )
{ pop(); cnt--; }
};
// Assignment operator
void operator=(const _buffer_filo& p_in)
{
_size = p_in.size();
_ptr = mqp_ArrayResize(buffer, _size) - 1;
for(int cnt = NULL; (cnt < _size) && !_StopFlag; cnt++)
{ buffer[cnt] = p_in[cnt]; }
};
// 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
//
template <typename T>
struct buffer_fifo
{
protected:
// Internal state
uint pop_buffer;
uint pop_ptr;
bool push_buffer;
uint push_ptr;
uint buffer_1_end;
uint buffer_1_size;
uint buffer_2_end;
uint buffer_2_size;
uint element_cnt;
T _empty;
// Buffer
T buffer_1[];
T buffer_2[];
public:
// Constructor
buffer_fifo() :
pop_buffer (0x01),
pop_ptr (NULL),
push_buffer (false),
push_ptr (NULL),
buffer_1_end (NULL),
buffer_1_size (NULL),
buffer_2_end (NULL),
buffer_2_size (NULL),
element_cnt (NULL)
{
::ZeroMemory(_empty);
mqp_ArrayResize(buffer_1, NULL);
mqp_ArrayResize(buffer_1, NULL);
};
// Reset
void reset()
{
mqp_ArrayResize(buffer_1, NULL, (4096 / sizeof(T)));
mqp_ArrayResize(buffer_2, NULL, (4096 / sizeof(T)));
pop_buffer = 0x01;
pop_ptr = NULL;
push_buffer = false;
push_ptr = NULL;
buffer_1_end = NULL;
buffer_1_size = NULL;
buffer_2_end = NULL;
buffer_2_size = NULL;
element_cnt = NULL;
};
// Size
int size() const
{ return((int)(element_cnt - (element_cnt > NULL))); };
// Push new element
void push(const T &p_in)
{
const bool buffer_change = ((!(pop_buffer == 0x01) == push_buffer) && (pop_ptr > NULL));
push_buffer = (buffer_change) ? !push_buffer : push_buffer;
push_ptr = (buffer_change) ? NULL : push_ptr;
element_cnt += 1 + (element_cnt == NULL);
if(push_buffer)
{
buffer_2_size = (buffer_2_size > push_ptr) ? buffer_2_size : mqp_ArrayResize(buffer_2, buffer_2_size + 1);
buffer_2[push_ptr++] = p_in;
buffer_2_end = push_ptr;
return;
}
buffer_1_size = (buffer_1_size > push_ptr) ? buffer_1_size : mqp_ArrayResize(buffer_1, buffer_1_size + 1);
buffer_1[push_ptr++] = p_in;
buffer_1_end = push_ptr;
return;
};
// Pop oldest element
T pop()
{
// Switch buffer
switch(pop_buffer * (element_cnt != NULL))
{
case 0x00:
return(_empty);
case 0x01:
pop_buffer = (pop_ptr == buffer_1_end) ? 0x02 : 0x01;
pop_ptr = (pop_ptr == buffer_1_end) ? NULL : pop_ptr;
break;
case 0x02:
pop_buffer = (pop_ptr == buffer_2_end) ? 0x01 : 0x02;
pop_ptr = (pop_ptr == buffer_2_end) ? NULL : pop_ptr;
break;
}
// Element counter
element_cnt -= (1 + (element_cnt == 2));
// Return
switch(pop_buffer)
{
case 0x01:
return(buffer_1[pop_ptr++]);
case 0x02:
return(buffer_2[pop_ptr++]);
}
// Return
return(_empty);
};
// Access operator
T operator[](const int _idx) const
{
const uint idx = (_idx < NULL) ? element_cnt - _idx : _idx;
uint cnt_buffer = NULL;
switch(pop_buffer * ((element_cnt != NULL) && ((element_cnt - 1) > idx)))
{
case 0x01:
cnt_buffer = buffer_1_end - pop_ptr;
return((idx < cnt_buffer) ? buffer_1[pop_ptr + idx] : buffer_2[idx - cnt_buffer]);
case 0x02:
cnt_buffer = buffer_2_end - pop_ptr;
return((idx < cnt_buffer) ? buffer_2[pop_ptr + idx] : buffer_1[idx - cnt_buffer]);
}
return(_empty);
};
};
//
// END MQL data structures */
//*********************************************************************************************************************************************************/
#endif // LIB_MQLPLUS_BASE_BUFFERS_TEMPLATES_MQH_INCLUDED