Igor🇺🇦
Pavel
Can you provide the code. From what you explained it seems that the problem may be that the implementation of the templated class should be in hpp. But without looking at the code it is just a wild guess.
Pavel
Pavel
I was answering to another message, sorry for the confusion
Anonymous
https://gist.github.com/4a73bcdd3a6bbf6c3790ff7529e0c069
how do i handle undoing a FIFO full add?
eg 123 > 234 > 345 > undo > 234 > undo > 123
size == 3
stack {1,2,3,4,5}
size == 5
front == 1, back == 5
Pavel
First of all it looks incorrect that your implementations are in cpp, but not sure if it's the case of the problem in this situation (it should be a linker error, I guess, in that case).
Does the error point to a specific line of the code?
Pavel
Templated functions/classes are generated for each type (combination of types) they were instantiated with. Basically if you use std::vector<int> and std::vector<float> in your app, you will have two generated usual classes.
But in order to generate them for each type, both the type and the implementation code should be visible in one place.
One way: you can put your implementation to hpp, then when the compiler will meet the place when it's instantiated, e.g.
std::vector<int> myVector; it will be able to generate the implementation for this specific type.
Another way, you can add full specializations of your template to the cpp for specific types. Then linker will make sure to link callers to these specializations.
Pavel
Pavel
I think so, I mean about visibility in one place I pretty sure it works always. You can put the implementation code somewhere where it visible for the called and it will work.
Usually if it's just a template or partial specialization you just put it to the header. If it's full specialization you put it in cpp (treating it just as a usual function)
Thierry
thank you for your assistance and help @gameraccoon
Pavel
About this I'm not sure, my phone battery is almost dead, I'll have a look later if no one else will be able to help before that
Igor🇺🇦
Why do you have templates twice on line 33 and 34?
Shouldn't it be only one line?
Anonymous
Hi
Ehsan
Ehsan
Ehsan
so what’s the implementation you want to do?
Ehsan
Anonymous
eg
123 > push(4) > 234 > undo() > 123
Ehsan
what is the one you decided to do?
Ehsan
we can save instants of the stack
Anonymous
at the moment i just keep all values in a ring buffer
Anonymous
eg for a full buffer:
add 3
MAIN: (size = 3, capacity = 3) 1, 2, 3
UNDO: (size = 6, capacity = 6) { ADD, 1 }, { ADD, 2 }, { ADD, 3 }
overwrite the buffer by pushing another value, causing the last value to be removed
add 4
MAIN: (size = 3, capacity = 3) 2, 3, 4
UNDO: (size = 6, capacity = 6) { ADD, 2 }, { ADD, 3 }, { ADD, 4 }
Igor🇺🇦
eg for a full buffer:
add 3
MAIN: (size = 3, capacity = 3) 1, 2, 3
UNDO: (size = 6, capacity = 6) { ADD, 1 }, { ADD, 2 }, { ADD, 3 }
overwrite the buffer by pushing another value, causing the last value to be removed
add 4
MAIN: (size = 3, capacity = 3) 2, 3, 4
UNDO: (size = 6, capacity = 6) { ADD, 2 }, { ADD, 3 }, { ADD, 4 }
What does it mean to have capacity if you want to restore everything since the beginning?
Ehsan
Anonymous
Anonymous
for example, this is with a main buffer of 3 and a undo buffer of 4 (* 2 for commands)
add 3
MAIN: (size = 3, capacity = 3) 1, 2, 3
UNDO: (size = 6, capacity = 8 ) { ADD, 1 }, { ADD, 2 }, { ADD, 3 }, _
add 4
MAIN: (size = 3, capacity = 3) 2, 3, 4
UNDO: (size = 8, capacity = 8 ) { ADD, 1 }, { ADD, 2 }, { ADD, 3 }, { ADD, 4 }
Ehsan
Anonymous
eg it could undo up to 10 uperations, or up to 50 operations, or just up to 4 operations
while the main buffer may only hold say 2 values max, or 20 values max or even just 1 value max
Anonymous
Ehsan
ok so it’s very easy actually, all you need to do is reverse the command 🙂
if a queue is full you can make an array that holds the numbers that got deleted
Ehsan
it’s so simple
Anonymous
the main importance here is that i do not allocate memory to store the history
Ehsan
Anonymous
ok so it’s very easy actually, all you need to do is reverse the command 🙂
if a queue is full you can make an array that holds the numbers that got deleted
like, if say this?
UNDO: 1, 2, 3
EXTENDED_UNDO: _, _, _
add 8
UNDO: 2, 3, 8
EXTENDED_UNDO: 1, _, _
add 16
UNDO: 3, 8, 16
EXTENDED_UNDO: 1, 16, _
Ehsan
unless you have a big queue, let’s say 60, 10 for history 50 for entries
Ehsan
then you can implement
Ehsan
like, if say this?
UNDO: 1, 2, 3
EXTENDED_UNDO: _, _, _
add 8
UNDO: 2, 3, 8
EXTENDED_UNDO: 1, _, _
add 16
UNDO: 3, 8, 16
EXTENDED_UNDO: 1, 16, _
add 1 2 3
1 2 3
add 8
stack push 81 in the undo buff
8 2 3
back = 0 forward = 1
undo
back = 2
forward = 0
pop the 1 and add it
1 2 3
Ehsan
easy
Ehsan
you can always use the back to assign the value 🙂 because it’s cirular
Ehsan
if stack is not empty:
queue(back++) = pop(stack)
forward—
else
back—
Anonymous
Ehsan
Anonymous
Anonymous
eg this->next = new History(val) ?
Ehsan
Anonymous
to undo an add
Igor🇺🇦
Ehsan
if you want to undo a remove it’s also as simple
Anonymous
and push_front(main, push_front(redo_, command.cmd, pop_back(main)).data); to undo a remove (though i have not tested undoing a remove yet)
Ehsan
you don’t need linked list since the buff capacity is determined
Ehsan
Ehsan
all you need is to reverse a command
Ehsan
Anonymous
@neko_code any java group, connect please??
Anonymous
specifically with
MAIN: (size = 3, capacity = 3) 3, 4, 5
UNDO: (size = 10, capacity = 12) { ADD, 1 }, { ADD, 2 }, { ADD, 3 }, { ADD, 4 }, { ADD, 5 }, _
Anonymous
as front would be 1 and back would be 5
but i need to obtain 2
Ehsan
it’s working 🙂
Anonymous
like the only option i see would be to rebuild the queue, removing the value at the computed index that i need
Ehsan
Ehsan
you can implement two queues
one for the MAIN
and one for the UNDO
Anonymous
Ehsan
okay so?
Ehsan
what’s the problem? I don’t see any problem?
Anonymous
mine works like this
push 1, push 6
MAIN: (size = 2, capacity = 3) 1, 6, _
UNDO: (size = 0, capacity = 6) _, _, _
front = 1, back = 6
pop back (remove 6, or 1 if pop front instead)
MAIN: (size = 1, capacity = 3) 1, _, _
UNDO: (size = 0, capacity = 6) _, _, _
Ehsan
mine works like this
push 1, push 6
MAIN: (size = 2, capacity = 3) 1, 6, _
UNDO: (size = 0, capacity = 6) _, _, _
front = 1, back = 6
pop back (remove 6, or 1 if pop front instead)
MAIN: (size = 1, capacity = 3) 1, _, _
UNDO: (size = 0, capacity = 6) _, _, _
ok?
Anonymous
Ehsan
nein nein, you use a queue here, you don’t pop the six
Ehsan
you just move ther back to the left
Ehsan
back—
Ehsan
you don’t even need to store the one because all you need to do is:
back—