00001 #region License
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #endregion
00027
00028 using System;
00029 using System.Collections.Generic;
00030 using System.Text;
00031 using System.Runtime.InteropServices;
00032 using System.Diagnostics;
00033 using System.Reflection;
00034
00035 namespace OpenTK
00036 {
00037 #region BlittableValueType<T>
00038
00046 public static class BlittableValueType<T>
00047 {
00048 #region Fields
00049
00050 static readonly Type Type;
00051 static readonly int stride;
00052
00053 #endregion
00054
00055 #region Constructors
00056
00057 static BlittableValueType()
00058 {
00059 Type = typeof(T);
00060 if (Type.IsValueType)
00061 {
00062
00063
00064 stride = Marshal.SizeOf(typeof(T));
00065 }
00066 }
00067
00068 #endregion
00069
00070 #region Public Members
00071
00078 public static int Stride { get { return stride; } }
00079
00080 #region Check
00081
00085 public static bool Check()
00086 {
00087 return Check(Type);
00088 }
00089
00094 public static bool Check(Type type)
00095 {
00096 if (!CheckStructLayoutAttribute(type))
00097 Debug.Print("Warning: type {0} does not specify a StructLayoutAttribute with Pack=1. The memory layout of the struct may change between platforms.", type.Name);
00098
00099 return CheckType(type);
00100 }
00101
00102 #endregion
00103
00104 #endregion
00105
00106 #region Private Members
00107
00108
00109
00110 static bool CheckType(Type type)
00111 {
00112
00113 if (type.IsPrimitive)
00114 return true;
00115
00116 if (!type.IsValueType)
00117 return false;
00118
00119 FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
00120 Debug.Indent();
00121 foreach (FieldInfo field in fields)
00122 {
00123 if (!CheckType(field.FieldType))
00124 return false;
00125 }
00126 Debug.Unindent();
00127
00128 return true;
00129 }
00130
00131
00132
00133 static bool CheckStructLayoutAttribute(Type type)
00134 {
00135 StructLayoutAttribute[] attr = (StructLayoutAttribute[])
00136 type.GetCustomAttributes(typeof(StructLayoutAttribute), true);
00137
00138 if ((attr == null) ||
00139 (attr != null && attr.Length > 0 && attr[0].Value != LayoutKind.Explicit && attr[0].Pack != 1))
00140 return false;
00141
00142 return true;
00143 }
00144
00145 #endregion
00146 }
00147
00148 #endregion
00149
00150 #region BlittableValueType
00151
00159 public static class BlittableValueType
00160 {
00161 #region Check
00162
00167 public static bool Check<T>(T type)
00168 {
00169 return BlittableValueType<T>.Check();
00170 }
00171
00176 public static bool Check<T>(T[] type)
00177 {
00178 return BlittableValueType<T>.Check();
00179 }
00180
00185 public static bool Check<T>(T[,] type)
00186 {
00187 return BlittableValueType<T>.Check();
00188 }
00189
00194 public static bool Check<T>(T[, ,] type)
00195 {
00196 return BlittableValueType<T>.Check();
00197 }
00198
00203 [CLSCompliant(false)]
00204 public static bool Check<T>(T[][] type)
00205 {
00206 return BlittableValueType<T>.Check();
00207 }
00208
00209 #endregion
00210
00211 #region StrideOf
00212
00220 public static int StrideOf<T>(T type)
00221 {
00222 if (!Check(type))
00223 throw new ArgumentException("type");
00224
00225 return BlittableValueType<T>.Stride;
00226 }
00227
00235 public static int StrideOf<T>(T[] type)
00236 {
00237 if (!Check(type))
00238 throw new ArgumentException("type");
00239
00240 return BlittableValueType<T>.Stride;
00241 }
00242
00250 public static int StrideOf<T>(T[,] type)
00251 {
00252 if (!Check(type))
00253 throw new ArgumentException("type");
00254
00255 return BlittableValueType<T>.Stride;
00256 }
00257
00265 public static int StrideOf<T>(T[, ,] type)
00266 {
00267 if (!Check(type))
00268 throw new ArgumentException("type");
00269
00270 return BlittableValueType<T>.Stride;
00271 }
00272
00273 #endregion
00274 }
00275
00276 #endregion
00277 }