Recent

Author Topic: [Solved] Generic Buffer Class with dynamic arrays  (Read 1439 times)

ppan

  • New Member
  • *
  • Posts: 13
[Solved] Generic Buffer Class with dynamic arrays
« on: July 04, 2023, 03:06:31 pm »
Hi,

I'm facing a problem where I want to write a small generic buffer class. This class shall be capable of buffering any type in an internal TArray<T>. So far I have the definition of the Class:

Code: Pascal  [Select][+][-]
  1. unit Buffer;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.   TDataBuffer<T> = class
  12.   private
  13.     FBuffer: TArray<T>;
  14.     FCapacity: integer;
  15.     FCount: integer;
  16.     FStartIndex: integer;
  17.     FOwnsData: boolean;
  18.   public
  19.     constructor Create(const Capacity: integer);
  20.     procedure Add(const Value: T);
  21.     property Count: integer read FCount;
  22.   end;
  23.  
  24. implementation
  25.  
  26. constructor TDataBuffer<T>.Create(const Capacity: integer);
  27. begin
  28.   FCapacity := Capacity;
  29.   SetLength(FBuffer, Capacity);
  30.   FCount := 0;
  31.   FStartIndex := 0;
  32. end;
  33.  
  34. procedure TDataBuffer<T>.Add(const Value: T);
  35. begin
  36.    FBuffer[(FStartIndex + FCount) mod FCapacity] := Value //this wont do any copys of the actual content from value to FBuffer
  37.  
  38.    if FCount < FCapacity then
  39.      Inc(FCount)
  40.    else
  41.      FStartIndex := (FStartIndex + 1) mod FCapacity
  42.    end;
  43. end;
  44.  

This do the job for types like integer bot don't work for dynamic arrays, because they only share pointers. In my case I want to fill 'FBuffer' with the type
Code: Pascal  [Select][+][-]
  1. TArrayOfByte = array of byte;
, so 'FBuffer' are basically a
Code: Pascal  [Select][+][-]
  1. array of array of byte
.

Does anyone have any idea how I need to modify the code in order to do deep copys of every type?

I tried to distinguish the types of T with:
Code: Pascal  [Select][+][-]
  1. TTypeInfo(TypeInfo(T)^)
With this approach I get the information that T is of type:
Code: Pascal  [Select][+][-]
  1. tkDynArray
But I don't know how to copy the content from Value to FBuffer. Copying like:
Code: Pascal  [Select][+][-]
  1. for i := 0 to length(Value)-1 do
  2. begin
  3.  FBuffer[(FStartIndex + FCount) mod FCapacity][i] := Value[i];
  4. end;
  5.  

don't work. The code is somehow wrong and debuging this lines results in skipping this for loop. Obviously I have a understanding problem of generics and/or dynamic arrays.

Hopefully someone can enlight me :)

Thanks in advance!
« Last Edit: July 06, 2023, 10:36:29 am by ppan »

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Generic Buffer Class with dynamic arrays
« Reply #1 on: July 04, 2023, 06:04:20 pm »
It looks like what you need is some sort of variant in the code to detect arrays, and given that you would need to then determine the number of elements in the array etc.

 Mybe Generics isn't suitable for your needs? Have you looked at TCollection and TCollectionItemClass ?
The only true wisdom is knowing you know nothing

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Generic Buffer Class with dynamic arrays
« Reply #2 on: July 04, 2023, 06:57:16 pm »
Code: Pascal  [Select][+][-]
  1. FBuffer[x]:=copy(Value);

ppan

  • New Member
  • *
  • Posts: 13
Re: Generic Buffer Class with dynamic arrays
« Reply #3 on: July 05, 2023, 09:42:03 am »
Hi and thanks to your replys.

It looks like what you need is some sort of variant in the code to detect arrays, and given that you would need to then determine the number of elements in the array etc.

 Mybe Generics isn't suitable for your needs? Have you looked at TCollection and TCollectionItemClass ?

You are right, generics are propably the wrong approach. I changed the class to a fixed definition of the type that has to be stored. I thought generics are the way to do a more generalised method of storing data. I will take a look at TCollection, haven't done yet.

Thanks!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Generic Buffer Class with dynamic arrays
« Reply #4 on: July 05, 2023, 10:47:13 am »
For an generic array of arrays have a look at my lightcontainers

ppan

  • New Member
  • *
  • Posts: 13
Re: Generic Buffer Class with dynamic arrays
« Reply #5 on: July 05, 2023, 04:29:16 pm »
For an generic array of arrays have a look at my lightcontainers

Thanks for sharing but is there a github or so? Im not feeling comfortable by just opening a zip-File.

TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: Generic Buffer Class with dynamic arrays
« Reply #6 on: July 05, 2023, 04:32:11 pm »
Thanks for sharing but is there a github or so? Im not feeling comfortable by just opening a zip-File.
ROFL.

@marco:
It seems to me that you have some serious trust issues there  :P  ;D

