diff options
Diffstat (limited to 'libphobos/libdruntime/core/stdcpp/array.d')
-rw-r--r-- | libphobos/libdruntime/core/stdcpp/array.d | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/libphobos/libdruntime/core/stdcpp/array.d b/libphobos/libdruntime/core/stdcpp/array.d new file mode 100644 index 00000000000..eb63d4ccaab --- /dev/null +++ b/libphobos/libdruntime/core/stdcpp/array.d @@ -0,0 +1,133 @@ +/** + * 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"); + } +} |