170 lines
6.7 KiB
MQL5
170 lines
6.7 KiB
MQL5
|
#ifndef LIB_MQLPLUS_CONTAINER_TEMPLATES_MQH_INCLUDED
|
||
|
#define LIB_MQLPLUS_CONTAINER_TEMPLATES_MQH_INCLUDED
|
||
|
#property version "1.2";
|
||
|
/**********************************************************************************
|
||
|
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
|
||
|
*
|
||
|
* This file is the containers 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 buffers
|
||
|
//
|
||
|
#include "lib_buffers.mqh"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*********************************************************************************************************************************************************/
|
||
|
/* */
|
||
|
/* MQLplus data structures */
|
||
|
/* */
|
||
|
/*********************************************************************************************************************************************************/
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
//
|
||
|
// Unordered container structure
|
||
|
//
|
||
|
|
||
|
template <typename T>
|
||
|
struct object_container
|
||
|
{
|
||
|
protected:
|
||
|
|
||
|
// Internal state
|
||
|
|
||
|
buffer_filo<int> free_list;
|
||
|
|
||
|
|
||
|
// Object database
|
||
|
|
||
|
T _obj_db[];
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
// Constructor
|
||
|
|
||
|
object_container()
|
||
|
{ };
|
||
|
|
||
|
|
||
|
// Element functions
|
||
|
|
||
|
T set(const int _obj_idx, const T& p_in) { _obj_db[_obj_idx] = p_in; return(_obj_db[_obj_idx]); }
|
||
|
T clear(const int _obj_idx) { ::ZeroMemory(_obj_db[_obj_idx]); return(_obj_db[_obj_idx]); }
|
||
|
bool remove(const int _obj_idx) { return((_obj_idx > -1) && (free_list.push(_obj_idx))); }
|
||
|
|
||
|
int add(const T& p_in) { const int tmp = add(); _obj_db[tmp] = p_in; return(tmp); };
|
||
|
int add()
|
||
|
{
|
||
|
const int arr_size = ::ArraySize(_obj_db);
|
||
|
return((free_list.size() > NULL) ? free_list.pop() : (mqp_ArrayResize(_obj_db, arr_size + 1) - 1));
|
||
|
};
|
||
|
|
||
|
|
||
|
// Access operator
|
||
|
|
||
|
T operator[](const int _obj_idx) const { return(_obj_db[_obj_idx]); };
|
||
|
|
||
|
|
||
|
// Store handler functions
|
||
|
|
||
|
int get_size() const { return(::ArraySize(_obj_db) - free_list.size()); };
|
||
|
void free() { ::ArrayFree(_obj_db); free_list.reset(); };
|
||
|
|
||
|
|
||
|
// Get container association
|
||
|
|
||
|
bool associated(const ulong _obj_id) const { return(true); }
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
//
|
||
|
// Unordered container structure
|
||
|
// with unique object ID
|
||
|
//
|
||
|
|
||
|
template <typename T>
|
||
|
struct object_container_uid : public object_container<T>
|
||
|
{
|
||
|
private:
|
||
|
|
||
|
// Container ID
|
||
|
|
||
|
const uint container_id;
|
||
|
T null_obj;
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
// Constructor
|
||
|
|
||
|
object_container_uid() :
|
||
|
container_id (__object_container_counter++)
|
||
|
{ };
|
||
|
|
||
|
|
||
|
// Element functions
|
||
|
|
||
|
T set(const int _obj_idx, const T& p_in) { return(object_container<T>::set(_obj_idx, p_in)); }
|
||
|
T clear(const int _obj_idx) { return(object_container<T>::clear(_obj_idx)); }
|
||
|
bool remove(const int _obj_idx) { return(object_container<T>::remove(_obj_idx)); }
|
||
|
|
||
|
T set(const ulong _obj_id, const T& p_in) { if(associated(_obj_id)) { _obj_db[(int)(_obj_id & 0x00000000FFFFFFFF)] = p_in; return(_obj_db[(int)(_obj_id & 0x00000000FFFFFFFF)]); } return(null_obj); }
|
||
|
T clear(const ulong _obj_id) { if(associated(_obj_id)) { ::ZeroMemory(_obj_db[(int)(_obj_id & 0x00000000FFFFFFFF)]); return(_obj_db[(int)(_obj_id & 0x00000000FFFFFFFF)]); } return(null_obj); }
|
||
|
bool remove(const ulong _obj_id) { int _obj_idx = (int)(_obj_id & 0x00000000FFFFFFFF); return(associated(_obj_id) && (free_list.push(_obj_idx))); }
|
||
|
ulong add(const T& p_in) { const ulong tmp = add(); _obj_db[(int)(tmp & 0x00000000FFFFFFFF)] = p_in; return(tmp); }
|
||
|
ulong add()
|
||
|
{
|
||
|
const int arr_size = ::ArraySize(_obj_db);
|
||
|
return((ulong)((free_list.size() > NULL) ? free_list.pop() : (mqp_ArrayResize(_obj_db, arr_size + 1) - 1)) | ((ulong)container_id << 32));
|
||
|
};
|
||
|
|
||
|
|
||
|
// Access operator
|
||
|
|
||
|
T operator[](const int _obj_idx) const { return(object_container<T>::operator[](_obj_idx)); }
|
||
|
T operator[](const ulong _obj_id) const { if(associated(_obj_id)) { return(_obj_db[(int)(_obj_id & 0x00000000FFFFFFFF)]); } return(null_obj); }
|
||
|
|
||
|
|
||
|
// Get container association
|
||
|
|
||
|
bool associated(const ulong _obj_id) const { return(((int)(_obj_id & 0x00000000FFFFFFFF) > -1) && (_obj_id & 0xFFFFFFFF00000000) == ((ulong)container_id << 32)); }
|
||
|
};
|
||
|
|
||
|
|
||
|
// Initialize serial counter
|
||
|
static uint __object_container_counter = NULL;
|
||
|
|
||
|
|
||
|
//
|
||
|
// END MQL data structures */
|
||
|
//*********************************************************************************************************************************************************/
|
||
|
#endif // LIB_MQLPLUS_CONTAINER_TEMPLATES_MQH_INCLUDED
|