|  | /** | 
|  | * 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; | 
|  |  | 
|  | 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_Microsoft) | 
|  | { | 
|  | /// | 
|  | 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_GNU) | 
|  | { | 
|  | /// | 
|  | 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_LLVM) | 
|  | { | 
|  | /// | 
|  | 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"); | 
|  | } | 
|  | } |