//+------------------------------------------------------------------+ //| UView.mqh | //| Copyright 2026, Niquel Mendoza | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Niquel Mendoza" #property link "https://www.mql5.com" #property strict #ifndef TSNSTD_SRC_STRING_UVIEW_MQH #define TSNSTD_SRC_STRING_UVIEW_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Buffer.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Generalmente no se chekea rangos solo en At #define MQLARTICLES_STRVIEW_IDX(POS) (m_start + (POS)) #define MQLARTICLES_STRVIEW_VAL(IDX) m_ctx.m_raw[MQLARTICLES_STRVIEW_IDX(IDX)] //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // View // las funciones de materializacion como SubStr entre otras... tineen 2-3 variantes Raw\Ctx\Buffer // - Raw: usa CharArray to string directo // - Ctx: usa el metodo que provee ctx.. // Las demas funciones como find etc.. trabajan sobre el buffer raw. //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template struct CStringView { TOuner* const m_ctx; int m_len; int m_start; //--- CStringView(const int start, const int len, TOuner* ctx) : m_len(len), m_start(start), m_ctx(ctx) {} //--- acceso __forceinline uchar operator[](const int pos) const { return MQLARTICLES_STRVIEW_VAL(pos); } __forceinline uchar At(const int pos) const { return pos < 0 || pos >= m_len ? 0 : MQLARTICLES_STRVIEW_VAL(pos); } __forceinline uchar Front() const { return MQLARTICLES_STRVIEW_VAL(0); } __forceinline uchar Back() const { return MQLARTICLES_STRVIEW_VAL(m_len - 1); } //--- modificadores de ventana __forceinline void RemovePrefix(int n) { m_len -= n; } __forceinline void RemoveSuffix(int n) { m_start += n; } //--- operaciones //- subtr (materializacino del view .. a string o uchar o tambien otro subview) // num no peude ser negativo si quiere usar "MAX" use INT_MAX o algo asi.. luego ya se noramloza con min // string final __forceinline string SubtrStr(const int pos, const int num, uint cp = CP_ACP) const; __forceinline int SubtrStr(uchar& in[], const int pos, const int num) const; // view __forceinline CStringView SubtrView(const int pos, const int num) const; //- compare __forceinline uchar CmpLex(const string& other) const; //- stats with __forceinline bool StartsWith(const uchar c) const { return MQLARTICLES_STRVIEW_VAL(0) == c; } __forceinline bool EndsWith(const uchar c) const { return MQLARTICLES_STRVIEW_VAL(m_len - 1) == c; } //- apis __forceinline void Trim(); //- find __forceinline int Find(const uchar c, int pos = 0) const; __forceinline int FindWithSwar(const uchar c, int pos = 0) const; //int FindWithMComp(const uchar c, int pos = 0) const; //- reverse find __forceinline int RFind(const uchar c, int rend = 1) const; //------- extras movidos para que compile (el compilador no esta tan bueno) template __forceinline uchar CmpLexW(const CStringView& other) const { return CStringBuffer::CmpLex( // this m_ctx.m_raw, m_start, m_len, // other other.m_ctx.m_raw, other.m_start, other.m_len ); } }; //+------------------------------------------------------------------+ //| Subtr | //+------------------------------------------------------------------+ template __forceinline string CStringView::SubtrStr(const int pos, const int num, uint cp = CP_ACP) const { return CharArrayToString(m_ctx.m_raw, MQLARTICLES_STRVIEW_IDX(pos), fmin(num, m_len), cp); } //+------------------------------------------------------------------+ template __forceinline int CStringView::SubtrStr(uchar& in[], const int pos, const int num) const { return ArrayCopy(in, m_ctx.m_raw, 0, MQLARTICLES_STRVIEW_IDX(pos), fmin(num, m_len)); } //+------------------------------------------------------------------+ // view template __forceinline CStringView CStringView::SubtrView(const int pos, const int num) const { // retorna el minimo de len si num es mucho se usa el len acutal si no el que se nos paso return CStringView(MQLARTICLES_STRVIEW_IDX(pos), fmin(num, m_len), m_ctx); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template __forceinline uchar CStringView::CmpLex(const string& other) const { return CStringBuffer::CmpLex(m_ctx.m_raw, m_start, m_len, other); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template __forceinline int CStringView::Find(const uchar c, int pos = 0) const { return CStringBuffer::Find(c, m_ctx.m_raw, MQLARTICLES_STRVIEW_IDX(pos), m_len, m_start); } //+------------------------------------------------------------------+ template __forceinline int CStringView::FindWithSwar(const uchar c, int pos = 0) const { return CStringBuffer::FindSwar(c, m_ctx.m_raw, MQLARTICLES_STRVIEW_IDX(pos), m_len, m_start); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template __forceinline int CStringView::RFind(const uchar c, int rend = 1) const { return CStringBuffer::RFind(c, m_ctx.m_raw, (m_start + m_len) - rend, m_start); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template __forceinline void CStringView::Trim() { CStringBuffer::Trim(m_ctx.m_raw, m_len, m_start); } } //+------------------------------------------------------------------+ #endif // TSNSTD_SRC_STRING_UVIEW_MQH