1 /** 2 * Betterc: Frequently used primitives suitable for use in the BetterC D subset. 3 * 4 * Copyright: Maxim Freck, 2018. 5 * Authors: Maxim Freck <maxim@freck.pp.ru> 6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 7 */ 8 module betterc.stringz; 9 10 /******* 11 * Reference-counted null-terminated string 12 */ 13 struct Stringz 14 { 15 private struct Payload { 16 char* dst; 17 size_t length; 18 19 size_t count; 20 @disable this(this); // not copyable 21 } 22 23 private Payload *payload; 24 25 /******* 26 * Constructor 27 * 28 * Params: 29 * src = the D-style string 30 */ 31 public this(string src) nothrow @nogc 32 { 33 import core.stdc.stdlib: malloc; 34 import core.stdc.string: memcpy; 35 36 payload = (cast(Payload*)malloc(Payload.sizeof)); 37 38 payload.count = 1; 39 payload.length = src.length; 40 payload.dst = cast(char*)malloc(src.length+1); 41 memcpy(payload.dst, src.ptr, src.length); 42 payload.dst[src.length] = 0; 43 44 } 45 46 this (this) nothrow @nogc 47 { 48 if (payload !is null) 49 payload.count++; 50 } 51 52 ///Ref. counting during structure assignment 53 ref typeof(this) opAssign()(auto ref typeof(this) rhs) nothrow @nogc 54 { 55 this.payload = rhs.payload; 56 if (payload !is null) 57 payload.count++; 58 return this; 59 } 60 61 ~this() nothrow @nogc 62 { 63 import core.stdc.stdlib: free; 64 if (payload !is null && --payload.count == 0) { 65 free(payload.dst); 66 free(payload); 67 } 68 } 69 70 pragma(inline) 71 T opCast(T:immutable(char)*)() pure nothrow @nogc 72 { 73 return *this; 74 } 75 76 immutable(char)* opUnary(string s)() nothrow @nogc if (s == "*") 77 { 78 return cast(immutable(char)*)payload.dst; 79 } 80 81 immutable(size_t) length() nothrow @nogc 82 { 83 return payload.length; 84 } 85 }