AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   Array Copy Stock (https://forums.alliedmods.net/showthread.php?t=166930)

Tirant 09-09-2011 11:08

Array Copy Stock
 
1 Attachment(s)
I made this the other day because I could not find one. Maybe someone else will need it. It will copy data from one array to another for a max length of cells and you're able to set starting positions. If someone sees optimization errors or has any other, better, ideas feel free to edit/comment.

Code:

/**
 * Copies information from one array into another.
 *
 * @param into        The array to place the data into
 * @param from        The array to get the data from
 * @param len        The number of cells to copy
 * @param ignoretags  True to enable tag comparison, false to
 *                    ignore them.
 * @param intotag    The tagof constant for the into array
 * @param intosize    The max size of data to place into
 *                    the array
 * @param intopos    The starting position to place data
 *                    into
 * @param fromtag    The tagof constant for the from array
 * @param fromsize    The max size of data to place from
 *                    the array
 * @param frompos    The starting position to begin copying
 *                    data from
 */
stock arraycopy( any:into[], any:from[], len = sizeof into, bool:ignoretags = false, intotag = tagof into, intosize = sizeof into, intopos = 0, fromtag = tagof from, fromsize = sizeof from, frompos = 0) {
    if (!ignoretags && intotag != fromtag) {
        //So we know no elements were copied (we did not remove an element ie. returning -1)
        return 0;
    }
   
    new i
    while (i < len) {
        if (intopos >= intosize || frompos >= fromsize) {
            break;
        }
       
        into[intopos++] = from[frompos++];
        i++;
    }
   
    return i;
}


ConnorMcLeod 09-09-2011 11:17

Re: Array Copy Stock
 
So you don't need to cast anything with that stock ?

Tirant 09-09-2011 17:57

Re: Array Copy Stock
 
I don't think so. Does pawn have an instanceof operator? Like to verify one bar type == another.

fysiks 09-09-2011 18:17

Re: Array Copy Stock
 
Technically Pawn is typeless but what he is refering to is tags matching up.

Tirant 09-09-2011 18:23

Re: Array Copy Stock
 
I know it's typeless. So a tags instanceof operator was what I was referring to.

Emp` 09-09-2011 19:39

Re: Array Copy Stock
 
You could just tag both into and from as any and you won't get any tag mismatches.

Tirant 09-10-2011 13:35

Re: Array Copy Stock
 
Quote:

Originally Posted by Emp` (Post 1551817)
You could just tag both into and from as any and you won't get any tag mismatches.

I'm also thinking that they should be the same type though. Like, if someone wanted to copy explicitly from a[5] into Float:b[5], there should be a tag mismatch there, so they should place the any tag when copying. So what I'm saying, is maybe there should be an error.

fysiks 09-10-2011 13:39

Re: Array Copy Stock
 
Quote:

Originally Posted by Tirant (Post 1552369)
I'm also thinking that they should be the same type though. Like, if someone wanted to copy explicitly from a[5] into Float:b[5], there should be a tag mismatch there, so they should place the any tag when copying. So what I'm saying, is maybe there should be an error.

To correctly implement a tag mismatch error for a stock that can be used on multiple tags would require a function to detect the tag which doesn't exist (granted, it would be a preprocessor function).

Emp` 09-10-2011 13:44

Re: Array Copy Stock
 
Quote:

Originally Posted by fysiks (Post 1552373)
To correctly implement a tag mismatch error for a stock that can be used on multiple tags would require a function to detect the tag which doesn't exist (granted, it would be a preprocessor function).

tagof ?

fysiks 09-10-2011 13:55

Re: Array Copy Stock
 
Quote:

Originally Posted by Emp` (Post 1552377)

Does it work here?

Emp` 09-10-2011 14:05

Re: Array Copy Stock
 
Quote:

Originally Posted by fysiks (Post 1552390)
Does it work here?

Yes.

Tirant 09-10-2011 14:07

Re: Array Copy Stock
 
Ya, why not do

Code:

if (tagof into != tagof from)
    break

so

PHP Code:

stock arraycopy(into[], size1pos1from[], size2pos2len) {
    if (
tagof into != tagof from) {
        
log_error(AMX_ERR_PARAMS"Tag of ^"into^" does not match tag of ^"from^"");
        return;
    }
    
    for (new 
ileni++) {
        if (
pos1 >= size1 || pos2 >= size2) {
            break;
        }
        
        
into[pos1++] = from[pos2++];
    }


Yea! so there is basically an instanceof operator!

Emp` 09-10-2011 14:11

Re: Array Copy Stock
 
Quote:

Originally Posted by Tirant (Post 1552400)
Ya, why not do

Code:

if (tagof into != tagof from)
    break


That would just be
Code:

if (0 != 0)
    break

You need to store the tags into an argument like it is done in the link provided earlier.

Something you should also do is return the amount of values copied.

Tirant 09-10-2011 14:31

Re: Array Copy Stock
 
So something like this

PHP Code:

stock arraycopy(into[], tag1 tagof intosize1pos1from[], tag2 tagof fromsize2pos2len) {
    if (
tag1 != tag2) {
        
log_error(AMX_ERR_PARAMS"Tag of ^"into^" (%d) does not match tag of ^"from^" (%d)"tag1tag2);
        return -
1;
    }
    
    new 
i
    
while (len) {
        if (
pos1 >= size1 || pos2 >= size2) {
            break;
        }
        
        
into[pos1++] = from[pos2++];
        
i++;
    }
    
    return 
i;



Emp` 09-10-2011 14:44

Re: Array Copy Stock
 
Yes; however, you still need to tag both into and from as any so that any tag can be used. Currently it will give you a tag mismatch.

I suggest you move the tags to the end of the parameter list, so people don't have to use an underscore to skip the argument.

I would also suggest a parameter for ignoring tags.

Personally, how I would make it:
Code:

stock arraycopy( any:into[], any:from[], len, bool:ignoretags = false, intotag = tagof into, intosize = sizeof into, intopos = 0, fromtag = tagof from, fromsize = sizeof from, frompos = 0) {
    if (!ignoretags && intotag != fromtag) {
        //So we know no elements were copied (we did not remove an element ie. returning -1)
        return 0;
    }
   
    new i
    while (i < len) {
        if (intopos >= intosize || frompos >= fromsize) {
            break;
        }
       
        into[intopos++] = from[frompos++];
        i++;
    }
   
    return i;
}


Tirant 09-10-2011 15:01

Re: Array Copy Stock
 
Quote:

Originally Posted by Emp` (Post 1552431)
Yes; however, you still need to tag both into and from as any so that any tag can be used. Currently it will give you a tag mismatch.

I suggest you move the tags to the end of the parameter list, so people don't have to use an underscore to skip the argument.

I would also suggest a parameter for ignoring tags.

Personally, how I would make it:
Code:

stock arraycopy( any:into[], any:from[], len, bool:ignoretags = false, intotag = tagof into, intosize = sizeof into, intopos = 0, fromtag = tagof from, fromsize = sizeof from, frompos = 0) {
    if (!ignoretags && intotag != fromtag) {
        //So we know no elements were copied (we did not remove an element ie. returning -1)
        return 0;
    }
   
    new i
    while (i < len) {
        if (intopos >= intosize || frompos >= fromsize) {
            break;
        }
       
        into[intopos++] = from[frompos++];
        i++;
    }
   
    return i;
}


Okay, I like that. Maybe we should have "len = sizeof into" within the parameter list also.

Also, why remove the error reporting? IMO, if the tags are not right when they should be, I think the client should be notified.

Emp` 09-10-2011 15:05

Re: Array Copy Stock
 
Quote:

Originally Posted by Tirant (Post 1552450)
Okay, I like that. Maybe we should have "len = sizeof into" within the parameter list also.

Also, why remove the error reporting? IMO, if the tags are not right when they should be, I think the client should be notified.

That's up to you, I was just showing how I would make it.

Arkshine 09-10-2011 15:10

Re: Array Copy Stock
 
Did you test your stock ? Because I'm doing some tests just by curiosity, and by using tagof in the header will result 0 always or using multi-tag (any, or {Float, bool, etc..} ) and the value will be always the same (more the first tag). In others words, and if I don't say bullshits, it works only with mono-tag, and tagof has to used inside the function.

Tirant 09-10-2011 15:13

Re: Array Copy Stock
 
Quote:

Originally Posted by Emp` (Post 1552454)
That's up to you, I was just showing how I would make it.

I think I'm going to agree with you and keep it out. It will return 0, so there will be a way to know if your loop did not work.

Emp` 09-10-2011 15:21

Re: Array Copy Stock
 
Quote:

Originally Posted by Arkshine (Post 1552457)
Did you test your stock ? Because I'm doing some tests just by curiosity, and by using tagof in the header will result 0 always or using multi-tag (any, or {Float, bool, etc..} ) and the value will be always the same. In others words, and if I don't say bullshits, it works only with mono-tag, and tagof has to used inside the function.

Ah, it does seem to bugger up when used as a default value for a parameter. I thought it might work like sizeof/charsmax.

However, this works fine:
Code:

arraycopy( copyarray, initarray, sizeof copyarray, .intotag = tagof copyarray, .fromtag = tagof initarray );
The only way I see it working well is by using a macro to auto fill the required info.

Something like:
Code:

#define array_copy(%1, %2, %3) arraycopy( %1, %2, %3, .intotag = tagof %1, .fromtag = tagof %2 )

Tirant 09-10-2011 15:38

Re: Array Copy Stock
 
I'm putting together some tests right now. Tell me what it prints when you run this code...

Code:

new Float:a[5]    = { 0.0, 1.0, ... };
server_print("Printing Test Values for Variable 'a'");
for (new i; i < sizeof a; i++) {
    server_print("a[%d] = %.1f", i, a[i]);
}

I always thought using that notation for registering an array would work with floating points.

Arkshine 09-10-2011 15:43

Re: Array Copy Stock
 
Wooh, it's tricky. Using macro, indeed, tag is now well got. Good to know.

EDIT :

Code:

Printing Test Values for Variable 'a'
a[0] = 0.0
a[1] = 1.0
a[2] = 170141183460469200000000000000000000000.0
a[3] = -0.2
a[4] = -42535295865117300000000000000000000000.0

So ? Just some garbage. I guess it does't auto-increment with float value ?

Tirant 09-10-2011 16:01

Re: Array Copy Stock
 
1 Attachment(s)
This is my output from the simple tests... Notice that the tags boolean doesn't do anything when the other parameters are not set properly.

Quote:

L 09/10/2011 - 12:57:41: [test1.amxx] Printing Test Values for Variable 'a'...
L 09/10/2011 - 12:57:41: [test1.amxx] a[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] a[1] = 1.0
L 09/10/2011 - 12:57:41: [test1.amxx] a[2] = 2.0
L 09/10/2011 - 12:57:41: [test1.amxx] a[3] = 3.0
L 09/10/2011 - 12:57:41: [test1.amxx] a[4] = 4.0
L 09/10/2011 - 12:57:41: [test1.amxx] Printing Test Values for Variable 'b'...
L 09/10/2011 - 12:57:41: [test1.amxx] b[0] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] b[1] = 1
L 09/10/2011 - 12:57:41: [test1.amxx] b[2] = 2
L 09/10/2011 - 12:57:41: [test1.amxx] b[3] = 3
L 09/10/2011 - 12:57:41: [test1.amxx] b[4] = 4
L 09/10/2011 - 12:57:41: [test1.amxx] Printing Test Values for Variable 'c'...
L 09/10/2011 - 12:57:41: [test1.amxx] c[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] c[1] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] c[2] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(c, a); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] c[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] c[1] = 1.0
L 09/10/2011 - 12:57:41: [test1.amxx] c[2] = 2.0
L 09/10/2011 - 12:57:41: [test1.amxx] Printing Test Values for Variable 'd'...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(d, b); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 1
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 2
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 3
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 4
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(d, a, _, true); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 1.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 2.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 3.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 4.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(d, a, _, false); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 1.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 2.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 3.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 4.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(d, a, _, true, tagof d, _, _, tagof a, _, _); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 1.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 2.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 3.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 4.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] arraycopy(d, a, _, false, tagof d, _, _, tagof a, _, _); Printing resulting into...
L 09/10/2011 - 12:57:41: [test1.amxx] d[0] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[1] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[2] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[3] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[4] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[5] = 0.0
L 09/10/2011 - 12:57:41: [test1.amxx] d[6] = 0.0

Emp` 09-10-2011 16:16

Re: Array Copy Stock
 
Quote:

Originally Posted by Tirant (Post 1552514)
Notice that the tags boolean doesn't do anything when the other parameters are not set properly.

Quote:

Originally Posted by Arkshine (Post 1552457)
Because I'm doing some tests just by curiosity, and by using tagof in the header will result 0 always or using multi-tag (any, or {Float, bool, etc..} ) and the value will be always the same (more the first tag). In others words, and if I don't say bullshits, it works only with mono-tag, and tagof has to used inside the function.


abdul-rehman 09-11-2011 05:42

Re: Array Copy Stock
 
Tags are numbers ? I mean the the Float: tag is a specific number ?

Arkshine 09-11-2011 05:43

Re: Array Copy Stock
 
You can say that, yes.

Bugsy 09-11-2011 10:04

Re: Array Copy Stock
 
Quote:

Originally Posted by abdul-rehman (Post 1552859)
Tags are numbers ? I mean the the Float: tag is a specific number ?

Everything is a number of some sort on a computer.

abdul-rehman 09-11-2011 10:19

Re: Array Copy Stock
 
Quote:

Originally Posted by Bugsy (Post 1552980)
Everything is a number of some sort on a computer.

I thought about that, but its confirmed :up:

G[o]Q 03-14-2012 15:31

Re: Array Copy Stock
 
to copy arrays you can use something like this

Code:

new array1[5]={1,2,3,4,5}
new array2[5];
new i=0;

while(array1[i]=array2[i]){i++;}

you can change value of 'i' and copy only from first position

Exolent[jNr] 03-14-2012 16:04

Re: Array Copy Stock
 
Quote:

Originally Posted by G[o]Q (Post 1668944)
to copy arrays you can use something like this

Code:

new array1[5]={1,2,3,4,5}
new array2[5];
new i=0;

while(array1[i]=array2[i]){i++;}

you can change value of 'i' and copy only from first position

Loop until the plugin breaks at a runtime error of "index out of bounds" ?
Good one.

xPaw 03-14-2012 16:43

Re: Array Copy Stock
 
Quote:

Originally Posted by Exolent[jNr] (Post 1668956)
Loop until the plugin breaks at a runtime error of "index out of bounds" ?
Good one.

I approve

Tirant 03-15-2012 14:13

Re: Array Copy Stock
 
Ya, that's why you should test code before posting. It would also not be able to work on an array with data less than equal 0.

Use arrayset(array, value, size)
arrayset(array2, array1[0], sizeof array2);
Precondition that sizeof array1 <= array2.

G[o]Q 03-30-2012 16:50

Re: Array Copy Stock
 
Quote:

Originally Posted by Exolent[jNr] (Post 1668956)
Loop until the plugin breaks at a runtime error of "index out of bounds" ?
Good one.

if you don't belive me then try

you can try it in Pawn or other languages: C++,C# etc.

Exolent[jNr] 03-30-2012 17:47

Re: Array Copy Stock
 
You don't understand.

Code:
new array[3]; for(new i = 0; i < 10; i++) {     log_amx("%d", array[i]); }

That will produce a runtime error of "index out of bounds" when i equals 3 since it isn't within the index range for the array.

Tirant 03-30-2012 21:27

Re: Array Copy Stock
 
Quote:

Originally Posted by Exolent[jNr] (Post 1678876)
You don't understand.

Code:
new array[3]; for(new i = 0; i < 10; i++) { log_amx("%d", array[i]); }


That will produce a runtime error of "index out of bounds" when i equals 3 since it isn't within the index range for the array.

+1

Tirant 10-09-2012 07:23

Re: Array Copy Stock
 
Quote:

Originally Posted by josephpeter1 (Post 1815455)
Have you encountered any situation where you quickly wanted to convert your array to ArrayList or ArrayList to array ?Array BioPharma Inc., a discovery research company, creates drug candidates.

Amxx pawn doesn't directly support dynamic memory allocation. You would need to implement the cell array structure, which I believe is an array list . I don't know of any real fast way other than copying each element iteratively. It would definitely be easier in another language like java or c, but you wouldn't need to then (since an array list is still an array). In java you can just return the array copy (System.arraycopy or Arrays.copyRangeOf), in c just get a pointer and length. But if your making a new copy, just make a new array and copy iteratively.


All times are GMT -4. The time now is 18:57.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.