@@ -3891,3 +3891,231 @@ unittest
3891
3891
assert (appS.data == " hellow" );
3892
3892
assert (appA.data == " hellow" );
3893
3893
}
3894
+
3895
+ version (all )
3896
+ {
3897
+
3898
+ import std.traits : CommonType, Unqual, isStaticArray;
3899
+ import std.conv : emplaceRef;
3900
+
3901
+ // @nogc: https://issues.dlang.org/show_bug.cgi?id=18439
3902
+ // nothrow @safe pure:
3903
+ nothrow :
3904
+ @safe :
3905
+ pure :
3906
+
3907
+ /+ +
3908
+ Returns a static array constructed from `a`. The type of elements can be
3909
+ specified implicitly (`int[2] a = staticArray(1,2);`) or explicitly
3910
+ (`float[2] a = staticArray!float(1,2)`).
3911
+ D20180214T203015: The result is an rvalue, therefore uses like
3912
+ `foo(staticArray(1, 2, 3))` may be inefficient because of the copies.
3913
+ +/
3914
+ // D20180214T185602: Workaround https://issues.dlang.org/show_bug.cgi?id=16779 (make alias to staticArray once fixed)
3915
+ pragma (inline, true ) U[T.length] staticArray(U = CommonType! T, T... )(T a) @nogc
3916
+ {
3917
+ return [a];
3918
+ }
3919
+
3920
+ // / ditto
3921
+ pragma (inline, true ) U[T.length] staticArrayCast(U, T... )(T a) @nogc
3922
+ {
3923
+ enum n = T.length;
3924
+ U[n] ret = void ;
3925
+ static foreach (i; 0 .. n)
3926
+ {
3927
+ // TODO: If any of these throws, the destructors of the already-constructed elements is not called. https://github.com/dlang/phobos/pull/4936/files#r131709329
3928
+ emplaceRef! U(ret[i], cast (U) a[i]);
3929
+ }
3930
+ return ret;
3931
+ }
3932
+
3933
+ // /
3934
+ @safe unittest
3935
+ {
3936
+ int val = 3 ;
3937
+ staticArray(1 , 2 , val).assertSame! int ([1 , 2 , 3 ]);
3938
+ staticArray(1 , 2.0 ).assertSame! double ([1 , 2.0 ]);
3939
+ assert (! __traits(compiles, staticArray(1 , " " )));
3940
+ staticArray().assertSame! void ([]);
3941
+ staticArray! float (1 , 2 ).assertSame! float ([1 , 2 ]);
3942
+ // see D20180214T185602
3943
+ // auto a = staticArray!byte(1, 2);
3944
+ staticArrayCast! byte (1 , 2 ).assertSame! byte ([1 , 2 ]);
3945
+ staticArrayCast! byte (1 , 129 ).assertSame! byte ([1 , - 127 ]);
3946
+
3947
+ staticArrayCast! (const (int ))(1 , 2 ).assertSame! (const (int ))([1 , 2 ]);
3948
+ staticArrayCast! (immutable (int ))(1 , 2 ).assertSame! (immutable (int ))([1 , 2 ]);
3949
+ staticArray([1 ]).assertSame! (int [])([[1 ]]);
3950
+ version (Bug)
3951
+ {
3952
+ // NOTE: correctly issues a deprecation
3953
+ int [] a2 = staticArray(1 , 2 );
3954
+ }
3955
+ }
3956
+
3957
+ /+ +
3958
+ Returns a static array constructed from `arr`. The type of elements can be
3959
+ specified implicitly (`int[2] a = [1,2].asStatic;`) or explicitly
3960
+ (`float[2] a = [1,2].asStaticCast!float`).
3961
+ See also D20180214T203015.
3962
+ +/
3963
+ pragma (inline, true ) T[n] asStatic(T, size_t n)(auto ref T[n] arr) @nogc
3964
+ {
3965
+ return arr;
3966
+ }
3967
+
3968
+ // / ditto
3969
+ U[n] asStaticCast (U, T, size_t n)(auto ref T[n] arr) @nogc
3970
+ {
3971
+ U[n] ret = void ;
3972
+ static foreach (i; 0 .. n)
3973
+ {
3974
+ emplaceRef! U(ret[i], cast (U) arr[i]);
3975
+ }
3976
+ return ret;
3977
+ }
3978
+
3979
+ // /
3980
+ @safe unittest
3981
+ {
3982
+ int val = 3 ;
3983
+ static immutable gold = [1 , 2 , 3 ];
3984
+ [1 , 2 , val].asStatic.assertSame! int ([1 , 2 , 3 ]);
3985
+
3986
+ @nogc void checkNogc()
3987
+ {
3988
+ [1 , 2 , val].asStatic.assertSame! int (gold);
3989
+ }
3990
+
3991
+ [1 , 2 , val].asStaticCast! double .assertSame! double (gold);
3992
+ [1 , 2 , 3 ].asStaticCast! int .assertSame! int (gold);
3993
+
3994
+ [1 , 2 , 3 ].asStaticCast! (const (int )).assertSame! (const (int ))(gold);
3995
+ [1 , 2 , 3 ].asStaticCast! (const (double )).assertSame! (const (double ))(gold);
3996
+ {
3997
+ const (int )[3 ] a2 = [1 , 2 , 3 ].asStatic;
3998
+ }
3999
+
4000
+ [1 , 129 ].asStaticCast! byte .assertSame! byte ([1 , - 127 ]);
4001
+
4002
+ version (Bug)
4003
+ {
4004
+ // https://issues.dlang.org/show_bug.cgi?id=16779
4005
+ auto a2 = [1 , 2 , 3 ].asStatic! byte ;
4006
+ auto a3 = [1 , 2 , 3 ].asStatic! ubyte ;
4007
+
4008
+ // NOTE: correctly issues a deprecation
4009
+ int [] a2 = [1 , 2 ].asStatic;
4010
+ }
4011
+ }
4012
+
4013
+ // / ditto but with an range
4014
+ auto asStatic (size_t n, T)(T a) @nogc
4015
+ {
4016
+ // TODO: ElementType vs ForeachType
4017
+ alias U = typeof (a[0 ]);
4018
+ U[n] ret = void ;
4019
+ size_t i;
4020
+ foreach (ref ai; a)
4021
+ {
4022
+ emplaceRef! U(ret[i++ ], ai);
4023
+ }
4024
+ assert (i == n);
4025
+ return ret;
4026
+ }
4027
+
4028
+ // / ditto
4029
+ auto asStaticCast (Un : U[n], U, size_t n, T)(T a) @nogc
4030
+ {
4031
+ U[n] ret = void ;
4032
+ size_t i;
4033
+ foreach (ref ai; a)
4034
+ {
4035
+ emplaceRef! U(ret[i++ ], cast (U) ai);
4036
+ }
4037
+ assert (i == n);
4038
+ return ret;
4039
+ }
4040
+
4041
+ // /
4042
+ @safe unittest
4043
+ {
4044
+ import std.range ;
4045
+
4046
+ 2. iota.asStatic! 2. assertSame! int ([0 , 1 ]);
4047
+ 2. iota.asStaticCast! (double [2 ]).assertSame! double ([0 , 1 ]);
4048
+ 2. iota.asStaticCast! (byte [2 ]).assertSame! byte ([0 , 1 ]);
4049
+ }
4050
+
4051
+ // /
4052
+ @system unittest
4053
+ {
4054
+ import std.range ;
4055
+
4056
+ assert (isThrown! Error(2. iota.asStatic! 1 ));
4057
+ assert (isThrown! Error(2. iota.asStatic! 3 ));
4058
+ }
4059
+
4060
+ // / ditto but with an alias
4061
+ auto asStatic (alias arr)() @nogc
4062
+ {
4063
+ enum n = arr.length;
4064
+ alias U = typeof (arr[0 ]);
4065
+ U[n] ret = void ;
4066
+ static foreach (i; 0 .. n)
4067
+ {
4068
+ emplaceRef! U(ret[i], arr[i]);
4069
+ }
4070
+ return ret;
4071
+ }
4072
+
4073
+ // / ditto
4074
+ auto asStaticCast (U, alias arr)() @nogc
4075
+ {
4076
+ enum n = arr.length;
4077
+ U[n] ret = void ;
4078
+ static foreach (i; 0 .. n)
4079
+ {
4080
+ emplaceRef! U(ret[i], cast (U) arr[i]);
4081
+ }
4082
+ return ret;
4083
+ }
4084
+
4085
+ // /
4086
+ @safe unittest
4087
+ {
4088
+ import std.range ;
4089
+
4090
+ enum a = asStatic! (2. iota);
4091
+ asStatic! (2. iota).assertSame! int ([0 , 1 ]);
4092
+ asStaticCast! (double , 2. iota).assertSame! double ([0 , 1 ]);
4093
+ asStaticCast! (byte , 2. iota).assertSame! byte ([0 , 1 ]);
4094
+ }
4095
+
4096
+ // Note: can't use `version (unittest)` because of https://issues.dlang.org/show_bug.cgi?id=18488
4097
+ void assertSame (T, T1 , T2 )(T1 a, T2 b) @nogc
4098
+ {
4099
+ assert (is (T1 == T[T1 .length]));
4100
+ assert (a == b);
4101
+ }
4102
+
4103
+ // TODO: add this to assertThrown in std.exception
4104
+ bool isThrown (T : Throwable = Exception , E)(lazy E expression) @system
4105
+ {
4106
+ try
4107
+ {
4108
+ expression();
4109
+ return false ;
4110
+ }
4111
+ catch (T)
4112
+ {
4113
+ return true ;
4114
+ }
4115
+ catch (Exception )
4116
+ {
4117
+ return false ;
4118
+ }
4119
+ }
4120
+
4121
+ }
0 commit comments