123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778(* This file is free software, part of containers. See file "license" for more details. *)(** {1 Bit Field} *)exceptionTooManyFieldsexceptionFrozenletmax_width=Sys.word_size-2moduletypeS=sigtypet=privateint(** Generative type of bitfields. Each instantiation of the functor
should create a new, incompatible type *)valempty:t(** Empty bitfields (all bits 0) *)typefieldvalget:field->t->bool(** Get the value of this field *)valset:field->bool->t->t(** Set the value of this field *)valmk_field:unit->field(** Make a new field *)valfreeze:unit->unit(** Prevent new fields from being added. From now on, creating
a field will raise Frozen *)valtotal_width:unit->int(** Current width of the bitfield *)end(* all bits from 0 to w-1 set to true *)letrecall_bits_accw=ifw=0thenaccelse(letacc=acclor((1lslw)-1)inall_bits_acc(w-1))(* increment and return previous value *)letget_then_incrn=letx=!ninincrn;xmoduleMake():S=structtypet=intletempty=0letwidth_=ref0letfrozen_=reffalsetypefield=int(* a mask *)letgetfieldx=xlandfield<>0letsetfieldbx=ifbthenxlorfieldelsexlandlnotfieldletmk_field()=if!frozen_thenraiseFrozen;letn=get_then_incrwidth_inifn>max_widththenraiseTooManyFields;letmask=1lslninmaskletfreeze()=frozen_:=truelettotal_width()=!width_end