patch.index = ctx->data_id;
patch.location = offset;
patch.offset = 0;
+ patch.data_id = 0;
// Here, we cannot use the data_id property of the
// memory reservation because there is no guarantee that
package core.io
-use core {memory, math, array}
+use core {memory, math, array, iter}
Reader :: struct {
stream : ^Stream;
return 0, .None;
}
-lines :: (r: ^Reader, inplace := false) -> Iterator(str) {
- Context :: struct {
- r: ^Reader;
- inplace: bool;
- }
-
- c := new(Context, allocator=context.temp_allocator);
- c.r = r;
- c.inplace = inplace;
+lines :: (r: ^Reader, inplace := false) =>
+ iter.generator(^.{
+ r = r, inplace = inplace
- next :: (use c: ^Context) -> (str, bool) {
- line := r->read_line(consume_newline=true, inplace=inplace);
+ }, (ctx: $C) -> (str, bool) {
+ line := ctx.r->read_line(consume_newline=true, inplace=ctx.inplace);
if line.count > 0 do return line, true;
else do return "", false;
- }
-
- return .{ c, next };
-}
+ });
#local reader_consume_error :: (use reader: ^Reader) -> Error {
use core
+#doc "Generic procedure for turning something into a string."
as_str :: #match {}
+#local HasAsStrMethod :: interface (t: $T) {
+ { T.as_str(t) } -> str;
+}
+
+#overload #precedence 10000
+as_str :: macro (t: $T/HasAsStrMethod) -> str {
+ return T.as_str(t);
+}
+
+
+
free :: (s: str, allocator := context.allocator) do raw_free(allocator, s.data);
alloc_copy :: (original: str, allocator := context.allocator) -> str {
--- /dev/null
+package core.sync
+
+Once :: struct {
+ done: bool;
+ mutex: Mutex;
+}
+
+#inject Once.exec :: #match #local {}
+
+#overload
+Once.exec :: (o: ^Once, f: () -> $R) {
+ if o.done do return;
+
+ mutex_lock(^o.mutex);
+ o.done = true;
+ f();
+ mutex_unlock(^o.mutex);
+}
+
+#overload
+Once.exec :: (o: ^Once, ctx: $Ctx, f: (Ctx) -> $R) {
+ if o.done do return;
+
+ mutex_lock(^o.mutex);
+ o.done = true;
+ f(ctx);
+ mutex_unlock(^o.mutex);
+}