Recursive symbol checking - c++

I am getting an error that I am having problems fixing as recursion hasn't "sunk in" yet.
It is supposed to go through an array of symbols already placed by the Class OrderManager Object and check if the symbol passed in is already there or not, if it is not there it should allow the trade, otherwise it will block it (multiple orders on the same currency compounds risk)
[Error] '}' - not all control paths return a value.
I believe it is because of the retest portion not having a return value but again I'm still newish to making my own recursive functions. However it may also be because my base and test cases are wrong possibly?
P.S I added (SE) comments in places to clarify language specific things since it is so close to C++.
P.P.S Due to the compiler error, I have no clue if this meets MVRC. Sorry everyone.
bool OrderManager::Check_Risk(const string symbol, uint iter = 0) {
if((iter + 1) != ArraySize(m_symbols) &&
m_trade_restrict != LEVEL_LOW) // Index is one less than Size (SE if
// m_trade_restrict is set to LOW, it
// allows all trades so just break out)
{
if(OrderSelect(OrderManager::Get(m_orders[iter]),
SELECT_BY_TICKET)) // Check the current iterator position
// order (SE OrderSelect() sets an
// external variable in the terminal,
// sort of like an environment var)
{
string t_base = SymbolInfoString(
OrderSymbol(),
SYMBOL_CURRENCY_BASE); // Test base (SE function pulls apart
// the Symbol into two strings
// representing the currency to check
// against)
string t_profit =
SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_PROFIT);
string c_base =
SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); // Current base
// (SE does the same as above but for the passed variable instead):
string c_profit = SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT);
// Uses ENUM_LEVELS from Helpers.mqh (SE ENUM of 5 levels: Strict,
// High, Normal, Low, None in that order):
switch(m_trade_restrict) {
case LEVEL_STRICT: {
if(t_base == c_base || t_profit == c_profit) {
return false; // Restrictions won't allow doubling
// orders on any currency
} else
return Check_Risk(symbol, iter++);
};
case LEVEL_NORMAL: {
if(symbol == OrderSymbol()) {
return false; // Restrictions won't allow doubling
// orders on that curr pair
} else
return Check_Risk(symbol, iter++);
};
default: {
// TODO: Logging Manager
// Hardcoded constant global (SE set to LEVEL_NORMAL):
ENB_Trade_Restrictions(default_level);
return Check_Risk(symbol, iter);
}
}
}
} else {
return true;
}
}

So, I must just have been staring at the code for too long but the problem was the if(OrderSelect(...)) on ln 7 did not have a return case if the order was not properly set in the terminal. I will need to polish this but the following code removes the error.
bool OrderManager::Check_Risk(const string symbol, uint iter=0)
{
if((iter + 1) != ArraySize(m_symbols) && m_trade_restrict != LEVEL_LOW) // Index is one less than Size
{
if(OrderSelect(OrderManager::Get(m_orders[iter]), SELECT_BY_TICKET)) //Check the current iterator position order
{
string t_base = SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_BASE); //Test base
string t_profit = SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_PROFIT);
string c_base = SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); //Current base
string c_profit = SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT);
switch(m_trade_restrict) // Uses ENUM_LEVELS from Helpers.mqh
{
case LEVEL_STRICT :
{
if(t_base == c_base || t_profit == c_profit)
{
return false;
}
else return Check_Risk(symbol, ++iter);
};
case LEVEL_NORMAL :
{
if(symbol == OrderSymbol())
{
return false;
}
else return Check_Risk(symbol, ++iter);
};
default: {
// TODO: Logging Messages
ENB_Trade_Restrictions(default_level); //Hardcoded constant global
return Check_Risk(symbol, iter);
}
}
}
else {return Check_Risk(symbol, ++iter);}
}
else {return true;}
}

Related

Calling next multiple times in loop causes stack overflow in ue4 Lua machine

