std.boxer
このモジュールは、任意のオブジェクト(値オブジェクトでもヒープオブジェクトでも) を汎用のBox型に変換して、ユーザーが Box の中身を知らずともオブジェクトを運べるようにして、 あとでBoxから元の値を取り出せるようにする機能を提供する型と関数の集まりです。例:
// 整数45をboxに変換 Box b = box(45); // 整数を取り出して、realにキャスト real r = unbox!(real)(b);これが基本的なインターフェイスで、ほとんどの場合、これさえ理解していれば十分です。 指定された型でunboxできなかった場合は、UnboxException例外が投げられます。 上の例で示したように、unboxの際には暗黙変換をかけることができ、 その挙動は普通の型の場合と全く同じです。ですから例えば、int から real へと unbox することは可能ですが、逆に明示的なキャストの必要な real から int への unbox はできません。
これはつまり、int から string を unbox しようとすると、 整数が文字列化されたりはせずに例外が発生するということです。こういう時は一般に、 Boxオブジェクトの toString を呼ぶと欲しい結果が得られるかもしれません。toString は std.string.format に依存します。
Box同士は互いに比較することができ、 連想配列のキーとして使用できます。
Boxの配列に関する変換関数も用意されています。
例:
// 引数をboxの配列に変換 Box[] a = boxArray(1, 45.4, "foobar"); // boxの配列を引数配列に戻す TypeInfo[] arg_types; void* arg_data; boxArrayToArguments(a, arg_types, arg_data); // 引数の配列を、別の形式の関数で // boxの配列へと再び変換 a = boxArray(arg_types, arg_data);この機能の使い道の一つは、可変個引数関数をより簡単で頑強に扱う 道具としての使い方です。"boxArray(_arguments, _argptr)" を呼んでしまえば、 あとは配列に対する好きな操作を何でも実行できます。
Authors:
Burton Radons
License:
Public Domain >
BUGS:
- enum TypeClass;
- Box.findTypeClass が返す型情報です。エントリの順番が重要です。
- Bool
- < bool
- Integer
- < byte, ubyte, short, ushort, int, uint, long, ulong
- Float
- < float, double, real
- Complex
- < cfloat, cdouble, creal
- Imaginary
- < ifloat, idouble, ireal
- Class
- < Object から派生
- Pointer
- < ポインタ型 (T *)
- Array
- < 配列型 (T [])
- Other
- < その他の型。delegate、関数ポインタ、構造体、void、...
- struct Box;
- Box は、
(値およびヒープ)オブジェクトを保持する汎用コンテナです。
ユーザーは、任意のオブジェクトをBox化して汎用的に処理し、
あとで元の型に復元することができます。
Boxオブジェクトはbox関数の呼び出しによって作成し、
unboxテンプレートをインスタンス化して値を復元します。
- bool unboxable(TypeInfo test);
- 格納された値を、指定されたtype型へと例外を投げることなく unbox できるかどうかを返します。
- TypeInfo type();
- Boxに格納されたオブジェクトの型情報。
このプロパティの初期値は null で、直接書き換えることはできません。
Returns:
格納されたオブジェクトの型情報
- void[] data();
- Boxに格納されたオブジェクトを指すポインタ。
このプロパティの初期値は null で、直接書き換えることはできません。
Returns:
データ配列
- string toString();
- 格納された値を、std.string.format を使用して文字列への変換を試みます。
format関数がサポートしない型が入っていた場合、例外を投げます。
Boxが未初期化の時は、文字列 "" を返します。
- bool opEquals(Box other);
- boxと別のboxを比較します。格納された型が違っていた場合、
通常の型システムと同じように、暗黙のキャストを行います。
- float opCmp(Box other);
- boxと別のboxを比較します。格納された型が違っていた場合、
通常の型システムと同じように、暗黙のキャストを行います。
- hash_t toHash();
- 値のハッシュ値を返します。
- Box box(...);
- 関数に渡された一つの引数をBox化します。0個か2個以上の引数が渡された場合、
assert で停止します。
- Box box(TypeInfo type, void* data);
- 明示的に定義されたオブジェクトをBox化します。type に null は指定できません。data は、
type のサイズがゼロの時以外は
null を指定できません。data はコピーされます。
- Box[] boxArray(TypeInfo[] types, void* data);
- 引数のリストをBoxのリストに変換します。
- Box[] boxArray(...);
- 引数のリストをBoxのリストに変換します。
- void boxArrayToArguments(Box[] arguments, out TypeInfo[] types, out void* data);
- Boxのリストを引数のリストに変換します。
- class UnboxException: object.Exception;
- unboxが指定された型へのキャストに失敗した場合、
このクラスの例外が送出されます。
- Box object;
- ユーザーがunboxを試みたBoxオブジェクト
- TypeInfo outputType;
- ユーザがunbox先に指定した型
- this(Box object, TypeInfo outputType);
- 以上の二つのパラメタを設定し、
"Could not unbox from type ... to ... ." という形式のエラー文字列を生成します。
- T unboxCastReal(T)(Box value);
- 実数型用の汎用unboxer
- T unboxCastInteger(T)(Box value);
- 整数型用の汎用unboxer
- T unboxCastComplex(T)(Box value);
- 複素数型用の汎用unboxer
- T unboxCastImaginary(T)(Box value);
- 虚数型用の汎用unboxer
- T unbox(T)(Box value);
- unbox テンプレートは型引数を一つ取り、
Boxオブジェクトを引数の型に変換する関数を作ります。
使用するには、欲しい返値型で関数テンプレートをインスタンス化し、 できた関数に変換したいBoxを渡して呼び出します。 この関数は、必要ならば通常の型システムと同様の暗黙変換を行います。 例えば、Box化されたbyteをintへ変換することはありますが、 Box化されたfloatをshortへ変換することはありません。
Throws:
変換できない場合は UnboxException を送出
例:
Box b = box(4.5); bit u = unboxable!(real)(b); // trueになる real r = unbox!(real)(b); Box y = box(4); int x = unbox!(int) (y);
- bool unboxable(T)(Box value);
- 指定された型へとunbox可能かどうかを返します。この結果が false
の時は、unboxしようとすると UnboxException 例外が発生します。