305 lines
18 KiB
MQL5
305 lines
18 KiB
MQL5
|
#ifndef LIB_MQLPLUS_OBJECT_MAP_RB_TREE_NODE_MQH_INCLUDED
|
||
|
#define LIB_MQLPLUS_OBJECT_MQP_RB_TREE_NODE_MQH_INCLUDED
|
||
|
#property version "1.0";
|
||
|
/**********************************************************************************
|
||
|
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
|
||
|
*
|
||
|
* This file is the objects 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.0
|
||
|
* State: production
|
||
|
*
|
||
|
* File information
|
||
|
* ================
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
#ifdef DBG_MSG_TRACE_FILE_LOADER
|
||
|
DBG_MSG_TRACE_FILE_LOADER;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
// Incluse base object
|
||
|
#include "lib_base_obj_node_map_rbtree.mqh"
|
||
|
|
||
|
|
||
|
|
||
|
/*********************************************************************************************************************************************************/
|
||
|
/* */
|
||
|
/* MQLplus data structures */
|
||
|
/* */
|
||
|
/*********************************************************************************************************************************************************/
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
//
|
||
|
// Object Red Black Tree Node
|
||
|
//
|
||
|
|
||
|
// Data holding object
|
||
|
|
||
|
// Derived simple type class object
|
||
|
#define NODE_SUBTYPE _object_map_rb_t_node<USER_DATA, USER_KEY>
|
||
|
#define NODE_TYPE object_map_node<USER_DATA, USER_KEY>
|
||
|
#define TYPE_CASTING _object_typecast_tree_node<USER_KEY, NODE_SUBTYPE, NODE_TYPE>
|
||
|
|
||
|
template <typename USER_DATA, typename USER_KEY>
|
||
|
class object_map_node : public TYPE_CASTING
|
||
|
{
|
||
|
public:
|
||
|
// Constructors / Destructor
|
||
|
|
||
|
// Default constructor
|
||
|
object_map_node() : TYPE_CASTING() { };
|
||
|
|
||
|
// Copy constructor
|
||
|
object_map_node(const NODE_TYPE& p_in) { NODE_SUBTYPE(p_in); this_payload = p_in.this_payload; };
|
||
|
|
||
|
// Key constructor
|
||
|
/*
|
||
|
template <typename CUSTOM_KEY>
|
||
|
object_map_node(CUSTOM_KEY* p_in, bool& valid_data) { valid_data = _autocreate(this_obj, p_in); };
|
||
|
template <typename CUSTOM_KEY>
|
||
|
object_map_node(const CUSTOM_KEY& p_in, bool& valid_data) { valid_data = _autocreate(this_obj, p_in); };
|
||
|
*/
|
||
|
object_map_node(const USER_KEY& p_key, bool& valid_data) { valid_data = true; this_obj = p_key; };
|
||
|
|
||
|
// Value constructor
|
||
|
object_map_node(const USER_KEY& p_key, USER_DATA& p_in) { this_obj = p_key; this_payload = p_in; };
|
||
|
|
||
|
|
||
|
// Destructor
|
||
|
~object_map_node() { };
|
||
|
|
||
|
|
||
|
// Element selectors
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* root_element() { return((NODE_TYPE*)NODE_SUBTYPE::root()); };
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* lowest_element() { return((NODE_TYPE*)NODE_SUBTYPE::left()); };
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* highest_element() { return((NODE_TYPE*)NODE_SUBTYPE::right()); };
|
||
|
|
||
|
// Parent tree element
|
||
|
NODE_TYPE* parent_element() { return((NODE_TYPE*)_parent); };
|
||
|
|
||
|
// Left leaf element
|
||
|
NODE_TYPE* left_element() { return((NODE_TYPE*)_left); };
|
||
|
|
||
|
// Right leaf element
|
||
|
NODE_TYPE* right_element() { return((NODE_TYPE*)_right); };
|
||
|
|
||
|
// Next smaller value
|
||
|
NODE_TYPE* next_smaller_element(const USER_KEY& p_in, const bool or_equal = false) { return((NODE_TYPE*)NODE_SUBTYPE::smaller(p_in, or_equal)); };
|
||
|
|
||
|
// Next bigger value
|
||
|
NODE_TYPE* next_greater_element(const USER_KEY& p_in, const bool or_equal = false) { return((NODE_TYPE*)NODE_SUBTYPE::greater(p_in, or_equal)); };
|
||
|
|
||
|
|
||
|
// Tree element functions
|
||
|
|
||
|
// Insert element
|
||
|
NODE_TYPE* insert(NODE_TYPE* p_root) { return((NODE_TYPE*)NODE_SUBTYPE::insert(p_root)); };
|
||
|
|
||
|
// Get value key
|
||
|
USER_KEY get_key() const { return(this_obj); };
|
||
|
|
||
|
// Get object
|
||
|
USER_DATA get_obj() const { return(this_payload); };
|
||
|
|
||
|
// Detach object
|
||
|
USER_DATA detach_obj() { return(this_payload); };
|
||
|
|
||
|
// Remove object from tree
|
||
|
NODE_TYPE* remove(NODE_TYPE* p_root, const bool do_not_delete = false) { return((NODE_TYPE*)NODE_SUBTYPE::remove(p_root)); };
|
||
|
|
||
|
// Smallest node by key
|
||
|
NODE_TYPE* smallest_node() { return((NODE_TYPE*)_object_binary_t_node<USER_KEY>::_subtree_smallest_key((_parent != NULL) ? _parent : (_object_binary_t_node<USER_KEY>*)::GetPointer(this))); }
|
||
|
|
||
|
// Greatest node by key
|
||
|
NODE_TYPE* greatest_node() { return((NODE_TYPE*)_object_binary_t_node<USER_KEY>::_subtree_greatest_key((_parent != NULL) ? _parent : (_object_binary_t_node<USER_KEY>*)::GetPointer(this))); }
|
||
|
|
||
|
|
||
|
// Operators
|
||
|
|
||
|
// Key assignment operator
|
||
|
USER_KEY operator=(USER_KEY& p_in) { this_obj = p_in; return(this_obj); };
|
||
|
|
||
|
// Value assignment operator
|
||
|
USER_DATA operator=(const USER_DATA& p_in) { this_payload = p_in; return(this_payload); };
|
||
|
|
||
|
// Access operator
|
||
|
template <typename CUSTOM_KEY>
|
||
|
NODE_TYPE* operator[](CUSTOM_KEY p_in) { USER_KEY tmp = p_in; return((NODE_TYPE*)NODE_SUBTYPE::operator[](tmp)); };
|
||
|
NODE_TYPE* operator[](USER_KEY& p_in) { return((NODE_TYPE*)NODE_SUBTYPE::operator[](p_in)); };
|
||
|
|
||
|
//NODE_TYPE* operator[](USER_KEY& p_in) { return((NODE_TYPE*)NODE_SUBTYPE::operator[](p_in)); };
|
||
|
|
||
|
|
||
|
/*
|
||
|
template <typename CUSTOM_DATA>
|
||
|
const USER_DATA operator=(CUSTOM_DATA p_in) { this_obj = p_in; return(this_obj); };
|
||
|
template <typename CUSTOM_DATA>
|
||
|
const USER_DATA operator=(const CUSTOM_DATA& p_in) { this_obj = p_in; return(this_obj); };
|
||
|
const USER_DATA operator=(USER_DATA& p_in) { this_obj = p_in; return(this_obj); };
|
||
|
*/
|
||
|
|
||
|
|
||
|
// Copy assignment operator
|
||
|
void operator=(const NODE_TYPE& p_in) { NODE_SUBTYPE::operator=((NODE_SUBTYPE)p_in); };
|
||
|
|
||
|
// Comparison operator
|
||
|
const bool operator>(NODE_TYPE* p_in) const { return(this_obj > p_in.this_obj); };
|
||
|
const bool operator<(NODE_TYPE* p_in) const { return(p_in.this_obj > this_obj); };
|
||
|
|
||
|
template <typename CUSTOM_KEY>
|
||
|
const bool operator>(CUSTOM_KEY p_in) const { return(this_obj > p_in); };
|
||
|
template <typename CUSTOM_KEY>
|
||
|
const bool operator>(const CUSTOM_KEY& p_in) const { return(this_obj > p_in); };
|
||
|
const bool operator>(USER_KEY& p_in) const { return(this_obj > p_in); };
|
||
|
const bool operator>(const USER_KEY& p_in) { return(this_obj > p_in); };
|
||
|
|
||
|
template <typename CUSTOM_KEY>
|
||
|
const bool operator<(CUSTOM_KEY p_in) const { return(p_in > this_obj); };
|
||
|
template <typename CUSTOM_KEY>
|
||
|
const bool operator<(const CUSTOM_KEY& p_in) const { return(p_in > this_obj); };
|
||
|
const bool operator<(USER_KEY& p_in) const { return(p_in > this_obj); };
|
||
|
const bool operator<(const USER_KEY& p_in) { return(p_in > this_obj); };
|
||
|
|
||
|
|
||
|
// Debugging helper
|
||
|
|
||
|
const uchar _node_color() { return(this._state); };
|
||
|
const bool _node_isleaf() { return((left_element() == NULL) && (right_element() == NULL)); };
|
||
|
const string _node_to_string(int& count) { return(NODE_SUBTYPE::_node_to_string(count)); };
|
||
|
};
|
||
|
|
||
|
#undef NODE_TYPE
|
||
|
#undef TYPE_CASTING
|
||
|
#undef NODE_SUBTYPE
|
||
|
|
||
|
|
||
|
|
||
|
// Derived complex type class object for pointers
|
||
|
#define NODE_SUBTYPE _object_map_rb_t_node<USER_KEY, USER_DATA*>
|
||
|
#define NODE_TYPE ptr_object_map_node<USER_KEY, USER_DATA>
|
||
|
|
||
|
template <typename USER_KEY, typename USER_DATA>
|
||
|
class ptr_object_map_node : protected NODE_SUBTYPE
|
||
|
{
|
||
|
public:
|
||
|
// Constructors / Destructor
|
||
|
|
||
|
// Default constructor
|
||
|
ptr_object_map_node() : NODE_SUBTYPE() { };
|
||
|
|
||
|
// Copy constructor
|
||
|
ptr_object_map_node(const NODE_TYPE& p_in) { NODE_SUBTYPE(p_in); this_payload = p_in.this_payload; };
|
||
|
|
||
|
// Key constructor
|
||
|
ptr_object_map_node(const USER_KEY& p_key) { this_obj = p_key; ZeroMemory(this_payload); };
|
||
|
|
||
|
// Value constructor
|
||
|
ptr_object_map_node(const USER_KEY& p_key, const USER_DATA& p_in) { this_obj = p_key; this_payload = new USER_DATA(p_in); };
|
||
|
ptr_object_map_node(const USER_KEY& p_key, USER_DATA* p_in) { this_obj = p_key; this_payload = p_in; };
|
||
|
|
||
|
// Destructor
|
||
|
~ptr_object_map_node() { if((this_payload != NULL) && (CheckPointer(this_payload) == POINTER_DYNAMIC)) { delete(this_payload); } };
|
||
|
|
||
|
|
||
|
// Element selectors
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* root_element() { return((NODE_TYPE*)root()); };
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* lowest_element() { return((NODE_TYPE*)left()); };
|
||
|
|
||
|
// Root tree element
|
||
|
NODE_TYPE* highest_element() { return((NODE_TYPE*)right()); };
|
||
|
|
||
|
// Parent tree element
|
||
|
NODE_TYPE* parent_element() { return((NODE_TYPE*)_parent); };
|
||
|
|
||
|
// Left leaf element
|
||
|
NODE_TYPE* left_element() { return((NODE_TYPE*)_left); };
|
||
|
|
||
|
// Right leaf element
|
||
|
NODE_TYPE* right_element() { return((NODE_TYPE*)_right); };
|
||
|
|
||
|
|
||
|
// Tree element functions
|
||
|
|
||
|
// Insert element
|
||
|
NODE_TYPE* insert(NODE_TYPE* p_root) { return((NODE_TYPE*)NODE_SUBTYPE::insert(p_root)); };
|
||
|
|
||
|
/*
|
||
|
// Insert element
|
||
|
void insert(const USER_KEY& p_key, USER_DATA* p_in) { NODE_TYPE* new_ptr = new NODE_TYPE(p_key, p_in); NODE_SUBTYPE::insert((NODE_SUBTYPE*)new_ptr); };
|
||
|
void insert(const USER_KEY& p_key, USER_DATA& p_in) { NODE_TYPE* new_ptr = new NODE_TYPE(p_key, new USER_DATA(p_in)); NODE_SUBTYPE::insert((NODE_SUBTYPE*)new_ptr); };
|
||
|
*/
|
||
|
/*
|
||
|
// Set value key
|
||
|
void set_key(const USER_KEY& p_in) { this_obj = p_in; };
|
||
|
|
||
|
// Set object
|
||
|
void set_obj(USER_DATA& p_in) { this_payload = new USER_DATA(p_in); return(this_payload); };
|
||
|
void set_obj(USER_DATA* p_in) { this_payload = p_in; return(this_payload); };
|
||
|
*/
|
||
|
|
||
|
// Get value key
|
||
|
USER_KEY get_key() { return(this_obj); };
|
||
|
|
||
|
// Get object
|
||
|
USER_DATA* get_obj() { return(this_payload); };
|
||
|
|
||
|
// Detach object
|
||
|
USER_DATA* detach_obj() { USER_DATA* tmp = this_payload; this_payload = NULL; return(tmp); }
|
||
|
|
||
|
// Remove object from tree
|
||
|
NODE_TYPE* remove(NODE_TYPE* p_root, const bool do_not_delete = false) { if(do_not_delete) { detach_obj(); }; return(NODE_SUBTYPE::remove(p_root)); };
|
||
|
|
||
|
// Smallest node by key
|
||
|
NODE_TYPE* smallest_node() { return((NODE_TYPE*)_object_t_node<USER_DATA*, NODE_SUBTYPE>::_subtree_smallest_key((_parent != NULL) ? _parent : (_object_t_node<USER_DATA*, NODE_SUBTYPE>*)::GetPointer(this))); }
|
||
|
|
||
|
// Greatest node by key
|
||
|
NODE_TYPE* greatest_node() { return((NODE_TYPE*)_object_t_node<USER_DATA*, NODE_SUBTYPE>::_subtree_greatest_key((_parent != NULL) ? _parent : (_object_t_node<USER_DATA*, NODE_SUBTYPE>*)::GetPointer(this))); }
|
||
|
|
||
|
|
||
|
// Operators
|
||
|
|
||
|
// Key assignment operator
|
||
|
USER_KEY operator=(USER_KEY& p_in) { this_obj = p_in; return(this_obj); };
|
||
|
|
||
|
// Value assignment operator
|
||
|
USER_DATA* operator=(USER_DATA*& p_in) { this_payload = p_in; return(this_payload); };
|
||
|
|
||
|
// Access operator
|
||
|
NODE_TYPE* operator[](USER_KEY& p_in) { return((NODE_TYPE*)NODE_SUBTYPE::operator[](p_in)); };
|
||
|
|
||
|
// Copy assignment operator
|
||
|
void operator=(const NODE_TYPE& p_in) { NODE_SUBTYPE::operator=((NODE_SUBTYPE)p_in); };
|
||
|
};
|
||
|
|
||
|
#undef NODE_TYPE
|
||
|
#undef NODE_SUBTYPE
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// END MQL data structures */
|
||
|
//*********************************************************************************************************************************************************/
|
||
|
#endif // LIB_MQLPLUS_OBJECT_MQP_RB_TREE_NODE_MQH_INCLUDED
|