There is a need for the standardization of the representation of absent of values (henceforth referred to as "None"). Currently, the way to set a variable to None is to set it at the edge of its limit. (eg. double x = DBL_MAX) These vary greatly from type to type. Additionally there is currently no way to set None values using templates. This library solves these issues. If you want to continue using a plethera of MQL constants and making overloaded funcitons instead of using template then don't use it. Those who understand the concept of None will instantly see the value in having both 1. new constants defined with prefix NONE_XXX and 2. A macro which you can pass the type and receive the None value in return. Either can be used or None (pun intended), it's your choice.
I agree with you about the need, I just think there is more then one way to solve the problem, there is not a must for using a static class and it doesn't mean you have to have plethora of MQL constants and overloaded functions, for example if you use CObject.
Amir Yacoby: I agree with you about the need, I just think there is more then one way to solve the problem, there is not a must for using a static class and it doesn't mean you have to have plethora of MQL constants and overloaded functions, for example if you use CObject.
Ok... then please allow me to present a challenge for you. Show me how I can do this...
// This code will not change, only your implementation of None.mqh!
#include <None.mqh>
template <typename T>
int array_resize_with_none_init(T &array[], int new_size)
{
int total = ArrayResize(array, new_size);
for(int i=0;i<total;i++)
array[i] = NONE(T);return total;
}
...without cluttering the global namespace with unnecessary functions.
Just to make sure we're on the same page... I'm using the naming convention for marking something private (i.e. _NoneType) for a class with only static methods as a way to create a private namespace, which I'm doing intentionally to keep the functions out of the global namespace. The only things globally exposed are the NONE_TYPE constants and the NONE macro.
Edit: and while we're on the topic of namespace, MQL allows inline scoping. Within this scope you can define functions inside of functions provided you use the class/static method pattern. I'm pretty sure this has to be new because I don't remember class definitions obeying scope in the past.
voidOnStart()
{
string words[] = {"THIS","IS","JUST","A","STUPID","EXAMPLE"};
{// inline namespace
//defining function within an inline namespace inside of a function
class Str{public:template<typename T>
staticstring join(string joiner,T &array[]){
string res = NULL;
int total = ArraySize(array);
for(int i=0; i<total; i++){
res += string(array[i]);
if(i < total -1)
res += joiner;
}
return res;
}};
Print(Str::join(" ", words)); //THIS IS JUST A STUPID EXAMPLE
}
Print(Str::join(" ", words)); //Compilation error: 'Str' - import not defined
}
Ok... then please allow me to present a challenge for you. Show me how I can do this...
...without cluttering the global namespace with unnecessary functions.
Once again I have to tell you that I write the code for classes only. Did you place a global function on purpose or you just not listen to what I say? If you make it a method of a class I can post a code.
nicholi shen:
Just to make sure we're on the same page... I'm using the naming convention for marking something private (i.e. _NoneType) for a class with only static methods as a way to create a private namespace, which I'm doing intentionally to keep the functions out of the global namespace. The only things globally exposed are the NONE_TYPE constants and the NONE macro.
Again I'm hearing arrogance, you seem to not believe that I understand what you mean.. why is that?
Once again I have to tell you that I write the code for classes only. Did you place a global function on purpose or you just not listen to what I say? If you make it a method of a class I can post a code.
Again I'm hearing arrogance, you seem to not believe that I understand what you mean.. why is that?
I'm sorry if that's they way it's coming across, but I feel the need to be specific because you don't seem to understand that I'm using a class as a pseudo namespace and that None has to be global and not a class member.
Would you also argue that the global DBL_MAX constant should be a member of CObject and only available to its descendants?
The only method available is None<>() - just one method, protected. And the templated ArrayRing (you can find the Init() inside, as you wanted)
template<typename T>
class CArrayRing : public CObject
{
private:
T m_data[]; // ring buffer of dataint m_size; // buffer sizeint m_last_pos; // last buffer element position
T m_filling; // value, which used for the array fillingpublic:
CArrayRing();
~CArrayRing() { ArrayFree(m_data); }
//--- buffer initialization method:bool Init(int size,T volue=NULL);
//--- method returns the buffer size:int Size() { return m_size-1; }
//--- method changes the ring buffer size:bool Resize(constint size);
//--- method of adding a new element to the buffer:void Add(T element);
//--- method returns the value of element with the specified index:
T At(constint index) const;
T operator[](constint index) const { return(At(index)); }
//--- method returns the value of the last element stored in the buffer:
T Last() const { return(m_data[m_last_pos]); }
//--- method overwrites the value of the last element in the buffer:void Last(T element) { m_data[m_last_pos]=element; }
//--- method overwrites the value of element with the specified index:bool Update(T element,constint index=0);
};
//+------------------------------------------------------------------+//| Constructor. |//+------------------------------------------------------------------+template<typename T>
CArrayRing::CArrayRing()
{
m_last_pos=0; // last element position
m_filling=None<T>(); // value for buffer filling
m_size=ArraySize(m_data); // get size of the ring buffer
}
//+------------------------------------------------------------------+//| Buffer initialization method. |//+------------------------------------------------------------------+template<typename T>
bool CArrayRing::Init(int size,T volue=NULL)
{
m_last_pos=0; // last element position
volue=volue==NULL ? None<T>() : volue;
m_filling=volue; // value for buffer filling
m_size=ArraySize(m_data); // get size of the buffer bool result=Resize(size); // create a buffer with the desired sizefor(int i=0;i<ArraySize(m_data);i++)
m_data[i]=m_filling;
return(result);
}
//+------------------------------------------------------------------+//| Set the new size of the array. |//+------------------------------------------------------------------+template<typename T>
bool CArrayRing::Resize(constint new_size)
{
//--- checkif(new_size<0) return(false);
//--- increase array size:if(new_size>m_size)
{
int set_size=ArrayResize(m_data,new_size);
if(set_size<0) return(false);
//--- copy elements to restore their order:if(set_size>m_size)
{
for(int i=m_size-1,j=set_size-1;i>m_last_pos;i--,j--)
{
m_data[j]=m_data[i];
m_data[i]=m_filling;
}
}
m_size=set_size;
//--- result:return(true);
}
//--- reduce array size://--- prepare array to reduce the size:if(new_size>m_last_pos+1)
for(int i=m_size-1,j=new_size-1;j>m_last_pos;i--,j--) m_data[j]=m_data[i];
else
{
for(int i=m_last_pos+1-new_size,j=0;i<=m_last_pos;i++,j++) m_data[j]=m_data[i];
m_last_pos=new_size-1;
}
//--- reduce the size:
m_size=new_size;
ArrayResize(m_data,new_size);
//--- result:return(true);
}
//+------------------------------------------------------------------+//| Adding a new element to the buffer. |//+------------------------------------------------------------------+template<typename T>
void CArrayRing::Add(T element)
{
m_last_pos=++m_last_pos%m_size;
m_data[m_last_pos]=element;
}
//+------------------------------------------------------------------+//| Gets the element at the specified index. |//+------------------------------------------------------------------+template<typename T>
T CArrayRing::At(constint index) const
{
//--- check the index correctness:if((index/m_size)==0)
//--- return the value of element with the specified index:return(m_data[(m_size+m_last_pos-index)%m_size]);
//--- if the index is wrong:return(None<T>());
}
//+------------------------------------------------------------------+//| Update the element at the specified position in the array. |//+------------------------------------------------------------------+template<typename T>
bool CArrayRing::Update(T element,constint index=0)
{
//--- check the index correctness:if((index/m_size)==0)
{
//--- update
m_data[(m_size+m_last_pos-index)%m_size]=element;
//--- successfulreturn(true);
}
//--- if the index is wrong:return(false);
}
test
class CTest : public CObject
{
private:
int m_id;
public:
CTest(int id) {m_id=id;}
int Get() {return m_id;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
CArrayRing<double>ringd;
ringd.Init(50);
for(int i=0;i<50;i++)
ringd.Add((double)i);
for(int i=49;i>=0;i--)
Print("ring ",i," is ",ringd.At(i));
printf("last is %d",ringd.Last());
CArrayRing<short>rings;
rings.Init(50);
for(short i=0;i<50;i++)
rings.Add((short)(i*2));
for(int i=49;i>=0;i--)
Print("ring ",i," is ",rings.At(i));
printf("last is %d",rings.Last());
CArrayRing<datetime>ringdt;
ringdt.Init(50);
for(int i=49;i>=0;i--)
Print("ring date ",i," is initialized to ",ringdt.At(i));
for(short i=0;i<50;i++)
ringdt.Add(iTime(Symbol(),PERIOD_D1,i));
for(int i=49;i>=0;i--)
Print("ring ",i," is ",ringdt.At(i));
printf("last is %d",ringdt.Last());
CArrayRing<CTest*>ringtst;
ringtst.Init(50);
for(short i=0;i<50;i++)
ringtst.Add(new CTest(i));
for(int i=49;i>=0;i--)
Print("ring ",i," is ",ringtst[I].Get());
printf("last is %d",ringtst.Last());
}
Amir Yacoby: No, it's not because I don't "seem" to understand. It seems like you can not comprehend that I can understand and disagree. The only method available is None<>() - just one method, protected. And the templated ArrayRing (you can find the Init() inside, as you wanted) test
Your code, however you decide to implement it, should be able to compile and pass these unit tests.
//+------------------------------------------------------------------+//| NoneScript.mq5 |//| nicholishen |//| interwebs.com |//+------------------------------------------------------------------+#property copyright"nicholishen"#property link"interwebs.com"#property version"1.00"#include <None.mqh>
//--- Global variablesdouble g_double = NONE_DOUBLE;
string g_string = NONE_STRING;
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
int array[];
int total = array_resize_init_none(array, 10);
printf("%s: %s",
assert_equals(INT_MAX, array),
"Array test."
);
printf("%s: %s",
assert_equals(INT_MAX, NONE_INT),
"NONE_INT constant test."
);
printf("%s: %s",
assert_equals(INT_MAX, NONE(int)),
"NONE(int) MACRO test."
);
printf("%s: %s",
assert_equals(g_double, DBL_MAX),
"Global var, type double test."
);
printf("%s: %s",
assert_equals(DBL_MAX, NONE_DOUBLE, NONE(double)),
"All type double values correct"
);
}
//+------------------------------------------------------------------+template <typename T>
int array_resize_init_none(T &array[], int size)
{
int total = ArrayResize(array, size);
for(int i=0; i<total; i++){
array[i] = NONE(T);
}
return total;
}
template <typename T>
string assert_equals(T value1, T value2)
{
if(value1 != value2)
return"Failed";
return"Passed";
}
template <typename T>
string assert_equals(T value1, T value2, T value3)
{
if(!(value1 == value2 && value2 == value3))
return"Failed";
return"Passed";
}
template <typename T>
string assert_equals(T value1, T &array[])
{
for(int i=ArraySize(array)-1; i>=0; --i)
if(value1 != array[i])
return"Failed";
return"Passed";
}
There is a need for the standardization of the representation of absent of values (henceforth referred to as "None"). Currently, the way to set a variable to None is to set it at the edge of its limit. (eg. double x = DBL_MAX) These vary greatly from type to type. Additionally there is currently no way to set None values using templates. This library solves these issues. If you want to continue using a plethera of MQL constants and making overloaded funcitons instead of using template then don't use it. Those who understand the concept of None will instantly see the value in having both; 1. new constants defined with prefix NONE_TYPE and 2. A macro which you can pass the type and receive the appropriate None value in return. Either can be used or None (pun intended), it's your choice.
I showed you that I can template, and standardize without using the static class (it does not matter to me you restrict the access with a macro).
Your code, however you decide to implement it, should be able to compile and pass these unit tests.
Again, you code for functions, and for me it does not worth introducing static classes for that(it does not matter to me that you restrict the access with the macro). It's my choice, ok? Live with that, and don't come up again and again with same thing. I need that from class scope because I keep oo. that's it, simple.
Amir Yacoby: I showed you that I can template, and standardize without using the static class (it does not matter to me you restrict the access with a macro).
Then you are redefining the purpose of 'None' for your own edge case and need to open your own thread because we are not discussing the same concept.
Then you are redefining the purpose of 'None' for your own edge case and need to open your own thread because we are not discussing the same concept.
We talked about it already and I said it clearly. You also acknoledged it. Then you come back to it, among other wrong ideas that it should be public or I must clutter etc. Well no, it shouldnt be public and for me its the better solution. Anyway, our stands are clear as I said, let the people choose. Thats it, its your thread but I think there are many people that will agree with me also so I wrote here. Have a good day.
I am right.
There is a need for the standardization of the representation of absent of values (henceforth referred to as "None"). Currently, the way to set a variable to None is to set it at the edge of its limit. (eg. double x = DBL_MAX) These vary greatly from type to type. Additionally there is currently no way to set None values using templates. This library solves these issues. If you want to continue using a plethera of MQL constants and making overloaded funcitons instead of using template then don't use it. Those who understand the concept of None will instantly see the value in having both 1. new constants defined with prefix NONE_XXX and 2. A macro which you can pass the type and receive the None value in return. Either can be used or None (pun intended), it's your choice.
I agree with you about the need, I just think there is more then one way to solve the problem, there is not a must for using a static class and it doesn't mean you have to have plethora of MQL constants and overloaded functions, for example if you use CObject.
Ok... then please allow me to present a challenge for you. Show me how I can do this...
...without cluttering the global namespace with unnecessary functions.
Just to make sure we're on the same page... I'm using the naming convention for marking something private (i.e. _NoneType) for a class with only static methods as a way to create a private namespace, which I'm doing intentionally to keep the functions out of the global namespace. The only things globally exposed are the NONE_TYPE constants and the NONE macro.
Edit: and while we're on the topic of namespace, MQL allows inline scoping. Within this scope you can define functions inside of functions provided you use the class/static method pattern. I'm pretty sure this has to be new because I don't remember class definitions obeying scope in the past.
Ok... then please allow me to present a challenge for you. Show me how I can do this...
...without cluttering the global namespace with unnecessary functions.
Once again I have to tell you that I write the code for classes only. Did you place a global function on purpose or you just not listen to what I say? If you make it a method of a class I can post a code.
Just to make sure we're on the same page... I'm using the naming convention for marking something private (i.e. _NoneType) for a class with only static methods as a way to create a private namespace, which I'm doing intentionally to keep the functions out of the global namespace. The only things globally exposed are the NONE_TYPE constants and the NONE macro.
Again I'm hearing arrogance, you seem to not believe that I understand what you mean.. why is that?
Once again I have to tell you that I write the code for classes only. Did you place a global function on purpose or you just not listen to what I say? If you make it a method of a class I can post a code.
Again I'm hearing arrogance, you seem to not believe that I understand what you mean.. why is that?
Because you don't seem to understand that I'm using a class as a pseudo namespace and that None has to be global and not a class member.
The only method available is None<>() - just one method, protected.
And the templated ArrayRing (you can find the Init() inside, as you wanted)
test
No, it's not because I don't "seem" to understand. It seems like you can not comprehend that I can understand and disagree.
The only method available is None<>() - just one method, protected.
And the templated ArrayRing (you can find the Init() inside, as you wanted)
test
Your code, however you decide to implement it, should be able to compile and pass these unit tests.
I am right.
There is a need for the standardization of the representation of absent of values (henceforth referred to as "None"). Currently, the way to set a variable to None is to set it at the edge of its limit. (eg. double x = DBL_MAX) These vary greatly from type to type. Additionally there is currently no way to set None values using templates. This library solves these issues. If you want to continue using a plethera of MQL constants and making overloaded funcitons instead of using template then don't use it. Those who understand the concept of None will instantly see the value in having both; 1. new constants defined with prefix NONE_TYPE and 2. A macro which you can pass the type and receive the appropriate None value in return. Either can be used or None (pun intended), it's your choice.
Your code, however you decide to implement it, should be able to compile and pass these unit tests.
I showed you that I can template, and standardize without using the static class (it does not matter to me you restrict the access with a macro).
Then you are redefining the purpose of 'None' for your own edge case and need to open your own thread because we are not discussing the same concept.
Then you are redefining the purpose of 'None' for your own edge case and need to open your own thread because we are not discussing the same concept.