I've been working on lua machine json object system. But I've hit a snag with the json object merger(You can see the functions code used below). When I try to iterate through a table using a while loop and IterateTable function, and then ether call Next or a function containing Next it causes an infinite loop that leads to a stack overflow crash.
Loops through the map elements of a user data object
void UJsonMergetFunctionLibrary::MergeLuaJsonObject(UMyDynamicObject* Origional, UMyDynamicObject* ToMerge, bool Override)
{
//Get all user data object keys
for (TPair<FString, FLuaValue>& P: ToMerge->GetTableContent())
{
//Holds the value of current key
FLuaValue Hold;
if (Origional->hasField(P.Key))
{
if ((P.Value.Type == ELuaValueType::Table) || (P.Value.Type == ELuaValueType::UObject))
{
Hold = Origional->LuaGetField(P.Key);
MergeLuaJsonObject(Hold, P.Value, Override);
}
else if (Override)
{
Origional->LuaSetField(P.Key, P.Value);
}
}
else
{
Origional->LuaSetField(P.Key, P.Value);
}
}
}
Loops through the elements of ether a lua table or user data object
void UJsonMergetFunctionLibrary::MergeLuaJsonObject(FLuaValue& Origional, FLuaValue& ToMerge, bool Override)
{
if (Origional.Type != ToMerge.Type) {
if (Override)
{
Origional = ToMerge;
return;
}
else
{
return;
}
}
//Table
if ((Origional.Type == ELuaValueType::Table) || (ToMerge.Type == ELuaValueType::Table)) {
TPair<FLuaValue, FLuaValue> Pair;
int32 MaxDex = MaxTableIndex(Origional);
while (IterateTable(ToMerge, Pair)) {
if (Pair.Key.Type == ELuaValueType::Integer)
{
MaxDex += 1;
Origional.SetFieldByIndex(MaxDex, Pair.Value);
}
else if (HasTableField(Origional, Pair.Key.ToString()))
{
FLuaValue Hold = Origional.GetField(Pair.Key.ToString());
if ((Pair.Value.Type == ELuaValueType::Table) && (Hold.Type == ELuaValueType::Table))
{
//Hold = OrigionalObj->LuaGetField(P.Key);
MergeLuaJsonObject(Hold, Pair.Value, Override);
}
else if((Pair.Value.Type == ELuaValueType::UObject) && (Hold.Type == ELuaValueType::UObject))
{
MergeLuaJsonObject(Hold, Pair.Value, Override);
}
else if (Override) {
Origional.SetField(Pair.Key.ToString(), Pair.Value);
}
}
else
{
Origional.SetField(Pair.Key.ToString(), Pair.Value);
}
}
}
//Object
else if ((Origional.Type == ELuaValueType::UObject) || (ToMerge.Type == ELuaValueType::UObject)) {
UMyDynamicObject* ToMergeObj = Cast<UMyDynamicObject>(ULuaBlueprintFunctionLibrary::Conv_LuaValueToObject(ToMerge));
UMyDynamicObject* OrigionalObj = Cast<UMyDynamicObject>(ULuaBlueprintFunctionLibrary::Conv_LuaValueToObject(Origional));
TMap<FString, FLuaValue> Keys = ToMergeObj->GetTableContent();
for (TPair<FString, FLuaValue>& P: Keys)
{
FLuaValue Hold;
if (OrigionalObj->hasField(P.Key))
{
if ((P.Value.Type == ELuaValueType::Table) || (P.Value.Type == ELuaValueType::UObject))
{
Hold = OrigionalObj->LuaGetField(P.Key);
MergeLuaJsonObject(Hold, P.Value, Override);
}
else if (Override)
{
OrigionalObj->LuaSetField(P.Key, P.Value);
}
}
else
{
OrigionalObj->LuaSetField(P.Key, P.Value);
}
//OrigionalObj->LuaSetField(P.Key, P)
}
Origional = FLuaValue(OrigionalObj);
}
}
Iterates and retrieves the next key in a table
bool UJsonMergetFunctionLibrary::IterateTable(FLuaValue Table, TPair<FLuaValue, FLuaValue>& Pair)
{
if (Table.Type != ELuaValueType::Table)
return false;
ULuaState* L = Table.LuaState;
if (!L)
return false;
if (Pair.Key.IsNil())
{
L->FromLuaValue(Table);
L->PushNil(); // first key
}
if (L->Next(-2))
{
Pair.Key = L->ToLuaValue(-2);
Pair.Value = L->ToLuaValue(-1);
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, Pair.Key.ToString());
L->Pop(); // pop the value
return true;
}
else
{
L->Pop(); // pop the table
return false;
}
}
Checks if the table contains a key
bool UJsonMergetFunctionLibrary::HasTableField(FLuaValue Table, FString FieldName)
{
if (Table.Type != ELuaValueType::Table)
return false;
ULuaState* L = Table.LuaState;
if (!L)
return false;
L->FromLuaValue(Table);
L->PushNil(); // first key
while (L->Next(-2))
{
FLuaValue Key = L->ToLuaValue(-2);
if (Key.ToString() == FieldName)
{
L->Pop(); // pop the value
L->Pop(); // pop the table
return true;
}
else {
L->Pop(); // pop the value
}
}
L->Pop(); // pop the table
return false;
}
1.I have tried poping both the value and the key when calling next within the loop, and than reassigning the old key once the internal next call ends.
2.I have tried googling it and Wasn't able to find anything.
3.I added a limit to how many times the loop can execute, to test if a infinite loops is causing the crash.
4.I tried making a function in pure lua that loops through a table and calls next within it(Didn't work, but do note I'm new to lua).
None of what I've tried has worked. What I want to happen is that when both Original and ToMerge have the same key, and the value assigned to that key is table I want it to perform recursion and merge those two tables than once thats done return to the execution on the original loop. Any help would be appreciated.

