//
//	clipptr_net.cs
//
//	配列ポインタ
//
//	CLiP - Common Library for P/ECE
//	Copyright (C) 2017 Naoyuki Sawa
//
//	* Fri Mar 03 22:34:24 JST 2017 Naoyuki Sawa
//	- 1st リリース。
//	  当モジュールはC言語版には有りません。
//	- 配列のベースアドレスとオフセットをまとめて扱い、C言語のポインタに相当する構造体です。
//	  C言語ならばポインタ一つで済むのですが、C#はunsafe無しでポインタを扱うのが難しいので、このような構造体を用意する事にしました。
//	  .NET FrameworkのArraySegment<T>に似ていますが、自分の使い方には合っていなかったので…
//	  既存の関数の移植のために、極力、C言語のポインタと同じ感覚で使えるようにしてみました。
//	- 各構造体の実装は似ているので、Int32Ptr構造体の実装をコピーして、他の構造体の実装も作成しました。
//	  今後もし、変更や修正を行う場合は、まずInt32Ptrを修正して、その後、他の構造体にも反映して下さい。
//	  いずれ、テンプレートから各構造体の実装を自動生成するような、sedスクリプトを作りたいと思います。(※TODO:)
//	- BytePtrとSBytePtr構造体だけは、BitConverter.ToByte()が無いので、インデクサの実装が少し違います。
//	  上記の方法で反映した後、BytePtrとSBytePtr構造体のインデクサだけは、手作業で少し変更して下さい。
//	- VoidPtr構造体は、適用出来ない処理が有るので、他とはかなり違います。
//	  上記の方法で反映した後、VoidPtr構造体は手作業で少し変更して下さい。
//	* Mon Mar 13 21:21:21 JST 2017 Naoyuki Sawa
//	- StringPtrを追加しました。
//	  VoidPtr～DoublePtrはbyte[]をカプセル化する構造体だったのに対して、StringPtrはchar[]をカプセル化する構造体です。
//	  VoidPtr～DoublePtrとStringPtrを、相互に変換する事は出来ません。
//	* Sat Apr 01 22:28:12 JST 2017 Naoyuki Sawa
//	- VoidPtr～DoublePtrの実装を大幅に変更しました。
//	  変更前はbyte[]しかカプセル化出来ませんでしたが、変更後は任意のプリミティブ配列をカプセル化出来るようになりました。
//	  カプセル化したプリミティブ配列の型と、VoidPtr～DoublePtrの対応は固定的ではなく、任意に組み合わせられます。
//	  例えば、ushort[]をInt32Ptrでカプセル化する事も出来ます。
//	  配列の型とVoidPtr～DoublePtrの型が同じならば、キャストは不要です。
//	  配列の型とVoidPtr～DoublePtrの型が同じでなくても、明示的なキャストによって変換出来ます。
//	  C言語のポインタとほぼ同じ感覚で使えると思います。
//	- 今回の実装において、仕方無く静的なコンパイルチェックが掛からない点が生じてしまいました。
//	  本当は、
//	  │VoidPtr p = new object[10];
//	  │VoidPtr q = new VoidPtr(new object[10], 0);
//	  を、静的なコンパイルチェックによってコンパイルエラーとなるべきなのですが、そうならずに、実行時エラーになります。
//	  なぜこうなってしまったかと言うと、
//	  │VoidPtr p = null;
//	  │VoidPtr q = new VoidPtr(null, 0);
//	  を許容するために、引数を具体的なプリミティブ配列の型でなく、Arrayポインタとせざるを得なかったからです。
//	  或いは、後者を許容せずに、
//	  │VoidPtr p = (byte[])null;
//	  │VoidPtr q = new VoidPtr((byte[])null, 0);
//	  と書かせる方法も考えたのですが、元のC言語プログラムには無かったキャストを追記する際に却ってエンバグしそうなので、この方法は取りませんでした。
//	  結論としては、非プリミティブ配列を指定してVoidPtrを初期化した場合に、コンパイルエラーにならず実行時エラで検出するのを受け入れる事にしました。
//	  実際のところ、プリミティブ配列を渡すべき所にクラス配列を渡すようなバグはあまり起きないと思うので、危険は小さいと思います。
//	- 今回は変更量が多かったので、変更前のコードはコメントアウトして残していません。
//	  変更前のコードも、(短期間ですが)安定して動作していた実績が有るので、/clip/keep/20_配列ポインタ変更前保存/clipptr_net.csに保存しておきました。
//	* Mon Apr 10 21:37:40 JST 2017 Naoyuki Sawa
//	- GenericPtr<T>を追加しました。
//	  プリミティブ型に対するVoidPtr,BytePtr,…や、文字列に対するStringPtrと同様に、任意の型の配列に対しても途中を指したいと思ったからです。
//	  具体的には、cliprnd.csのshuffle()を実装するために追加しました。
//	  今後、shuffle()以外や、アプリケーションからも利用する予定です。
//	* Fri Apr 14 22:51:13 JST 2017 Naoyuki Sawa
//	- 全てのクラスの、ArrayプロパティとOffsetプロパティの、「private set」アクセサを削除しました。
//	  これまで、コンストラクタの中で上記のプロパティを格納するために、「private set」アクセサを設けていたのですが、
//	  C#の仕様で、コンストラクタの中では、setアクセサが無いプロパティにも値を代入出来る事に気付きました。(直観に反しますが…そういう仕様だそうです。)
//	  従って、ArrayプロパティとOffsetプロパティの「private set」アクセサを削除しても、その他のコードには一切の変更不要で、動作する事に気付きました。
//	- ちなみに、Read()やoperator ++やoperator --は、一見mutableな処理に見えるので、「private set」アクセサが必要であるように見えるかも知れませんが、
//	  operator ++やoperator --はC#の仕様によって、フィールドの変更ではなく構造体変数全体の代入の動作になるので、setアクセサは不要です。
//	  operator ++を呼び出している、Read()にもsetアクセサは不要です。(ちょっと直観的でないので納得し辛いですが…そういうものらしいです。)
//	* Sat Apr 15 21:38:10 JST 2017 Naoyuki Sawa
//	- 全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//	  昨日(2017/04/14)、「private set」アクセサが不要である事に気付いて、「private set」アクセサを削除したのですが、
//	  その結果、getアクセサだけを持つ自動実装プロパティとなり、それは単純にreadonlyフィールドと同じだという事に気付きました。
//	  getアクセサだけを持つ自動実装プロパティのままにしておいても動作は同じなのですが、余計な複雑さを避けるために、readonlyフィールドに変更しました。
//
using System;
namespace org.piece_me {
	public static partial class libclip {
		//*****************************************************************************
		//	VoidPtr
		//*****************************************************************************
		public struct VoidPtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(VoidPtr x, VoidPtr y) { return  x.Equals(y); }
			public static bool operator !=(VoidPtr x, VoidPtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
		#if false
			//本当はこうしたかったのだが、「new VoidPtr(null,0);」に対してコンパイラがどの関数を呼び出して良いかを判断出来ず、コンパイルエラーになるので駄目だった。
			private VoidPtr(Array     Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  VoidPtr(Byte[]    Array, int Offset) : this((Array)Array, Offset * sizeof(Byte   )) { /** no job **/ }
			public  VoidPtr(SByte[]   Array, int Offset) : this((Array)Array, Offset * sizeof(SByte  )) { /** no job **/ }
			public  VoidPtr(Int16[]   Array, int Offset) : this((Array)Array, Offset * sizeof(Int16  )) { /** no job **/ }
			public  VoidPtr(UInt16[]  Array, int Offset) : this((Array)Array, Offset * sizeof(UInt16 )) { /** no job **/ }
			public  VoidPtr(Int32[]   Array, int Offset) : this((Array)Array, Offset * sizeof(Int32  )) { /** no job **/ }
			public  VoidPtr(UInt32[]  Array, int Offset) : this((Array)Array, Offset * sizeof(UInt32 )) { /** no job **/ }
			public  VoidPtr(Int64[]   Array, int Offset) : this((Array)Array, Offset * sizeof(Int64  )) { /** no job **/ }
			public  VoidPtr(UInt64[]  Array, int Offset) : this((Array)Array, Offset * sizeof(UInt64 )) { /** no job **/ }
			public  VoidPtr(Boolean[] Array, int Offset) : this((Array)Array, Offset * sizeof(Boolean)) { /** no job **/ }
			public  VoidPtr(Char[]    Array, int Offset) : this((Array)Array, Offset * sizeof(Char   )) { /** no job **/ }
			public  VoidPtr(Single[]  Array, int Offset) : this((Array)Array, Offset * sizeof(Single )) { /** no job **/ }
			public  VoidPtr(Double[]  Array, int Offset) : this((Array)Array, Offset * sizeof(Double )) { /** no job **/ }
		#else
			//仕方が無いのでこうした。間違って非プリミティブ配列を渡した場合にコンパイルエラーにならず、実行時までエラーを検出出来ないのがいまいちだが仕方が無い。
			public  VoidPtr(Array     Array, int Offset) {
				if(Array != null) {
					if(Array is Byte[]   ) { Offset *= sizeof(Byte   ); } else
					if(Array is SByte[]  ) { Offset *= sizeof(SByte  ); } else
					if(Array is Int16[]  ) { Offset *= sizeof(Int16  ); } else
					if(Array is UInt16[] ) { Offset *= sizeof(UInt16 ); } else
					if(Array is Int32[]  ) { Offset *= sizeof(Int32  ); } else
					if(Array is UInt32[] ) { Offset *= sizeof(UInt32 ); } else
					if(Array is Int64[]  ) { Offset *= sizeof(Int64  ); } else
					if(Array is UInt64[] ) { Offset *= sizeof(UInt64 ); } else
					if(Array is Boolean[]) { Offset *= sizeof(Boolean); } else
					if(Array is Char[]   ) { Offset *= sizeof(Char   ); } else
					if(Array is Single[] ) { Offset *= sizeof(Single ); } else
					if(Array is Double[] ) { Offset *= sizeof(Double ); } else { throw new ApplicationException(); }
				}
				this.Array  = Array;
				this.Offset = Offset;
			}
		#endif
			//-----------------------------------------------------------------------------
			//変換演算子
		#if false
			//本当はこうしたかったのだが、「VoidPtr p = null;」に対してコンパイラがどの関数を呼び出して良いかを判断出来ず、コンパイルエラーになるので駄目だった。
			public static implicit operator VoidPtr(Byte[]    Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(SByte[]   Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Int16[]   Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(UInt16[]  Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Int32[]   Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(UInt32[]  Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Int64[]   Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(UInt64[]  Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Boolean[] Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Char[]    Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Single[]  Array) { return new VoidPtr(Array, 0); }
			public static implicit operator VoidPtr(Double[]  Array) { return new VoidPtr(Array, 0); }
		#else
			//仕方が無いのでこうした。間違って非プリミティブ配列を渡した場合にコンパイルエラーにならず、実行時までエラーを検出出来ないのがいまいちだが仕方が無い。
			public static implicit operator VoidPtr(Array     Array) { return new VoidPtr(Array, 0); }
		#endif
			public static implicit operator bool(VoidPtr x) { return x.Array != null; }
		//不要	public static bool operator true( VoidPtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(VoidPtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不可	public static implicit operator VoidPtr(VoidPtr    x) { return new VoidPtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static implicit operator VoidPtr(BytePtr    x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(SBytePtr   x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(Int16Ptr   x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(UInt16Ptr  x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(Int32Ptr   x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(UInt32Ptr  x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(Int64Ptr   x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(UInt64Ptr  x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(BooleanPtr x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(CharPtr    x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(SinglePtr  x) { return new VoidPtr(x.Array, x.Offset); }
			public static implicit operator VoidPtr(DoublePtr  x) { return new VoidPtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(VoidPtr x, VoidPtr y) {
		//不可		return (x - y) < 0;
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset < y.Offset;
			}
			public static bool operator >(VoidPtr x, VoidPtr y) {
		//不可		return (x - y) > 0;
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset > y.Offset;
			}
			public static bool operator <=(VoidPtr x, VoidPtr y) {
		//不可		return (x - y) <= 0;
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset <= y.Offset;
			}
			public static bool operator >=(VoidPtr x, VoidPtr y) {
		//不可		return (x - y) >= 0;
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset >= y.Offset;
			}
		//不可	public static int operator -(VoidPtr x, VoidPtr y) { ～ }
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
		//不可	public Void this[int i] { ～ }
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
		//不可	public Void Read() { ～ }
		//不可	public void Write(Void value) { ～ }
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
		//不可	public static VoidPtr operator +(VoidPtr x, int i) { ～ }
		//不可	public static VoidPtr operator -(VoidPtr x, int i) { ～ }
		//不可	public static VoidPtr operator ++(VoidPtr x) { ～ }
		//不可	public static VoidPtr operator --(VoidPtr x) { ～ }
		}
		//*****************************************************************************
		//	BytePtr
		//*****************************************************************************
		public struct BytePtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(BytePtr x, BytePtr y) { return  x.Equals(y); }
			public static bool operator !=(BytePtr x, BytePtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private BytePtr(Array  Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  BytePtr(Byte[] Array, int Offset) : this((Array)Array, Offset * sizeof(Byte)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator BytePtr(Byte[] Array) { return new BytePtr(Array, 0); }
			public static implicit operator bool(BytePtr x) { return x.Array != null; }
		//不要	public static bool operator true( BytePtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(BytePtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator BytePtr(VoidPtr    x) { return new BytePtr(x.Array, x.Offset); }
		//不可	public static implicit operator BytePtr(BytePtr    x) { return new BytePtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator BytePtr(SBytePtr   x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(Int16Ptr   x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(UInt16Ptr  x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(Int32Ptr   x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(UInt32Ptr  x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(Int64Ptr   x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(UInt64Ptr  x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(BooleanPtr x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(CharPtr    x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(SinglePtr  x) { return new BytePtr(x.Array, x.Offset); }
			public static explicit operator BytePtr(DoublePtr  x) { return new BytePtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(BytePtr x, BytePtr y) { return (x - y) < 0; }
			public static bool operator >(BytePtr x, BytePtr y) { return (x - y) > 0; }
			public static bool operator <=(BytePtr x, BytePtr y) { return (x - y) <= 0; }
			public static bool operator >=(BytePtr x, BytePtr y) { return (x - y) >= 0; }
			public static int operator -(BytePtr x, BytePtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Byte)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Byte);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Byte this[int i] {
				get { return Buffer.GetByte(Array, Offset + (i * sizeof(Byte))); }
				set { Buffer.SetByte(Array, Offset + (i * sizeof(Byte)), value); }
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Byte Read() {
				return (this++)[0];
			}
			public void Write(Byte value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static BytePtr operator +(BytePtr x, int i) { return new BytePtr(x.Array, x.Offset + (i * sizeof(Byte))); }
			public static BytePtr operator -(BytePtr x, int i) { return new BytePtr(x.Array, x.Offset - (i * sizeof(Byte))); }
			public static BytePtr operator ++(BytePtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static BytePtr operator --(BytePtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	SBytePtr
		//*****************************************************************************
		public struct SBytePtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(SBytePtr x, SBytePtr y) { return  x.Equals(y); }
			public static bool operator !=(SBytePtr x, SBytePtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private SBytePtr(Array   Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  SBytePtr(SByte[] Array, int Offset) : this((Array)Array, Offset * sizeof(SByte)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator SBytePtr(SByte[] Array) { return new SBytePtr(Array, 0); }
			public static implicit operator bool(SBytePtr x) { return x.Array != null; }
		//不要	public static bool operator true( SBytePtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(SBytePtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator SBytePtr(VoidPtr    x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(BytePtr    x) { return new SBytePtr(x.Array, x.Offset); }
		//不可	public static implicit operator SBytePtr(SBytePtr   x) { return new SBytePtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator SBytePtr(Int16Ptr   x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(UInt16Ptr  x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(Int32Ptr   x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(UInt32Ptr  x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(Int64Ptr   x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(UInt64Ptr  x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(BooleanPtr x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(CharPtr    x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(SinglePtr  x) { return new SBytePtr(x.Array, x.Offset); }
			public static explicit operator SBytePtr(DoublePtr  x) { return new SBytePtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(SBytePtr x, SBytePtr y) { return (x - y) < 0; }
			public static bool operator >(SBytePtr x, SBytePtr y) { return (x - y) > 0; }
			public static bool operator <=(SBytePtr x, SBytePtr y) { return (x - y) <= 0; }
			public static bool operator >=(SBytePtr x, SBytePtr y) { return (x - y) >= 0; }
			public static int operator -(SBytePtr x, SBytePtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(SByte)) != 0) { throw new ApplicationException(); }
				return n / sizeof(SByte);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public SByte this[int i] {
				get { return (SByte)Buffer.GetByte(Array, Offset + (i * sizeof(SByte))); }
				set { Buffer.SetByte(Array, Offset + (i * sizeof(SByte)), (byte)value); }
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public SByte Read() {
				return (this++)[0];
			}
			public void Write(SByte value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static SBytePtr operator +(SBytePtr x, int i) { return new SBytePtr(x.Array, x.Offset + (i * sizeof(SByte))); }
			public static SBytePtr operator -(SBytePtr x, int i) { return new SBytePtr(x.Array, x.Offset - (i * sizeof(SByte))); }
			public static SBytePtr operator ++(SBytePtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static SBytePtr operator --(SBytePtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	Int16Ptr
		//*****************************************************************************
		public struct Int16Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(Int16Ptr x, Int16Ptr y) { return  x.Equals(y); }
			public static bool operator !=(Int16Ptr x, Int16Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private Int16Ptr(Array   Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  Int16Ptr(Int16[] Array, int Offset) : this((Array)Array, Offset * sizeof(Int16)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator Int16Ptr(Int16[] Array) { return new Int16Ptr(Array, 0); }
			public static implicit operator bool(Int16Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( Int16Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(Int16Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator Int16Ptr(VoidPtr    x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(BytePtr    x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(SBytePtr   x) { return new Int16Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator Int16Ptr(Int16Ptr   x) { return new Int16Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator Int16Ptr(UInt16Ptr  x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(Int32Ptr   x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(UInt32Ptr  x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(Int64Ptr   x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(UInt64Ptr  x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(BooleanPtr x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(CharPtr    x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(SinglePtr  x) { return new Int16Ptr(x.Array, x.Offset); }
			public static explicit operator Int16Ptr(DoublePtr  x) { return new Int16Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(Int16Ptr x, Int16Ptr y) { return (x - y) < 0; }
			public static bool operator >(Int16Ptr x, Int16Ptr y) { return (x - y) > 0; }
			public static bool operator <=(Int16Ptr x, Int16Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(Int16Ptr x, Int16Ptr y) { return (x - y) >= 0; }
			public static int operator -(Int16Ptr x, Int16Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Int16)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Int16);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Int16 this[int i] {
				get {
					byte[] x = new byte[sizeof(Int16)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Int16)), x, 0, x.Length);
					return BitConverter.ToInt16(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Int16)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Int16 Read() {
				return (this++)[0];
			}
			public void Write(Int16 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static Int16Ptr operator +(Int16Ptr x, int i) { return new Int16Ptr(x.Array, x.Offset + (i * sizeof(Int16))); }
			public static Int16Ptr operator -(Int16Ptr x, int i) { return new Int16Ptr(x.Array, x.Offset - (i * sizeof(Int16))); }
			public static Int16Ptr operator ++(Int16Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static Int16Ptr operator --(Int16Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	UInt16Ptr
		//*****************************************************************************
		public struct UInt16Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(UInt16Ptr x, UInt16Ptr y) { return  x.Equals(y); }
			public static bool operator !=(UInt16Ptr x, UInt16Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private UInt16Ptr(Array    Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  UInt16Ptr(UInt16[] Array, int Offset) : this((Array)Array, Offset * sizeof(UInt16)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator UInt16Ptr(UInt16[] Array) { return new UInt16Ptr(Array, 0); }
			public static implicit operator bool(UInt16Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( UInt16Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(UInt16Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator UInt16Ptr(VoidPtr    x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(BytePtr    x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(SBytePtr   x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(Int16Ptr   x) { return new UInt16Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator UInt16Ptr(UInt16Ptr  x) { return new UInt16Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator UInt16Ptr(Int32Ptr   x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(UInt32Ptr  x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(Int64Ptr   x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(UInt64Ptr  x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(BooleanPtr x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(CharPtr    x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(SinglePtr  x) { return new UInt16Ptr(x.Array, x.Offset); }
			public static explicit operator UInt16Ptr(DoublePtr  x) { return new UInt16Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(UInt16Ptr x, UInt16Ptr y) { return (x - y) < 0; }
			public static bool operator >(UInt16Ptr x, UInt16Ptr y) { return (x - y) > 0; }
			public static bool operator <=(UInt16Ptr x, UInt16Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(UInt16Ptr x, UInt16Ptr y) { return (x - y) >= 0; }
			public static int operator -(UInt16Ptr x, UInt16Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(UInt16)) != 0) { throw new ApplicationException(); }
				return n / sizeof(UInt16);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public UInt16 this[int i] {
				get {
					byte[] x = new byte[sizeof(UInt16)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(UInt16)), x, 0, x.Length);
					return BitConverter.ToUInt16(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(UInt16)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public UInt16 Read() {
				return (this++)[0];
			}
			public void Write(UInt16 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static UInt16Ptr operator +(UInt16Ptr x, int i) { return new UInt16Ptr(x.Array, x.Offset + (i * sizeof(UInt16))); }
			public static UInt16Ptr operator -(UInt16Ptr x, int i) { return new UInt16Ptr(x.Array, x.Offset - (i * sizeof(UInt16))); }
			public static UInt16Ptr operator ++(UInt16Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static UInt16Ptr operator --(UInt16Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	Int32Ptr
		//*****************************************************************************
		public struct Int32Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(Int32Ptr x, Int32Ptr y) { return  x.Equals(y); }
			public static bool operator !=(Int32Ptr x, Int32Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private Int32Ptr(Array   Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  Int32Ptr(Int32[] Array, int Offset) : this((Array)Array, Offset * sizeof(Int32)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator Int32Ptr(Int32[] Array) { return new Int32Ptr(Array, 0); }
			public static implicit operator bool(Int32Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( Int32Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(Int32Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator Int32Ptr(VoidPtr    x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(BytePtr    x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(SBytePtr   x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(Int16Ptr   x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(UInt16Ptr  x) { return new Int32Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator Int32Ptr(Int32Ptr   x) { return new Int32Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator Int32Ptr(UInt32Ptr  x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(Int64Ptr   x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(UInt64Ptr  x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(BooleanPtr x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(CharPtr    x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(SinglePtr  x) { return new Int32Ptr(x.Array, x.Offset); }
			public static explicit operator Int32Ptr(DoublePtr  x) { return new Int32Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(Int32Ptr x, Int32Ptr y) { return (x - y) < 0; }
			public static bool operator >(Int32Ptr x, Int32Ptr y) { return (x - y) > 0; }
			public static bool operator <=(Int32Ptr x, Int32Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(Int32Ptr x, Int32Ptr y) { return (x - y) >= 0; }
			public static int operator -(Int32Ptr x, Int32Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Int32)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Int32);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Int32 this[int i] {
				get {
					byte[] x = new byte[sizeof(Int32)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Int32)), x, 0, x.Length);
					return BitConverter.ToInt32(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Int32)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Int32 Read() {
				return (this++)[0];
			}
			public void Write(Int32 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static Int32Ptr operator +(Int32Ptr x, int i) { return new Int32Ptr(x.Array, x.Offset + (i * sizeof(Int32))); }
			public static Int32Ptr operator -(Int32Ptr x, int i) { return new Int32Ptr(x.Array, x.Offset - (i * sizeof(Int32))); }
			public static Int32Ptr operator ++(Int32Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static Int32Ptr operator --(Int32Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	UInt32Ptr
		//*****************************************************************************
		public struct UInt32Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(UInt32Ptr x, UInt32Ptr y) { return  x.Equals(y); }
			public static bool operator !=(UInt32Ptr x, UInt32Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private UInt32Ptr(Array    Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  UInt32Ptr(UInt32[] Array, int Offset) : this((Array)Array, Offset * sizeof(UInt32)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator UInt32Ptr(UInt32[] Array) { return new UInt32Ptr(Array, 0); }
			public static implicit operator bool(UInt32Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( UInt32Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(UInt32Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator UInt32Ptr(VoidPtr    x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(BytePtr    x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(SBytePtr   x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(Int16Ptr   x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(UInt16Ptr  x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(Int32Ptr   x) { return new UInt32Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator UInt32Ptr(UInt32Ptr  x) { return new UInt32Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator UInt32Ptr(Int64Ptr   x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(UInt64Ptr  x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(BooleanPtr x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(CharPtr    x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(SinglePtr  x) { return new UInt32Ptr(x.Array, x.Offset); }
			public static explicit operator UInt32Ptr(DoublePtr  x) { return new UInt32Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(UInt32Ptr x, UInt32Ptr y) { return (x - y) < 0; }
			public static bool operator >(UInt32Ptr x, UInt32Ptr y) { return (x - y) > 0; }
			public static bool operator <=(UInt32Ptr x, UInt32Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(UInt32Ptr x, UInt32Ptr y) { return (x - y) >= 0; }
			public static int operator -(UInt32Ptr x, UInt32Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(UInt32)) != 0) { throw new ApplicationException(); }
				return n / sizeof(UInt32);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public UInt32 this[int i] {
				get {
					byte[] x = new byte[sizeof(UInt32)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(UInt32)), x, 0, x.Length);
					return BitConverter.ToUInt32(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(UInt32)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public UInt32 Read() {
				return (this++)[0];
			}
			public void Write(UInt32 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static UInt32Ptr operator +(UInt32Ptr x, int i) { return new UInt32Ptr(x.Array, x.Offset + (i * sizeof(UInt32))); }
			public static UInt32Ptr operator -(UInt32Ptr x, int i) { return new UInt32Ptr(x.Array, x.Offset - (i * sizeof(UInt32))); }
			public static UInt32Ptr operator ++(UInt32Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static UInt32Ptr operator --(UInt32Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	Int64Ptr
		//*****************************************************************************
		public struct Int64Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(Int64Ptr x, Int64Ptr y) { return  x.Equals(y); }
			public static bool operator !=(Int64Ptr x, Int64Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private Int64Ptr(Array   Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  Int64Ptr(Int64[] Array, int Offset) : this((Array)Array, Offset * sizeof(Int64)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator Int64Ptr(Int64[] Array) { return new Int64Ptr(Array, 0); }
			public static implicit operator bool(Int64Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( Int64Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(Int64Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator Int64Ptr(VoidPtr    x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(BytePtr    x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(SBytePtr   x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(Int16Ptr   x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(UInt16Ptr  x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(Int32Ptr   x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(UInt32Ptr  x) { return new Int64Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator Int64Ptr(Int64Ptr   x) { return new Int64Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator Int64Ptr(UInt64Ptr  x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(BooleanPtr x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(CharPtr    x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(SinglePtr  x) { return new Int64Ptr(x.Array, x.Offset); }
			public static explicit operator Int64Ptr(DoublePtr  x) { return new Int64Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(Int64Ptr x, Int64Ptr y) { return (x - y) < 0; }
			public static bool operator >(Int64Ptr x, Int64Ptr y) { return (x - y) > 0; }
			public static bool operator <=(Int64Ptr x, Int64Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(Int64Ptr x, Int64Ptr y) { return (x - y) >= 0; }
			public static int operator -(Int64Ptr x, Int64Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Int64)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Int64);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Int64 this[int i] {
				get {
					byte[] x = new byte[sizeof(Int64)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Int64)), x, 0, x.Length);
					return BitConverter.ToInt64(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Int64)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Int64 Read() {
				return (this++)[0];
			}
			public void Write(Int64 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static Int64Ptr operator +(Int64Ptr x, int i) { return new Int64Ptr(x.Array, x.Offset + (i * sizeof(Int64))); }
			public static Int64Ptr operator -(Int64Ptr x, int i) { return new Int64Ptr(x.Array, x.Offset - (i * sizeof(Int64))); }
			public static Int64Ptr operator ++(Int64Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static Int64Ptr operator --(Int64Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	UInt64Ptr
		//*****************************************************************************
		public struct UInt64Ptr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(UInt64Ptr x, UInt64Ptr y) { return  x.Equals(y); }
			public static bool operator !=(UInt64Ptr x, UInt64Ptr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private UInt64Ptr(Array    Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  UInt64Ptr(UInt64[] Array, int Offset) : this((Array)Array, Offset * sizeof(UInt64)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator UInt64Ptr(UInt64[] Array) { return new UInt64Ptr(Array, 0); }
			public static implicit operator bool(UInt64Ptr x) { return x.Array != null; }
		//不要	public static bool operator true( UInt64Ptr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(UInt64Ptr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator UInt64Ptr(VoidPtr    x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(BytePtr    x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(SBytePtr   x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(Int16Ptr   x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(UInt16Ptr  x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(Int32Ptr   x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(UInt32Ptr  x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(Int64Ptr   x) { return new UInt64Ptr(x.Array, x.Offset); }
		//不可	public static implicit operator UInt64Ptr(UInt64Ptr  x) { return new UInt64Ptr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator UInt64Ptr(BooleanPtr x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(CharPtr    x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(SinglePtr  x) { return new UInt64Ptr(x.Array, x.Offset); }
			public static explicit operator UInt64Ptr(DoublePtr  x) { return new UInt64Ptr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(UInt64Ptr x, UInt64Ptr y) { return (x - y) < 0; }
			public static bool operator >(UInt64Ptr x, UInt64Ptr y) { return (x - y) > 0; }
			public static bool operator <=(UInt64Ptr x, UInt64Ptr y) { return (x - y) <= 0; }
			public static bool operator >=(UInt64Ptr x, UInt64Ptr y) { return (x - y) >= 0; }
			public static int operator -(UInt64Ptr x, UInt64Ptr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(UInt64)) != 0) { throw new ApplicationException(); }
				return n / sizeof(UInt64);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public UInt64 this[int i] {
				get {
					byte[] x = new byte[sizeof(UInt64)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(UInt64)), x, 0, x.Length);
					return BitConverter.ToUInt64(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(UInt64)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public UInt64 Read() {
				return (this++)[0];
			}
			public void Write(UInt64 value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static UInt64Ptr operator +(UInt64Ptr x, int i) { return new UInt64Ptr(x.Array, x.Offset + (i * sizeof(UInt64))); }
			public static UInt64Ptr operator -(UInt64Ptr x, int i) { return new UInt64Ptr(x.Array, x.Offset - (i * sizeof(UInt64))); }
			public static UInt64Ptr operator ++(UInt64Ptr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static UInt64Ptr operator --(UInt64Ptr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	BooleanPtr
		//*****************************************************************************
		public struct BooleanPtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(BooleanPtr x, BooleanPtr y) { return  x.Equals(y); }
			public static bool operator !=(BooleanPtr x, BooleanPtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private BooleanPtr(Array     Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  BooleanPtr(Boolean[] Array, int Offset) : this((Array)Array, Offset * sizeof(Boolean)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator BooleanPtr(Boolean[] Array) { return new BooleanPtr(Array, 0); }
			public static implicit operator bool(BooleanPtr x) { return x.Array != null; }
		//不要	public static bool operator true( BooleanPtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(BooleanPtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator BooleanPtr(VoidPtr    x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(BytePtr    x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(SBytePtr   x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(Int16Ptr   x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(UInt16Ptr  x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(Int32Ptr   x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(UInt32Ptr  x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(Int64Ptr   x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(UInt64Ptr  x) { return new BooleanPtr(x.Array, x.Offset); }
		//不可	public static implicit operator BooleanPtr(BooleanPtr x) { return new BooleanPtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator BooleanPtr(CharPtr    x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(SinglePtr  x) { return new BooleanPtr(x.Array, x.Offset); }
			public static explicit operator BooleanPtr(DoublePtr  x) { return new BooleanPtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(BooleanPtr x, BooleanPtr y) { return (x - y) < 0; }
			public static bool operator >(BooleanPtr x, BooleanPtr y) { return (x - y) > 0; }
			public static bool operator <=(BooleanPtr x, BooleanPtr y) { return (x - y) <= 0; }
			public static bool operator >=(BooleanPtr x, BooleanPtr y) { return (x - y) >= 0; }
			public static int operator -(BooleanPtr x, BooleanPtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Boolean)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Boolean);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Boolean this[int i] {
				get {
					byte[] x = new byte[sizeof(Boolean)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Boolean)), x, 0, x.Length);
					return BitConverter.ToBoolean(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Boolean)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Boolean Read() {
				return (this++)[0];
			}
			public void Write(Boolean value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static BooleanPtr operator +(BooleanPtr x, int i) { return new BooleanPtr(x.Array, x.Offset + (i * sizeof(Boolean))); }
			public static BooleanPtr operator -(BooleanPtr x, int i) { return new BooleanPtr(x.Array, x.Offset - (i * sizeof(Boolean))); }
			public static BooleanPtr operator ++(BooleanPtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static BooleanPtr operator --(BooleanPtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	CharPtr
		//*****************************************************************************
		public struct CharPtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(CharPtr x, CharPtr y) { return  x.Equals(y); }
			public static bool operator !=(CharPtr x, CharPtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private CharPtr(Array  Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  CharPtr(Char[] Array, int Offset) : this((Array)Array, Offset * sizeof(Char)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator CharPtr(Char[] Array) { return new CharPtr(Array, 0); }
			public static implicit operator bool(CharPtr x) { return x.Array != null; }
		//不要	public static bool operator true( CharPtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(CharPtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator CharPtr(VoidPtr    x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(BytePtr    x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(SBytePtr   x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(Int16Ptr   x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(UInt16Ptr  x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(Int32Ptr   x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(UInt32Ptr  x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(Int64Ptr   x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(UInt64Ptr  x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(BooleanPtr x) { return new CharPtr(x.Array, x.Offset); }
		//不可	public static implicit operator CharPtr(CharPtr    x) { return new CharPtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator CharPtr(SinglePtr  x) { return new CharPtr(x.Array, x.Offset); }
			public static explicit operator CharPtr(DoublePtr  x) { return new CharPtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(CharPtr x, CharPtr y) { return (x - y) < 0; }
			public static bool operator >(CharPtr x, CharPtr y) { return (x - y) > 0; }
			public static bool operator <=(CharPtr x, CharPtr y) { return (x - y) <= 0; }
			public static bool operator >=(CharPtr x, CharPtr y) { return (x - y) >= 0; }
			public static int operator -(CharPtr x, CharPtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Char)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Char);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Char this[int i] {
				get {
					byte[] x = new byte[sizeof(Char)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Char)), x, 0, x.Length);
					return BitConverter.ToChar(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Char)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Char Read() {
				return (this++)[0];
			}
			public void Write(Char value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static CharPtr operator +(CharPtr x, int i) { return new CharPtr(x.Array, x.Offset + (i * sizeof(Char))); }
			public static CharPtr operator -(CharPtr x, int i) { return new CharPtr(x.Array, x.Offset - (i * sizeof(Char))); }
			public static CharPtr operator ++(CharPtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static CharPtr operator --(CharPtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	SinglePtr
		//*****************************************************************************
		public struct SinglePtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(SinglePtr x, SinglePtr y) { return  x.Equals(y); }
			public static bool operator !=(SinglePtr x, SinglePtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private SinglePtr(Array    Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  SinglePtr(Single[] Array, int Offset) : this((Array)Array, Offset * sizeof(Single)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator SinglePtr(Single[] Array) { return new SinglePtr(Array, 0); }
			public static implicit operator bool(SinglePtr x) { return x.Array != null; }
		//不要	public static bool operator true( SinglePtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(SinglePtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator SinglePtr(VoidPtr    x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(BytePtr    x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(SBytePtr   x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(Int16Ptr   x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(UInt16Ptr  x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(Int32Ptr   x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(UInt32Ptr  x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(Int64Ptr   x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(UInt64Ptr  x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(BooleanPtr x) { return new SinglePtr(x.Array, x.Offset); }
			public static explicit operator SinglePtr(CharPtr    x) { return new SinglePtr(x.Array, x.Offset); }
		//不可	public static implicit operator SinglePtr(SinglePtr  x) { return new SinglePtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			public static explicit operator SinglePtr(DoublePtr  x) { return new SinglePtr(x.Array, x.Offset); }
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(SinglePtr x, SinglePtr y) { return (x - y) < 0; }
			public static bool operator >(SinglePtr x, SinglePtr y) { return (x - y) > 0; }
			public static bool operator <=(SinglePtr x, SinglePtr y) { return (x - y) <= 0; }
			public static bool operator >=(SinglePtr x, SinglePtr y) { return (x - y) >= 0; }
			public static int operator -(SinglePtr x, SinglePtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Single)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Single);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Single this[int i] {
				get {
					byte[] x = new byte[sizeof(Single)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Single)), x, 0, x.Length);
					return BitConverter.ToSingle(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Single)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Single Read() {
				return (this++)[0];
			}
			public void Write(Single value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static SinglePtr operator +(SinglePtr x, int i) { return new SinglePtr(x.Array, x.Offset + (i * sizeof(Single))); }
			public static SinglePtr operator -(SinglePtr x, int i) { return new SinglePtr(x.Array, x.Offset - (i * sizeof(Single))); }
			public static SinglePtr operator ++(SinglePtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static SinglePtr operator --(SinglePtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	DoublePtr
		//*****************************************************************************
		public struct DoublePtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(DoublePtr x, DoublePtr y) { return  x.Equals(y); }
			public static bool operator !=(DoublePtr x, DoublePtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public Array Array { get; /*private set;{{2017/04/14削除}}*/ }	//プリミティブ配列
//			public int  Offset { get; /*private set;{{2017/04/14削除}}*/ }	//バイトオフセット
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly Array Array;	//プリミティブ配列
			public readonly int  Offset;	//バイトオフセット
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			private DoublePtr(Array    Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			public  DoublePtr(Double[] Array, int Offset) : this((Array)Array, Offset * sizeof(Double)) { /** no job **/ }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator DoublePtr(Double[] Array) { return new DoublePtr(Array, 0); }
			public static implicit operator bool(DoublePtr x) { return x.Array != null; }
		//不要	public static bool operator true( DoublePtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(DoublePtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator DoublePtr(VoidPtr    x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(BytePtr    x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(SBytePtr   x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(Int16Ptr   x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(UInt16Ptr  x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(Int32Ptr   x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(UInt32Ptr  x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(Int64Ptr   x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(UInt64Ptr  x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(BooleanPtr x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(CharPtr    x) { return new DoublePtr(x.Array, x.Offset); }
			public static explicit operator DoublePtr(SinglePtr  x) { return new DoublePtr(x.Array, x.Offset); }
		//不可	public static implicit operator DoublePtr(DoublePtr  x) { return new DoublePtr(x.Array, x.Offset); }	//error CS0555: ユーザー定義の演算子は、それを囲む型のオブジェクトの取得、およびそれを囲む型のオブジェクトへの変換を行えません。
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(DoublePtr x, DoublePtr y) { return (x - y) < 0; }
			public static bool operator >(DoublePtr x, DoublePtr y) { return (x - y) > 0; }
			public static bool operator <=(DoublePtr x, DoublePtr y) { return (x - y) <= 0; }
			public static bool operator >=(DoublePtr x, DoublePtr y) { return (x - y) >= 0; }
			public static int operator -(DoublePtr x, DoublePtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				int n = x.Offset - y.Offset;
				if((n % sizeof(Double)) != 0) { throw new ApplicationException(); }
				return n / sizeof(Double);
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public Double this[int i] {
				get {
					byte[] x = new byte[sizeof(Double)];
					Buffer.BlockCopy(Array, Offset + (i * sizeof(Double)), x, 0, x.Length);
					return BitConverter.ToDouble(x, 0);
				}
				set {
					byte[] x = BitConverter.GetBytes(value);
					Buffer.BlockCopy(x, 0, Array, Offset + (i * sizeof(Double)), x.Length);
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public Double Read() {
				return (this++)[0];
			}
			public void Write(Double value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static DoublePtr operator +(DoublePtr x, int i) { return new DoublePtr(x.Array, x.Offset + (i * sizeof(Double))); }
			public static DoublePtr operator -(DoublePtr x, int i) { return new DoublePtr(x.Array, x.Offset - (i * sizeof(Double))); }
			public static DoublePtr operator ++(DoublePtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static DoublePtr operator --(DoublePtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	StringPtr
		//*****************************************************************************
		public struct StringPtr {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(StringPtr x, StringPtr y) { return  x.Equals(y); }
			public static bool operator !=(StringPtr x, StringPtr y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public char[] Array { get; /*private set;{{2017/04/14削除}}*/ }
//			public int   Offset { get; /*private set;{{2017/04/14削除}}*/ }
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly char[] Array;
			public readonly int   Offset;
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			public StringPtr(char[] Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator StringPtr(char[] Array) { return new StringPtr(Array, 0); }
			public static implicit operator bool(StringPtr x) { return x.Array != null; }
		//不要	public static bool operator true( StringPtr x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(StringPtr x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			public static implicit operator StringPtr(string x) { return new StringPtr(x.ToCharArray(), 0); }
			public static implicit operator string(StringPtr x) {	//現在の位置から'\0'まで,又は,配列の終端までを、文字列に変換して返します。ただし、配列が設定されていないStringPtrが指定された場合は、nullポインタを返します。
				if(x.Array == null) { return null; }
				int i = System.Array.IndexOf(x.Array, '\0', x.Offset);	//「Array.IndexOf()」と書くとArrayクラスでなくArrayフィールドと見なされてコンパイルエラーになるので、「System.Array.IndexOf()」と書く必要が有ります。
				if(i == -1) { i = x.Array.Length; }
				return new string(x.Array, x.Offset, i - x.Offset);
			}
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(StringPtr x, StringPtr y) { return (x - y) < 0; }
			public static bool operator >(StringPtr x, StringPtr y) { return (x - y) > 0; }
			public static bool operator <=(StringPtr x, StringPtr y) { return (x - y) <= 0; }
			public static bool operator >=(StringPtr x, StringPtr y) { return (x - y) >= 0; }
			public static int operator -(StringPtr x, StringPtr y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset - y.Offset;
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public char this[int i] {
				get {
					i += Offset;
					if(i == Array.Length) { return '\0'; }	//文字配列の終端には仮想的な'\0'が有るものと見なす事にしました。「String.ToCharArray()」では終端の'\0'が付かないので新たな配列を作成して'\0'を追加しないで良いようにするためです。
					return Array[i];
				}
				set {
					i += Offset;
					if((i == Array.Length) && (value == '\0')) { return; }	//文字配列の終端への'\0'書き込みは許容して無視する事にしました。上記のgetアクセサの仕様との対称性のためです。
					Array[i] = value;
				}
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public char Read() {
				return (this++)[0];
			}
			public void Write(char value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static StringPtr operator +(StringPtr x, int i) { return new StringPtr(x.Array, x.Offset + i); }
			public static StringPtr operator -(StringPtr x, int i) { return new StringPtr(x.Array, x.Offset - i); }
			public static StringPtr operator ++(StringPtr x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static StringPtr operator --(StringPtr x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
		//*****************************************************************************
		//	GenericPtr<T>
		//*****************************************************************************
		public struct GenericPtr<T> {
			//-----------------------------------------------------------------------------
			//定型処理
			public override int GetHashCode() { return base.GetHashCode(); }
			public override bool Equals(object obj) { return base.Equals(obj); }
			public static bool operator ==(GenericPtr<T> x, GenericPtr<T> y) { return  x.Equals(y); }
			public static bool operator !=(GenericPtr<T> x, GenericPtr<T> y) { return !x.Equals(y); }
			//-----------------------------------------------------------------------------
			//プロパティ
//{{2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
//			public T[]  Array { get; /*private set;{{2017/04/14削除}}*/ }
//			public int Offset { get; /*private set;{{2017/04/14削除}}*/ }
//↓2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			public readonly T[]  Array;
			public readonly int Offset;
//}}2017/04/15変更:全てのクラスのArrayとOffsetを、getアクセサだけを持つ自動実装プロパティ⇒readonlyフィールドに変更しました。
			//-----------------------------------------------------------------------------
			//コンストラクタ
			public GenericPtr(T[] Array, int Offset) { this.Array = Array; this.Offset = Offset; }
			//-----------------------------------------------------------------------------
			//変換演算子
			public static implicit operator GenericPtr<T>(T[] Array) { return new GenericPtr<T>(Array, 0); }
			public static implicit operator bool(GenericPtr<T> x) { return x.Array != null; }
		//不要	public static bool operator true( GenericPtr<T> x) { return x.Array != null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
		//不要	public static bool operator false(GenericPtr<T> x) { return x.Array == null; }	//boolの変換演算子で充分なので、trueとfalseの個別の変換演算子は不要です。
			//-----------------------------------------------------------------------------
			//比較演算子
			public static bool operator <(GenericPtr<T> x, GenericPtr<T> y) { return (x - y) < 0; }
			public static bool operator >(GenericPtr<T> x, GenericPtr<T> y) { return (x - y) > 0; }
			public static bool operator <=(GenericPtr<T> x, GenericPtr<T> y) { return (x - y) <= 0; }
			public static bool operator >=(GenericPtr<T> x, GenericPtr<T> y) { return (x - y) >= 0; }
			public static int operator -(GenericPtr<T> x, GenericPtr<T> y) {
				if(x.Array != y.Array) { throw new ApplicationException(); }
				return x.Offset - y.Offset;
			}
			//-----------------------------------------------------------------------------
			//インデクスを指定して、配列要素を読み書きする。
			public T this[int i] {
				get { return Array[Offset + i]; }
				set { Array[Offset + i] = value; }
			}
			//-----------------------------------------------------------------------------
			//現在の位置から一要素読み書きし、次の位置へ進める。
			public T Read() {
				return (this++)[0];
			}
			public void Write(T value) {
			//不可	(this++)[0] = value;	//error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
				this[0] = value;
				this++;
			}
			//-----------------------------------------------------------------------------
			//配列ポインタとインデクスを加算,又は,減算して、配列ポインタを作成する。
			public static GenericPtr<T> operator +(GenericPtr<T> x, int i) { return new GenericPtr<T>(x.Array, x.Offset + i); }
			public static GenericPtr<T> operator -(GenericPtr<T> x, int i) { return new GenericPtr<T>(x.Array, x.Offset - i); }
			public static GenericPtr<T> operator ++(GenericPtr<T> x) { return x + 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
			public static GenericPtr<T> operator --(GenericPtr<T> x) { return x - 1; }	//C++と違いC#では言語が代入するので値を返すだけで良い。
		}
	}
}
