EA-Setka-2/framework/collection/list.mqh
super.admin a4b861dd93 convert
2025-05-30 14:50:44 +02:00

438 lines
No EOL
12 KiB
MQL5

#ifndef FRAMEWORK_LIST_MQH
#define FRAMEWORK_LIST_MQH
#define COMMA ,
#define LIST_FOREACH(list_foreach_collection, list_foreach_iterator_type, list_foreach_iterator_item_name, list_foreach_action) \
for(int list_foreach_iterator = 0; list_foreach_iterator < list_foreach_collection.count; list_foreach_iterator++){ \
list_foreach_iterator_type list_foreach_iterator_item_name = list_foreach_collection.items[list_foreach_iterator]; \
list_foreach_action; \
}
#define LIST_FOREACH_REVERSE(list_foreach_revese_collection, list_foreach_reverse_iterator_type, list_foreach_reverce_iterator_item_name, list_foreach_reverse_action) \
for(int list_foreach_reverse_iterator = list_foreach_revese_collection.count - 1; list_foreach_reverse_iterator >= 0; list_foreach_reverse_iterator--){ \
list_foreach_reverse_iterator_type list_foreach_reverce_iterator_item_name = list_foreach_revese_collection.items[list_foreach_reverse_iterator]; \
list_foreach_reverse_action; \
}
#define LIST_FOREACH2(dasdasda, iterate_type_kkkcvx, iterate_item_qwekwed, kfdsfodsi) \
for(int i_kdaskdgfgf = 0; i_kdaskdgfgf < dasdasda.count; i_kdaskdgfgf++){ \
iterate_type_kkkcvx iterate_item_qwekwed = dasdasda.items[i_kdaskdgfgf]; \
kfdsfodsi; \
}
#define LIST_WHERE(items_dsadasdasln, result_name_dsadasd, iterate_type_dsda, iterate_item_sdadasd, predicate_dsadada) \
list<iterate_type_dsda>* result_name_dsadasd = new list<iterate_type_dsda>(); \
for(int i = 0; i < items_dsadasdasln.count; i++){ \
iterate_type_dsda iterate_item_sdadasd = items_dsadasdasln.items[i]; \
if(predicate_dsadada){ \
result_name_dsadasd.add(iterate_item_sdadasd); \
} \
}
#define LIST_ACTION_WHERE(list, iterate_type, iterate_name, predicate, action) \
for(int i = 0; i < list.count; i++){ \
iterate_type iterate_name = list.items[i]; \
if(predicate) \
action; \
}
#define LIST_SORT_BUBBLE(list, field, asc) \
if ( asc ) { \
LIST_SORT_BUBBLE_ASC ( list, open_price ); \
} else { \
LIST_SORT_BUBBLE_DESC ( list, open_price ); \
}
#define LIST_SORT_BUBBLE_ASC(list, field) \
for(int i = 0; i < list.count - 1; i++){ \
bool any_change = false; \
for ( int j = 0; j < list.count - i - 1; j++ ){ \
if ( list.items[j].##field > list.items[j + 1].##field ) { \
list.swap ( j, j + 1 ); \
any_change = true; \
} \
} \
if ( !any_change ) \
break; \
}
#define LIST_SORT_BUBBLE_DESC(list, field) \
for(int i = 0; i < list.count - 1; i++){ \
bool any_change = false; \
for ( int j = 0; j < list.count - i - 1; j++ ){ \
if ( list.items[j].##field < list.items[j + 1].##field ) { \
list.swap ( j, j + 1 ); \
any_change = true; \
} \
} \
if ( !any_change ) \
break; \
}
#define LIST_SORT_INSERT_ASC(list, field) \
for(int i = 1; i < list.count; i++) \
for ( int j = i; j > 0 && list.items[j - 1].##field > list.items[j].##field; j-- ) \
list.swap ( j - 1, j );
#define LIST_SORT_INSERT_DESC(list, field) \
for(int i = 1; i < list.count; i++) \
for ( int j = i; j > 0 && list.items[j - 1].##field < list.items[j].##field; j-- ) \
list.swap ( j - 1, j );
#define LIST_FIRST_INDEX_OF(list,result,iterator_type,iterator,predicate) \
int result = -1;\
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){\
iterator_type iterator = list.items[dasdkljmfdsljfds];\
if((predicate)){ \
result = dasdkljmfdsljfds;\
break; \
}\
}
#define LIST_LAST_INDEX_OF(list,result,iterator_type,iterator,predicate) \
int result = -1;\
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){\
iterator_type iterator = list.items[dasdkljmfdsljfds];\
if((predicate)) \
result = dasdkljmfdsljfds;\
}
#define LIST_JOIN(left_list,right_list,left_iterator_type, left_iterator_name, right_iterator_type, right_iterator_name, predicate, action) \
for(int i = 0; i < left_list.count; i++){ \
left_iterator_type left_iterator_name = left_list.items[i]; \
for(int j = 0; j < right_list.count; j++){ \
right_iterator_type right_iterator_name = right_list.items[j]; \
if((predicate)) \
action; \
} \
}
#define LIST_COUNT(list, result, iterator_type, iterator, predicate) \
int result = 0; \
for(int i = 0; i < list.count; i++){ \
iterator_type iterator = list.items[i]; \
if(predicate) \
result += 1; \
}
#define LIST_SUM(list, result_type, result_name, result_default, iterator_type, iterator, field) \
result_type result_name = result_default; \
for(int i = 0; i < list.count; i++) { \
iterator_type iterator = list.items[i]; \
result_name += field; \
} \
#define LIST_SUM_EX(list, result_with_type, iterator_type, iterator, action) \
result_with_type; \
for(int i = 0; i < list.count; i++){ \
iterator_type iterator = list.items[i]; \
action; \
}
#define LIST_AVG(list, result_type, result_name, result_default, iterator_type, iterator, field) \
result_type result_name = result_default; \
for(int i = 0; i < list.count; i++) { \
iterator_type iterator = list.items[i]; \
result_name += field; \
} \
result_name /= list.count;
#define LIST_MIN(list, result_type, result_name, result_default, iterator_type, iterator, field) \
result_type result_name = result_default; \
for(int i = 0; i < list.count; i++) { \
iterator_type iterator = list.items[i]; \
if(i == 0) \
result_name = field; \
else if(result_name > field) \
result_name = field; \
}
#define LIST_MAX(list, result_type, result_name, result_default, iterator_type, iterator, field) \
result_type result_name = result_default; \
for(int i = 0; i < list.count; i++) { \
iterator_type iterator = list.items[i]; \
if(i == 0) \
result_name = field; \
else if(result_name < field) \
result_name = field; \
}
#define LIST_FIRST_OR_DEFAULT(list,result,iterator_type,iterator,predicate) \
iterator_type result = NULL;\
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){\
iterator_type iterator = list.items[dasdkljmfdsljfds];\
if((predicate)){ \
result = iterator;\
break; \
}\
}
#define LIST_CONTAINS(list,result,contains_check_item) \
bool result = false; \
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){ \
if(contains_check_item == list.items[dasdkljmfdsljfds]){ \
result = true; \
break; \
}\
}
#define LIST_ANY(list,result,iterator_type,iterator,predicate) \
bool result = false; \
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){ \
iterator_type iterator = list.items[dasdkljmfdsljfds];\
if((predicate)){ \
result = true; \
break; \
}\
}
#define LIST_ALL(list,result,iterator_type,iterator,predicate) \
bool result = true; \
for(int dasdkljmfdsljfds = 0; dasdkljmfdsljfds < list.count; dasdkljmfdsljfds++){ \
iterator_type iterator = list.items[dasdkljmfdsljfds];\
if(!(predicate)){ \
result = false; \
break; \
}\
}
template<typename t_left, typename t_right>
class left_right_t : public disposable_obj {
public:
t_left left;
t_right right;
};
#define LIST_LEFT_JOIN(result_name, left_list, right_list,left_iterator_type, left_iterator_name, right_iterator_type, right_iterator_name, predicate) \
list<left_right_t<left_iterator_type,right_iterator_type>*>* result_name = new list<left_right_t<left_iterator_type,right_iterator_type>*>(); \
for(int i = 0; i < left_list.count; i++){ \
left_iterator_type left_iterator_name = left_list.items[i]; \
for(int j = 0; j < right_list.count; j++){ \
right_iterator_type right_iterator_name = right_list.items[j]; \
if((predicate)) { \
left_right_t<left_iterator_type,right_iterator_type>* for_add = new left_right_t<left_iterator_type,right_iterator_type>(); \
for_add.left = left_iterator_name; \
for_add.right = right_iterator_name; \
result_name.add(for_add); \
} \
} \
} \
for(int i = 0; i < left_list.count; i++){ \
left_iterator_type left_iterator_name = left_list.items[i]; \
LIST_ANY( result_name, \
left_contains, \
left_right_t<left_iterator_type COMMA right_iterator_type>*, \
item, \
item.left == left_iterator_name ); \
if(!left_contains){ \
left_right_t<left_iterator_type,right_iterator_type>* for_add = new left_right_t<left_iterator_type,right_iterator_type>(); \
for_add.left = left_iterator_name; \
for_add.right = NULL; \
result_name.add(for_add); \
} \
}
#define GET_VALUE_OR_DEFAULT(item, action) \
item == NULL ? NULL : action
#define GET_VALUE_OR_MANUAL(item, action, manual) \
item == NULL ? manual : action
#define ACTION_ON_VALUE_OR_DEFAULT(item, action) \
if(item != NULL) { \
action; \
}
#define ACTION_ON_NONVALUE_OR_DEFAULT(item, action) \
if(item == NULL) { \
action; \
}
template<typename T>
class list_without_ptr : public disposable_obj {
public:
int _capacity;
int _capacity_step;
int position;
int count;
T items[];
list_without_ptr() {
position=0;
count=0;
_capacity = 3;
_capacity_step = _capacity;
ArrayResize ( items, _capacity );
}
list_without_ptr ( int capacity ) {
position=0;
count=0;
_capacity = capacity;
_capacity_step = _capacity;
ArrayResize ( items, _capacity );
}
void add ( T value ) {
if ( count + 1 > _capacity ) {
_capacity += _capacity_step;
ArrayResize ( items, _capacity );
}
items[count++] = value;
}
void clear() {
position = 0;
count = 0;
}
T get ( int index ) {
return items[index];
}
};
template<typename T>
class list : public disposable_obj {
public:
int _capacity;
int _capacity_step;
int position;
int count;
T items[];
~list() {
clear();
}
list() {
position=0;
count=0;
_capacity = 3;
_capacity_step = 3;
ArrayResize ( items, _capacity );
}
list ( int capacity ) {
position=0;
count=0;
_capacity = capacity;
_capacity_step = 3;
ArrayResize ( items, _capacity );
}
list ( int capacity,
int capacity_step ) {
position=0;
count=0;
_capacity = capacity;
_capacity_step = capacity_step;
ArrayResize ( items, _capacity );
}
void add ( T value ) {
if ( count + 1 > _capacity ) {
_capacity += _capacity_step;
ArrayResize ( items, _capacity );
}
items[count++] = value;
}
void delete_at ( int index ) {
if ( index > count - 1 ) {
return;
}
items[index] = NULL;
for ( int i = index; i < count - 1; i++ ) {
swap ( i, i + 1 );
}
int new_count = ArraySize ( items ) - 1;
ArrayResize ( items, new_count );
count = new_count;
}
void clear() {
LIST_FOREACH ( this, T, item, {
if ( item != NULL && CheckPointer ( item ) != POINTER_INVALID ) {
delete item;
}
} );
position = 0;
count = 0;
}
void clear_without_dispoce() {
position = 0;
count = 0;
}
T pop() {
return count == 0 ? NULL : items[count--];
}
void pop ( T value ) {
LIST_FIRST_INDEX_OF ( this, delete_item_index, T, item, item == value );
delete_at ( delete_item_index );
}
T get() {
return position >= count ? NULL : items[position];
}
T first_or_default() {
return count == 0 ? NULL : items[0];
}
T last_or_default() {
return count == 0 ? NULL : items[count - 1];
}
list<T> *skip ( int skip_count ) {
list<T> *result = new list<T> ( count - skip_count );
for ( int i = skip_count - 1; i < count; i++ ) {
result.add ( items[i] );
}
return result;
}
list<T> *take ( int take_count ) {
list<T> *result = new list<T> ( take_count );
for ( int i = 0; i < take_count; i++ ) {
result.add ( items[i] );
}
return result;
}
void swap ( int first_pos, int second_pos ) {
if ( first_pos >= count
|| second_pos >= count ) {
return;
}
T swap_item = items[first_pos];
items[first_pos] = items[second_pos];
items[second_pos] = swap_item;
}
void swap ( int swap_pos ) {
swap ( position, swap_pos );
}
};
#endif