1 
2 //          Copyright Ferdinand Majerech 2011.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 ///Zero terminated string.
8 module dyaml.zerostring;
9 
10 import core.stdc..string;
11 
12 /**
13  * Zero terminated string used to decrease data structure size. 
14  *
15  * TypeName is used to differentiate types (better than simple alias).
16  */
17 struct ZeroString(string TypeName)
18 {
19     private:
20         ///Zero terminated string.
21         immutable(char)* str_ = null;
22 
23     public:
24         @disable int opCmp(ref ZeroString);
25 
26         ///Construct a string.
27         this(const string str) pure nothrow @trusted
28         {
29             if(str is null || str == "")
30             {
31                 str_ = null;
32                 return;
33             }
34 
35             str_ = (str ~ '\0').ptr;
36         }
37 
38         ///Get the string.
39         @property string get() const nothrow @trusted
40         in{assert(!isNull());}
41         body
42         {
43             return cast(string)str_[0 .. strlen(str_)];
44         }
45 
46         ///Test for equality with another string.
47         bool opEquals(const ZeroString str) const nothrow @trusted
48         {
49             return isNull ? str.isNull : 
50                    str.isNull ? false : (0 == strcmp(str_, str.str_));
51         }
52 
53         ///Compute a hash.
54         hash_t toHash() const nothrow @safe
55         in{assert(!isNull);}
56         body
57         {
58             auto str = get();
59             return getHash(str);
60         }
61 
62         ///Compare with another string.
63         int opCmp(const ref ZeroString str) const nothrow @trusted
64         in{assert(!isNull && !str.isNull);}
65         body
66         {
67             return strcmp(str_, str.str_);
68         }
69 
70         ///Is this string null (invalid)?
71         @property bool isNull() pure const nothrow @safe {return str_ is null;}
72 
73     private:
74         ///Hack to allow toHash to be @safe.
75         //
76         //To remove this hack, need a typeid(string).getHash() replacement that does not take a pointer.
77         hash_t getHash(ref string str) const nothrow @trusted
78         {
79             return typeid(string).getHash(&str);
80         }
81 }