4 // Rodrigo Kumpera (rkumpera@novell.com)
6 // (C) 2008 Novell, Inc. (http://www.novell.com)
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System.Runtime.InteropServices;
32 public static class ArrayExtensions
34 [Acceleration (AccelMode.SSE1)]
36 public static Vector2d GetVector (this double[] array, int offset)
38 return new Vector2d (array [offset], array [offset + 1]);
41 [Acceleration (AccelMode.SSE1)]
43 public static Vector2l GetVector (this long[] array, int offset)
45 return new Vector2l (array [offset], array [offset + 1]);
48 [Acceleration (AccelMode.SSE1)]
50 public static Vector2ul GetVector (this ulong[] array, int offset)
52 return new Vector2ul (array [offset], array [offset + 1]);
55 [Acceleration (AccelMode.SSE1)]
57 public static Vector4f GetVector (this float[] array, int offset)
59 return new Vector4f (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
62 [Acceleration (AccelMode.SSE1)]
64 public static Vector4i GetVector (this int[] array, int offset)
66 return new Vector4i (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
69 [Acceleration (AccelMode.SSE1)]
71 public static Vector4ui GetVector (this uint[] array, int offset)
73 return new Vector4ui (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
76 [Acceleration (AccelMode.SSE1)]
78 public static Vector8s GetVector (this short[] array, int offset)
80 if (offset < 0 || offset > array.Length - 8)
81 throw new IndexOutOfRangeException ();
83 fixed (void *ptr = &array[offset]) {
84 return *(Vector8s*)ptr;
89 [Acceleration (AccelMode.SSE1)]
91 public static Vector8us GetVector (this ushort[] array, int offset)
93 if (offset < 0 || offset > array.Length - 8)
94 throw new IndexOutOfRangeException ();
96 fixed (void *ptr = &array[offset]) {
97 return *(Vector8us*)ptr;
102 [Acceleration (AccelMode.SSE1)]
103 [CLSCompliant(false)]
104 public static Vector16sb GetVector (this sbyte[] array, int offset)
106 if (offset < 0 || offset > array.Length - 16)
107 throw new IndexOutOfRangeException ();
109 fixed (void *ptr = &array[offset]) {
110 return *(Vector16sb*)ptr;
115 [Acceleration (AccelMode.SSE1)]
116 [CLSCompliant(false)]
117 public static Vector16b GetVector (this byte[] array, int offset)
119 if (offset < 0 || offset > array.Length - 16)
120 throw new IndexOutOfRangeException ();
122 fixed (void *ptr = &array[offset]) {
123 return *(Vector16b*)ptr;
128 [Acceleration (AccelMode.SSE1)]
129 [CLSCompliant(false)]
130 public static void SetVector (this double[] array, Vector2d val, int offset)
132 array [offset + 0] = val.X;
133 array [offset + 1] = val.Y;
136 [Acceleration (AccelMode.SSE1)]
137 [CLSCompliant(false)]
138 public static void SetVector (this long[] array, Vector2l val, int offset)
140 array [offset + 0] = val.X;
141 array [offset + 1] = val.Y;
144 [Acceleration (AccelMode.SSE1)]
145 [CLSCompliant(false)]
146 public static void SetVector (this ulong[] array, Vector2ul val, int offset)
148 array [offset + 0] = val.X;
149 array [offset + 1] = val.Y;
152 [Acceleration (AccelMode.SSE1)]
153 [CLSCompliant(false)]
154 public static void SetVector (this float[] array, Vector4f val, int offset)
156 array [offset + 0] = val.X;
157 array [offset + 1] = val.Y;
158 array [offset + 2] = val.Z;
159 array [offset + 3] = val.W;
162 [Acceleration (AccelMode.SSE1)]
163 [CLSCompliant(false)]
164 public static void SetVector (this int[] array, Vector4i val, int offset)
166 array [offset + 0] = val.X;
167 array [offset + 1] = val.Y;
168 array [offset + 2] = val.Z;
169 array [offset + 3] = val.W;
172 [Acceleration (AccelMode.SSE1)]
173 [CLSCompliant(false)]
174 public static void SetVector (this uint[] array, Vector4ui val, int offset)
176 array [offset + 0] = val.X;
177 array [offset + 1] = val.Y;
178 array [offset + 2] = val.Z;
179 array [offset + 3] = val.W;
182 [Acceleration (AccelMode.SSE1)]
183 [CLSCompliant(false)]
184 public static void SetVector (this short[] array, Vector8s val, int offset)
186 array [offset + 0] = val.V0;
187 array [offset + 1] = val.V1;
188 array [offset + 2] = val.V2;
189 array [offset + 3] = val.V3;
190 array [offset + 4] = val.V4;
191 array [offset + 5] = val.V5;
192 array [offset + 6] = val.V6;
193 array [offset + 7] = val.V7;
196 [Acceleration (AccelMode.SSE1)]
197 [CLSCompliant(false)]
198 public static void SetVector (this ushort[] array, Vector8us val, int offset)
200 array [offset + 0] = val.V0;
201 array [offset + 1] = val.V1;
202 array [offset + 2] = val.V2;
203 array [offset + 3] = val.V3;
204 array [offset + 4] = val.V4;
205 array [offset + 5] = val.V5;
206 array [offset + 6] = val.V6;
207 array [offset + 7] = val.V7;
210 [Acceleration (AccelMode.SSE1)]
211 [CLSCompliant(false)]
212 public static void SetVector (this sbyte[] array, Vector16sb val, int offset)
214 for (int i = 0; i < 16; ++i)
215 array [offset + i] = val [i];
218 [Acceleration (AccelMode.SSE1)]
219 [CLSCompliant(false)]
220 public static void SetVector (this byte[] array, Vector16b val, int offset)
222 for (int i = 0; i < 16; ++i)
223 array [offset + i] = val [i];
227 [Acceleration (AccelMode.SSE1)]
228 [CLSCompliant(false)]
229 public static Vector2d GetVectorAligned (this double[] array, int offset)
231 return new Vector2d (array [offset], array [offset + 1]);
234 [Acceleration (AccelMode.SSE1)]
235 [CLSCompliant(false)]
236 public static Vector2l GetVectorAligned (this long[] array, int offset)
238 return new Vector2l (array [offset], array [offset + 1]);
241 [Acceleration (AccelMode.SSE1)]
242 [CLSCompliant(false)]
243 public static Vector2ul GetVectorAligned (this ulong[] array, int offset)
245 return new Vector2ul (array [offset], array [offset + 1]);
248 [Acceleration (AccelMode.SSE1)]
249 [CLSCompliant(false)]
250 public static Vector4f GetVectorAligned (this float[] array, int offset)
252 return new Vector4f (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
255 [Acceleration (AccelMode.SSE1)]
256 [CLSCompliant(false)]
257 public static Vector4i GetVectorAligned (this int[] array, int offset)
259 return new Vector4i (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
262 [Acceleration (AccelMode.SSE1)]
263 [CLSCompliant(false)]
264 public static Vector4ui GetVectorAligned (this uint[] array, int offset)
266 return new Vector4ui (array [offset], array [offset + 1], array [offset + 2], array [offset + 3]);
269 [Acceleration (AccelMode.SSE1)]
270 [CLSCompliant(false)]
271 public static Vector8s GetVectorAligned (this short[] array, int offset)
273 if (offset < 0 || offset > array.Length - 8)
274 throw new IndexOutOfRangeException ();
276 fixed (void *ptr = &array[offset]) {
277 return *(Vector8s*)ptr;
282 [Acceleration (AccelMode.SSE1)]
283 [CLSCompliant(false)]
284 public static Vector8us GetVectorAligned (this ushort[] array, int offset)
286 if (offset < 0 || offset > array.Length - 8)
287 throw new IndexOutOfRangeException ();
289 fixed (void *ptr = &array[offset]) {
290 return *(Vector8us*)ptr;
295 [Acceleration (AccelMode.SSE1)]
296 [CLSCompliant(false)]
297 public static Vector16sb GetVectorAligned (this sbyte[] array, int offset)
299 if (offset < 0 || offset > array.Length - 16)
300 throw new IndexOutOfRangeException ();
302 fixed (void *ptr = &array[offset]) {
303 return *(Vector16sb*)ptr;
308 [Acceleration (AccelMode.SSE1)]
309 [CLSCompliant(false)]
310 public static Vector16b GetVectorAligned (this byte[] array, int offset)
312 if (offset < 0 || offset > array.Length - 16)
313 throw new IndexOutOfRangeException ();
315 fixed (void *ptr = &array[offset]) {
316 return *(Vector16b*)ptr;
321 [Acceleration (AccelMode.SSE1)]
322 [CLSCompliant(false)]
323 public static void SetVectorAligned (this double[] array, Vector2d val, int offset)
325 array [offset + 0] = val.X;
326 array [offset + 1] = val.Y;
329 [Acceleration (AccelMode.SSE1)]
330 [CLSCompliant(false)]
331 public static void SetVectorAligned (this long[] array, Vector2l val, int offset)
333 array [offset + 0] = val.X;
334 array [offset + 1] = val.Y;
337 [Acceleration (AccelMode.SSE1)]
338 [CLSCompliant(false)]
339 public static void SetVectorAligned (this ulong[] array, Vector2ul val, int offset)
341 array [offset + 0] = val.X;
342 array [offset + 1] = val.Y;
345 [Acceleration (AccelMode.SSE1)]
346 [CLSCompliant(false)]
347 public static void SetVectorAligned (this float[] array, Vector4f val, int offset)
349 array [offset + 0] = val.X;
350 array [offset + 1] = val.Y;
351 array [offset + 2] = val.Z;
352 array [offset + 3] = val.W;
355 [Acceleration (AccelMode.SSE1)]
356 [CLSCompliant(false)]
357 public static void SetVectorAligned (this int[] array, Vector4i val, int offset)
359 array [offset + 0] = val.X;
360 array [offset + 1] = val.Y;
361 array [offset + 2] = val.Z;
362 array [offset + 3] = val.W;
365 [Acceleration (AccelMode.SSE1)]
366 [CLSCompliant(false)]
367 public static void SetVectorAligned (this uint[] array, Vector4ui val, int offset)
369 array [offset + 0] = val.X;
370 array [offset + 1] = val.Y;
371 array [offset + 2] = val.Z;
372 array [offset + 3] = val.W;
375 [Acceleration (AccelMode.SSE1)]
376 [CLSCompliant(false)]
377 public static void SetVectorAligned (this short[] array, Vector8s val, int offset)
379 array [offset + 0] = val.V0;
380 array [offset + 1] = val.V1;
381 array [offset + 2] = val.V2;
382 array [offset + 3] = val.V3;
383 array [offset + 4] = val.V4;
384 array [offset + 5] = val.V5;
385 array [offset + 6] = val.V6;
386 array [offset + 7] = val.V7;
389 [Acceleration (AccelMode.SSE1)]
390 [CLSCompliant(false)]
391 public static void SetVectorAligned (this ushort[] array, Vector8us val, int offset)
393 array [offset + 0] = val.V0;
394 array [offset + 1] = val.V1;
395 array [offset + 2] = val.V2;
396 array [offset + 3] = val.V3;
397 array [offset + 4] = val.V4;
398 array [offset + 5] = val.V5;
399 array [offset + 6] = val.V6;
400 array [offset + 7] = val.V7;
403 [Acceleration (AccelMode.SSE1)]
404 [CLSCompliant(false)]
405 public static void SetVectorAligned (this sbyte[] array, Vector16sb val, int offset)
407 for (int i = 0; i < 16; ++i)
408 array [offset + i] = val [i];
411 [Acceleration (AccelMode.SSE1)]
412 [CLSCompliant(false)]
413 public static void SetVectorAligned (this byte[] array, Vector16b val, int offset)
415 for (int i = 0; i < 16; ++i)
416 array [offset + i] = val [i];
419 public static bool IsAligned<T> (this T[] vect, int index) where T : struct
421 int size = Marshal.SizeOf (typeof (T));
422 return size * index % 16 == 0;