3870

Tiens, c'est vrai qu'il manque un point Godzil pour les meilleures autocorrections / fautes de frappe grin
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3871

embarrassed
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

3872

Quand je vois cela, j'ai envie de serrer chaleureusement la main de l'auteur.
Puis tant que je la tiens, je lui brise les doigts en espérant que ça suffira pour qu'il n'utilise plus jamais un clavier.
Ce n'est pas de la haine, c'est que... comment dire, c'est dur à expliquer... certaines choses devraient rester dans les abysses, ne jamais être révélées aux yeux des hommes. C'est comme voir quelqu'un en train d'invoquer un Grand Ancien : tu SAIS que tu dois l'arrêter avant qu'il ne soit trop tard.
avatar
« Nous avons propagé sur Extranet une histoire fabriquée de toutes pièces selon laquelle une certaine disposition d'étoiles, vue depuis la planète d'origine des butariens, formaient le visage d'une déesse galarienne.
Sans chercher à vérifier ces informations, certains ont décrété que c'était la preuve de l'existence de la déesse. Ceux qui notaient le manque de preuves se faisaient attaquer. »

Legion, geth trolleur à portée galactique

3873

• Nil commence une incantation
avatar

3874

C'est excellent comme exploit! Cela dit, je signale que cette grammaire n'est pas du tout régulière, ni même algébrique (non contextuelle), son "expression régulière" abuse massivement des regards en avant (lookaheads) et des références en arrière (backreferences).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3875

Ideone.comIdeone.comIdeone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.


J'peux surement pas mal simplifier, surtout au niveau des surcharges, mais j'suis content grin

3876

eek Mais c'est absolument illisible, ce truc!

Quand je vois la simplicité de code Qt idiomatique et puis ça, difficile de croire qu'il s'agit du même langage (C++), et pourtant…
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3877

Ca serait plus propre avec les concepts mais c'est TS C++20 donc je peux me gratter pour le moment

Le PLUS CHIANT c'est que les infos de genericite sont "perdues"... jmexplique,

template <typename T> struct rebinder; template <template <typename...> typename Base, typename... BaseArgs> struct rebinder<Base<BaseArgs...>> { template <typename... Args> using rebound = Base<Args...>; };
(Exemple aligne en 2 secondes)

L'interet de ce truc c'est de pouvoir remapper des types a N parametres generiques en 1 ligne, p-ex

using pair_i2 = std::pair<int, int>; using pair_f2 = typename rebinder<pair_i2>::template bound<float, float>; // Revient a std::pair<float, float>
L'exemple est evidemment completement con mais c'est la base pour les concepts.

Le seul probleme c'est que si maintenant j'ai une methode generique qui prend une pair<T1, T2>:

template <typename Pair> void faire_choses_coquines_avec_paire(Paire const& paire) { // Telephone rose du C++ }Admettons que maintenant tu ne saches pas que c'est une paire, mais tu veux rebind vers pair<float, float> (Le compilo te casse la gueule si tu essaie de faire pair<float, float, float> etc)

template <typename Paire> void faire_choses_pas_trop_jolies(Paire paire) { using paire_floats_t = typename rebinder<Paire>::template bound<float, float>; paire_floats_t paire_floats_instance; }
Ben ca compile pas. Pourquoi? Parce que le compilo voit qu'on veut un rebinder<T>, soit la classe de base, et va donc gentillement te dire que cette derniere n'a pas de membre nomme bound.

Du coup la solution? Ceci:

template <template <typename, typename> typename Paire, typename A, typename B> void faire_choses_sales(Paire<A, B> const& paire) { using paire_floats = typename rebinder<Paire<A, B>>::template bound<float, float>; paire_floats ffs; }
Et la c'est tout bon, parce qu'on choisit la specialisation partielle qui expose bound.

Je pense pas que ce soit un bug pour autant, mais ca a du etre choisi comme ca pour pas rendre les compilo C++ encore plus usine-a-gaz-esque, et ca reste terriblement chiant. C'est pour ca que je me retrouve avec 4 specialisations partielles pour ma classe container_traits, parce que chaque container a un nombre differents de parametres generiques (pour le moment!), et que c'est pas evident d'aller chercher le N-ieme element d'un parameter pack (typename... Args), surtout quand N change d'un type a l'autre.

Par exemple la je suis coince car unordered_map expose un type dependant nomme value_type, qui vaut .... pair<const Clef, Valeur>. Mais a mes yeux, c'est un truc opaque, donc pour revenir a mon exemple, ben je peux pas reutiliser le type pair qu'un utilisateur foutrait dans sa librarie a facon STL, donc j'suis oblige d'imposer std::pair, et l'user se retrouve a jongler apres (operateurs de cast implicites / constructeurs par deplacement etc)

Bref c'est le bordel mais ca s'arrangera (faut esperer) avec les concepts, ou la on parlera plus telllement de templates mais plutot de features d'un type (constructible par copie, constructible par defaut, iterable dans un sens, dans les deux, etc)

3878

Donc en clair, c'est de la magie noire pour convertir foo<T1> en foo<T2>, voire avec plusieurs types paramètre comme dans ton exemple avec les paires? Je comprends mieux comment fonctionne ton snippet maintenant. Le but du snippet que tu as linké est de faire une opération map comme dans un langage fonctionnel, c'est bien ça? Donc au moins je comprends ta fonction main. L'implémentation, elle (donc tout ce qui est dans ton namespace xstd), reste de la magie noire.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3879

En gros ce qu'il manque pour pouvoir etre addressable dans tous les sens, c'est juste

template <template <typename... Args> typename Base> struct rebinder { template <typename... Map> using bound = Base<Map...>; };
Et paf, plus besoin de base vide, ni de specialisation partielle.

(Actuellement, si tu fais ca, on te dit que le type passe en argument a rebinder n'est pas un class template, ce qui est vrai, puisque l'info est perdue - template et type c'est pas pareil:

67:100: error: template argument for template template parameter must be a class template or type alias template

template <typename K2, typename V2, typename A2 = rebound_allocator_type<typename rebinder<pair_type>::template bound<const K2, V2>>

)

J'irais pas jusqua dire que c'est de la magie noire mais clairement si tu fais pas ce genre de choses proprement, 3 jours plus tard tu comprend plus rien

l'idee du snippet c'est avec un Container<A, B, C, ...>, obtenir Container<A2, B2, C2, ...> sachant que la fonction de transformation est fournie. Tu peux faire ca de facon brutale avec plein d'overload mais ca ne couvrira de facto pas les types conteneur de l'user. Avec ces traits, tout ce que l'user a a afaire c'est a) specialiser le template container-traits ou b) ajouter les typedef kivonbien

