1 /** 2 * This file is part of DCD, a development tool for the D programming language. 3 * Copyright (C) 2014 Brian Schott 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 module dsymbol.string_interning; 20 21 import std.traits : Unqual; 22 import dparse.lexer; 23 24 /// Obsolete, use `istring` constructor instead 25 istring internString(string s) nothrow @nogc @safe 26 { 27 return istring(s); 28 } 29 30 static this() 31 { 32 stringCache = StringCache(StringCache.defaultBucketCount); 33 } 34 35 static ~this() 36 { 37 destroy(stringCache); 38 } 39 40 private StringCache stringCache = void; 41 42 struct istring 43 { 44 nothrow @nogc @safe: 45 /// Interns the given string and returns the interned version. Handles empty strings too. 46 this(string s) 47 { 48 if (s.length > 0) 49 _data = stringCache.intern(s); 50 } 51 52 pure: 53 void opAssign(T)(T other) if (is(Unqual!T == istring)) 54 { 55 _data = other._data; 56 } 57 58 bool opCast(To : bool)() const 59 { 60 return _data.length > 0; 61 } 62 63 ptrdiff_t opCmpFast(const istring another) const @trusted 64 { 65 // Interned strings can be compared by the pointers. 66 // Identical strings MUST have the same address 67 return (cast(ptrdiff_t) _data.ptr) - (cast(ptrdiff_t) another._data.ptr); 68 } 69 ptrdiff_t opCmp(const string another) const 70 { 71 import std.algorithm.comparison : cmp; 72 // Compare as usual, because another string may come from somewhere else 73 return cmp(_data, another); 74 } 75 76 bool opEquals(const istring another) const @trusted 77 { 78 return _data.ptr is another._data.ptr; 79 } 80 bool opEquals(const string another) const 81 { 82 return _data == another; 83 } 84 85 size_t toHash() const @trusted 86 { 87 return (cast(size_t) _data.ptr) * 27_644_437; 88 } 89 90 string data() const 91 { 92 return _data; 93 } 94 95 alias data this; 96 private string _data; 97 }