Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ecriture de méta-fonctions.

    6 juin 2021 à 19:30:44

    Salut, j'ai vraiment du mal avec le c++17 moderne, parce que je trouve sa syntaxe assez complexe quand il s'agit de faire des opérations sur des types.

    En fait je souhaiterais faire ceci. (Le code est un pseudo code que j'ai écrit ça sera peut être possible de le faire en c++2x mais, pour l'instant, ce pseudo code ne compilera tout simplement pas) 

    /*Définition d'une liste de types.*/
    template <typename... Args>
    struct List {
        using type = Args...;
    };
    /* Ajoute un nouveau type à la liste de types.
    
       List<A, L> = List<A, L>::type<A, xs...>*/
    template <typename A, typename C = List> struct append {
              template<typename seq, typename... xs>
              using type = List<seq>::template type<A, C, xs...>;
    };
    template <typename pred, typename... Args>
    struct copy_if {
        //Déclaration d'un alias sur une constexpr.
        using types = constexpr {
        //On pourrait utiliser une boucle ici par exemple.
           template <typename... C>
           List copied;      
           for (unsigned int i = 0; i < sizeof...(Args); i++) {
              //Spécialisation (if) on accède au parameter pack par un index, plutôt que de devoir utiliser un
    std::tuple et des fonctions récursives qui alourdissent la syntaxe.      
             if (pred<args...[i]>::value) {
    /*Par exemple is_placeholder<args...[i]> vaut soit vrai si le type est un placeholder, soit faux si il ne l'est pas*/
                /*On insère le type, dans le paraméter pack, on pourrait imaginer que le c++ permette de faire ceci plutôt que de devoir mettre en œuvre des algorithmes très complexe qui alourdissent la syntaxe.*/
                copied = append<args...[i], copied>::type;
             }
              
          }    
          /*On retourne l'alias sur le parameter pack, pas besoin d'utiliser une classe pour encapsuler le parameter pack ce qui est embêtant si on veut juste récupérer le parameter pack pour le passer à un autre template variadique et le manipuler avec une autre structure ça évite de devoir faire des structures imbriquées ce qui alourdi le code.*/
          return copied::type;
       }  
       Args... args;
    };
      
    template <typename... Args>
    struct unique {
           using types = constexpr {     
           template <typename... U>
           List uniqueTypes;     
           for (unsigned int i = 0; i < sizeof...(Args); i++)
           {
              bool contains = false;
              for (unsigned int j = 0; j < sizeof...(U) && !contains; j++) {
                  if (args...[i] == uniqueTypes::type...[j]) {
                      contains = true;
                  }
              }
              if (!contains) {
                  uniqueTypes=append<args...[i], uniqueTypes>::type;<br>
              } 
           }
           return uniqueTypes;
       }
       Args... args;
    };
    template<typename T>
    struct Tmp {
       using type = T;
    };
    /*Et on effectue la même chose pour le tri :
    template<typename Pred, typename... Args>
    struct sort {
         unsigned type = constexpr {
         for (unsigned int i = 0; i < sizeof...(Args)-1; i++)
         {
              
         for (unsigned int j = i+1; j < sizeof...(Args); j++) {
            /*Inverse les types si le type j plus petit que le type i.*/
            if (Pred<args...[j], args[i]...>::value) {
                template<typename T>
                Tmp<args...[i]> = args...[i];
                args...[i] = args...[j];
                args...[j] = Tmp<args...[i]>::type;
            }  
         }
         return args;
         } 
         Args... args;  
    };
    Je souhaiterai transformer ce code en un code compilable en c++17 mais je ne vois pas du tout comment m'y prendre.
    
    Je ne vois pas comment ajouter la récursion (pour la boucle) avec en même temps, le if. 
    
    Je pensais à un truc du genre pour par exemple copy_if :
    template <class List>
    struct _append_if {
    };
    template <class A, class = std::enable_if<std::is_derived_from<std::true_type>::type>::type>
    struct append_if {
        template<class seq, class... xs>
        using f = typename _append_if<seq>::template f<A, xs...>;   
    };
    template <class A>
    struct append_if {
        template<class seq, class... xs>
        using f = typename _append_if<seq>::template f<xs...>;   
    };
    namespace emp {
        template <class Cond, class L, class A, class... xs>
        using append_if<A, Cond<A>> = typename _append_if<L>::template f<A, xs...>
    }
    template <class Cond, template<class...> class L>
    struct copy_if {    
       using type = typename emp::append_if<Cond, L, ...>::f;
    }



    Je ne pense pas que ça soit bon et que ça va compiler mais c'est juste pour vous montrer ce que je veux faire.



    -
    Edité par OmbreNoire 6 juin 2021 à 19:35:15

    • Partager sur Facebook
    • Partager sur Twitter
      6 juin 2021 à 19:47:27

      Heu ....

      Et c'est quoi le but de tout ceci ?

      • Partager sur Facebook
      • Partager sur Twitter
        6 juin 2021 à 20:28:18

        Transformer ce template variadique ci <int, placeholders<1, double>, placeholders<0, std::string>,float, placeholders<0, std::string>> en ça : <placeholders<0, std::string>,placeholders<1,double>> mais c'est surtout pour m'entraîner à comprendre la méta programmation.
        • Partager sur Facebook
        • Partager sur Twitter
          6 juin 2021 à 21:22:54

          Je veux pas être rabat-joie, mais au vue de tes posts précédent, commence par écouter les intervenant (surtout ceux qui sont très expérimentés), et écrire quelque chose qui à défaut d'être optimal, est correcte et produit le résultat escompté.
          L'optimisation se fera plus tard (en fin de projet).

          • Premature optimization is the root of all evil (or at least most of it) in programming.
            (Donald Knuth)
          Et, avant de t'adonner aux joies de la méta programmation, assure toi que le point précédent soit maîtrisé.
          • Partager sur Facebook
          • Partager sur Twitter
            6 juin 2021 à 23:39:00

            Bon je n'y arrive pas, je n'y comprend rien, je vais faire un langage de script qui va me générer le code que je veux, ça sera plus simple.
            • Partager sur Facebook
            • Partager sur Twitter
              6 juin 2021 à 23:52:25

              Il faut vraiment que tu apprennes à te fixer des objectifs et à déléguer, parce que là tu es en train de t'éparpiller de gauche à droite. Tu ne peux pas tout coder toi même. Tu es passé de créer un jeu à créer un moteur de jeu à créer un langage de script. C'est pas étonnant que tu avances aussi lentement en 10 ans. Personnellement je trouve que ce tu fais est du gâchis de motivation.

              En tous cas, good luck.

              • Partager sur Facebook
              • Partager sur Twitter

              Eug

                7 juin 2021 à 0:31:07

                Malheureusement, pour déléguer, il faut que le projet soit clair, les objectives définis, que cela intéresse et motive les gens, etc.

                Mais ce n'est pas le cas. Le GitHub montre très clairement des problèmes (fichiers qui n'ont rien a faire sur un repo, nommage non cohérent, pas d'issues/projets). Et une remarque qui revient très souvent dans toutes les discussions de OmbreNoire, c'est que les gens ne comprennent pas les questions posées et/ou quel est le but d'un code et/ou pourquoi une implémentation a été choisie et/ou le code est incompréhensible.

                Même s'il arrive a trouver quelqu'un, je ne vois pas comment ça pourrait bien se passer. Ca sera très probablement une expérience désastreuse pour lui et il va en sortir avec la conclusion qu'il est préférable qu'il travaille seul.

                -------------------------------

                Mon conseil était de reprendre de 0, sur un projet simple. Au moins pour montrer qu'il sait gérer correctement un projet et qu'il sait faire du C++ propre.

                Mais il a du mal à accepter qu'on remette en cause ses compétences, alors qu'il code depuis 10 ans.

                • Partager sur Facebook
                • Partager sur Twitter
                  7 juin 2021 à 0:52:41

                  Perso, ça fait 25 ans que je suis dans le métier.

                  Quand j'ai débarqué sur le forum, je me suis pris de sacrées tartes dans la gueule.
                  Je me suis remis en question, ce qui a bien amélioré mes compétences (et j'ai encore probablement bcp à apprendre).

                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 juin 2021 à 1:03:01

                    Deedolith a écrit:

                    (et j'ai encore probablement bcp à apprendre).

                    Etant en pleine crise existentielle sur mes propres compétences, je ne peux qu'approuver ce message :)

                    • Partager sur Facebook
                    • Partager sur Twitter
                      7 juin 2021 à 9:03:22

                      Ok finalement je pense que j'ai réussi, enfin tout du moins, le code compile, faudra vérifier si le type retourné est bon, faut encore que je vois comment faire ça, mais je vais continuer seul. (comme toujours)

                      template <class... A>
                      struct List {
                      };
                      template<class C>
                      struct unpack {
                          template<class seq, class... xs>
                          using f = typename List<seq>::template f<C, xs...>;
                      };
                      template<class A, class C>
                      struct push_front {
                          template<class seq, class... xs>
                          using f = typename List<seq>::template f<A, C, xs...>;
                      };
                      template<class A, class C, class Pred>
                      struct append_if {
                          template <typename seq>
                          requires std::derived_from<Pred, std::true_type>
                          List<push_front<A, C>> f() {
                      
                          }
                          template <typename seq>
                          List<unpack<C>> f() {
                      
                          }
                          using result = decltype(f());
                      };
                      template<class C, template <class> class Pred>
                      struct copy_if {
                          template<class seq, class... xs>
                          using f = typename List<seq>::template f<C, append_if<xs, C, Pred<xs>>...>;
                      };
                      int main(int argc, char* argv[])
                      {
                      
                      
                          List<copy_if< List<int, double, float, 
                          placeholder<0, std::string>>, is_placeholder>> ulist;
                          return 0;
                      }

                      Je met longtemps parce que je suis plus motiver pour apprendre de nouvelles choses et les implémenter plutôt que de coder un jeux. 

                      Mais je pense pas que créer un langage de script sera nécessaire si ce code fonctionne.

                      -
                      Edité par OmbreNoire 7 juin 2021 à 9:04:55

                      • Partager sur Facebook
                      • Partager sur Twitter
                        7 juin 2021 à 10:45:26

                        OmbreNoire a écrit:

                        mais je vais continuer seul. (comme toujours)


                        Ca, c'est très dommage.

                        Certes, on est très critique, ce n'est pas pour rien. Nos conseilles ont pour but de te faire progresser.

                        Mais pour cela, il faut savoir ravaler sa fierté, prendre du recul. C'est difficile, c'est humiliant, mais le bénéfice que tu en tireras est largement supérieur aux désagrément engendrés.

                        -
                        Edité par Deedolith 7 juin 2021 à 10:53:50

                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 juin 2021 à 16:48:51

                          J'ai fini par réussir comme quoi je dois continuer à croire en moi ce n'est pas de la fierté mais à chaque fois que je me suis laissé influencé par quelqu'un d'autre j'ai eu des problèmes.

                          A commencé par celui avec qui j'avais commencé le projet Sorrok il y a des années et qui a fini par se rebeller contre moi, il m'avait fait abandonné mon projet précédent pour passer de la 3D à la 2D iso et je croyais que j'allais avoir plus de chance en équipe, jusqu'à qu'il se rebelle contre les membres de l'équipe et ensuite contre moi.

                          -
                          Edité par OmbreNoire 11 juin 2021 à 16:53:35

                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 juillet 2021 à 18:12:39

                            Je suis entrain de faire ma propre librairie de méta fonctions, la librairie jnl ne compile pas sur tout les compilateurs :

                            template <size_t I, typename T>
                            struct placeholder {
                                using type = T;
                                static constexpr std::size_t index = I;
                            };
                            template<class T>
                            struct is_placeholder
                            : std::false_type
                            {};
                            
                            template<std::size_t I, class T>
                            struct is_placeholder<placeholder<I, T>>
                            : std::true_type
                            {};
                            struct LessPlaceceholder
                            {
                              template<class PlaceHolder1, class PlaceHolder2>
                              using f = std::bool_constant<PlaceHolder1::index < PlaceHolder2::index>;
                            };
                            template<std::size_t i, class T>
                            struct Parameter
                            {
                              T value;
                            };
                            template<class... Placeholders>
                            struct LateParameters : Parameter<Placeholders::index, typename Placeholders::type>... {
                                static void deleter(void * self)
                                {
                                    delete static_cast<LateParameters*>(self);
                                }
                            };
                            //Make index sequences from an offset.
                            template<std::size_t N, typename Seq> struct offset_sequence;
                            
                            template<std::size_t N, std::size_t... Ints>
                            struct offset_sequence<N, std::index_sequence<Ints...>>
                            {
                             using type = std::index_sequence<Ints + N...>;
                            };
                            template<std::size_t N, typename Seq>
                            using offset_sequence_t = typename offset_sequence<N, Seq>::type;
                            //Concatenate two sequences of indexes into one.
                            template<typename Seq1, typename Seq> struct cat_sequence;
                            template<std::size_t... Ints1, std::size_t... Ints2>
                            struct cat_sequence<std::index_sequence<Ints1...>,
                                                std::index_sequence<Ints2...>>
                            {
                             using type = std::index_sequence<Ints1..., Ints2...>;
                            };
                            template<typename Seq1, typename Seq2>
                            using cat_sequence_t = typename cat_sequence<Seq1, Seq2>::type;
                            template<typename T, typename Seq>
                            struct select_tuple;
                            template<typename T, size_t... Ints>
                            //Return a tuple with elements at indexes.
                            struct select_tuple<T, std::index_sequence<Ints...>>
                            {
                             using type = std::tuple<std::tuple_element_t<Ints, T>...>;
                            };
                            //Remove the Nth elements of a tuple.
                            template<std::size_t N, typename T>
                            struct remove_Nth
                            {
                              static constexpr auto size = std::tuple_size_v<T>;
                              using first = std::make_index_sequence<N>;
                              using rest = offset_sequence_t<N+1,
                                            std::make_index_sequence<size-N-1>>;
                              using indices = cat_sequence_t<first, rest>;
                              using type = typename select_tuple<T, indices>::type;
                            };
                            template <size_t I, class T, bool B>
                            struct get;
                            template <size_t I, class T>
                            struct get <I, T, true>
                            {
                                using type = T;
                            };
                            template <size_t I, class T>
                            struct get <I, T, false> {
                                using type = typename remove_Nth<I, T>::type;
                            };
                            template <template<class...> class Pred, class T, bool B, size_t NB, class Seq>
                            struct append_if {};
                            
                            template <template<class...> class Pred, class T, size_t NB, size_t IH, size_t... IT>
                            struct append_if<Pred, T, true, NB, std::index_sequence<IH, IT...>> {
                                using f = typename append_if<Pred, typename get<IH-NB, T, Pred<std::tuple_element_t<IH-NB, T>>::value>::type, Pred<std::tuple_element_t<IH-NB, T>>::value, NB, std::index_sequence<IT...>>::f;
                            };
                            template <template<class...> class Pred, class T, size_t NB, size_t IH, size_t... IT>
                            struct append_if<Pred, T, false, NB, std::index_sequence<IH, IT...>> {
                                using f = typename append_if<Pred, typename get<IH-NB, T, Pred<std::tuple_element_t<IH-NB, T>>::value>::type, Pred<std::tuple_element_t<IH-NB, T>>::value, NB+1, std::index_sequence<IT...>>::f;
                            };
                            template <template<class...> class Pred, class T, size_t NB, size_t IH>
                            struct append_if<Pred, T, true, NB, std::index_sequence<IH>> {
                                using f = typename get<IH-NB, T, Pred<std::tuple_element_t<IH-NB, T>>::value>::type;
                            };
                            template <template<class...> class Pred, class T, size_t NB, size_t IH>
                            struct append_if<Pred, T, false, NB, std::index_sequence<IH>> {
                                using f = typename get<IH-NB-1, T, Pred<std::tuple_element_t<IH-NB-1, T>>::value>::type;
                            };
                            
                            template<template <class...> class Pred, typename T>
                            struct copy_if {
                                using f = typename append_if<Pred, T, Pred<std::tuple_element_t<0, T>>::value, 0, std::make_index_sequence<std::tuple_size<T>::value>>::f;
                            };
                            template<template <class...> class Pred>
                            struct copy_if <Pred, std::tuple<>> {
                                using f = std::tuple<>;
                            };
                            template <class T, template<class...> class R, class Seq>
                            struct lift {
                            };
                            template <class T, template<class...> class R, size_t... Ints>
                            struct lift <T, R, std::index_sequence<Ints...>> {
                                using f = R<std::tuple_element_t<Ints, T>...>;
                            };
                            int main(int argc, char* argv[])
                            {
                                using tuple_t = /*sort<LessPlaceceholder, unique<*/copy_if<is_placeholder,std::tuple<placeholder<3, int>, int, placeholder<2, int>, float, placeholder<1, int>, char, placeholder<0, int>>>::f;/*>::f>::f;*/
                                using late_params_t = lift<tuple_t, LateParameters,std::make_index_sequence<std::tuple_size<tuple_t>::value>>::f;
                                tuple_t tp = std::make_tuple(placeholder<3, int>(),placeholder<2, int>(),placeholder<1, int>(),placeholder<0, int>());
                                return 0;
                            }


                            Je ne pensais pas pouvoir y arrive seul, il me reste plus qu'à faire les structures unique et sort.

                            J'ai retiré l'instanciation de tuple qui posait problème.

                            -
                            Edité par OmbreNoire 20 juillet 2021 à 18:13:52

                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 juillet 2021 à 21:45:05

                              > la librairie jnl ne compile pas sur tout les compilateurs

                              Cette librairie a perdu son combat contre msvc

                              Décris ce que tu veux faire au lieu d'écrire 150 lignes de pseudo code c++ que personne ne lit, ce serait plus simple :p

                              Des membres variadiques (Args... args;) ou des accès via un index (args...[i]) c'est faisable, mais il faut les packs dans une structure et appliquer les fonctions sur la structure ensuite.

                              Si tu veux juste t'entrainer, tu fais un type List, et t'appliques les transformations que tu veux dessus.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                21 juillet 2021 à 16:05:21

                                Un message utile de plus dans l'immense poubelle à messages d'OmbreNoire.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 juillet 2021 à 17:10:34

                                  > > la librairie jnl ne compile pas sur tous les compilateurs > Cette librairie a perdu son combat contre msvc

                                  La première bataille seulement ; la seconde est une victoire ! Depuis que github-action a monté de version il y a 6 mois, il n'y a eu besoin que de 36 commits pour être compatible avec msvc-19.28.

                                  Par contre, la macro de debug pour avoir des erreurs plus explicite est toujours activée, du coup c'est un peu plus lent qu'avec les autres compilateurs. Je prévois de séparer en 2 cette macro pour la prochaine version.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    21 juillet 2021 à 18:13:36

                                    D'accord pour ma part j'ai fais ma propre librairie pour la méta programmation. Parce que j'ai eu des problèmes de compilation avec g++ sous linux.

                                    Pas aussi parfais sans doute, mais ça m'évite de devoir m'y retrouver dans tout ce bazars.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      21 juillet 2021 à 18:24:45

                                      OmbreNoire a écrit:

                                      Pas aussi parfais sans doute, mais ça m'évite de devoir m'y retrouver dans tout ce bazars.

                                      "je ne comprends pas, donc je refais tout moi même"
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        21 juillet 2021 à 18:51:07

                                        gbdivers a écrit:

                                        OmbreNoire a écrit:

                                        Pas aussi parfais sans doute, mais ça m'évite de devoir m'y retrouver dans tout ce bazars.

                                        "je ne comprends pas, donc je refais tout moi même"


                                        Tu veux que je fasse comment pour corriger un fichier avec plus de 1000 lignes de codes, non commenté et avec pleins d'erreurs en compilation ?

                                        Pourquoi faire plus de 1000 lignes de code hors que je fais la même chose avec 200 lignes de code à peine ?

                                        -
                                        Edité par OmbreNoire 21 juillet 2021 à 18:52:32

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          21 juillet 2021 à 19:09:58

                                          Les devs de compilos pour GCC font plein d'erreurs sur des fichiers de 1000 lignes, c'est bien connu, ils sont mauvais.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            22 juillet 2021 à 1:30:14

                                            J'ai déjà eu un crash à cause d'un pointeur que j'alloue dynamiquement et que je stocke dans une std::Map ou un std::Vector, et qui change de valeur tout seul, juste en changeant l'endroit où je déclare le pointeur.

                                            Hors un pointeur alloué dynamiquement ne devrait pas être détruit dans la std::Map ou le std:: Vector même si je le déclare dans le constructeur plutôt que dans la classe.

                                            Ou alors c'est un bug de mingw.

                                            Mais ça prend clairement moins de temps de réimplementer sa propre implémentation que de chercher un bug dans des milliers de lignes de codes.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              22 juillet 2021 à 2:57:16

                                              Je te mets au défi d'écrire un code minimal qui reproduit ce crash et qui montre que le problème vient de map/vector et pas de ton code.

                                              J'utilise map et vector depuis des dizaines d'années avec des pointeurs. Tout comme des milliers de devs C++. Tu penses que je vais conclure que c'est le milliers de devs qui se plantent ou toi ? Je te laisse reflechir a ca.

                                              -
                                              Edité par gbdivers 22 juillet 2021 à 2:57:37

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                22 juillet 2021 à 8:53:46

                                                OmbreNoire a écrit:

                                                Ou alors c'est un bug de mingw.

                                                Mais ça prend clairement moins de temps de réimplementer sa propre implémentation que de chercher un bug dans des milliers de lignes de codes.


                                                Il va vraiment falloir que tu arrêtes avec ton délire de bug dans l'implémentation de la bibliothèque standard du C++. S'il y en avait, il y aurait une tonne d'applications dans le monde qui planteraient tous les jours. Enfin c'est le cas, mais à cause de leur propre erreur dans leur code à eux.

                                                Ni la libc++ (LLVM), libstdc++ (GCC) ou celle de Microsoft sont développés par un petit passionné le soir au travail sur un dépôt github perdu.

                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                git is great because Linus did it, mercurial is better because he didn't.

                                                  22 juillet 2021 à 9:14:27

                                                  J'avais mit un code source qui plantait sur mingw avec une std::map, je vais le tester sur g++ sous linux, je l'avais mit sur un autre sujet mais je vais le remettre dès que j'ai fini.

                                                  EDIT : bug de mingw, avec g++ sous linux ça ne plante pas.

                                                  -
                                                  Edité par OmbreNoire 22 juillet 2021 à 9:41:24

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    22 juillet 2021 à 10:01:59

                                                    Manifestement, tu n'as toujours pas compris. Montrer un code qui plante, ca ne prouve pas qu'il y a un bug dans map/vector, si tu ne localises pas la source du bug. En l'occurrence, vu ton code moisi, j'aurais tendance a penser que tu as fait n'importe quoi et que le bug ne vient pas de map/vector.

                                                    Et tu n'as a priori pas compris le mot "minimal". Parce qu'un code qui utilise les libs sfml, jnl et odfaeg, ce n'est pas du tout un code minimal.

                                                    MONTRE NOUS UN CODE MINIMAL QUI REPRODUIT LE BUG SUR MAP/VECTOR !

                                                    -
                                                    Edité par gbdivers 22 juillet 2021 à 10:03:36

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      22 juillet 2021 à 13:44:37

                                                      gbdivers a écrit:

                                                      Manifestement, tu n'as toujours pas compris. Montrer un code qui plante, ca ne prouve pas qu'il y a un bug dans map/vector, si tu ne localises pas la source du bug. En l'occurrence, vu ton code moisi, j'aurais tendance a penser que tu as fait n'importe quoi et que le bug ne vient pas de map/vector.

                                                      Et tu n'as a priori pas compris le mot "minimal". Parce qu'un code qui utilise les libs sfml, jnl et odfaeg, ce n'est pas du tout un code minimal.

                                                      MONTRE NOUS UN CODE MINIMAL QUI REPRODUIT LE BUG SUR MAP/VECTOR !

                                                      -
                                                      Edité par gbdivers il y a environ 3 heures

                                                      C'était un bug de mingw pas de la stl, avec g++ sous linux, ça ne plante pas.

                                                      template <size_t I, typename T>
                                                      struct ph {
                                                          using type = T;
                                                          static constexpr std::size_t index = I;
                                                      };
                                                      template<class T, class U>
                                                      struct ArgType
                                                      {
                                                        using type = T;
                                                      };
                                                      
                                                      template<class T, class U>
                                                      struct ArgType<T, std::reference_wrapper<U>>
                                                      {
                                                        using type = U&;
                                                      };
                                                      
                                                      template<class T, std::size_t I, class U>
                                                      struct ArgType<T, ph<I, U>>
                                                      {
                                                        using type = ph<I, U>;
                                                      };
                                                      
                                                      template<class T>
                                                      using ArgType_t = typename ArgType<T, std::remove_cv_t<T>>::type;
                                                      
                                                      
                                                      template<class T>
                                                      struct ToStoreImpl
                                                      { using type = T; };
                                                      
                                                      template<class T>
                                                      struct ToStoreImpl<std::reference_wrapper<T>>
                                                      { using type = T; };
                                                      template<size_t I, class T>
                                                      struct ToStoreImpl<ph<I,T>>
                                                      { using type = T; };
                                                      
                                                      template<class T>
                                                      struct ToStore
                                                          : ToStoreImpl<std::remove_reference_t<T>>
                                                      {};
                                                      
                                                      template<class T>
                                                      using ToStore_t = typename
                                                          ToStore<T>::type;
                                                      
                                                      template<class R, class C, class... ArgT>
                                                      struct DynamicWrapper {
                                                      
                                                          DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf){}
                                                          template<class O, class... ArgU>
                                                          R operator()(O* o, ArgU&&... arg) const
                                                          {
                                                              //std::cout<<"address : "<<o<<std::endl;
                                                              if(dynamic_cast<C*>(o))
                                                                  return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
                                                              throw std::runtime_error("Invalid cast : types are nor polymorphic!");
                                                          }
                                                          template<class O, class... ArgU>
                                                          R operator()(O o, ArgU&&... arg) const
                                                          {
                                                              //std::cout<<"address : "<<o<<std::endl;
                                                              return (o.*pfunc)(std::forward<ArgU>(arg)...);
                                                          }
                                                      private:
                                                          R (C::*pfunc)(ArgT...);
                                                      };
                                                      
                                                      
                                                      template<class F>
                                                      class DynamicFunction;
                                                      
                                                      template<class R, class... ArgT>
                                                      class DynamicFunction<R(ArgT...)>
                                                      
                                                      {
                                                          std::function<R(ArgT...)> func;
                                                      public:
                                                          template<class F>
                                                          DynamicFunction(F&& f) : func(std::forward<F>(f))
                                                          {}
                                                      
                                                          template<class C, class... ArgU>
                                                          DynamicFunction(R(C::*pf)(ArgU...))
                                                              : func(DynamicWrapper<R,C,ArgU...>(pf))
                                                          {}
                                                          template <typename... ArgU>
                                                          R operator()(ArgU&&... args) {
                                                               return func(std::forward<ArgU>(args)...);
                                                          }
                                                      };
                                                      template<class F, class... ArgT>
                                                      struct DelegateStorage {
                                                      
                                                          F func;
                                                          using TupleArgs = std::tuple<ArgT...>;
                                                          TupleArgs params;
                                                      };
                                                      template<std::size_t i, class T>
                                                      struct Parameter
                                                      {
                                                        T value;
                                                      };
                                                      template<class... Placeholders>
                                                      struct LateParameters : Parameter<Placeholders::index, typename Placeholders::type>... {
                                                          static void deleter(void * self)
                                                          {
                                                              delete static_cast<LateParameters*>(self);
                                                          }
                                                      };
                                                      template<class T, class Params>
                                                      T&& get_arg(T&& x, Params& params)
                                                      {
                                                          return static_cast<T&&>(x);
                                                      }
                                                      template <size_t I, class T, class Params>
                                                      T& get_arg(ph<I, T>&, Params& params) {
                                                          return static_cast<Parameter<I, T>&>(params).value;
                                                      }
                                                      
                                                      template<class T>
                                                      struct is_placeholder
                                                      : std::false_type
                                                      {};
                                                      
                                                      template<std::size_t I, class T>
                                                      struct is_placeholder<ph<I, T>>
                                                      : std::true_type
                                                      {};
                                                      struct LessPlaceceholder
                                                      {
                                                        template<class PlaceHolder1, class PlaceHolder2>
                                                        using f = std::bool_constant<PlaceHolder1::index < PlaceHolder2::index>;
                                                      };
                                                      template<typename R>
                                                      struct FastDelegate {
                                                          FastDelegate() {
                                                              data.delegate = nullptr;
                                                              data.params = nullptr;
                                                              data.storage_deleter = nullptr;
                                                              data.params_deleter = nullptr;
                                                              data.storage = nullptr;
                                                              data.storage_size = 0;
                                                              data.params_size = 0;
                                                              name = "default";
                                                          };
                                                          template <typename F, typename... Args>
                                                          FastDelegate(F&& f, Args&&... args)
                                                          : data([&]{
                                                          namespace mp = jln::mp;
                                                      
                                                          using late_params_t
                                                            = mp::copy_if<mp::lift<is_placeholder>,
                                                                          mp::unique<mp::sort<LessPlaceceholder,
                                                                                              mp::lift<LateParameters>>>>
                                                              ::f<std::remove_cv_t<Args>...>;
                                                          using storage_t = DelegateStorage<DynamicFunction<R(ToStore_t<Args>...)>, ArgType_t<Args>...>;
                                                          auto delegate = [](Data& data) mutable {
                                                            auto& storage = *static_cast<storage_t*>(data.storage);
                                                            auto& params = *static_cast<late_params_t*>(data.params);
                                                      
                                                            return std::apply([&](auto&... xs){
                                                               return storage.func(get_arg(xs, params)...);
                                                            }, storage.params);
                                                          };
                                                      
                                                          auto storage_deleter = [](void * storage){
                                                              delete static_cast<storage_t*>(storage);
                                                          };
                                                          return Data {
                                                            delegate,
                                                            storage_deleter,
                                                            &late_params_t::deleter,
                                                            new storage_t{
                                                              static_cast<DynamicFunction<R(ToStore_t<Args>...)>&&>(f),
                                                              typename storage_t::TupleArgs{static_cast<Args&&>(args)...}
                                                            },
                                                            nullptr,
                                                            sizeof(storage_t),
                                                            0
                                                          };
                                                        }())
                                                        {
                                                      
                                                        }
                                                        FastDelegate(FastDelegate& rhs) {
                                                         char* tab1 = new char[rhs.data.storage_size];
                                                         memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                         char* tab2 = nullptr;
                                                         if (rhs.data.params != nullptr) {
                                                             tab2 = new char[rhs.data.params_size];
                                                             memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                         }
                                                         data.delegate = rhs.data.delegate;
                                                         data.storage_deleter = rhs.data.storage_deleter;
                                                         data.params_deleter = rhs.data.params_deleter;
                                                         data.storage = tab1;
                                                         data.params = tab2;
                                                         data.storage_size = rhs.data.storage_size;
                                                         data.params_size  = rhs.data.params_size;
                                                         name = rhs.name;
                                                         //std::cout<<"FastDelegate(FastDelegate& rhs) : "<<data.params_deleter<<" : "<<name<<std::endl;
                                                        }
                                                      
                                                      
                                                      
                                                      
                                                      
                                                      FastDelegate(const FastDelegate& rhs) {
                                                          char* tab1 = new char[rhs.data.storage_size];
                                                          memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                          char* tab2 = nullptr;
                                                          if (rhs.data.params != nullptr) {
                                                              tab2 = new char[rhs.data.params_size];
                                                              memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                          }
                                                          data.delegate = rhs.data.delegate;
                                                          data.storage_deleter = rhs.data.storage_deleter;
                                                          data.params_deleter = rhs.data.params_deleter;
                                                          data.storage = tab1;
                                                          data.params = tab2;
                                                          data.storage_size = rhs.data.storage_size;
                                                          data.params_size  = rhs.data.params_size;
                                                          name = rhs.name;
                                                          //std::cout<<"FastDelegate(const FastDelegate& rhs) : "<<data.storage<<" : "<<name<<std::endl;
                                                      }
                                                      
                                                      
                                                      
                                                      FastDelegate(FastDelegate&& rhs) {
                                                          char* tab1 = new char[rhs.data.storage_size];
                                                          memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                          char* tab2 = nullptr;
                                                          if (rhs.data.params != nullptr) {
                                                              tab2 = new char[rhs.data.params_size];
                                                              memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                          }
                                                          data.delegate = rhs.data.delegate;
                                                          data.storage_deleter = rhs.data.storage_deleter;
                                                          data.params_deleter = rhs.data.params_deleter;
                                                          data.storage = tab1;
                                                          data.params = tab2;
                                                          data.storage_size = rhs.data.storage_size;
                                                          data.params_size  = rhs.data.params_size;
                                                          name = rhs.name;
                                                          //std::cout<<"FastDelegate(FastDelegate&& rhs) : "<<data.storage<<" : "<<rhs.name<<std::endl;
                                                      }
                                                      
                                                      FastDelegate& operator=(FastDelegate& rhs)
                                                      {
                                                          char* tab1 = new char[rhs.data.storage_size];
                                                          memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                          char* src = (char*) rhs.data.storage;
                                                          char* tab2 = nullptr;
                                                          if (rhs.data.params != nullptr) {
                                                              tab2 = new char[rhs.data.params_size];
                                                              memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                          }
                                                          data.delegate = rhs.data.delegate;
                                                          data.storage_deleter = rhs.data.storage_deleter;
                                                          data.params_deleter = rhs.data.params_deleter;
                                                          data.storage = tab1;
                                                          data.params = tab2;
                                                          data.storage_size = rhs.data.storage_size;
                                                          data.params_size = rhs.data.params_size;
                                                          name = rhs.name;
                                                          //std::cout<<"operator= (FastDelegate&) : "<<data.storage<<" : "<<name<<std::endl;
                                                          return *this;
                                                      }
                                                      FastDelegate& operator=(const FastDelegate& rhs)
                                                      {
                                                          char* tab1 = new char[rhs.data.storage_size];
                                                          memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                          char* src = (char*) rhs.data.storage;
                                                          char* tab2 = nullptr;
                                                          if (rhs.data.params != nullptr) {
                                                              tab2 = new char[rhs.data.params_size];
                                                              memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                          }
                                                          data.delegate = rhs.data.delegate;
                                                          data.storage_deleter = rhs.data.storage_deleter;
                                                          data.params_deleter = rhs.data.params_deleter;
                                                          data.storage = tab1;
                                                          data.params = tab2;
                                                          data.storage_size = rhs.data.storage_size;
                                                          data.params_size = rhs.data.params_size;
                                                          name = rhs.name;
                                                          //std::cout<<"operator= (const FastDelegate&) : "<<data.storage<<" : "<<name<<std::endl;
                                                          return *this;
                                                      }
                                                      
                                                      FastDelegate& operator=(FastDelegate&& rhs) {
                                                          char* tab1 = new char[rhs.data.storage_size];
                                                          memcpy(tab1, rhs.data.storage, rhs.data.storage_size);
                                                          char* tab2 = nullptr;
                                                          if (rhs.data.params != nullptr) {
                                                              tab2 = new char[rhs.data.params_size];
                                                              memcpy(tab2, rhs.data.params, rhs.data.params_size);
                                                          }
                                                          data.delegate = rhs.data.delegate;
                                                          data.storage_deleter = rhs.data.storage_deleter;
                                                          data.params_deleter = rhs.data.params_deleter;
                                                          data.storage = tab1;
                                                          data.params = tab2;
                                                          data.storage_size = rhs.data.storage_size;
                                                          data.params_size  = rhs.data.params_size;
                                                          name = rhs.name;
                                                          //std::cout<<"operator=(FastDelegate&&) : "<<data.params_deleter<<" : "<<name<<std::endl;
                                                          return *this;
                                                      }
                                                        template<typename... Args>
                                                        void bind(Args&&... args) {
                                                            bind_impl(std::index_sequence_for<Args...>(), std::forward<Args>(args)...);
                                                        }
                                                        template<typename... Args>
                                                        void setParams(Args&&... args) {
                                                          //std::cout<<"set params  : "<<data.storage<<" : "<<name<<std::endl;
                                                          if (data.storage) {
                                                              using storage_t = DelegateStorage<DynamicFunction<R(ToStore_t<Args>...)>, ArgType_t<Args>...>;
                                                              auto& storage = *static_cast<storage_t*>(data.storage);
                                                              storage.params = typename storage_t::TupleArgs{static_cast<Args&&>(args)...};
                                                          }
                                                        }
                                                        R operator()() {
                                                            //void* ret = nullptr;
                                                            if (data.delegate) {
                                                              return data.delegate(data);
                                                            }
                                                        }
                                                        ~FastDelegate()
                                                        {
                                                          if (data.params_deleter) {
                                                              data.params_deleter(data.params);
                                                          }
                                                          if (data.storage_deleter) {
                                                              //std::cout<<"delete storage : "<<data.storage<<" : "<<name<<std::endl;
                                                              data.storage_deleter(data.storage);
                                                          }
                                                        }
                                                        private :
                                                        template<std::size_t... Ints, class... Args>
                                                        void bind_impl(std::index_sequence<Ints...>, Args&&... args)
                                                        {
                                                            //assert(!data.params);
                                                            using params_t = LateParameters<ph<Ints, ArgType_t<Args>>...>;
                                                            //std::cout<<"param deleter adr : "<<&params_t::deleter<<","<<data.params_deleter<<std::endl;
                                                            //if (&params_t::deleter == data.params_deleter) {
                                                              data.params = new params_t{std::forward<Args>(args)...};
                                                              data.params_size = sizeof(params_t);
                                                      
                                                        }
                                                        struct Data
                                                        {
                                                            R(*delegate)(Data&);
                                                            void (*storage_deleter)(void*);
                                                            void (*params_deleter)(void*);
                                                            void * storage;
                                                            void * params;
                                                            size_t storage_size;
                                                            size_t params_size;
                                                        };
                                                        Data data;
                                                        public :
                                                        std::string name;
                                                      };
                                                      struct Command {
                                                          FastDelegate<void> slot;
                                                          std::unique_ptr<FastDelegate<bool>> trigger;
                                                      
                                                          std::string name;
                                                          void setName(std::string name) {
                                                              this->name = name;
                                                          }
                                                          Command() {
                                                              this->trigger = nullptr;
                                                          }
                                                          Command (FastDelegate<bool> trigger, FastDelegate<void> slot) : slot(slot) {
                                                              this->trigger = std::make_unique<FastDelegate<bool>>(trigger);
                                                          }
                                                          Command(const Command& other) : slot(other.slot) {
                                                             if (other.trigger != nullptr) {
                                                                 //std::cout<<"fd : "<<fd()<<std::endl;
                                                                 trigger = std::make_unique<FastDelegate<bool>>(*other.trigger);
                                                                  std::cout<<"command copy : "<<(*trigger)()<<std::endl;
                                                             }
                                                             name = other.name;
                                                          }
                                                      
                                                          bool isTriggered()
                                                          {
                                                      
                                                              if (trigger != nullptr) {
                                                                  return (*trigger)();
                                                              }
                                                              return false;
                                                          }
                                                          void operator()()
                                                          {
                                                              slot();
                                                          }
                                                      
                                                          Command& operator=(const Command& other) {
                                                              if (other.trigger != nullptr) {
                                                                  trigger = std::make_unique<FastDelegate<bool>>(*other.trigger);
                                                                  std::cout<<"command copy affector : "<<(*trigger)()<<std::endl;
                                                              }
                                                              slot = FastDelegate<void>(other.slot);
                                                              return *this;
                                                          }
                                                      };
                                                      class Listener {
                                                      
                                                      public :
                                                      
                                                           Listener() {
                                                           }
                                                      
                                                           void connect(std::string key, Command command) {
                                                              std::cout<<"add command"<<std::endl;
                                                              command.setName(key);
                                                              commands[key] = command;
                                                              //commands = new Command[1]{command};
                                                           }
                                                      
                                                      
                                                           void processEvents() {
                                                               std::map<std::string, Command>::iterator it;
                                                      
                                                               for (it = commands.begin(); it != commands.end(); it++) {
                                                      
                                                                  if (it->second.isTriggered()) {
                                                                      std::cout<<"triggered "<<std::endl;
                                                                      (it->second)();
                                                                  }
                                                               }
                                                               //std::cout<<commands[0].isTriggered()<<std::endl;
                                                           }
                                                           private :
                                                           std::map<std::string, Command> commands;
                                                           //Command* commands;
                                                      };
                                                      #include "odfaeg/Graphics/GUI/label.hpp"
                                                      struct Test {
                                                          Listener listener;
                                                          odfaeg::graphic::RenderComponentManager rcm;
                                                          //odfaeg::graphic::gui::Label* lab;
                                                          Test(odfaeg::graphic::RenderWindow &rw) : rcm(rw) {
                                                              odfaeg::graphic::Font font;
                                                              font.loadFromFile("fonts/Arial.ttf");
                                                              odfaeg::graphic::gui::Label* lab = new odfaeg::graphic::gui::Label(rw, odfaeg::math::Vec3f(0, 0, 0),odfaeg::math::Vec3f(100, 50, 0),&font,"test",15);
                                                              std::cout<<"lab : "<<lab<<std::endl;
                                                              FastDelegate<bool> signal(&odfaeg::graphic::gui::Label::isMouseInside, lab);
                                                              FastDelegate<void> slot(&Test::onMouseInLab, this, lab);
                                                              Command cmd(signal, slot);
                                                              listener.connect("test", cmd);
                                                              rcm.addComponent(lab);
                                                              //std::cout<<cmd.isTriggered()<<std::endl;
                                                          }
                                                          void onMouseInLab(odfaeg::graphic::gui::Label* lab) {
                                                          }
                                                          void processEvents() {
                                                              listener.processEvents();
                                                          }
                                                      };
                                                      int main(int argc, char* argv[]){
                                                          odfaeg::graphic::RenderWindow rw(sf::VideoMode(800, 600), "test");
                                                          Test test(rw);
                                                          test.processEvents();
                                                          return 0;
                                                      }




                                                      -
                                                      Edité par OmbreNoire 22 juillet 2021 à 13:45:47

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        22 juillet 2021 à 13:48:43

                                                        > Tu veux que je fasse comment pour corriger un fichier avec plus de 1000 lignes de codes, non commenté et avec pleins d'erreurs en compilation ?

                                                        Ce que je trouve incroyable ici, est cette capacité à ne regarder qu'une chose: 1 fichier de 13k lignes. Alors qu'il suffit de lire le readme pour comprendre que ce fichier est une fusion de plus d'une 100 centaine de fichier avec tests et tout le tralala.

                                                        Mais c'est vrai qu'un readme d'une ligne et compliqué à lire...

                                                        Concernant ton code, il est faux. Il n'a pas fondamentalement changé depuis plusieurs semaines et contient toujours les mêmes conneries. Tu fais n'importe quoi avec memcpy, le code ne fonctionne et c'est normal.

                                                        Et comme d'habitude, ceci n'est absolument pas un code minimal.

                                                        -
                                                        Edité par jo_link_noir 22 juillet 2021 à 13:52:33

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          22 juillet 2021 à 15:19:09

                                                          Avec g++-10 je n'ai pas de soucis avec le memcpy, cette fonction est bête et ne fait que de copier les données se trouvant dans les void* d'un delegate à l'autre, je n'ai besoin de ne faire qu'une bêtes copie d'octets, rien d'autre, ce n'est pas le delegate qui se charge de cloner les objets qu'il contient.

                                                          -
                                                          Edité par OmbreNoire 22 juillet 2021 à 15:19:42

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            22 juillet 2021 à 15:26:25

                                                            Undefined behavior

                                                            -
                                                            Edité par Orochi 22 juillet 2021 à 15:26:41

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              22 juillet 2021 à 15:51:52

                                                              OmbreNoire a écrit:

                                                              Avec g++-10 je n'ai pas de soucis avec le memcpy, cette fonction est bête et ne fait que de copier les données se trouvant dans les void* d'un delegate à l'autre, je n'ai besoin de ne faire qu'une bêtes copie d'octets, rien d'autre, ce n'est pas le delegate qui se charge de cloner les objets qu'il contient.


                                                              S'il te plait quitte ce forum. Tu énerves tout le monde avec tes hypothèses infondées. On est plusieurs à te dire que tu as tort et tu penses que tu as toujours raison. Tes interventions ne servent à rien ici.
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              git is great because Linus did it, mercurial is better because he didn't.

                                                              Ecriture de méta-fonctions.

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown