d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
[official-gcc.git] / libphobos / libdruntime / core / internal / array / capacity.d
blob254e9501f632c4905b40086d380f325678bb50e9
1 /**
2 This module contains support for controlling dynamic arrays' capacity and length
4 Copyright: Copyright Digital Mars 2000 - 2019.
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 Source: $(DRUNTIMESRC core/internal/_array/_capacity.d)
9 */
10 module core.internal.array.capacity;
12 // HACK: `nothrow` and `pure` is faked.
13 private extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure;
14 private extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure;
17 * This template is needed because there need to be a `_d_arraysetlengthTTrace!Tarr` instance for every
18 * `_d_arraysetlengthT!Tarr`. By wrapping both of these functions inside of this template we force the
19 * compiler to create a instance of both function for every type that is used.
22 /// Implementation of `_d_arraysetlengthT` and `_d_arraysetlengthTTrace`
23 template _d_arraysetlengthTImpl(Tarr : T[], T)
25 private enum errorMessage = "Cannot resize arrays if compiling without support for runtime type information!";
27 /**
28 * Resize dynamic array
29 * Params:
30 * arr = the array that will be resized, taken as a reference
31 * newlength = new length of array
32 * Returns:
33 * The new length of the array
34 * Bugs:
35 * The safety level of this function is faked. It shows itself as `@trusted pure nothrow` to not break existing code.
37 size_t _d_arraysetlengthT(return scope ref Tarr arr, size_t newlength) @trusted pure nothrow
39 pragma(inline, false);
40 version (D_TypeInfo)
42 auto ti = typeid(Tarr);
44 static if (__traits(isZeroInit, T))
45 ._d_arraysetlengthT(ti, newlength, cast(void[]*)&arr);
46 else
47 ._d_arraysetlengthiT(ti, newlength, cast(void[]*)&arr);
49 return arr.length;
51 else
52 assert(0, errorMessage);
55 version (D_ProfileGC)
57 import core.internal.array.utils : _d_HookTraceImpl;
59 /**
60 * TraceGC wrapper around $(REF _d_arraysetlengthT, core,internal,array,core.internal.array.capacity).
61 * Bugs:
62 * This function template was ported from a much older runtime hook that bypassed safety,
63 * purity, and throwabilty checks. To prevent breaking existing code, this function template
64 * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
66 alias _d_arraysetlengthTTrace = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT, errorMessage);
70 @safe unittest
72 struct S
74 float f = 1.0;
77 int[] arr;
78 _d_arraysetlengthTImpl!(typeof(arr))._d_arraysetlengthT(arr, 16);
79 assert(arr.length == 16);
80 foreach (int i; arr)
81 assert(i == int.init);
83 shared S[] arr2;
84 _d_arraysetlengthTImpl!(typeof(arr2))._d_arraysetlengthT(arr2, 16);
85 assert(arr2.length == 16);
86 foreach (s; arr2)
87 assert(s == S.init);