@@ -81,6 +81,7 @@ import std.meta;
81
81
import std.traits ;
82
82
83
83
import std.range.primitives ;
84
+ import std.conv : emplaceRef;
84
85
public import std.range.primitives : save, empty, popFront, popBack, front, back;
85
86
86
87
/**
@@ -3891,3 +3892,286 @@ unittest
3891
3892
assert (appS.data == " hellow" );
3892
3893
assert (appA.data == " hellow" );
3893
3894
}
3895
+
3896
+ /+ +
3897
+ Params: a = The array elements
3898
+
3899
+ Returns: A static array constructed from `a`.The type of elements can be
3900
+ specified implicitly (`int[2] a = staticArray(1,2);`) or explicitly
3901
+ (`float[2] a = staticArray!float(1,2)`).
3902
+ The result is an rvalue, therefore uses like
3903
+ `foo(staticArray(1, 2, 3))` may be inefficient because of the copies.
3904
+ +/
3905
+ pragma (inline, true ) U[T.length] staticArray(U = CommonType! T, T... )(T a) nothrow @safe pure @nogc
3906
+ {
3907
+ return [a];
3908
+ }
3909
+
3910
+ // / ditto
3911
+ // Workaround https://issues.dlang.org/show_bug.cgi?id=16779 (make alias to staticArray once fixed)
3912
+ pragma (inline, true ) U[T.length] staticArrayCast(U, T... )(T a) nothrow @safe pure @nogc
3913
+ {
3914
+ enum n = T.length;
3915
+ U[n] ret = void ;
3916
+ static foreach (i; 0 .. n)
3917
+ {
3918
+ // 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
3919
+ emplaceRef! U(ret[i], cast (U) a[i]);
3920
+ }
3921
+ return ret;
3922
+ }
3923
+
3924
+ // /
3925
+ nothrow pure @safe unittest
3926
+ {
3927
+ auto a = staticArray(1 , 2 );
3928
+ assert (is (typeof (a) == int [2 ]) && a == [1 , 2 ]);
3929
+
3930
+ auto b = staticArrayCast! byte (1 , 2 );
3931
+ assert (is (typeof (b) == byte [2 ]) && b == [1 , 2 ]);
3932
+ }
3933
+
3934
+ nothrow pure @safe unittest
3935
+ {
3936
+ int val = 3 ;
3937
+ staticArray(1 , 2 , val).checkStaticArray! int ([1 , 2 , 3 ]);
3938
+ staticArray(1 , 2.0 ).checkStaticArray! double ([1 , 2.0 ]);
3939
+ assert (! __traits(compiles, staticArray(1 , " " )));
3940
+ staticArray().checkStaticArray! void ([]);
3941
+ staticArray! float (1 , 2 ).checkStaticArray! float ([1 , 2 ]);
3942
+ // auto a = staticArray!byte(1, 2);
3943
+ staticArrayCast! byte (1 , 2 ).checkStaticArray! byte ([1 , 2 ]);
3944
+ staticArrayCast! byte (1 , 129 ).checkStaticArray! byte ([1 , - 127 ]);
3945
+
3946
+ staticArrayCast! (const (int ))(1 , 2 ).checkStaticArray! (const (int ))([1 , 2 ]);
3947
+ staticArrayCast! (immutable (int ))(1 , 2 ).checkStaticArray! (immutable (int ))([1 , 2 ]);
3948
+ staticArray([1 ]).checkStaticArray! (int [])([[1 ]]);
3949
+ }
3950
+
3951
+ @system unittest
3952
+ {
3953
+ version (Bug)
3954
+ {
3955
+ // NOTE: correctly issues a deprecation
3956
+ int [] a2 = staticArray(1 , 2 );
3957
+ }
3958
+ }
3959
+
3960
+ /+ +
3961
+ Params: arr = The array elements
3962
+
3963
+ Returns: A static array constructed from `arr`. The type of elements can be
3964
+ specified implicitly (`int[2] a = [1,2].asStatic;`) or explicitly
3965
+ (`float[2] a = [1,2].asStaticCast!float`).
3966
+ +/
3967
+ pragma (inline, true ) T[n] asStatic(T, size_t n)(auto ref T[n] arr) nothrow @safe pure @nogc
3968
+ {
3969
+ return arr;
3970
+ }
3971
+
3972
+ // / ditto
3973
+ U[n] asStaticCast (U, T, size_t n)(auto ref T[n] arr) nothrow @safe pure @nogc
3974
+ {
3975
+ U[n] ret = void ;
3976
+ static foreach (i; 0 .. n)
3977
+ {
3978
+ emplaceRef! U(ret[i], cast (U) arr[i]);
3979
+ }
3980
+ return ret;
3981
+ }
3982
+
3983
+ // /
3984
+ nothrow pure @safe unittest
3985
+ {
3986
+ auto a = [0 , 1 ].asStatic;
3987
+ assert (is (typeof (a) == int [2 ]) && a == [0 , 1 ]);
3988
+
3989
+ auto b = [0 , 1 ].asStaticCast! byte ;
3990
+ assert (is (typeof (b) == byte [2 ]) && b == [0 , 1 ]);
3991
+ }
3992
+
3993
+ nothrow pure @safe unittest
3994
+ {
3995
+ int val = 3 ;
3996
+ static immutable gold = [1 , 2 , 3 ];
3997
+ [1 , 2 , val].asStatic.checkStaticArray! int ([1 , 2 , 3 ]);
3998
+
3999
+ @nogc void checkNogc()
4000
+ {
4001
+ [1 , 2 , val].asStatic.checkStaticArray! int (gold);
4002
+ }
4003
+
4004
+ [1 , 2 , val].asStaticCast! double .checkStaticArray! double (gold);
4005
+ [1 , 2 , 3 ].asStaticCast! int .checkStaticArray! int (gold);
4006
+
4007
+ [1 , 2 , 3 ].asStaticCast! (const (int )).checkStaticArray! (const (int ))(gold);
4008
+ [1 , 2 , 3 ].asStaticCast! (const (double )).checkStaticArray! (const (double ))(gold);
4009
+ {
4010
+ const (int )[3 ] a2 = [1 , 2 , 3 ].asStatic;
4011
+ }
4012
+
4013
+ [1 , 129 ].asStaticCast! byte .checkStaticArray! byte ([1 , - 127 ]);
4014
+
4015
+ }
4016
+
4017
+ /+ +
4018
+ Params: a = input range of elements
4019
+
4020
+ Returns: A static array constructed from `a`.
4021
+ +/
4022
+ auto asStatic (size_t n, T)(T a) nothrow @safe pure @nogc
4023
+ {
4024
+ // TODO: ElementType vs ForeachType
4025
+ alias U = typeof (a[0 ]);
4026
+ U[n] ret = void ;
4027
+ size_t i;
4028
+ foreach (ref ai; a)
4029
+ {
4030
+ emplaceRef! U(ret[i++ ], ai);
4031
+ }
4032
+ assert (i == n);
4033
+ return ret;
4034
+ }
4035
+
4036
+ // / ditto
4037
+ auto asStaticCast (Un : U[n], U, size_t n, T)(T a) nothrow @safe pure @nogc
4038
+ {
4039
+ U[n] ret = void ;
4040
+ size_t i;
4041
+ foreach (ref ai; a)
4042
+ {
4043
+ emplaceRef! U(ret[i++ ], cast (U) ai);
4044
+ }
4045
+ assert (i == n);
4046
+ return ret;
4047
+ }
4048
+
4049
+ // /
4050
+ nothrow pure @safe unittest
4051
+ {
4052
+ import std.range : iota;
4053
+
4054
+ auto a = 2. iota.asStatic! 2 ;
4055
+ assert (is (typeof (a) == int [2 ]) && a == [0 , 1 ]);
4056
+ auto b = 2. iota.asStaticCast! (byte [2 ]);
4057
+ assert (is (typeof (b) == byte [2 ]) && b == [0 , 1 ]);
4058
+ }
4059
+
4060
+ nothrow pure @safe unittest
4061
+ {
4062
+
4063
+ auto a = [1 , 2 ].asStatic;
4064
+ assert (is (typeof (a) == int [2 ]) && a == [1 , 2 ]);
4065
+
4066
+ import std.range : iota;
4067
+
4068
+ 2. iota.asStatic! 2. checkStaticArray! int ([0 , 1 ]);
4069
+ 2. iota.asStaticCast! (double [2 ]).checkStaticArray! double ([0 , 1 ]);
4070
+ 2. iota.asStaticCast! (byte [2 ]).checkStaticArray! byte ([0 , 1 ]);
4071
+ }
4072
+
4073
+ nothrow pure @system unittest
4074
+ {
4075
+ import std.range : iota;
4076
+
4077
+ assert (isThrown! Error(2. iota.asStatic! 1 ));
4078
+ assert (isThrown! Error(2. iota.asStatic! 3 ));
4079
+ // NOTE: alternatives are not nothrow:
4080
+ version (none )
4081
+ {
4082
+ import std.exception : assertThrown;
4083
+
4084
+ assertThrown! Error(2. iota.asStatic! 3 );
4085
+ import std.exception : ifThrown;
4086
+
4087
+ assert (ifThrown! Error({ 2. iota.asStatic! 1 ; return false ; }(), true ));
4088
+ }
4089
+ }
4090
+
4091
+ @system unittest
4092
+ {
4093
+ version (Bug)
4094
+ {
4095
+ // https://issues.dlang.org/show_bug.cgi?id=16779
4096
+ auto a2 = [1 , 2 , 3 ].asStatic! byte ;
4097
+ auto a3 = [1 , 2 , 3 ].asStatic! ubyte ;
4098
+
4099
+ // NOTE: correctly issues a deprecation
4100
+ int [] a2 = [1 , 2 ].asStatic;
4101
+ }
4102
+ }
4103
+
4104
+ /+ +
4105
+ Params: arr = the compile time range
4106
+
4107
+ Returns: A static array constructed from `arr`.
4108
+ +/
4109
+ auto asStatic (alias arr)() nothrow @safe pure @nogc
4110
+ {
4111
+ enum n = arr.length;
4112
+ alias U = typeof (arr[0 ]);
4113
+ U[n] ret = void ;
4114
+ static foreach (i; 0 .. n)
4115
+ {
4116
+ emplaceRef! U(ret[i], arr[i]);
4117
+ }
4118
+ return ret;
4119
+ }
4120
+
4121
+ // / ditto
4122
+ auto asStaticCast (U, alias arr)() nothrow @safe pure @nogc
4123
+ {
4124
+ enum n = arr.length;
4125
+ U[n] ret = void ;
4126
+ static foreach (i; 0 .. n)
4127
+ {
4128
+ emplaceRef! U(ret[i], cast (U) arr[i]);
4129
+ }
4130
+ return ret;
4131
+ }
4132
+
4133
+ // /
4134
+ nothrow pure @safe unittest
4135
+ {
4136
+ import std.range : iota;
4137
+
4138
+ enum a = asStatic! (2. iota);
4139
+ assert (is (typeof (a) == int [2 ]) && a == [0 , 1 ]);
4140
+
4141
+ enum b = asStaticCast! (byte , 2. iota);
4142
+ assert (is (typeof (b) == byte [2 ]) && b == [0 , 1 ]);
4143
+ }
4144
+
4145
+ nothrow pure @safe unittest
4146
+ {
4147
+ import std.range : iota;
4148
+
4149
+ enum a = asStatic! (2. iota);
4150
+ asStatic! (2. iota).checkStaticArray! int ([0 , 1 ]);
4151
+ asStaticCast! (double , 2. iota).checkStaticArray! double ([0 , 1 ]);
4152
+ asStaticCast! (byte , 2. iota).checkStaticArray! byte ([0 , 1 ]);
4153
+ }
4154
+
4155
+ void checkStaticArray (T, T1 , T2 )(T1 a, T2 b) nothrow @safe pure @nogc
4156
+ {
4157
+ assert (is (T1 == T[T1 .length]));
4158
+ assert (a == b);
4159
+ }
4160
+
4161
+ // TODO: add this to assertThrown in std.exception
4162
+ bool isThrown (T : Throwable = Exception , E)(lazy E expression) nothrow pure @system
4163
+ {
4164
+ try
4165
+ {
4166
+ expression();
4167
+ return false ;
4168
+ }
4169
+ catch (T)
4170
+ {
4171
+ return true ;
4172
+ }
4173
+ catch (Exception )
4174
+ {
4175
+ return false ;
4176
+ }
4177
+ }
0 commit comments