Recent

Author Topic: sets as bitmasks typecast to longword  (Read 4236 times)

jamie

  • Hero Member
  • *****
  • Posts: 5052
Re: sets as bitmasks typecast to longword
« Reply #15 on: October 11, 2021, 04:11:59 pm »
just an idea..
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyDataType = bitpacked Record
  3.      case word of
  4.      0:(AllofIt:DWORD);
  5.      1:(one:0..1;
  6.        two:0..1;
  7.        three:0..1;
  8.        four:0..1;
  9.        five:0..1;
  10.        six:0..1); //etc;
  11.   end;                          
  12.  
The only true wisdom is knowing you know nothing

damieiro

  • Full Member
  • ***
  • Posts: 188
Re: sets as bitmasks typecast to longword
« Reply #16 on: October 11, 2021, 06:16:20 pm »
Quote
But /why/ are you copying it? That definition ought to be global and /never/ redefined... I have to conclude that you are, basically, abusing the language since the intention of enumerations (unlike subranges) was that they were purely symbolic and didn't have an implicit ordering: they were basically there as the foundation type for sets.

MarkMLl
I copy them, because i'm traslating a c header into a set header, so i can have mistakes. (allthough i will make automatic tool)
I think i'm not abusing languaje  :D. As you say, sets has not implicit order, but... when these are used as bitmask (a languaje facility) these are ordered.
This part (of the order in set) is the weak point as you pointed. In pascal a set can have any order, but in FPC it's stored in their set order, first, the least bit. And it's a feature of the fpc, not a bug or undocumented one.