3880

Bon je suis mauvaise langue grin Le sommeil aidant...

https://godbolt.org/z/YfyKi4

Je suis sur a 99% que MSVC sera incapable de deduire les types d'arguments par contre

( du coup j'ai du mal comprendre un truc )

3881

GCC compile ça aussi, en tout cas. (J'ai essayé dans Godbolt.)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3882

zF0Kdkg.jpg
Félicitations Flan ! top
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3883

./3881

#include <type_traits> #include <unordered_map> #include <vector> #include <queue> #include <iostream> #include <map> #include <memory> #include <functional> #include <cmath> #include <list> #include <unordered_set> #include <boost/core/demangle.hpp> namespace xstd { template <typename Source, typename Target> struct forward_modifiers { using type = Target; }; template <typename Source, typename Target> struct forward_modifiers<const Source, Target> { using type = typename forward_modifiers<Source, const Target>::type; }; template <typename Source, typename Target> struct forward_modifiers<volatile Source, Target> { using type = typename forward_modifiers<Source, volatile Target>::type; }; template <typename Source, typename Target> struct forward_modifiers<Source*, Target> { using type = typename forward_modifiers<Source, Target*>::type; }; template <typename Source, typename Target> struct forward_modifiers<Source&, Target> { using type = typename forward_modifiers<Source, Target&>::type; }; template <typename Source, typename Target> struct forward_modifiers<Source&&, Target> { using type = typename forward_modifiers<Source, Target&&>::type; }; template <typename T> struct pack_arity { constexpr static const size_t arity = 0; }; template <template <typename...> typename Base, typename... Args> struct pack_arity<Base<Args...>> { constexpr static const size_t arity = sizeof...(Args); }; namespace details { template <typename Source, typename Target, typename Container> struct rebind_lookup { using corrected_type = Container; }; // Replaces every occurence of Source in Args by Target. template <typename Source, typename Target, template <typename...> typename Container, typename... Args> struct rebind_lookup<Source, Target, Container<Args...>> { private: template <size_t Idx> using nth_element_t = typename std::decay<decltype(std::get<Idx>(std::tuple<Args...>{}))>::type; template <size_t Idx> using corrected_type_i = typename std::conditional< std::is_same< Source, nth_element_t<Idx> >::value, typename forward_modifiers<nth_element_t<Idx>, Target>::type, //nth_element_t<Idx> typename rebind_lookup<Source, Target, nth_element_t<Idx>>::corrected_type >::type; template <size_t... Is> constexpr static auto rebind_all(std::index_sequence<Is...>) { return Container<corrected_type_i<Is>...>{}; } public: template <size_t... Is> using corrected_types = Container<corrected_type_i<Is>...>; using corrected_type = decltype(rebind_all(std::make_index_sequence<pack_arity<Container<Args...>>::arity>())); }; } template <typename Container> struct container_traits; template <template <typename...> typename Container, typename... Args> struct container_traits<Container<Args...>> { using container_type = Container<Args...>; using allocator_type = typename container_type::allocator_type; using value_type = typename container_type::value_type; template <typename T> using rebound_container_type = typename details::rebind_lookup< value_type, T, Container<Args...> >::corrected_type; }; } int main() { std::vector<int> v; using vector_traits = xstd::container_traits<std::vector<int>>; using rebound_vector = typename vector_traits::template rebound_container_type<float>; std::cout << boost::core::demangle(typeid(v).name()) << std::endl; return 0; }
grin

3884

C'est quand même violemment inbranlable la syntaxe du C++ ##gerbe##

3885

oui
Enfin si ça permettait de faire plus, ça pourrait être un mal nécessaire, mais en pratique c'est juste perdre son temps avec des complications inutiles. Sans même parler du problème de la maintenance ou du manque de fiabilité que cette complexité entraîne.

3886

(#vomi#)

(ah ouf, j'ai cru que c'était cassé embarrassed)

3887

Tu fais du LISP?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

3888

(grin)

3889

J'en ai fait cheeky

3890

Tiens marrant, je ne te connaissais pas ce talent grin
C'était dans quel contexte ?
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3891

En fac, tout simplement ^^
Et un jour, j'ai découvert qu'AutoCAD était scriptable avec cheeky

3892

Et là, les profs/collègues n'ont pas compris pourquoi ta productivité avait soudain été décuplée ? grin

Ou alors c'est le contraire ?
"Pourquoi t'as pas encore fini ce plan ? C'est juste un cube !"
"Attends, je finis juste d'optimiser mon générateur de cubes configurable, et ensuite..."
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3893

Vala, c'était plutôt ça grin

3894

Je trouve pas ca si pire moi grin

apres y a des trucs cons lies a la fatigue, par exemple

pack_arity<Container<Args...>>::arity devient

sizeof...(Args)
et termine grin

et je vous ai pas montre la version qui rebind un ensemble de Target sur un ensemble de Source grin p-ex std::unordered_map<float, int, ...>mine de rien c'est pas evidement, si je veux remapper en std::unordered_map<int, float, ...> je peux pas le faire sequentiellement sur un pack du genre <int, float> pcq jvais me retrouver avec:

premiere passe: unordered_map<int, int, ...> (on assigne int a float)
deuxieme passe: unordered_map<float, float, ...> (on assigne float a int)

au lieu de unordered_map<float, int>
du coup faut se trimballer (pour chaque niveau de recursion!) un ensemble d'offets a ignorer lors de rebind successif. Bref, une vrai purge cheeky

Pour le moment j'ai ca
Le lisp c'est mieux :D
// Replaces every occurence of Source in Args by Target. template <typename Source, typename Target, template <typename...> typename Container, typename... Args, size_t... Exclusion> struct rebind_single<Source, Target, Container<Args...>, Exclusion...> { private: template <size_t I> using corrected_type_i = typename std::conditional< has_element<I, Exclusion...>::value, // If we were told to ignore this position in the pack ... nth_element_t<I, Args...>, // Then just assign the type and move on typename std::conditional< // Otherwise ... std::is_same< // If we need to map it Source, nth_element_t<I, Args...> // Obtains a lvalue-ref-removed type (std::get returns T&&) >::value, // Forward type modifiers from the source to the raw target type typename forward_modifiers< nth_element_t<I, Args...>, typename std::decay<Target>::type // Retrieve a decayed type to make sure the caller doesn't fuck up >::type, typename rebind_single< // We don't need to map it Source, // Try to see if this type is a template and needs Target, // remapping too. nth_element_t<I, Args...> >::corrected_type >::type >::type; template <size_t... Is> constexpr static auto rebind_all(std::index_sequence<Is...>) { return Container<corrected_type_i<Is>...>{}; } public: template <size_t... Is> using corrected_types = Container<corrected_type_i<Is>...>; using corrected_type = decltype(rebind_all(std::make_index_sequence<sizeof...(Args)>())); };

faut encore que je trouve comment garder les exclusions des types enfant

3895

Honnêtement j'ai pas trop lu ce que tu voulais faire, mais un truc du genre HashMap<Number, Number> ça fait pas plus ou moins pareil ? Évidemment ça pert un peu d'info mais si tu peux passer de l'un à l'autre de toute façon... ?
Vu de loin et d'après ce que j'ai compris, ce que tu fais sembles un peu borderline donc à la rigueur... cheeky

(mais j'ai peut-être rien compris cheeky)

3896

C'est la meme chose que plus haut, mais une autre approche, j'veux avoir un truc fonctionnel pour pouvoir transformer des conteneurs d'objets

par exemple j'ai une map<int, T>, jveux pouvoir, avec une fonction de transformation du style R(*)(T const&), avoir une fonction qui me retourne une map<int, R>, sans avoir a reecrire des surcharges qu'il s'agisse de maps, unordered_map, set, list, vector, ou meme des conteneurs de l'utilisateur (qui n'aurait qu'a ajouter des traits pour que mon code gere son type)

(et c'est plus pour m'occuper qu'autre chose, j'ai pas la motivation de reprendre l'apprentissage de vulkan en ce moment cheeky)

(C'est pas non plus impossible que ce soit deja implemente dans boost mais c'est pas intellectuellement stimulant d'utiliser ca grin)

3897

Faut franchement être motivé de nos jours pour faire du C++ quand même cheeky
avatar

3898

Les gens qui font ce genre de conneries sont payes a faire autre chose grin

3899

SCPCD : ça marche aussi si tu remplaces "C++" par "Java" (ou "Javascript", ou "PHP"...)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3900

Ou quoi? grin