Recent

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

damieiro

  • Full Member
  • ***
  • Posts: 200
Re: sets as bitmasks typecast to longword
« Reply #15 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: 200
Re: sets as bitmasks typecast to longword
« Reply #16 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 »

damieiro

  • Full Member
  • ***
  • Posts: 200
Re: sets as bitmasks typecast to longword
« Reply #17 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 »

damieiro

  • Full Member
  • ***
  • Posts: 200
Re: sets as bitmasks typecast to longword
« Reply #18 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