Skip to content

Commit 31ad563

Browse files
authored
Merge pull request #467 from mobotsar/enrich_char
Additional functions for the `Char` module to check common character properties
2 parents f310bc5 + 2dcaa12 commit 31ad563

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

src/core/CCChar.ml

+9
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ module Infix = struct
2323
end
2424

2525
include Infix
26+
27+
let is_uppercase_ascii c = c > '\064' && c < '\091'
28+
let is_lowercase_ascii c = c > '\096' && c < '\123'
29+
30+
let is_letter_ascii c =
31+
(is_lowercase_ascii [@inlined]) c || (is_uppercase_ascii [@inlined]) c
32+
33+
let is_digit_ascii c = c > '\047' && c < '\058'
34+
let is_whitespace_ascii c = c = '\032' || (c > '\008' && c < '\014')

src/core/CCChar.mli

+26
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,32 @@ val pp_buf : Buffer.t -> t -> unit
4040
val pp : Format.formatter -> t -> unit
4141
(** Renamed from [print] since 2.0. *)
4242

43+
val is_uppercase_ascii : t -> bool
44+
(** [is_uppercase_ascii c] is true exactly when [c] is an
45+
uppercase ASCII character, i.e. ['\064'] < [c] < ['\091'].
46+
@since 3.16 *)
47+
48+
val is_lowercase_ascii : t -> bool
49+
(** [is_lowercase_ascii c] is true exactly when [c] is a
50+
lowercase ASCII character, i.e. ['\096'] < [c] < ['\123'].
51+
@since 3.16 *)
52+
53+
val is_letter_ascii : t -> bool
54+
(** [is_letter_ascii c] is true exactly when [c] is an ASCII
55+
letter, i.e. [is_uppercase_ascii c || is_lowercase_ascii c].
56+
@since 3.16 *)
57+
58+
val is_digit_ascii : t -> bool
59+
(** [is_digit_ascii c] is true exactly when [c] is an
60+
ASCII digit, i.e. ['\047'] < [c] < ['\058'].
61+
@since 3.16 *)
62+
63+
val is_whitespace_ascii : t -> bool
64+
(** [is_whitespace_ascii c] is true exactly when [c] is an ASCII
65+
whitespace character as defined by Unicode, i.e. either [c = ' ']
66+
or ['\008'] < [c] < ['\014'].
67+
@since 3.16 *)
68+
4369
(** {2 Infix Operators}
4470
4571
@since 3.3 *)

tests/core/t_char.ml

+73
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,76 @@ eq None (of_int 257);;
88
q
99
(Q.string_of_size (Q.Gen.return 1))
1010
(fun s -> Stdlib.( = ) (to_string s.[0]) s)
11+
;;
12+
13+
q (Q.int_range 65 90 |> Q.map Char.chr) CCChar.is_uppercase_ascii;;
14+
15+
q
16+
(Q.int_range 0 64 |> Q.map Char.chr)
17+
(fun c -> not @@ CCChar.is_uppercase_ascii c)
18+
;;
19+
20+
q
21+
(Q.int_range 91 127 |> Q.map Char.chr)
22+
(fun c -> not @@ CCChar.is_uppercase_ascii c)
23+
;;
24+
25+
q (Q.int_range 97 122 |> Q.map Char.chr) CCChar.is_lowercase_ascii;;
26+
27+
q
28+
(Q.int_range 0 96 |> Q.map Char.chr)
29+
(fun c -> not @@ CCChar.is_lowercase_ascii c)
30+
;;
31+
32+
q
33+
(Q.int_range 123 127 |> Q.map Char.chr)
34+
(fun c -> not @@ CCChar.is_lowercase_ascii c)
35+
;;
36+
37+
q (Q.int_range 48 57 |> Q.map Char.chr) CCChar.is_digit_ascii;;
38+
q (Q.int_range 0 47 |> Q.map Char.chr) (fun c -> not @@ CCChar.is_digit_ascii c)
39+
;;
40+
41+
q
42+
(Q.int_range 58 127 |> Q.map Char.chr)
43+
(fun c -> not @@ CCChar.is_digit_ascii c)
44+
;;
45+
46+
eq true
47+
(Stdlib.List.for_all CCChar.is_whitespace_ascii
48+
[ '\n'; '\t'; ' '; '\010'; '\011'; '\012'; '\013' ])
49+
;;
50+
51+
eq false
52+
(Stdlib.List.exists CCChar.is_whitespace_ascii
53+
[
54+
'H';
55+
'e';
56+
'l';
57+
'l';
58+
'o';
59+
'!';
60+
'-';
61+
'-';
62+
'N';
63+
'O';
64+
't';
65+
'h';
66+
'i';
67+
'n';
68+
'a';
69+
'\055';
70+
'k';
71+
'a';
72+
'g';
73+
'$';
74+
'$';
75+
'$';
76+
'%';
77+
'^';
78+
'b';
79+
'c';
80+
'h';
81+
'\008';
82+
'h';
83+
])

0 commit comments

Comments
 (0)