The OpenD Programming Language

1 /**
2  * D header file for interaction with C++ std::array.
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/array.d)
10  */
11 
12 module core.stdcpp.array;
13 
14 // LDC: empty module for unsupported C++ runtimes
15 version (CppRuntime_Microsoft)  version = Supported;
16 else version (CppRuntime_Gcc)   version = Supported;
17 else version (CppRuntime_Clang) version = Supported;
18 version (Supported):
19 
20 import core.stdcpp.xutility : StdNamespace;
21 
22 // hacks to support DMD on Win32
23 version (CppRuntime_Microsoft)
24 {
25     version = CppRuntime_Windows; // use the MS runtime ABI for win32
26 }
27 else version (CppRuntime_DigitalMars)
28 {
29     version = CppRuntime_Windows; // use the MS runtime ABI for win32
30     pragma(msg, "std::array not supported by DMC");
31 }
32 
33 extern(C++, (StdNamespace)):
34 
35 /**
36  * D language counterpart to C++ std::array.
37  *
38  * C++ reference: $(LINK2 https://en.cppreference.com/w/cpp/container/array)
39  */
40 extern(C++, class) struct array(T, size_t N)
41 {
42 extern(D):
43 pragma(inline, true):
44 
45     ///
46     alias size_type = size_t;
47     ///
48     alias difference_type = ptrdiff_t;
49     ///
50     alias value_type = T;
51     ///
52     alias pointer = T*;
53     ///
54     alias const_pointer = const(T)*;
55 
56     ///
57     alias as_array this;
58 
59     /// Variadic constructor
60     this(T[N] args ...)                                 { this[] = args[]; }
61 
62     ///
63     void fill()(auto ref const(T) value)                { this[] = value; }
64 
65 pure nothrow @nogc:
66     ///
67     size_type size() const @safe                        { return N; }
68     ///
69     alias length = size;
70     ///
71     alias opDollar = length;
72     ///
73     size_type max_size() const @safe                    { return N; }
74     ///
75     bool empty() const @safe                            { return N == 0; }
76 
77     ///
78     ref inout(T) front() inout @safe                    { static if (N > 0) { return this[0]; } else { return as_array()[][0]; /* HACK: force OOB */ } }
79     ///
80     ref inout(T) back() inout @safe                     { static if (N > 0) { return this[N-1]; } else { return as_array()[][0]; /* HACK: force OOB */ } }
81 
82     version (CppRuntime_Windows)
83     {
84         ///
85         inout(T)* data() inout @safe                    { return &_Elems[0]; }
86         ///
87         ref inout(T)[N] as_array() inout @safe          { return _Elems[0 .. N]; }
88         ///
89         ref inout(T) at(size_type i) inout @safe        { return _Elems[0 .. N][i]; }
90 
91     private:
92         T[N ? N : 1] _Elems;
93     }
94     else version (CppRuntime_Gcc)
95     {
96         ///
97         inout(T)* data() inout @safe                    { static if (N > 0) { return &_M_elems[0]; } else { return null; } }
98         ///
99         ref inout(T)[N] as_array() inout @trusted       { return data()[0 .. N]; }
100         ///
101         ref inout(T) at(size_type i) inout @trusted     { return data()[0 .. N][i]; }
102 
103     private:
104         static if (N > 0)
105         {
106             T[N] _M_elems;
107         }
108         else
109         {
110             struct _Placeholder {}
111             _Placeholder _M_placeholder;
112         }
113     }
114     else version (CppRuntime_Clang)
115     {
116         ///
117         inout(T)* data() inout @trusted                 { static if (N > 0) { return &__elems_[0]; } else { return cast(inout(T)*)__elems_.ptr; } }
118         ///
119         ref inout(T)[N] as_array() inout @trusted       { return data()[0 .. N]; }
120         ///
121         ref inout(T) at(size_type i) inout @trusted     { return data()[0 .. N][i]; }
122 
123     private:
124         static if (N > 0)
125         {
126             T[N] __elems_;
127         }
128         else
129         {
130             struct _ArrayInStructT { T[1] __data_; }
131             align(_ArrayInStructT.alignof)
132             byte[_ArrayInStructT.sizeof] __elems_ = void;
133         }
134     }
135     else
136     {
137         static assert(false, "C++ runtime not supported");
138     }
139 }