-
Notifications
You must be signed in to change notification settings - Fork 0
LSW::v4::SuperMap
LSW::v4::SuperMap
- Arquivo:
"Templates/templates.h"
- Tipo:
semi-dependente
- Abort
SuperMap
é um std::map
customizado que permite diferentes keys (tipos diferentes) para o mesmo valor.
Assim como std::map
, SuperMap
tem seus "pairs", os SuperPair
, responsáveis por essa parte de valor e keys. Ao contrário da biblioteca std, SuperPair
permite os vários "tipos" de key. Vale constar que ele não diferencia const char*
de um char*
ou char[]
.
SuperPair
é bem simples, levemente diferente, mas semelhante ao std::pair
. Cada SuperPair
lida com um valor que você queira salvar, do tipo base do seu respectivo SuperMap
(se houver). A forma mais direta de inicializar ele é com uma sequência de valores no seu construtor (o valor base e as keys).
- Ao passar um array ou ponteiro como argumento, não esqueça de passar o tamanho logo em seguida, como
... "alfafa", 6, ...
. Provavelmente se você esquecer ele vai te avisar de forma bem legal que você esqueceu disso. SuperMap
é simples também, você pode inicializar um diretamente por umstd::initializer
deSuperPair
que por natureza cada um recebe argumentos variáveis, então fica extremamente mais fácil, ou pode definir conforme roda o programa.
class data_any{
void* d = nullptr;
size_t siz = 0;
public:
void set(T*, size_t);
void set(const T*, size_t);
void*& get();
void* get() const;
void unset();
size_t size() const;
bool isSet() const;
operator==(const data_any&) const;
isEq(const void*, size_t) const;
};
data_any
é a base de como é salvo qualquer coisa no programa. Com esse cara fica mais fácil controlar ponteiros, porque você sabe qual o tamanho do que criou (ao contrário de um std::shared_ptr
ou ponteiro comum). Composto internamente de um void*
e um size_t
, você pode alocar qualquer coisa por ele e permanecer com o tamanho (com base no tipo, então não há "tamanho * sizeof()
do que você mandou", só "tamanho") passado ao gerar os dados.
- set: cria um objeto ou array do tipo
T
com tamanho a ser definido (1 ou mais); - get: retorna o endereço de onde alocou;
- unset: apaga a memória alocada;
- size: retorna quanto de memória foi alocada (na chamada do set, dependente do tipo, por exemplo pode ser 4
int
(4 bytes) ou 4char
(1 byte). Lembre-se do tipo que você gerou em primeiro lugar!); - isSet: retorna verdadeiro se há alguma memória alocada;
- operator==: compara se o outro
data_any
é exatamente igual a ele em tamanho e conteúdo; - isEq: mesma coisa que o operator==, mas com
void*
e você passando manualmente o tamanho;
class SuperPair{
std::vector<std::pair<std::type_index, data_any>> pairs;
K value = K();
public:
SuperPair(); // default
SuperPair(const K&, Args...);
SuperPair(const K&);
void clear();
void setKey(T(&)[]);
void setKey(T*, size_t);
void setKey(T&);
void delKey(T);
void setValue(const K&);
const K* getValue() const;
K* getValue();
const K* operator[](T&) const;
const K* operator[](T(&)[]) const;
K* operator()(T&);
K* operator()(T(&)[]);
K* operator()(T*, size_t);
bool hasKeyVal(T(&)[]) const;
bool hasKeyVal(T*, size_t) const;
bool hasKeyVal(T&) const;
T getKeyVal(bool&, size_t&) const;
bool hasType(T(&)[]) const;
bool hasType(T*, size_t) const;
bool hasType(T&) const;
bool hasType() const;
amIThis(SuperPair*&) const;
};
SuperPair
é, em geral, semelhante a um std::map
. Em geral você pode acessar as coisas com operator[]
, mas aí que muda um pouco: o SuperPair
tem tanto o operator[]
quanto operator()
, e eles têm de fato propósitos diferentes. Se você quer garantir que o valor não seja alterado, use operator[]
, mas se quiser, operator()
. Assim fica um pouco mais fácil de controlar as coisas, mas, se quiser, use só operator()
. Internamente um SuperPair
contém um std::vector
de pares de std::type_index
e data_any
. Dessa maneira ele pode gerar qualquer coisa e salvar o tipo num par indefinidas vezes.
- SuperPair: O construtor dessa classe permite que você a inicialize diretamente com seu valor e várias keys, inicialize apenas com seu valor, ou apenas crie-o normalmente para depois definir tudo;
- clear: Essa função limpa o
std::vector
interno, apagando todas as keys. Ele não apaga o valor salvo, só as keys; - setKey: Define ou redefine o valor de um tipo de key (por exemplo
char*
); - delKey: Apaga a key do tipo que mandar a ele ou que você definir dentro dos
<>
; - setValue: Define o valor o qual todas essas keys apontam;
- getValue(): Pega o ponteiro para o valor desse
SuperPair
; - operator[]: Acessa (no modo
const
) o valor se a key passada bater com a key definida; - operator(): Acessa o valor se a key passada bater com a key definida (direto ponteiro);
- getKeyVal: Retorna o valor de uma key do tipo (se definida) passando
true
para obool&
do argumento e o tamanho da key (se for array pode retornar maior que 1) nosize_t&
. Se não encontrar nenhuma key, retornará um valor indeterminado e daráfalse
ao argumentobool&
; - hasType: Retorna
true
se há uma key do tipo que deseja testar; - amIThis: Retorna
true
se o ponteiro que mandou corresponde ao ponteiro dele mesmo;
class SuperMap {
std::vector<SuperPair<K>> keys;
public:
SuperMap();
SuperMap(std::initializer_list<SuperPair<K>>);
SuperMap(const SuperMap&);
SuperMap& operator=(const SuperMap&);
void clear();
auto begin() const;
auto end() const;
void add(SuperPair<K>);
const K* operator[](T) const;
const K* operator[](T(&)[]) const;
K* operator()(T);
K* operator()(T(&)[]);
K* operator()(T*, size_t);
SuperPair<K>* getPair(J) const;
SuperPair<K>* getPair(J(&)[]) const;
SuperPair<K>* getPair(T*, size_t) const;
void delPair(SuperPair<K>*);
bool isThere() const;
};
SuperMap
é uma classe que basicamente contém diversos SuperPair
do mesmo tipo, mas com quaisquer keys (podem ser definidos independentemente por causa da forma como o sistema funciona). Dessa maneira, você pode ter qualquer coisa apontando pra alguma coisa em algum lugar dentro dessa gigante classe.
- SuperMap: O construtor dessa classe permite que você inicie loucamente com vários
SuperPair
, que cada um permite iniciar de forma totalmente customizável, ou então de forma normal sem definir nenhum valor; - clear: Limpa todos os
SuperPair
doSuperMap
; - begin:
begin()
dostd::vector
deSuperPair
(útil para umfor (auto& i : supermap){}
, se quiser); - end:
end()
dostd::vector
deSuperPair
(útil para umfor (auto& i : supermap){}
, se quiser); - add: Recebe um
SuperPair
e salva-o internamente; - operator[]: Acessa (no modo
const
) e retorna o valor correspondente à key, se tiver algumSuperPair
definido com ela; - operator(): Acessa e retorna o valor correspondente à key, se tiver algum
SuperPair
definido com ela; - getPair: Retorna um
SuperPair
que corresponda com a key; - delPair: Apaga do
std::vector
interno o ponteiro correspondente; - isThere: Retorna se há algum
SuperPair
com esse tipo de key;
- CHAR_INIT(a): Um
macro
para facilitar a criação direta dechar*
para a definição de uma das keys doSuperPair
(ele já transforma astring
emstring, tamanho
). Limite: 512. - strlen_s(char(&)[]): Uma função semelhante aos
strlen
por aí, só que pronta para receber diretamente um array (automaticamente interpreta o tamanho máximo do array por ele mesmo). - assert_cast(const T*, const Abort::abort_level): Uma função simples que causa
Abort
caso o ponteiro passado pra ela não seja diferente denullptr
. O tipo deAbort
pode ser definido, sendo o padrãoAbort::abort_level::GIVEUP
. Se o ponteiro não for nulo, retorna ele mesmo.
Em geral você só vai usar o SuperMap
, com talvez alguns pontos lidando com uns SuperPair
, mas provavelmente você não vai querer encostar no data_any
.
int main()
{
SuperMap<int> mapp = { {1, CHAR_INIT("alfafa")}, {2, CHAR_INIT("potato"), 'p'} }; // CHAR_INIT é a própria string e seu tamanho, em sequência, o MACRO em si
// exemplo de acesso
printf_s("Value contained on \"alfafa\" : %d\n", *assert_cast(mapp["alfafa"])); // mostra 1
printf_s("Value contained on \"potato\" : %d\n", *assert_cast(mapp["potato"])); // mostra 2
*mapp("alfafa") = 20; // define o valor 20 para onde "alfafa" aponta
printf_s("Value contained on const \"alfafa\": %d\n", *assert_cast(mapp["alfafa"])); // mostra 20
mapp.getPair("potato")->delKey<char*>(); // apaga a key char* dele, logo "potato" deixa de existir
mapp.delPair(mapp.getPair("alfafa")); // apaga completamente o cara que contém a key "alfafa". Não se preocupe, tem verificação de nullptr em delPair() caso ele não encontre por algum motivo
auto* ruf = mapp["alfafa"]; // tenta achar algum SuperPair com key "alfafa"
auto* rug = mapp["potato"]; // tenta achar algum SuperPair com key "potato"
auto* ruh = mapp['p']; // tenta achar algum SuperPair com key 'p'
printf_s("Value contained on \"alfafa\" : %s\n", ruf ? std::to_string(*ruf).c_str() : "not found"); // not found
printf_s("Value contained on \"potato\" : %s\n", rug ? std::to_string(*rug).c_str() : "not found"); // not found
printf_s("Value contained on \'p\' : %s\n", ruh ? std::to_string(*ruh).c_str() : "not found"); // mostra 2
mapp.clear(); // se não for usar mais, é uma boa prática deixar explícito pra limpar
}
Essas classes são extremamente versáteis dentro do programa e em diversas outras aplicações. Basicamente preparei uma base sem limites (até onde é possível no momento) para poder usar em situações adversas durante o programa. Enfim, SuperMap
é de fato uma das classes mais interessantes do programa, junto com as outras relacionadas a ela.
- LSW: Biblioteca
- Abort
- Core
- Download
- Camera
- Presence
- Sprite
- Entity
- Text
- BubblesFX
- LiningFX
- SHA256
- Logger
- Button
- Slider
- connection_core
- connection_each
- connection_host
- Launch
- Mixer
- Track
- Database
- Display
- SuperMap
- SmartTimer
- ResourceOf
- CustomThread
- Shared