MT5APIStorage.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. //+------------------------------------------------------------------+
  2. //| MetaTrader 5 API |
  3. //| Copyright 2000-2019, MetaQuotes Software Corp. |
  4. //| http://www.metaquotes.net |
  5. //+------------------------------------------------------------------+
  6. #pragma once
  7. #include <new.h>
  8. #include <stdlib.h>
  9. #include "MT5APISearch.h"
  10. //+------------------------------------------------------------------+
  11. //| Dynamic array base class |
  12. //| For POD data types only! |
  13. //+------------------------------------------------------------------+
  14. class CMTArrayBase
  15. {
  16. protected:
  17. UCHAR *m_data; // array
  18. UINT m_data_total; // array records total
  19. UINT m_data_max; // array records max
  20. UINT m_data_width; // record size in bytes
  21. UINT m_data_step; // reallocation step
  22. public:
  23. CMTArrayBase(const UINT width,const UINT step);
  24. virtual ~CMTArrayBase();
  25. //--- common properties
  26. UINT Total(void) const { return(m_data_total); }
  27. UINT Width(void) const { return(m_data_width); }
  28. UINT Max(void) const { return(m_data_max); }
  29. UINT Step(void) const { return(m_data_step); }
  30. bool Compare(const CMTArrayBase& array) const;
  31. //--- global management
  32. void Clear(void) { m_data_total=0; }
  33. bool Zero(void);
  34. void Shutdown(void);
  35. void Compact(void);
  36. bool Assign(const CMTArrayBase& array);
  37. void Swap(CMTArrayBase &arr);
  38. bool Reserve(const UINT size);
  39. bool Resize(const UINT size);
  40. //--- add
  41. bool Add(const void *elem) { return Add(elem,1); }
  42. bool Add(const void *elem,const UINT total);
  43. bool Add(const CMTArrayBase& array);
  44. bool AddRange(const CMTArrayBase& array,const UINT from,const UINT to);
  45. bool AddEmpty(const UINT total);
  46. void* Append(void);
  47. bool Insert(const UINT pos,const void *elem) { return Insert(pos,elem,1); }
  48. bool Insert(const UINT pos,const void *elem,const UINT total);
  49. bool InsertEmpty(const UINT pos,const UINT total);
  50. void* Insert(const void *elem,SMTSearch::SortFunctionPtr sort_function);
  51. //--- delete
  52. bool Delete(const UINT pos);
  53. bool Delete(const void *elem);
  54. bool DeleteRange(const UINT from,const UINT to);
  55. bool Remove(const void *elem,SMTSearch::SortFunctionPtr sort_function);
  56. //--- modify
  57. bool Update(const UINT pos,const void *elem);
  58. bool Shift(const UINT pos,const int shift);
  59. bool Trim(const UINT size);
  60. //--- data access
  61. bool Next(const UINT pos,void *elem) const;
  62. void* Next(const void *elem) const;
  63. void* Prev(const void *elem) const;
  64. const void* At(const UINT pos) const;
  65. void* At(const UINT pos);
  66. int Position(const void* ptr) const;
  67. bool Range(const UINT from,const UINT to,void* data) const;
  68. //--- sort & search
  69. void Sort(SMTSearch::SortFunctionPtr sort_function);
  70. void* Search(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  71. void* SearchGreatOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  72. void* SearchGreater(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  73. void* SearchLessOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  74. void* SearchLess(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  75. void* SearchLeft(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  76. void* SearchRight(const void *key,SMTSearch::SortFunctionPtr sort_function) const;
  77. protected:
  78. CMTArrayBase(void):m_data(NULL),m_data_total(0),m_data_max(0),m_data_width(0),m_data_step(0){}
  79. bool Realloc(const UINT total);
  80. };
  81. //+------------------------------------------------------------------+
  82. //| |
  83. //+------------------------------------------------------------------+
  84. inline CMTArrayBase::CMTArrayBase(const UINT width,const UINT step) : m_data(NULL),m_data_total(0),
  85. m_data_max(0),m_data_width(width),m_data_step(step)
  86. {
  87. }
  88. //+------------------------------------------------------------------+
  89. //| |
  90. //+------------------------------------------------------------------+
  91. inline CMTArrayBase::~CMTArrayBase(void)
  92. {
  93. Shutdown();
  94. }
  95. //+------------------------------------------------------------------+
  96. //| Zero all elements |
  97. //+------------------------------------------------------------------+
  98. inline bool CMTArrayBase::Zero(void)
  99. {
  100. if(m_data) ZeroMemory(m_data,m_data_width*m_data_max);
  101. return(true);
  102. }
  103. //+------------------------------------------------------------------+
  104. //| Full shutdown with memory free |
  105. //+------------------------------------------------------------------+
  106. inline void CMTArrayBase::Shutdown(void)
  107. {
  108. //--- clear all
  109. if(m_data) { delete[] m_data; m_data=NULL; }
  110. //--- zero sizes
  111. m_data_total=m_data_max=0;
  112. }
  113. //+------------------------------------------------------------------+
  114. //| Arrays comparison |
  115. //+------------------------------------------------------------------+
  116. inline bool CMTArrayBase::Compare(const CMTArrayBase& array) const
  117. {
  118. //--- check total and with
  119. if(m_data_width!=array.m_data_width || m_data_total!=array.m_data_total)
  120. return(false);
  121. //--- check total
  122. if(Total())
  123. {
  124. //--- check data
  125. if(!m_data || !array.m_data) return(false);
  126. //--- check record by record
  127. for(UINT i=0;i<m_data_total;i++)
  128. if(memcmp(At(i),array.At(i),m_data_width)!=0) return(false);
  129. }
  130. //--- ok
  131. return(true);
  132. }
  133. //+------------------------------------------------------------------+
  134. //| Memory check and reallocation to store 'total' records |
  135. //+------------------------------------------------------------------+
  136. inline bool CMTArrayBase::Realloc(const UINT total)
  137. {
  138. //--- check
  139. if(total<1 || m_data_step<1) return(true);
  140. //--- check size
  141. if(m_data && (m_data_total+total)<=m_data_max) return(true);
  142. //--- calculate reallocation
  143. UINT add=((total/m_data_step)+1)*m_data_step;
  144. //--- allocate new buffer
  145. UCHAR *buffer=new(std::nothrow) UCHAR[(m_data_max+add)*m_data_width];
  146. //--- check
  147. if(!buffer) return(false);
  148. //--- previous data?
  149. if(m_data)
  150. {
  151. if(m_data_total>0) memcpy(buffer,m_data,m_data_width*m_data_total);
  152. delete[] m_data;
  153. }
  154. //--- replace
  155. m_data =buffer;
  156. m_data_max+=add;
  157. //--- ok
  158. return(true);
  159. }
  160. //+------------------------------------------------------------------+
  161. //| Compact allocated memory |
  162. //+------------------------------------------------------------------+
  163. inline void CMTArrayBase::Compact(void)
  164. {
  165. UINT freespace=m_data_max-m_data_total;
  166. UCHAR *newdata;
  167. //--- check
  168. if(!m_data || freespace<=m_data_step) return;
  169. //--- allocate new block
  170. newdata=new(std::nothrow) UCHAR[(m_data_total+m_data_step)*m_data_width];
  171. //--- check memory
  172. if(!newdata) return;
  173. //--- copy old data
  174. memcpy(newdata,m_data,m_data_total*m_data_width);
  175. //--- free old buffer
  176. delete[] m_data;
  177. //--- replace
  178. m_data =newdata;
  179. m_data_max=m_data_total+m_data_step;
  180. }
  181. //+------------------------------------------------------------------+
  182. //| Assign from 'array' and |
  183. //+------------------------------------------------------------------+
  184. inline bool CMTArrayBase::Assign(const CMTArrayBase& array)
  185. {
  186. //--- check
  187. if(this==&array) return(true);
  188. //--- check width
  189. if(array.m_data_width!=m_data_width) return(false);
  190. //--- clear self
  191. Clear();
  192. //--- check data
  193. if(!array.m_data || array.m_data_total<1) return(true);
  194. //--- add
  195. return(Add(array.m_data,array.m_data_total));
  196. }
  197. //+------------------------------------------------------------------+
  198. //| Swap arrays content |
  199. //+------------------------------------------------------------------+
  200. inline void CMTArrayBase::Swap(CMTArrayBase &arr)
  201. {
  202. UCHAR *data;
  203. UINT data_total;
  204. UINT data_max;
  205. //--- check
  206. if(this==&arr) return;
  207. //--- check width
  208. if(arr.m_data_width!=m_data_width) return;
  209. //--- swap them
  210. data =m_data;
  211. data_total=m_data_total;
  212. data_max =m_data_max;
  213. m_data =arr.m_data;
  214. m_data_total=arr.m_data_total;
  215. m_data_max =arr.m_data_max;
  216. arr.m_data =data;
  217. arr.m_data_total=data_total;
  218. arr.m_data_max =data_max;
  219. }
  220. //+------------------------------------------------------------------+
  221. //| Reserve free space |
  222. //+------------------------------------------------------------------+
  223. inline bool CMTArrayBase::Reserve(const UINT size)
  224. {
  225. if(size<=m_data_max) return(true);
  226. else return(Realloc(size-m_data_total));
  227. }
  228. //+------------------------------------------------------------------+
  229. //| Resize array |
  230. //+------------------------------------------------------------------+
  231. inline bool CMTArrayBase::Resize(const UINT size)
  232. {
  233. //--- check
  234. if(!m_data) return(false);
  235. if(size==m_data_total) return(true);
  236. //--- resize or realloc
  237. if(size<m_data_total) m_data_total=size;
  238. else
  239. if(size>m_data_total) return(AddEmpty(size-m_data_total));
  240. //--- ok
  241. return(true);
  242. }
  243. //+------------------------------------------------------------------+
  244. //| Add total records to tail |
  245. //+------------------------------------------------------------------+
  246. inline bool CMTArrayBase::Add(const void *elem,const UINT total)
  247. {
  248. //--- check ptr
  249. if(!elem) return(false);
  250. //--- check total
  251. if(total<1) return(true);
  252. //--- check and reallocate memory
  253. if(!Realloc(total)) return(false);
  254. //--- add
  255. memcpy((char*)m_data+(m_data_width*m_data_total),(const char*)elem,m_data_width*total);
  256. m_data_total+=total;
  257. //--- ok
  258. return(true);
  259. }
  260. //+------------------------------------------------------------------+
  261. //| Add array |
  262. //+------------------------------------------------------------------+
  263. inline bool CMTArrayBase::Add(const CMTArrayBase& array)
  264. {
  265. //--- check
  266. if(this==&array || !array.m_data || array.m_data_total<1) return(true);
  267. //--- check width
  268. if(array.m_data_width!=m_data_width) return(false);
  269. //--- add
  270. return(Add(array.m_data,array.m_data_total));
  271. }
  272. //+------------------------------------------------------------------+
  273. //| Add records [from,to] from array |
  274. //+------------------------------------------------------------------+
  275. inline bool CMTArrayBase::AddRange(const CMTArrayBase& array,const UINT from,const UINT to)
  276. {
  277. //--- check
  278. if(this==&array) return(true);
  279. //--- check width
  280. if(array.m_data_width!=m_data_width) return(false);
  281. //--- check borders
  282. if(from>to || to>=array.Total()) return(false);
  283. //--- add
  284. return(Add((char*)array.m_data+(from*array.m_data_width),(to-from)+1));
  285. }
  286. //+------------------------------------------------------------------+
  287. //| Add total uninitialized records |
  288. //+------------------------------------------------------------------+
  289. inline bool CMTArrayBase::AddEmpty(const UINT total)
  290. {
  291. if(!Realloc(total)) return(false);
  292. m_data_total+=total;
  293. return(true);
  294. }
  295. //+------------------------------------------------------------------+
  296. //| Add new uninitialized record and return pointer to them |
  297. //+------------------------------------------------------------------+
  298. inline void* CMTArrayBase::Append(void)
  299. {
  300. //--- check free space
  301. if(!Realloc(1)) return(NULL);
  302. //--- allocate
  303. if(m_data_total<m_data_max)
  304. {
  305. m_data_total++;
  306. return((char*)m_data+(m_data_total-1)*m_data_width);
  307. }
  308. //--- something wrong
  309. return(NULL);
  310. }
  311. //+------------------------------------------------------------------+
  312. //| Insert total records into pos position |
  313. //+------------------------------------------------------------------+
  314. inline bool CMTArrayBase::Insert(const UINT pos,const void *elem,const UINT total)
  315. {
  316. //--- check
  317. if(!elem || pos>m_data_total) return(false);
  318. //--- check free space
  319. if(!Realloc(total)) return(false);
  320. //--- move it if neccessary
  321. if(pos<m_data_total)
  322. memmove((char*)m_data+((pos+total)*m_data_width),(char*)m_data+(pos*m_data_width),(m_data_total-pos)*m_data_width);
  323. //--- insert
  324. memcpy((char*)m_data+(m_data_width*pos),(const char*)elem,m_data_width*total);
  325. m_data_total+=total;
  326. //--- ok
  327. return(true);
  328. }
  329. //+------------------------------------------------------------------+
  330. //| Insert total uninitialized records into pos position |
  331. //+------------------------------------------------------------------+
  332. inline bool CMTArrayBase::InsertEmpty(const UINT pos,const UINT total)
  333. {
  334. //--- check
  335. if(pos>m_data_total) return(false);
  336. //--- reallocate
  337. if(!Realloc(total)) return(false);
  338. //--- move it
  339. if(pos<m_data_total)
  340. memmove((char*)m_data+((pos+total)*m_data_width),(char*)m_data+(pos*m_data_width),(m_data_total-pos)*m_data_width);
  341. //--- correct total
  342. m_data_total+=total;
  343. //--- ok
  344. return(true);
  345. }
  346. //+------------------------------------------------------------------+
  347. //| Insert new record into sorted array |
  348. //| Returns NULL if record already exist or reallocation problem |
  349. //| Returns inserted record ptr otherwise |
  350. //+------------------------------------------------------------------+
  351. inline void* CMTArrayBase::Insert(const void *elem,SMTSearch::SortFunctionPtr sort_function)
  352. {
  353. void *result=NULL;
  354. //--- check
  355. if(!elem || !sort_function) return(result);
  356. //--- reallocate
  357. if(Realloc(1))
  358. if((result=SMTSearch::Insert(m_data,elem,m_data_total,m_data_width,sort_function))!=NULL)
  359. m_data_total++;
  360. //--- result
  361. return(result);
  362. }
  363. //+------------------------------------------------------------------+
  364. //| Delete record by position |
  365. //+------------------------------------------------------------------+
  366. inline bool CMTArrayBase::Delete(const UINT pos)
  367. {
  368. //--- check
  369. if(pos>=m_data_total || !m_data) return(false);
  370. //--- remove
  371. if((pos+1)<m_data_total)
  372. memmove((char*)m_data+(pos*m_data_width),(char*)m_data+((pos+1)*m_data_width),((m_data_total-pos)-1)*m_data_width);
  373. m_data_total--;
  374. //--- ok
  375. return(true);
  376. }
  377. //+------------------------------------------------------------------+
  378. //| Delete record by pointer |
  379. //+------------------------------------------------------------------+
  380. inline bool CMTArrayBase::Delete(const void *elem)
  381. {
  382. //--- check
  383. if(!elem || !m_data || elem<m_data || elem>=((char*)m_data+m_data_total*m_data_width)) return(false);
  384. //--- calculate position and delete
  385. return Delete(((UINT)((const char*)elem-(char*)m_data)/m_data_width));
  386. }
  387. //+------------------------------------------------------------------+
  388. //| Delete range [from,to] |
  389. //+------------------------------------------------------------------+
  390. inline bool CMTArrayBase::DeleteRange(const UINT from,const UINT to)
  391. {
  392. //--- check
  393. if(from>to || to>=m_data_total || !m_data) return(false);
  394. //--- delete
  395. if(from+1<m_data_total)
  396. memmove((char*)m_data+(from*m_data_width),
  397. (char*)m_data+((to+1)*m_data_width),((m_data_total-to)-1)*m_data_width);
  398. //--- correct total
  399. m_data_total-=((to-from)+1);
  400. //--- ok
  401. return(true);
  402. }
  403. //+------------------------------------------------------------------+
  404. //| Search and remove record from sorted array |
  405. //+------------------------------------------------------------------+
  406. inline bool CMTArrayBase::Remove(const void *elem,SMTSearch::SortFunctionPtr sort_function)
  407. {
  408. void *temp;
  409. UINT64 i;
  410. //--- check
  411. if(!elem || !sort_function || !m_data || m_data_total<1 || m_data_width<1) return(false);
  412. //--- search it
  413. if((temp=SMTSearch::Search(elem,m_data,m_data_total,m_data_width,sort_function))==NULL) return(false);
  414. //--- calc position
  415. i=((UINT64)((char*)temp-(char*)m_data))/m_data_width;
  416. //--- remove it
  417. if(i<m_data_total-1) memmove(temp,(char *)temp+m_data_width,(size_t)((m_data_total-i)-1)*m_data_width);
  418. m_data_total--;
  419. //--- ok
  420. return(true);
  421. }
  422. //+------------------------------------------------------------------+
  423. //| Update record |
  424. //+------------------------------------------------------------------+
  425. inline bool CMTArrayBase::Update(const UINT pos,const void *elem)
  426. {
  427. //--- check
  428. if(!elem || pos>=m_data_total || !m_data) return(false);
  429. //--- update
  430. memcpy((char*)m_data+(pos*m_data_width),(const char*)elem,m_data_width);
  431. //--- ok
  432. return(true);
  433. }
  434. //+------------------------------------------------------------------+
  435. //| Shift record from pos |
  436. //+------------------------------------------------------------------+
  437. inline bool CMTArrayBase::Shift(const UINT pos,const int shift)
  438. {
  439. UINT i,newpos=UINT((int)pos+shift);
  440. //--- check
  441. if(pos>=m_data_total || newpos>=m_data_total || !m_data) return(false);
  442. //--- we need one more record
  443. if(!Realloc(1)) return(false);
  444. //--- save current
  445. memcpy((char*)m_data+(m_data_total*m_data_width),(char*)m_data+(pos*m_data_width),m_data_width);
  446. //--- shift record by record
  447. if(newpos>pos)
  448. for(i=pos+1;i<=newpos;i++) memcpy((char*)m_data+((i-1)*m_data_width),(char*)m_data+(i*m_data_width),m_data_width);
  449. else
  450. for(i=pos;i>newpos;i--) memcpy((char*)m_data+(i*m_data_width),(char*)m_data+((i-1)*m_data_width),m_data_width);
  451. //--- restore current
  452. memcpy((char*)m_data+(newpos*m_data_width),(char*)m_data+(m_data_total*m_data_width),m_data_width);
  453. //--- ok
  454. return(true);
  455. }
  456. //+------------------------------------------------------------------+
  457. //| Remove size first elements |
  458. //+------------------------------------------------------------------+
  459. inline bool CMTArrayBase::Trim(const UINT size)
  460. {
  461. //--- check
  462. if(!m_data || size>m_data_total) return(false);
  463. //--- trim
  464. m_data_total-=size;
  465. memmove((char*)m_data,(char*)m_data+size*m_data_width,m_data_width*m_data_total);
  466. //--- ok
  467. return(true);
  468. }
  469. //+------------------------------------------------------------------+
  470. //| Next record by position |
  471. //+------------------------------------------------------------------+
  472. inline bool CMTArrayBase::Next(const UINT pos,void *elem) const
  473. {
  474. //--- check
  475. if(pos>=m_data_total || !elem || !m_data) return(false);
  476. //--- copy and return
  477. memcpy((char*)elem,(char*)m_data+(pos*m_data_width),m_data_width);
  478. return(true);
  479. }
  480. //+------------------------------------------------------------------+
  481. //| Next record by ptr |
  482. //+------------------------------------------------------------------+
  483. inline void* CMTArrayBase::Next(const void *elem) const
  484. {
  485. //--- check
  486. if(!elem || !m_data || elem<m_data || elem>=((char*)m_data+(m_data_total-1)*m_data_width)) return(NULL);
  487. //--- return next element
  488. return((char*)elem+m_data_width);
  489. }
  490. //+------------------------------------------------------------------+
  491. //| Prev record by ptr |
  492. //+------------------------------------------------------------------+
  493. inline void* CMTArrayBase::Prev(const void *elem) const
  494. {
  495. //--- check
  496. if(!elem || !m_data || elem<=m_data || elem>((char*)m_data+(m_data_total-1)*m_data_width)) return(NULL);
  497. //--- return next element
  498. return((char*)elem-m_data_width);
  499. }
  500. //+------------------------------------------------------------------+
  501. //| Ptr by position |
  502. //+------------------------------------------------------------------+
  503. inline const void* CMTArrayBase::At(const UINT pos) const
  504. {
  505. return((const char*)m_data+(pos*m_data_width));
  506. }
  507. //lint –restore
  508. //+------------------------------------------------------------------+
  509. //| Ptr by position |
  510. //+------------------------------------------------------------------+
  511. inline void* CMTArrayBase::At(const UINT pos)
  512. {
  513. return((char*)m_data+(pos*m_data_width));
  514. }
  515. //+------------------------------------------------------------------+
  516. //| Position by ptr |
  517. //+------------------------------------------------------------------+
  518. inline int CMTArrayBase::Position(const void* ptr) const
  519. {
  520. //--- check
  521. if(!ptr || !m_data || !m_data_width || ptr<m_data || ptr>=(char*)m_data+(m_data_total*m_data_width)) return(-1);
  522. //--- calc offset
  523. ldiv_t res=ldiv((long)((const char*)ptr-(char*)m_data),(long)m_data_width);
  524. //--- check ptr
  525. return(res.rem ? -1 : int(res.quot));
  526. }
  527. //+------------------------------------------------------------------+
  528. //| Receive range |
  529. //+------------------------------------------------------------------+
  530. inline bool CMTArrayBase::Range(const UINT from,const UINT to,void* data) const
  531. {
  532. //--- check
  533. if(from>to || from>=m_data_total || to>=m_data_total || !data || !m_data) return(false);
  534. //--- copy
  535. memcpy(data,(char*)m_data+(from*m_data_width),((to-from)+1)*m_data_width);
  536. return(true);
  537. }
  538. //+------------------------------------------------------------------+
  539. //| Sort array |
  540. //+------------------------------------------------------------------+
  541. inline void CMTArrayBase::Sort(SMTSearch::SortFunctionPtr sort_function)
  542. {
  543. if(m_data && m_data_total>0 && sort_function)
  544. qsort(m_data,m_data_total,m_data_width,sort_function);
  545. }
  546. //+------------------------------------------------------------------+
  547. //| Search by key value on sorted array |
  548. //+------------------------------------------------------------------+
  549. inline void* CMTArrayBase::Search(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  550. {
  551. //--- check
  552. if(key && m_data && m_data_total>0 && sort_function)
  553. return(SMTSearch::Search(key,m_data,m_data_total,m_data_width,sort_function));
  554. //--- something wrong
  555. return(NULL);
  556. }
  557. //+------------------------------------------------------------------+
  558. //| Search great or equal than key value on sorted array |
  559. //+------------------------------------------------------------------+
  560. inline void* CMTArrayBase::SearchGreatOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  561. {
  562. //--- check
  563. if(key && m_data && m_data_total>0 && sort_function)
  564. return(SMTSearch::SearchGreatOrEq(key,m_data,m_data_total,m_data_width,sort_function));
  565. //--- something wrong
  566. return(NULL);
  567. }
  568. //+------------------------------------------------------------------+
  569. //| Search great than key value on sorted array |
  570. //+------------------------------------------------------------------+
  571. inline void* CMTArrayBase::SearchGreater(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  572. {
  573. //--- check
  574. if(key && m_data && m_data_total>0 && sort_function)
  575. return(SMTSearch::SearchGreater(key,m_data,m_data_total,m_data_width,sort_function));
  576. //--- something wrong
  577. return(NULL);
  578. }
  579. //+------------------------------------------------------------------+
  580. //| Search less or equal than key value on sorted array |
  581. //+------------------------------------------------------------------+
  582. inline void* CMTArrayBase::SearchLessOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  583. {
  584. //--- check
  585. if(key && m_data && m_data_total>0 && sort_function)
  586. return(SMTSearch::SearchLessOrEq(key,m_data,m_data_total,m_data_width,sort_function));
  587. //--- something wrong
  588. return(NULL);
  589. }
  590. //+------------------------------------------------------------------+
  591. //| Search less than key value on sorted array |
  592. //+------------------------------------------------------------------+
  593. inline void* CMTArrayBase::SearchLess(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  594. {
  595. //--- check
  596. if(key && m_data && m_data_total>0 && sort_function)
  597. return(SMTSearch::SearchLess(key,m_data,m_data_total,m_data_width,sort_function));
  598. //--- something wrong
  599. return(NULL);
  600. }
  601. //+------------------------------------------------------------------+
  602. //| Search first element with key equal to key value on sorted array |
  603. //+------------------------------------------------------------------+
  604. inline void* CMTArrayBase::SearchLeft(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  605. {
  606. //--- check
  607. if(key && m_data && m_data_total>0 && sort_function)
  608. return(SMTSearch::SearchLeft(key,m_data,m_data_total,m_data_width,sort_function));
  609. //--- something wrong
  610. return(NULL);
  611. }
  612. //+------------------------------------------------------------------+
  613. //| Search last element with key equal to key value on sorted array |
  614. //+------------------------------------------------------------------+
  615. inline void* CMTArrayBase::SearchRight(const void *key,SMTSearch::SortFunctionPtr sort_function) const
  616. {
  617. //--- check
  618. if(key && m_data && m_data_total>0 && sort_function)
  619. return(SMTSearch::SearchRight(key,m_data,m_data_total,m_data_width,sort_function));
  620. //--- something wrong
  621. return(NULL);
  622. }
  623. //+------------------------------------------------------------------+
  624. //| Dynamic array template |
  625. //| For POD data types only! |
  626. //+------------------------------------------------------------------+
  627. template <class T,UINT step=16> class TMTArray : public CMTArrayBase
  628. {
  629. public:
  630. TMTArray() : CMTArrayBase(sizeof(T),step) {}
  631. virtual ~TMTArray(){}
  632. //--- global management
  633. void Swap(TMTArray<T,step> &arr) { CMTArrayBase::Swap(arr); }
  634. //--- add
  635. bool Add(const T *elem) { return CMTArrayBase::Add(elem); }
  636. bool Add(const T *elem,const UINT total) { return CMTArrayBase::Add(elem,total); }
  637. bool Add(const TMTArray<T,step>& arr) { return CMTArrayBase::Add(arr); }
  638. bool AddRange(const TMTArray<T,step>& arr,const UINT from,const UINT to)
  639. { return CMTArrayBase::AddRange(arr,from,to); }
  640. T* Append(void) { return(T*)CMTArrayBase::Append(); }
  641. bool Insert(const UINT pos,const T *elem) { return CMTArrayBase::Insert(pos,elem); }
  642. bool Insert(const UINT pos,const T *elem,const UINT total){ return CMTArrayBase::Insert(pos,elem,total); }
  643. T* Insert(const T *elem,SMTSearch::SortFunctionPtr order) { return(T*)CMTArrayBase::Insert(elem,order);}
  644. //--- delete
  645. bool Delete(const UINT pos) { return CMTArrayBase::Delete(pos); }
  646. bool Delete(const T *elem) { return CMTArrayBase::Delete(elem); }
  647. bool Remove(const T *elem,SMTSearch::SortFunctionPtr order) { return CMTArrayBase::Remove(elem,order); }
  648. //--- modify
  649. bool Update(const UINT pos,const T *elem) { return CMTArrayBase::Update(pos,elem); }
  650. //--- data access
  651. bool Next(const UINT pos,T *elem) const { return CMTArrayBase::Next(pos,elem); }
  652. T* Next(const T* elem) const { return(T*)CMTArrayBase::Next(elem); }
  653. T* Prev(const T* elem) { return(T*)CMTArrayBase::Prev(elem); }
  654. T* First(void) { return(T*)CMTArrayBase::At(0); }
  655. int Position(const T* ptr) const { return CMTArrayBase::Position(ptr); }
  656. bool Range(const UINT from,const UINT to,T* data) const { return CMTArrayBase::Range(from,to,data); }
  657. //--- search
  658. T* Search(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::Search(key,sort_function); }
  659. T* SearchGreatOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchGreatOrEq(key,sort_function); }
  660. T* SearchGreater(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchGreater(key,sort_function); }
  661. T* SearchLessOrEq(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchLessOrEq(key,sort_function); }
  662. T* SearchLess(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchLess(key,sort_function); }
  663. T* SearchLeft(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchLeft(key,sort_function); }
  664. T* SearchRight(const void *key,SMTSearch::SortFunctionPtr sort_function) const { return(T*)CMTArrayBase::SearchRight(key,sort_function); }
  665. //--- operators
  666. const T& operator[](const UINT pos) const { return(*(T*)CMTArrayBase::At(pos)); }
  667. T& operator[](const UINT pos) { return(*(T*)CMTArrayBase::At(pos)); }
  668. bool operator==(const TMTArray<T,step>& arr) const { return(CMTArrayBase::Compare(arr)); }
  669. bool operator!=(const TMTArray<T,step>& arr) const { return(!CMTArrayBase::Compare(arr)); }
  670. TMTArray<T,step>& operator= (const TMTArray<T,step>& arr) { if(this!=&arr) Assign(arr); return(*this); }
  671. private:
  672. TMTArray(const TMTArray&) {};
  673. };
  674. //+------------------------------------------------------------------+
  675. //| Predefined arrays |
  676. //+------------------------------------------------------------------+
  677. typedef TMTArray<UCHAR> MTByteArray;
  678. typedef TMTArray<wchar_t> MTCharArray;
  679. typedef TMTArray<SHORT> MTShortArray;
  680. typedef TMTArray<USHORT> MTUShortArray;
  681. typedef TMTArray<int> MTIntArray;
  682. typedef TMTArray<UINT> MTUIntArray;
  683. typedef TMTArray<INT64> MTInt64Array;
  684. typedef TMTArray<UINT64> MTUInt64Array;
  685. typedef TMTArray<double> MTDoubleArray;
  686. //+------------------------------------------------------------------+