@ppan:
Sorry for the (inside) joke but it is marcov's personal website. You are ofc. right to be cautious/suspicious but in this case it can be trusted. For more information see f.e. https://wiki.freepascal.org/Data_Structures,_Containers,_Collections#3rd_party
« Last Edit: July 05, 2023, 04:36:31 pm by TRon »

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Generic Buffer Class with dynamic arrays
« Reply #7 on: July 05, 2023, 04:56:14 pm »
. This class shall be capable of buffering any type in an internal TArray<T>. So far I have the definition of the Class:
Hm. What stupid I write here... I am less angry than in previous answers on different subjects because I  drank some proper wine ( a Barolo 2001).
Next week in Italy.

 Anyway, a programmer that is not able to write  a buffer is not a programmer.
« Last Edit: July 05, 2023, 05:02:21 pm by Thaddy »
Specialize a type, not a var.

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Generic Buffer Class with dynamic arrays
« Reply #8 on: July 05, 2023, 07:50:23 pm »
... I  drank some proper wine ( a Barolo 2001).
Next week in Italy.

!! A man very much after my own heart !!

Cheers   :D
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Paolo

  • Sr. Member
  • ****
  • Posts: 499
Re: Generic Buffer Class with dynamic arrays
« Reply #9 on: July 05, 2023, 08:20:11 pm »
Quote
Next week in Italy
Be careful, temperature above 35°C are expected  :D

ppan

  • New Member
  • *
  • Posts: 13
Re: Generic Buffer Class with dynamic arrays
« Reply #10 on: July 06, 2023, 10:36:10 am »
Thank you for your appropriate comment, much appreciated. Guys like you need stupid guys like me making those questions.

Hm. What stupid I write here... I am less angry than in previous answers on different subjects because I  drank some proper wine ( a Barolo 2001).
Next week in Italy.

Anyway, a programmer that is not able to write a buffer is not a programmer.

Yes sorry for that  :)....I had a look on this site and got your point. I'm about to read lightcontainer class, thanks for the tips.

ROFL.

@marco:
It seems to me that you have some serious trust issues there  :P  ;D

@ppan:
Sorry for the (inside) joke but it is marcov's personal website. You are ofc. right to be cautious/suspicious but in this case it can be trusted. For more information see f.e. https://wiki.freepascal.org/Data_Structures,_Containers,_Collections#3rd_party

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: Generic Buffer Class with dynamic arrays
« Reply #11 on: July 06, 2023, 11:02:35 am »
For an generic array of arrays have a look at my lightcontainers

Thanks for sharing but is there a github or so? Im not feeling comfortable by just opening a zip-File.

No.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: [Solved] Generic Buffer Class with dynamic arrays
« Reply #12 on: July 06, 2023, 12:27:46 pm »
The whole OP problem seems somewhat artificial.
The container should just store what you put in it. It's up to the client code to decide specifically what to put in the container.

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: [Solved] Generic Buffer Class with dynamic arrays
« Reply #13 on: July 06, 2023, 12:37:09 pm »
program varsettest does not compile, lazarus trunk and fpc 3.2.2
Code: Pascal  [Select][+][-]
  1. Compile Project, Target: C:\Users\Bruno Krayenbuhl\Downloads\lightcontainers\varsettest.exe: Exit code 1, Errors: 10, Hints: 13
  2. genlight.pas(253,14) Note: Call to subroutine "operator >(const op1:Variant;const op2:Variant):Boolean;" marked as inline is not inlined
  3. genlight.pas(256,16) Note: Call to subroutine "operator <(const op1:Variant;const op2:Variant):Boolean;" marked as inline is not inlined
  4. genlight.pas(431,13) Note: Local variable "j" not used
  5. genlight.pas(431,13) Note: Local variable "j" not used
  6. varsettest.lpr(11,51) Error: Generics without specialization cannot be used as a type for a variable
  7. varsettest.lpr(14,5) Error: Illegal qualifier
  8. varsettest.lpr(20,28) Hint: Local variable "v" does not seem to be initialized
  9. varsettest.lpr(34,27) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  10. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  11. varsettest.lpr(35,23) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  12. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  13. varsettest.lpr(36,22) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  14. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  15. varsettest.lpr(37,32) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  16. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  17. varsettest.lpr(38,27) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  18. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  19. varsettest.lpr(39,22) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  20. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  21. varsettest.lpr(40,34) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  22. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
  23. varsettest.lpr(41,28) Error: Incompatible type for arg no. 2: Got "TLightVariantMap<System.LongInt>", expected "<erroneous type>"
  24. varsettest.lpr(11,11) Hint: Found declaration: add_to_set(Variant;<erroneous type>);
What is missing ?


TRon

  • Hero Member
  • *****
  • Posts: 2432
Re: [Solved] Generic Buffer Class with dynamic arrays
« Reply #14 on: July 06, 2023, 04:35:00 pm »
What is missing ?

Literally the characters "int".

Change

Code: Pascal  [Select][+][-]
  1. procedure add_to_set(v:variant;ts:TLightVariantMap);
  2. begin
  3.  // lightmap<> is a map<key,value>, not a set. Use integer as dummy value.
  4.  ts.putpair(v,0);
  5. end;
  6.  
to
Code: Pascal  [Select][+][-]
  1. procedure add_to_set(v:variant;ts:TLightVariantIntMap);
  2. begin
  3.  // lightmap<> is a map<key,value>, not a set. Use integer as dummy value.
  4.  ts.putpair(v,0);
  5. end;
  6.  

 

TinyPortal © 2005-2018