import paged.*;
import paged.misc.*;

import strings;
import io.mapping.*;
import io.paths.*;



//
// NamedScalar[T]
//

record NamedScalar[T] (
    fileName : strings.String,
    file : File,
    mapping : FileMapping,
);

[T]
overload RegularRecord?(static NamedScalar[T]) = false;



//
// constructor
//

[S,T | String?(S)]
overload NamedScalar[T](fileName:S, initial:T) {
    if (pathExists?(fileName)) {
        var f = File(fileName, READ_WRITE);
        var mapping = FileMapping(f, MAP_READ_WRITE);
        return NamedScalar[T](strings.String(fileName), f, mapping);
    }
    else {
        var f = File(fileName, CREATE);
        // FIXME: not exception safe
        resizeFile(f, TypeSize(T));
        var mapping = FileMapping(f, MAP_READ_WRITE);
        var ptr = Pointer[T](mappingAddress(mapping));
        ptr^ <-- initial;
        return NamedScalar[T](strings.String(fileName), f, mapping);
    }
}



//
// destroy
//

[T]
overload destroy(x:NamedScalar[T]) {
    destroy(x.mapping);
    destroy(x.file);
    destroy(x.fileName);
}



//
// dereference
//

[T]
overload dereference(x:NamedScalar[T]) =
    ref Pointer[T](mappingAddress(x.mapping))^;
