1/** 2 This module contains support for controlling dynamic arrays' capacity and length 3 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*/ 10module core.internal.array.capacity; 11 12// HACK: `nothrow` and `pure` is faked. 13private extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure; 14private extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p) nothrow pure; 15 16/* 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. 20 */ 21 22/// Implementation of `_d_arraysetlengthT` and `_d_arraysetlengthTTrace` 23template _d_arraysetlengthTImpl(Tarr : T[], T) 24{ 25 import core.internal.array.utils : _d_HookTraceImpl; 26 27 private enum errorMessage = "Cannot resize arrays if compiling without support for runtime type information!"; 28 29 /** 30 * Resize dynamic array 31 * Params: 32 * arr = the array that will be resized, taken as a reference 33 * newlength = new length of array 34 * Returns: 35 * The new length of the array 36 * Bugs: 37 * The safety level of this function is faked. It shows itself as `@trusted pure nothrow` to not break existing code. 38 */ 39 size_t _d_arraysetlengthT(return scope ref Tarr arr, size_t newlength) @trusted pure nothrow 40 { 41 pragma(inline, false); 42 version (D_TypeInfo) 43 { 44 auto ti = typeid(Tarr); 45 46 static if (__traits(isZeroInit, T)) 47 ._d_arraysetlengthT(ti, newlength, cast(void[]*)&arr); 48 else 49 ._d_arraysetlengthiT(ti, newlength, cast(void[]*)&arr); 50 51 return arr.length; 52 } 53 else 54 assert(0, errorMessage); 55 } 56 57 /** 58 * TraceGC wrapper around $(REF _d_arraysetlengthT, core,internal,array,core.internal.array.capacity). 59 * Bugs: 60 * This function template was ported from a much older runtime hook that bypassed safety, 61 * purity, and throwabilty checks. To prevent breaking existing code, this function template 62 * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations. 63 */ 64 alias _d_arraysetlengthTTrace = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT, errorMessage); 65} 66 67@safe unittest 68{ 69 struct S 70 { 71 float f = 1.0; 72 } 73 74 int[] arr; 75 _d_arraysetlengthTImpl!(typeof(arr))._d_arraysetlengthT(arr, 16); 76 assert(arr.length == 16); 77 foreach (int i; arr) 78 assert(i == int.init); 79 80 shared S[] arr2; 81 _d_arraysetlengthTImpl!(typeof(arr2))._d_arraysetlengthT(arr2, 16); 82 assert(arr2.length == 16); 83 foreach (s; arr2) 84 assert(s == S.init); 85} 86