#ifndef LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED #define LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED #property version "1.2"; /********************************************************************************** * Copyright (C) 2010-2022 Dominik Egert * * 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 "base/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 class buffer_filo : public _buffer_filo { public: // Constructor / Destructor // Default constructor buffer_filo() : _buffer_filo() { }; // Destructor ~buffer_filo() { _buffer_filo::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 class ptr_buffer_filo : public _buffer_filo { 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::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 struct buffer_circle : public buffer_fifo { 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::size()); case 0x00: _max_size = NULL; buffer_fifo::reset(); return(NULL); } while(buffer_fifo::size() > max_size) { pop(); } _max_size = max_size; return(buffer_fifo::size()); } // Overwritten push function void push(const T p_in) { if(buffer_fifo::size() >= (int)_max_size) { pop(); } buffer_fifo::push(p_in); } // Overwritten push function void push(const T &p_in) { if(buffer_fifo::size() >= (int)_max_size) { pop(); } buffer_fifo::push(p_in); } }; // // END MQL data structures */ //*********************************************************************************************************************************************************/ #endif // LIB_MQLPLUS_BUFFERS_TEMPLATES_MQH_INCLUDED