1 /**
2  * D header file for interaction with C++ std::string_view.
3  *
4  * Copyright: Copyright (c) 2018 D Language Foundation
5  * License: Distributed under the
6  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7  *    (See accompanying file LICENSE)
8  * Authors:   Manu Evans
9  * Source:    $(DRUNTIMESRC core/stdcpp/string_view.d)
10  */
11 
12 module core.stdcpp.string_view;
13 
14 import core.stdc.stddef : wchar_t;
15 import core.stdcpp.xutility : StdNamespace;
16 
17 // hacks to support DMD on Win32
18 version (CppRuntime_Microsoft)
19 {
20     version = CppRuntime_Windows; // use the MS runtime ABI for win32
21 }
22 else version (CppRuntime_DigitalMars)
23 {
24     version = CppRuntime_Windows; // use the MS runtime ABI for win32
25     pragma(msg, "std::basic_string_view not supported by DMC");
26 }
27 
28 extern(C++, (StdNamespace)):
29 @nogc:
30 
31 ///
32 alias string_view = basic_string_view!char;
33 ///
34 alias u16string_view = basic_string_view!wchar;
35 ///
36 alias u32string_view = basic_string_view!dchar;
37 ///
38 alias wstring_view = basic_string_view!wchar_t;
39 
40 
41 /**
42  * Character traits classes specify character properties and provide specific
43  * semantics for certain operations on characters and sequences of characters.
44  */
45 extern(C++, struct) struct char_traits(CharT) {}
46 
47 
48 /**
49 * D language counterpart to C++ std::basic_string_view.
50 *
51 * C++ reference: $(LINK2 hhttps://en.cppreference.com/w/cpp/string/basic_string_view)
52 */
53 extern(C++, class) struct basic_string_view(T, Traits = char_traits!T)
54 {
55 extern(D):
56 pragma(inline, true):
57 pure nothrow @nogc:
58 
59     ///
60     enum size_type npos = size_type.max;
61 
62     ///
63     alias size_type = size_t;
64     ///
65     alias difference_type = ptrdiff_t;
66     ///
67     alias value_type = T;
68     ///
69     alias pointer = T*;
70     ///
71     alias const_pointer = const(T)*;
72 
73     ///
74     alias as_array this;
75     ///
76     alias toString = as_array;
77 
78     ///
79     this(const(T)[] str) @trusted                   { __data = str.ptr; __size = str.length; }
80 
81     ///
82     alias length = size;
83     ///
84     alias opDollar = length;
85     ///
86     size_type size() const @safe                    { return __size; }
87     ///
88     bool empty() const @safe                        { return __size == 0; }
89 
90     ///
91     const(T)* data() const @safe                    { return __data; }
92     ///
93     const(T)[] as_array() const @trusted            { return __data[0 .. __size]; }
94 
95     ///
96     ref const(T) at(size_type i) const @trusted     { return __data[0 .. __size][i]; }
97 
98     ///
99     ref const(T) front() const @safe                { return this[0]; }
100     ///
101     ref const(T) back() const @safe                 { return this[$-1]; }
102 
103 private:
104     // use the proper field names from C++ so debugging doesn't get weird
105     version (CppRuntime_Windows)
106     {
107         const_pointer _Mydata;
108         size_type _Mysize;
109 
110         alias __data = _Mydata;
111         alias __size = _Mysize;
112     }
113     else version (CppRuntime_Gcc)
114     {
115         size_t _M_len;
116         const(T)* _M_str;
117 
118         alias __data = _M_str;
119         alias __size = _M_len;
120     }
121     else version (CppRuntime_Clang)
122     {
123         const value_type* __data;
124         size_type __size;
125     }
126     else
127     {
128         static assert(false, "C++ runtime not supported");
129     }
130 }