www.digitalmars.com
Last update Sat Oct 7 23:28:53 2006

std.boxer

Este móduloé um conjunto de tipos e funções para converter qualquer objeto (valor ou pilha) em um tipo de caixa genérico, permitindo ao usuário passar esse objeto sem saber o que está na caixa, e então permitindo que ele recupere o valor depois.

Exemplo:
// Converte o inteiro 45 em uma caixa.
Box b = box(45);

// Recupera o inteiro e converte-o para real.
real r = unbox!(real)(b);
Essa é a interface básica e normalmente será tudo o que você precisa entender. Se não poder desencaixotar o objeto para um dado tipo, lançará uma UnboxException. Como demsntrado, usa moldagens implícitas para proceder do mesmo jeito que tipos estáticos procedem. Então por exemplo, você pode desencaixotar de int para real, mas não pode desencaixotar de real para int: isso iria requerir uma moldagem explícita.

Portanto isso significa que tentar desencaixotar um int como uma string lançará um erro ao invés de formatá-lo. Em geral, você pode chamar o método toString em uma caixa e receber um bom resultado, dependendo se std.string.format aceitá-lo.

Caixas podem ser comparadas com outras e podem ser usadas como chaves para arrays associativos.

Também há funções para converter de e para arrays de caixas.

Exemplo:
// Converte argumentos para um array de caixas.
Box[] a = boxArray(1, 45.4, "foobar");

// Converte um array de caixas devolta para os argumentos.
TypeInfo[] arg_types;
void* arg_data;

boxArrayToArguments(a, arg_types, arg_data);

// Converte os argumentos devolta para caixas usando uma
// forma diferente da função.
a = boxArray(arg_types, arg_data);
Um uso disso é para suportar funções variádicas mais facil e robustamente; simplesmente chame "boxArray(argumentos, argptr)", então faça qualquer coisa que precisar fazer com o array.

Autores:
Burton Radons

Licença:
Public Domain

enum TypeClass;
O tipo de classe retornado por Box.findTypeClass; a ordem das entradas é importante.

Bool
< bool

Integer
< byte, ubyte, short, ushort, int, uint, long, ulong

Float
< float, double, real

Complex
< cfloat, cdouble, creal

Imaginary
< ifloat, idouble, ireal

Class
< Herdado de Object

Pointer
< Ponteiro do tipo (T *)

Array
< Array do tipo (T [])

Other
< Qualquer outro tipo, tais como delegados, ponteiros para função, estruturas, void...

struct Box;
Box é um contêiner genérico para objetos (valor e pilha), permitindo ao usuário encaixotá-los de forma genérica e recuperá-los depois. Um objeto encaixotado contém um valor em um estilo genérico, permitindo ser passado de um lugar para outro sem ter conhecimento de seu tipo. É criado chamando a função box, e você pode recuperar o valor instanciando o gabarito unbox.

bool unboxable(TypeInfo test);
Retorna se o valor puder ser desencaixotado como o dado tipo sem disparar.

TypeInfo type();
Propriedade para o tipo contido pela caixa. É inicialmente null e não pode ser atribuído diretamente.

Retorna:
o tipo do objeto contido.

void[] data();
Propriedade para o ponteiro dos dados para o valor da caixa. Inicialmente é null e não pode ser atribuído diretamente.

Retorna:
o array de dados.

char[] toString();
Tenta converter o valor encaixotado em uma string usando std.string.format; lançará se a função não puder controlar isso. Se a caixa não estiver inicializada, retornará "".

bool opEquals(Box other);
Compara o valor dessa caixa com outra caixa. Molda implicitamente se os tipos são diferentes, identico ao sistema de tipos regular.

float opCmp(Box other);
Compara o valor dessa caixa com outra caixa. Molda implicitamente se os tipos são diferentes, identico ao sistema de tipos regular.

uint toHash();
Retorna o hash do valor.

Box box(...);
Encaixota o único argumento passado para a função. Se mais ou menos que um argumento for passado, averá uma asserção.

Box box(TypeInfo type, void* data);
Encaixota o objeto definido explícitamente. type não deve ser null; data não deve ser null se o tamanho de type for maior que zero. data é copiado.

Box [] boxArray(TypeInfo[] types, void* data);
Converte uma lista de argumentos em uma lista de caixas.

Box [] boxArray(...);
Encaixota cada argumento passado para a função, retornando um array de caixas.

void boxArrayToArguments(Box [] arguments, out TypeInfo[] types, out void* data);
Converte um array de caixas para um array de arguments.

class UnboxException: object.Exception;
Essa classe é lançada se unbox é incapaz de moldar o valor para o resultado desejado.

Box object;
Essa é a caixa que o usuário tentou desencaixotar.

TypeInfo outputType;
Esse é o tipo que o usuário tentou desencaixotar.

this(Box object, TypeInfo outputType);
Atribui parâmetros e cria a mensagem na forma "Could not unbox from type ... to ... ."

template unboxCastReal(T)
Um desencaixotador genérico para tipos numéricos reais.

template unboxCastInteger(T)
Um desencaixotador genérico para tipos numéricos inteiros.

template unboxCastComplex(T)
Um desencaixotador genérico para tipos numéricos complexos.

template unboxCastImaginary(T)
Um desencaixotador genérico para tipos numéricos imaginários.

template unbox(T)
O gabarito unbox pega um parâmetro tipo e retorna uma função que pega um objeto caixa e retorna o tipo especificado.

Para usar, instancie o gabarito com o tipo de resultado desejado, então chame a função com a caixa para converter. Isso implicitamente moldará tipos base como necessário de forma consistente com tipos estáticos - por exemplo, isso moldará um tipo encaixotado em int, mas não moldará um float encaixotado em short.

Lança:
UnboxException se não pode moldar

Exemplo:
 Box b = box(4.5);
bit u = unboxable!(real)(b); // Isso é true.
real r = unbox!(real)(b);

Box y = box(4);
int x = unbox!(int) (y);


template unboxable(T)
Retorna se o valor pode ser desencaixotado como o dado tipo; se retornar false, tentar fazer resultará no lançamento de uma UnboxException.