| /** | |
| * 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"); | |
| } | |
| } |