forked from MLstate/opalang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sRope.mli
160 lines (117 loc) · 4.95 KB
/
sRope.mli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
(*
Copyright © 2011 MLstate
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.
You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
(**
Functionnal structure for efficient string production.
This module offers you an alternative to [FBuffer] implementing the same
interface, whenever you need to have a constant complexity for the concat
operation.
With [FBuffer], this module is for producing big strings in a functionnal way
with view allocations, e.g. for code generation.
The function [add] is not so fast as [FBfufer.add] when it is used with small
strings.
<!> See the function [diverge], the implementation is not fully functionnal.
Previous values of [t] are persistent but if you diverge from a point
of your functionnal historic, you should absolutelly use [diverge] to
avoid to compromise an other [t] value.
Note that every function of this Module is tail recursive.
<!> If you need to add a function to this module, respect this constraint.
(this module manipulate hudge structures)
@author Mathieu Barbin
@author Rudy Sicard
@author Valentin Gatien-Baron
*)
(** The abstract type of a SRope. Almost Functionnal (see [diverge] function) *)
type t
(** The empty value. The int is just a hint for the first memory allocation. *)
val create : int -> t
(** {6 Basic operations} *)
(** *)
val add : t -> string -> t
(** like [add] but add a new line at end *)
val addln : t -> string -> t
(** [concat a b] does not affect [a] or [b] (functionnal) *)
val concat : t -> t -> t
(** [add_substring t s start len] append to [t] the substring of s
startgin from [start] from length [len] *)
val add_substring : t -> string -> int -> int -> t
(** diverge is used whenever you need to start from a point of your history
and to diverge. (implementation is not fully functionnal, but by using
this function, you are sure not to erase anything in memory *)
val diverge : t -> t
(** {6 Accessing Contents} *)
(** *)
val contents : t -> string
val output : out_channel -> t -> unit
val length : t -> int
val sub : t -> int -> int -> string
(** {6 Interactive accessors} *)
(**
Interactive accessors are called with a string [s],
a start position [p], and a number of characters [n];
it is supposed to output characters [p] to [p + n - 1] of [s]
If for any reason you need to interactivelly access sub string,
you can use function [iter_sub] and [fold_sub] applied to
a function [f] of your choice, which is stricly equivalent
to
{[iter (fun s start len -> f (String.sub s start len))]}
and respectively
{[fold (fun acc s start len -> f acc (String.sub s start len))]}
(one more string allocation with [String.sub])
[iter], [fold], [rev_iter], [rev_fold] are equivalent in term of performance,
all are tail rec.
@see "Format" of the ocaml standard library
@see "Pervasives" of the ocaml standard library
*)
(** *)
val iter : (string -> int -> int -> unit) -> t -> unit
val fold : ('a -> string -> int -> int -> 'a) -> 'a -> t -> 'a
val rev_iter : (string -> int -> int -> unit) -> t -> unit
val rev_fold : ('a -> string -> int -> int -> 'a) -> 'a -> t -> 'a
val iter_sub : (string -> unit) -> t -> unit
val fold_sub : ('a -> string -> 'a) -> 'a -> t -> 'a
(** {6 Format Support} *)
(**
For outputting a type [t] using format, you can use :
[Format.printf "%a" SRope.fmt t]
it will be more optimized than
[Format.printf "%s" (SRope.contents t)]
*)
val fmt : Format.formatter -> t -> unit
(**
[SRope.printf t "I add %s" "this"]
Using the two function combined will give you a quite powerfull
concatenation possibility :
if [a], [b], [c] be [3] value of type [SRope.t],
you can do things like :
[SRope.printf t "%a foo %a bar %a" fmt a fmt b fmt c]
*)
val printf : t -> ('params, Format.formatter, unit, t) format4 -> 'params
(** {6 Dynamic choice of implementation} *)
(**
You may want to use this structure for having dynamic choice of implementation.
Modules are not value in caml, this is a defun feature.
@see "FBuffer.fbuffer" This is a record version of the module.
*)
val implementation : t FBuffer.implementation
(** {6 Backward Compatibility} *)
(**
For historical reason, some allias may result in old code.
Please do not use in new code.
*)
(** @deprecated use [create] instead *)
val make : ?name:string -> int -> t
(** @deprecated use [concat] instead *)
val union : t -> t -> t
(** @deprecated use [output] instead *)
val write : t -> out_channel -> unit