But sets has also good advantages:
- efficient in memory and time (are well optimiced by the compiler) and do the set operations fast.
- sugar syntax.
- very strong typing.
  (for example i cannot do this:
  tvflags=(off,badsignal);
  radioflag= (off, badsignal);
it would raise a compiler duplicate identifier, i would rename as
tvflags= (tvOff,tvBadsignal);
radioflags = (radioOff, radioBadSignal);

And well, i was tinkering on how doing things like this with sets.. And i like it  :D :D




« Last Edit: October 11, 2021, 06:40:13 pm by damieiro »

damieiro

  • Full Member
  • ***
  • Posts: 188
Re: sets as bitmasks typecast to longword
« Reply #17 on: October 11, 2021, 06:24:38 pm »
just an idea..
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyDataType = bitpacked Record
  3.      case word of
  4.      0:(AllofIt:DWORD);
  5.      1:(one:0..1;
  6.        two:0..1;
  7.        three:0..1;
  8.        four:0..1;
  9.        five:0..1;
  10.        six:0..1); //etc;
  11.   end;                          
  12.  

Thanks. I would try it with


Code: Pascal  [Select][+][-]
  1.   TMyDataType = bitpacked Record
  2.      case word of
  3.      0:(AllofIt:DWORD);
  4.      1:(flags:TMySetType);
  5.   end;                          
  6.  

but it makes too many boilerplate coding. The "word" form is only used for the call, not for the manipulation.
And the sets manipulation is very nice, because you use significative names.
With this record, it has the penalty of Naming MyVariable.Flags for all. Or MyVariable.Allofit Or MyVariable.one... etc..

as i said, because the "word" form is only used for external calling (c libraries) i prefer an absolute longword variable and it does the job.



And ... why sets for flags?. Well It's very readable.

Example
Code: Pascal  [Select][+][-]
  1. if tvOn in tvflags then write ('tv is on');
  2.  
or as a setter in a property
Code: Pascal  [Select][+][-]
  1. {pseudocode}
  2. procedure tvonSetter;
  3.  
  4. begin
  5.   if tvOn not in TvFlags then
  6.     begin
  7.        include (tvOn,tvflags);
  8.        Write ('turning on tv');  
  9.     end;
  10. end;
  11.  

« Last Edit: October 11, 2021, 06:31:35 pm by damieiro »

jamie

  • Hero Member
  • *****
  • Posts: 5052
Re: sets as bitmasks typecast to longword
« Reply #18 on: October 11, 2021, 07:44:41 pm »
Yes, but what you are missing is that with what I showed you you can specify multiple bits  if you need a value more than 1 within the object item, word, dword etc..

There are times, many times where two or more bits in a WORD represent a single state.
« Last Edit: October 11, 2021, 07:46:13 pm by jamie »
The only true wisdom is knowing you know nothing

damieiro

  • Full Member
  • ***
  • Posts: 188
Re: sets as bitmasks typecast to longword
« Reply #19 on: October 11, 2021, 08:29:14 pm »
Yes, but what you are missing is that with what I showed you you can specify multiple bits  if you need a value more than 1 within the object item, word, dword etc..

There are times, many times where two or more bits in a WORD represent a single state.

Yep, you're right.
But i do not follow how you make it with more bits (not excluding case). Could put an example?
 With "irregular aditive" masks it can be done with if's and it's safer if constant headers of library would change and doesn't need any
particular order in set. This is my default coding. But i would like to make this more automatic...

Code: Pascal  [Select][+][-]
  1. Procedure SeleccionarEstiloFuenteTTF (var pfuente:pfuenteTTF; flagsEstilo:setFlagsEstiloFuente);
  2.  
  3. Var
  4.   sumaflags:longword;
  5.  
  6. begin
  7.   sumaflags:=0;
  8.   if ftNegrita   in FlagsEstilo then Sumaflags:=SumaFlags+ TTF_STYLE_BOLD;                 //    =$0x01
  9.   if ftCursiva   in FlagsEstilo then Sumaflags:=SumaFlags+ TTF_STYLE_ITALIC;               //    =$0x02
  10.   if ftSubrayado in FlagsEstilo then Sumaflags:=SumaFlags+ TTF_STYLE_UNDERLINE;     //    =$0x04
  11.   if ftTachado   in FlagsEstilo then Sumaflags:=SumaFlags+ TTF_STYLE_STRIKETHROUGH; // =$0x18 (two bits)
  12.  
  13.   TTF_SetFontStyle  ( pFuente, sumaflags);
  14. end;
                                           
and yes, i could simply rename constants and pass a sum of desired constants (like in C). But i want to make a safer call. So you cannot pass any invalid number.





« Last Edit: October 11, 2021, 08:39:42 pm by damieiro »

jamie

  • Hero Member
  • *****
  • Posts: 5052
Re: sets as bitmasks typecast to longword
« Reply #20 on: October 12, 2021, 04:47:35 pm »
Apparently you are swapping positions around from an external source to a local order.

What I would do is create a loop using the BSRDWORD function to fine the first upper bit position that is set from the source so not to waste processing time and use the returned value as an INDEX into an array of constants defines to build your final type.

basically something like this..
MyFinalValue := 0;
MyStartingIndex := BSRWORD(InComingDWordField);

Use the index to get the power of 2 index as the mask for the incomingDwordField and the MyStartingIndex as the index to fetch the cross over value from a constant array.

 during the loop you shift right the myStartingIndex and repeat the process until the MyStartingIndex = 0.

etc

If you would like an example I can code it up but this should be a faster method to translation of bit positions using a constant array of desired values against a bit position of undesirable values.
The only true wisdom is knowing you know nothing

damieiro

  • Full Member
  • ***
  • Posts: 188
Re: sets as bitmasks typecast to longword
« Reply #21 on: October 14, 2021, 03:16:41 pm »
Jamie, not the case, but i understand what you are proposing.

I want type safety. For that reason i do not use sums of constants, i use enumerated types and if the enumerated types are non exclusive, sets of these.
This a great thing to show to beginners, because it's (INMHO) a better aproach than constants. You can only pass the set type for the call, not a value made of sums of constants and tie data to call.
If all values are one bit flags, the set to longword typecast do the word.
I there are other kind of masks, i would need a translate table, that, obviously do the job for all types.

But hre

 

TinyPortal © 2005-2018