<commit_before>open Std_internal

include Flags_intf

module Make (M : Make_arg) = struct
  include Int63

  let empty = zero

  let (+) a b = bit_or a b
  let (-) a b = bit_and a (bit_not b)

  let intersect = bit_and
  let complement = bit_not

  let do_intersect t1 t2 = bit_and t1 t2 <> zero
  let are_disjoint t1 t2 = bit_and t1 t2 =  zero

  let error message a sexp_of_a =
    let e = Error.create message a sexp_of_a in
    if M.should_print_error then
      eprintf "%s\n%!" (Sexp.to_string_hum (Error.sexp_of_t e));
    Error.raise e;
  ;;

  let () =
    if not M.allow_intersecting then begin
      let rec check l ac =
        match l with
        | [] -> ac
        | (flag, name) :: l ->
          let bad = List.filter l ~f:(fun (flag', _) -> do_intersect flag flag') in
          let ac = if List.is_empty bad then ac else (flag, name, bad) :: ac in
          check l ac
      in
      let bad = check M.known [] in
      if not (List.is_empty bad) then
        error "Flags.Make got intersecting flags" bad
          (<:sexp_of< (t * string * (t * string) list) list >>);
    end;
  ;;

  let () =
    let bad = List.filter M.known ~f:(fun (flag, _) -> flag = zero) in
    if not (List.is_empty bad) then
      error "Flag.Make got flags with no bits set" bad
        (<:sexp_of< (t * string) list >>)
  ;;

  let sexp_of_t =
    (* We reverse [known] so that the fold below accumulates from right to left, giving a
       final list with elements in the same order as [known]. *)
    let known = List.rev M.known in
    fun t ->
      let leftover, flag_names =
        List.fold known ~init:(t, []) ~f:(fun (t, flag_names) (flag, flag_name) ->
          if bit_and t flag = flag<commit_msg>disable the test for no bits set in Flags.Make<commit_after>open Std_internal

include Flags_intf

module Make (M : Make_arg) = struct
  include Int63

  let empty = zero

  let (+) a b = bit_or a b
  let (-) a b = bit_and a (bit_not b)

  let intersect = bit_and
  let complement = bit_not

  let do_intersect t1 t2 = bit_and t1 t2 <> zero
  let are_disjoint t1 t2 = bit_and t1 t2 =  zero

  let error message a sexp_of_a =
    let e = Error.create message a sexp_of_a in
    if M.should_print_error then
      eprintf "%s\n%!" (Sexp.to_string_hum (Error.sexp_of_t e));
    Error.raise e;
  ;;

  let () =
    if not M.allow_intersecting then begin
      let rec check l ac =
        match l with
        | [] -> ac
        | (flag, name) :: l ->
          let bad = List.filter l ~f:(fun (flag', _) -> do_intersect flag flag') in
          let ac = if List.is_empty bad then ac else (flag, name, bad) :: ac in
          check l ac
      in
      let bad = check M.known [] in
      if not (List.is_empty bad) then
        error "Flags.Make got intersecting flags" bad
          (<:sexp_of< (t * string * (t * string) list) list >>);
    end;
  ;;
(*
  let () =
    let bad = List.filter M.known ~f:(fun (flag, _) -> flag = zero) in
    if not (List.is_empty bad) then
      error "Flag.Make got flags with no bits set" bad
        (<:sexp_of< (t * string) list >>)
  ;;
*)
  let sexp_of_t =
    (* We reverse [known] so that the fold below accumulates from right to left, giving a
       final list with elements in the same order as [known]. *)
    let known = List.rev M.known in
    fun t ->
      let leftover, flag_names =
        List.fold known ~init:(t, []) ~f:(fun (t, flag_names) (flag, flag_name) ->
          if bit_and t flag = flag
{'fraction_non_alphanumeric': 0.10847555684119178, 'fraction_numerical': 0.005785363031530229, 'mean_word_length': 2.25, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1114776', 'n_tokens_mistral': 1234, 'n_tokens_neox': 1187, 'n_words': 443}