MQLArticles/Utils/FA/String/String.mqh
2026-09-15 15:46:48 -05:00

201 lines
5.2 KiB
MQL5

//+------------------------------------------------------------------+
//| String.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
#ifndef MQLARTICLES_UTILS_FA_STRING_STRING_MQH
#define MQLARTICLES_UTILS_FA_STRING_STRING_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| Macros |
//+------------------------------------------------------------------+
#define StringSubstrRange(s, ps, pe) s.Substr(ps,((pe)-(ps))+1)
//---
#define StringTrim(text) \
StringTrimRight(text); \
StringTrimLeft(text);
//+------------------------------------------------------------------+
//| Funcinoes extra de string |
//+------------------------------------------------------------------+
class CStringFunc
{
public:
CStringFunc(void) {}
~CStringFunc(void) {}
//--- Find
static __forceinline int FindCh(const string &str, const uchar c, int l, int r = 0);
//--- RFind
static __forceinline int RFindCh(const string &str, const uchar c, int r);
//---
template <typename TValue, typename TConvert>
static ulong ToVector(const string& str, vector<TValue>& vec, ushort sep)
{
//---
int pos = 0;
const int len = StringLen(str);
//TConvert::s_len = len;
//---
ulong r = vec.Size();
//---
ulong w = 0;
//--
while(pos < len)
{
//---
const ushort c = str[pos];
if(c < 33 || c == sep)
{
pos++;
continue;
}
//---
if(w >= r)
{
r = (r << 1) + 8;
vec.Resize(r);
}
//---
// CAracter real
// la idea es que convert haga su trabajo y pare hasta donde considere que debe
// luego nos deja.. y segimos nosotrs..
TConvert::ToValue(str, pos, vec[w++], len);
}
//---
return w;
}
//---
template <typename TValue, typename TConvert>
static int ToArr(const string& str, TValue& arr[], ushort sep)
{
//---
int pos = 0;
const int len = StringLen(str);
//TConvert::s_len = len;
//---
int r = ArraySize(arr);
//---
int w = 0;
//--
while(pos < len)
{
//---
const ushort c = str[pos];
if(c < 33 || c == sep)
{
pos++;
continue;
}
//---
if(w >= r)
{
r = (r << 1) + 8;
ArrayResize(arr, r);
}
//---
// CAracter real
// la idea es que convert haga su trabajo y pare hasta donde considere que debe
// luego nos deja.. y segimos nosotrs..
TConvert::ToValue(str, pos, arr[w++], len);
}
//---
return w;
}
//--- Split complejo (por "")
static int StringSplitStr(const string& str, const string& sep, string& arr[], int reserve);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static int CStringFunc::StringSplitStr(const string &str, const string &sep, string &arr[], int reserve)
{
//---
if(str == NULL)
return -1; // Vacio
//---
int last_start = 0;
const int len_str = int(str.Length());
const int len_sep = int(sep.Length());
int s = 0;
int r = ArrayResize(arr, reserve);
// 1||N||0||1||sAdasdasdasd"
//---
while(true)
{
int init;
if((init = str.Find(sep, last_start)) >= 0)
{
//---
if(s >= r)
{
r <<= 1;
ArrayResize(arr, r);
}
//---
arr[s++] = StringSubstrRange(str, last_start, init - 1);
last_start = init + len_sep;
}
else
{
// resize fijo desde ultima pos hasta todo..
arr[ArrayResize(arr, (++r)) - 1] = str.Substr(last_start, len_str);
return r;
}
}
}
//+------------------------------------------------------------------+
//| Find |
//+------------------------------------------------------------------+
static __forceinline int CStringFunc::FindCh(const string &str, const uchar c, int l, int r = 0)
{
l += r;
for(; r < l; r++)
if(str[r] == c)
return r; // posicion absoluta
return -1;
}
//+------------------------------------------------------------------+
//| RFind |
//+------------------------------------------------------------------+
static __forceinline int CStringFunc::RFindCh(const string &str, const uchar c, int r)
{
for(; r >= 0; r--)
if(str[r] == c)
return r; // posicion absoluta
return -1;
}
}
#endif // MQLARTICLES_UTILS_FA_STRING_STRING_MQH