list.remove_if() crashing the program

I'm working on a game and I'm trying to add collectables. I'm trying to remove the object from the list after the player has collided with it, but it ends up crashing and says:
Unhandled exception thrown: read access violation.
__that was 0xDDDDDDE9.
It says this on the for loop statement, but I think it has to do with the remove_if() function.
Here is my code:
for (sf::RectangleShape rect : world1.level1.brainFrag) {
collides = milo.sprite.getGlobalBounds().intersects(rect.getGlobalBounds());
if (collides == true) {
world1.level1.brainFrag.remove_if([rect](const sf::RectangleShape val) {
if (rect.getPosition() == val.getPosition()) {
return true;
}
else {
return false ;
}
});
brainFrag -= 1;
collides = false;
}
}
if (brainFrag == 0) {
milo.x = oldPos.x;
milo.y = oldPos.y;
brainFrag = -1;
}
I don't understand your approach, you loop the rects, then when you find the one you want to remove, you search for it again through list<T>::remove_if.
I think that you forgot about the fact that you can use iterators in addition to a range-based loop:
for (auto it = brainFrag.begin(); it != brainFrag.end(); /* do nothing */)
{
bool collides = ...;
if (collides)
it = world1.level1.brainFrag.erase(it);
else
++it;
}
This allows you to remove the elements while iterating the collection because erase will take care of returning a valid iterator to the element next to the one you removed.
Or even better you could move everything up directly:
brainFrag.remove_if([&milo] (const auto& rect) {
return milo.sprite.getGlobalBounds().intersects(rect.getGlobalBounds())
}
A side note: there's no need to use an if statement to return a boolean condition, so you don't need
if (a.getPosition() == b.getPosition()
return true;
else
return false;
You can simply
return a.getPosition() == b.getPosition();

how to check if personID is in my_customers (see my example)

In C++, the interface for this file says
*If no soup left returns OUT_OF_SOUP
* If personID not found in my_customers AND numbBowlsSoupLeft>0 then give this person a bowl of soup (return BOWL_OF_SOUP)
* and record it by creating new customer struct using personID, numbBowlsSoup=1 and adding this struct to my_customers, be sure to decrement numbBowlsSoupLeft.
for my implementation, I'm trying to put
int Soupline::getSoup(int personID) {
if (numBowlsSoupLeft == 0) {
return OUT_OF_SOUP;
}
if (!(personID : my_customers) && numbBowlsSoupLeft > 0) {
}
But that second if statement is giving me syntax errros, I just want to know how to check to see if the personID is IN my_customers?
my_customers was created in the soupline interface using:
std::vector<customer> my_customers; // keeps track of customers
First you want to use find() to search a vector.
Second, please handle the case if numbBowlsSoupLeft < 0, because that can be a huge source of problem.
Third, your syntax error is the (personID : my_customers), the : is for iteration.
int Soupline::getSoup(int personID) {
if (numBowlsSoupLeft <= 0) { // handles negative numBowlsSoupLeft
return OUT_OF_SOUP;
}
bool found_customer = false;
for (auto c : my_customers) {
if (personID == c.person_id()) { // This is my guess on how the id is stored in customer class
// Logic to process soup for customer
found_customer = true;
break;
}
}
if (!found_customer) {
// Logic to process non-customer asking for soup?
}
}
Sorry i dunno what is the return integer is supposed to be, so it is not defined in my code example.

C++ array - uses only first line

i have problems with the array function.. -
i put my mac on fist line and then says me approved , but if is on 2st line rejected. my real one is B6 on end. /address down are not real../
in heder file settings >
#define CLIENTSNUMBER 2
BOOL Checking2(LPCSTR MacID);
cpp >
char ClientMacs[CLIENTSNUMBER*1][18] = {
"5A-77-77-97-87-B7",
"5A-77-77-97-87-B6"
};
BOOL Checking2(LPCSTR MacID)
{
for(int x=0;x<CLIENTSNUMBER;x++)
{
if(!strcmp(MacID,ClientMacs[x]))
{
MessageBoxA(NULL,MacID,"APPROVED!",MB_OK);
return false;
} else {
MessageBoxA(NULL,MacID,"REJECTED!",MB_OK);
return false;
}
}
return false;
}
Because you return from your function (breaking out of your loop) when something matches or doesn't match. It will never actually loop.
Edit because it's a slow morning:
You need to go through the entire array and look at every element for a match before declaring it's rejected:
BOOL Checking2(LPCSTR MacID)
{
for(int x=0;x<CLIENTSNUMBER;x++)
{
if(strcmp(MacID,ClientMacs[x]) == 0)
{
MessageBoxA(NULL,MacID,"APPROVED!",MB_OK);
return false;
}
}
MessageBoxA(NULL,MacID,"REJECTED!",MB_OK);
return false;
}
Also, do you really mean to return false in both cases? I would assume if you find a match it should return true

How can I find the depth of a recursive function in C++

How can I find the current depth inside a recursive function in C++ without passing in the previous level? i.e. is it possible to know how many times the function was called without using a parameter to keep track of the level and passing that number in as a parameter each time the function is called?
For example my recursive function looks like this:
DoSomething(int level)
{
print level;
if (level > 10)
return;
DoSomething(++level);
}
main
{
DoSomething(0);
}
Building on the answer already given by JoshD:
void recursive()
{
static int calls = 0;
static int max_calls = 0;
calls++;
if (calls > max_calls)
max_calls = calls;
recursive();
calls--;
}
This resets the counter after the recursive function is complete, but still tracks the maximum depth of the recursion.
I wouldn't use static variables like this for anything but a quick test, to be deleted soon after. If you really need to track this on an ongoing basis there are better methods.
You could use a static variable in the function...
void recursive()
{
static int calls = 0;
calls++;
recursive();
}
Of course, this will keep counting when you start a new originating call....
If you want it to be re-entrant and thread-safe, why not:
void rec(int &level) // reference to your level var
{
// do work
rec(++level); // go down one level
}
main()
{
//and you call it like
int level=0;
rec(level);
cout<<level<<" levels."<<endl;
}
No static/global variables to mess up threading and you can use different variables for different recursive chains for re-entrancy issues.
You can use a local static variable, if you don't care about thread-safety.
Although, this will only give you a proper count the first time you run your recursive routine. A better technique would be a RAII guard-type class which contains an internal static variable. At the start of the recursive routine, construct the guard class. The constructor would increment the internal static variable, and the destructor would decrement it. This way, when you create a new stack-frame the counter increments by one, and when you return from each stack-frame the counter would decrement by one.
struct recursion_guard
{
recursion_guard() { ++counter; }
~recursion_guard() { --counter; }
static int counter;
};
int recursion_guard::counter = 0;
void recurse(int x)
{
recursion_guard rg;
if (x > 10) return;
recurse(x + 1);
}
int main()
{
recurse(0);
recurse(0);
}
Note however, that this is still not thread-safe. If you need thread-safety, you can replace the static-storage variable with a thread-local-storage variable, either using boost::thread_specific_ptr or the C++0x thread local facilities.
You could also pass in the level as a template parameter, if it can be determined at compile-time. You could also use a function object. This is by far and away the best option - less hassle, and static variables should be avoided wherever possible.
struct DoSomething {
DoSomething() {
calls = 0;
}
void operator()() {
std::cout << calls;
calls++;
if (calls < 10)
return operator()();
return;
}
int calls;
};
int main() {
DoSomething()(); // note the double ().
std::cin.get();
}
convert level to an instance variable of a new object (typically a template) capable of containing the arguments and (possibly) the function. then you can reuse the recursion accumulator interface.
You can also try using a global variable to log the depth.
var depth = 0;
DoSomething()
{
print ++depth;
if (depth > 10)
return;
DoSomething();
}
main
{
DoSomething(0);
}
I came here when I sensed that some recursion is required, because I was implementing a function that can validate the chain of trust in a certificate chain. This is not X.509 but instead it is just the basics wherein the issuer key of a certificate must match the public key of the signer.
bool verify_chain(std::vector<Cert>& chain,
Cert* certificate,
unsigned char* pOrigin = nullptr, int depth = 0)
{
bool flag = false;
if (certificate == nullptr) {
// use first element in case parameter is null
certificate = &chain[0];
}
if (pOrigin == nullptr) {
pOrigin = certificate->pubkey;
} else {
if (std::memcmp(pOrigin, certificate->pubkey, 32) == 0) {
return false; // detected circular chain
}
}
if (certificate->hasValidSignature()) {
if (!certificate->isRootCA()) {
Cert* issuerCert = certificate->getIssuer(chain);
if (issuerCert) {
flag = verify_chain(chain, issuerCert, pOrigin, depth+1);
}
} else {
flag = true;
}
}
if (pOrigin && depth == 1) {
pOrigin = nullptr;
}
return flag;
}
I needed to know the recursion depth so that I can correctly clean up pOrigin. at the right stack frame during the unwinding of the call stack.
I used pOrigin to detect a circular chain, without which the recursive call can go on forever. For example,
cert0 signs cert1
cert1 signs cert2
cert2 signs cert0
I later realized that a simple for-loop can do it for simple cases when there is only one common chain.
bool verify_chain2(std::vector<Cert> &chain, Cert& cert)
{
Cert *pCert = &cert;
unsigned char *startkey = cert.pubkey;
while (pCert != nullptr) {
if (pCert->hasValidSignature()) {
if (!pCert->isRootCA()) {
pCert = pCert->getIssuer(chain);
if (pCert == nullptr
|| std::memcmp(pCert->pubkey, startkey, 32) == 0) {
return false;
}
continue;
} else {
return true;
}
} else {
return false;
}
}
return false;
}
But recursion is a must when there is not one common chain but instead the chain is within each certificate. I welcome any comments. Thank you.