1 /**
2  This module contains support for controlling dynamic arrays' concatenation
3   Copyright: Copyright Digital Mars 2000 - 2019.
4   License: Distributed under the
5        $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
6      (See accompanying file LICENSE)
7   Source: $(DRUNTIMESRC core/internal/_array/_concatenation.d)
8 */
9 module core.internal.array.concatenation;
10 
11 /// See $(REF _d_arraycatnTX, rt,lifetime)
12 private extern (C) void[] _d_arraycatnTX(const TypeInfo ti, scope byte[][] arrs) pure nothrow;
13 
14 /// Implementation of `_d_arraycatnTX` and `_d_arraycatnTXTrace`
15 template _d_arraycatnTXImpl(Tarr : ResultArrT[], ResultArrT : T[], T)
16 {
17     import core.internal.array.utils : _d_HookTraceImpl;
18 
19     private enum errorMessage = "Cannot concatenate arrays if compiling without support for runtime type information!";
20 
21     /**
22     * Concatenating the arrays inside of `arrs`.
23     * `_d_arraycatnTX([a, b, c])` means `a ~ b ~ c`.
24     * Params:
25     *  arrs = Array containing arrays that will be concatenated.
26     * Returns:
27     *  A newly allocated array that contains all the elements from all the arrays in `arrs`.
28     * Bugs:
29     *  This function template was ported from a much older runtime hook that bypassed safety,
30     *  purity, and throwabilty checks. To prevent breaking existing code, this function template
31     *  is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
32     */
_d_arraycatnTX(scope const Tarr arrs)33     ResultArrT _d_arraycatnTX(scope const Tarr arrs) @trusted pure nothrow
34     {
35         pragma(inline, false);
36         version (D_TypeInfo)
37         {
38             auto ti = typeid(ResultArrT);
39 
40             byte[][] arrs2 = (cast(byte[]*)arrs.ptr)[0 .. arrs.length];
41             void[] result = ._d_arraycatnTX(ti, arrs2);
42             return (cast(T*)result.ptr)[0 .. result.length];
43         }
44         else
45             assert(0, errorMessage);
46     }
47 
48     /**
49     * TraceGC wrapper around $(REF _d_arraycatnTX, core,internal,array,concat).
50     * Bugs:
51     *  This function template was ported from a much older runtime hook that bypassed safety,
52     *  purity, and throwabilty checks. To prevent breaking existing code, this function template
53     *  is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
54     */
55     alias _d_arraycatnTXTrace = _d_HookTraceImpl!(ResultArrT, _d_arraycatnTX, errorMessage);
56 }
57 
58 @safe unittest
59 {
60     int counter;
61     struct S
62     {
63         int val;
thisS64         this(this)
65         {
66             counter++;
67         }
68     }
69 
70     S[][] arr = [[S(0), S(1), S(2), S(3)], [S(4), S(5), S(6), S(7)]];
71     S[] result = _d_arraycatnTXImpl!(typeof(arr))._d_arraycatnTX(arr);
72 
73     assert(counter == 8);
74     assert(result == [S(0), S(1), S(2), S(3), S(4), S(5), S(6), S(7)]);
75 }
76