Skip to content

HTTPS clone URL

Subversion checkout URL

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