


//
// StringConstant
//
// 'last' is assumed to be dereferenceable and should point to a null-char
//

record StringConstant (
    first : Pointer[Char],
    last : Pointer[Char],
);



//
// predicates
//

overload ContiguousSequence?(static StringConstant) = true;



//
// constructors
//

inline overload StringConstant() = "";

[I | Integer?(I)]
inline overload StringConstant(first : Pointer[Char], size:I) =
    StringConstant(first, first+size);

[T,I | ByteSizedInteger?(T) and Integer?(I)]
inline overload StringConstant(first : Pointer[T], size:I) {
    var firstChar = Pointer[Char](first);
    StringConstant(firstChar, firstChar+size);
}

[T | ByteSizedInteger?(T)]
inline overload StringConstant(first : Pointer[T], last : Pointer[T]) =
    StringConstant(Pointer[Char](first), Pointer[Char](last));



//
// size, index
//

inline overload size(a:StringConstant) = SizeT(a.last - a.first);

[I | Integer?(I)]
inline overload index(a:StringConstant, i:I) {
    assert[#boundsChecks](i >= 0 and i < size(a), "StringConstant index out of bounds");
    return ref (a.first + i)^;
}



//
// coordinates and iteration
//

inline overload begin(a:StringConstant) = a.first;
inline overload end(a:StringConstant) = a.last;

inline overload iterator(a:StringConstant) = coordinateRange(begin(a), end(a));

inline overload reverseIterator(a:StringConstant) =
    reverseCoordinateRange(end(a), begin(a));



//
// cstring
//

inline overload cstring(a:StringConstant) = Pointer[Int8](a.first);
