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 }