| /** |
| * D header file for interaction with C++ std::array. |
| * |
| * Copyright: Copyright (c) 2018 D Language Foundation |
| * License: Distributed under the |
| * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). |
| * (See accompanying file LICENSE) |
| * Authors: Manu Evans |
| * Source: $(DRUNTIMESRC core/stdcpp/array.d) |
| */ |
| |
| module core.stdcpp.array; |
| |
| import core.stdcpp.xutility : StdNamespace; |
| |
| // hacks to support DMD on Win32 |
| version (CppRuntime_Microsoft) |
| { |
| version = CppRuntime_Windows; // use the MS runtime ABI for win32 |
| } |
| else version (CppRuntime_DigitalMars) |
| { |
| version = CppRuntime_Windows; // use the MS runtime ABI for win32 |
| pragma(msg, "std::array not supported by DMC"); |
| } |
| |
| extern(C++, (StdNamespace)): |
| |
| /** |
| * D language counterpart to C++ std::array. |
| * |
| * C++ reference: $(LINK2 https://en.cppreference.com/w/cpp/container/array) |
| */ |
| extern(C++, class) struct array(T, size_t N) |
| { |
| extern(D): |
| pragma(inline, true): |
| |
| /// |
| alias size_type = size_t; |
| /// |
| alias difference_type = ptrdiff_t; |
| /// |
| alias value_type = T; |
| /// |
| alias pointer = T*; |
| /// |
| alias const_pointer = const(T)*; |
| |
| /// |
| alias as_array this; |
| |
| /// Variadic constructor |
| this(T[N] args ...) { this[] = args[]; } |
| |
| /// |
| void fill()(auto ref const(T) value) { this[] = value; } |
| |
| pure nothrow @nogc: |
| /// |
| size_type size() const @safe { return N; } |
| /// |
| alias length = size; |
| /// |
| alias opDollar = length; |
| /// |
| size_type max_size() const @safe { return N; } |
| /// |
| bool empty() const @safe { return N == 0; } |
| |
| /// |
| ref inout(T) front() inout @safe { static if (N > 0) { return this[0]; } else { return as_array()[][0]; /* HACK: force OOB */ } } |
| /// |
| ref inout(T) back() inout @safe { static if (N > 0) { return this[N-1]; } else { return as_array()[][0]; /* HACK: force OOB */ } } |
| |
| version (CppRuntime_Windows) |
| { |
| /// |
| inout(T)* data() inout @safe { return &_Elems[0]; } |
| /// |
| ref inout(T)[N] as_array() inout @safe { return _Elems[0 .. N]; } |
| /// |
| ref inout(T) at(size_type i) inout @safe { return _Elems[0 .. N][i]; } |
| |
| private: |
| T[N ? N : 1] _Elems; |
| } |
| else version (CppRuntime_Gcc) |
| { |
| /// |
| inout(T)* data() inout @safe { static if (N > 0) { return &_M_elems[0]; } else { return null; } } |
| /// |
| ref inout(T)[N] as_array() inout @trusted { return data()[0 .. N]; } |
| /// |
| ref inout(T) at(size_type i) inout @trusted { return data()[0 .. N][i]; } |
| |
| private: |
| static if (N > 0) |
| { |
| T[N] _M_elems; |
| } |
| else |
| { |
| struct _Placeholder {} |
| _Placeholder _M_placeholder; |
| } |
| } |
| else version (CppRuntime_Clang) |
| { |
| /// |
| inout(T)* data() inout @trusted { static if (N > 0) { return &__elems_[0]; } else { return cast(inout(T)*)__elems_.ptr; } } |
| /// |
| ref inout(T)[N] as_array() inout @trusted { return data()[0 .. N]; } |
| /// |
| ref inout(T) at(size_type i) inout @trusted { return data()[0 .. N][i]; } |
| |
| private: |
| static if (N > 0) |
| { |
| T[N] __elems_; |
| } |
| else |
| { |
| struct _ArrayInStructT { T[1] __data_; } |
| align(_ArrayInStructT.alignof) |
| byte[_ArrayInStructT.sizeof] __elems_ = void; |
| } |
| } |
| else |
| { |
| static assert(false, "C++ runtime not supported"); |
| } |
| } |