#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 * * 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 #define NODE_TYPE object_map_node #define TYPE_CASTING _object_typecast_tree_node template 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 object_map_node(CUSTOM_KEY* p_in, bool& valid_data) { valid_data = _autocreate(this_obj, p_in); }; template 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::_subtree_smallest_key((_parent != NULL) ? _parent : (_object_binary_t_node*)::GetPointer(this))); } // Greatest node by key NODE_TYPE* greatest_node() { return((NODE_TYPE*)_object_binary_t_node::_subtree_greatest_key((_parent != NULL) ? _parent : (_object_binary_t_node*)::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 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 const USER_DATA operator=(CUSTOM_DATA p_in) { this_obj = p_in; return(this_obj); }; template 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 const bool operator>(CUSTOM_KEY p_in) const { return(this_obj > p_in); }; template 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 const bool operator<(CUSTOM_KEY p_in) const { return(p_in > this_obj); }; template 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 #define NODE_TYPE ptr_object_map_node template 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::_subtree_smallest_key((_parent != NULL) ? _parent : (_object_t_node*)::GetPointer(this))); } // Greatest node by key NODE_TYPE* greatest_node() { return((NODE_TYPE*)_object_t_node::_subtree_greatest_key((_parent != NULL) ? _parent : (_object_t_node*)::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