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