Partage
  • Partager sur Facebook
  • Partager sur Twitter

[CPPSS] (CPP Syntax Simplifier) recrute!

Un projet pour simplifier la syntaxe du c++ moderne.

    6 juin 2021 à 14:33:26

    Le c++ moderne est un langage générique qui permet de faire des choses très complexe! Mais le problème c'est que pour faire ces choses très complexe il faut écrire du code très complexe qui peut faire jusqu'à plusieurs milliers de lignes de codes, pour au final ne rien faire d'extraordinaire. :/

    Le but de CPPSS sera de réduire le nombre de lignes de code (à partir d'un code simple mais qui ne compile pas en c++ moderne ou pas encore) pour générer un code qui compilera en c++ moderne.

    Ca prendra du temps de coder un outil de ce genre certes mais il ne faudra le faire qu'une seule fois tandis que le c++ moderne il faut écrire du code complexe à chaque fois qu'on a besoin de générer du code complexe avec des template variadiques.

    Le principal problème avec le c++ moderne c'est que avec les template variadiques on doit :

    -Ecrire des classes et fonctions template pour les parcourir et faire une spécialisation de la classe ou de la fonction pour les cas particuliers ce qui alourdi la syntaxe. (Apparemment en c++23 ça sera mieux parce que on pourra utiliser des boucles pour les parcourir, et surement un if pour gérer les cas particuliers comme par exemple si on doit afficher des variables avec un format différent pour chaque variable si c'est un pointeur, un entier ou une chaîne de caractère)

    -On ne peut pas utiliser de template variadique en variable membre à une classe ni définir un type avec using sur un template variadique. (Apparemment en c++ 23 on pourra le faire) Ce qui force à utiliser une structure ou une classe pour contenir le template variadique ce qui alourdit la syntaxe.

    -Mais surtout LORSQUE L'ON DOIT GENERER UN NOUVEAU TEMPLATE VARIADIQUE A PARTIR DE TEMPLATES VARIADIQUES EXISTANT C'EST LA VRAIE GALERE!!! (AUTREMENT DIT LORSQUE LE TYPE CHANGE EN COMPILATION!)

    Par exemple imaginons que nous ayons une liste de types dont certains sont des placeholders, et que l'on veut :

    ->récupérer les types qui sont des placeholders.

    ->Eliminer tout les placeholders qui sont les mêmes pour ne pas avoir de doublons.

    ->Trier les types suivant l'index du placeholder, du plus petit au plus grand.

    Pour écrire un code qui compile en c++ moderne pour faire ça, c'est la vrai galère!!!

    Par exemple ce fichier fait plus de 13 000 lignes de code :

    https://github.com/jonathanpoelen/jln.mp/blob/standalone/include/jln/mp.hpp

    Pour finalement ne faire que ceci :

    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>...>;

    Ce qui est vraiment aberrant, d'autant plus que avec mingw64 ça m'amène à un undefined behaviour :

    struct FastDelegate {
                FastDelegate() :
                data([&]{
                     return Data {
                         nullptr,
                         nullptr,
                         nullptr,
                         nullptr,
                         nullptr,
                         0,
                         0
                     };
                }())
                {
                    std::cout<<"default constructor"<<std::endl;
                }
                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);
                  //printf("%s%x%s", "value of this in delegate (delegate) : ",  std::get<Args>(storage.params)..., "\n");
                  return std::apply([&](auto&... xs){
                    //printf("%s%x%s", "value of this in delegate (std::apply) : ",  std::get<Args>(storage.params)..., "\n");
                    return storage.func(get_arg(xs, params)...);
                  }, storage.params);
                };
                auto storage_deleter = [](void * storage){
                    std::cout<<"delete storage : "<<storage<<std::endl;
                    delete static_cast<storage_t*>(storage);
                };
                size_t size = sizeof(storage_t);
                std::cout<<"size in ctor: "<<size<<","<<(size / 8)<<","<<(size / 8 * 8)<<std::endl;
                DynamicFunction<R(ToStore_t<Args>&...)> df(f);
                return Data {
                  delegate,
                  storage_deleter,
                  &late_params_t::deleter,
                  new storage_t{
                    static_cast<DynamicFunction<R(ToStore_t<Args>&...)>&&>(df),
                    typename storage_t::TupleArgs{static_cast<Args&&>(args)...}
                  },
                  nullptr,
                  sizeof(storage_t),
                  0
                };
              }())
              {
                  std::cout<<"constructor"<<std::endl;
              }

    car size / 8 * 8 ne me donne pas le bon résultat, le pointeur sur l'objet stocké dans le tuple n'est pas toujours bon et lorsque ça arrive il m'appelle le pointeur sur fonction membre sur un pointeur sur un objet qui n'est pas bon et ça plante!

     Sous visual studio, le fichier mp.hpp ne compile même pas.

    La syntaxe du c++ moderne ne compile donc pas sur tout les compilateurs et quand ça compile ça peut amener à des undefined behaviour tellement la syntaxe est complexe.

    Le but de CPPSS est donc d'éliminer la complexité de la syntaxe en générant du code c++ qui compile à partir d'une syntaxe plus simple autrement dit utiliser une syntaxe plus simple pour générer les types d'un template variadique devant être changé à la compilation, sans que ça produise d'undefined behaviour et que ça compile sur n'importe quel compilateur.

    Ca fait depuis plusieurs années que je m'intéresse au langage c++ pour créer des algorithmes générique et complexe (comme par exemple le système de sérialisation de boost qui ne fonctionnait pas lorsque je l'ai utilisé) et je me suis rendu compte que pour y arriver il me faut élaborer une autre syntaxe car la syntaxe du c++ moderne devient trop complexe à mettre en œuvre.

    Voici un exemple qui montre une syntaxe plus simple, permettant de créer de nouveau types de template variadique. (autrement dit un parameter pack) ce qui permet de récupérer le parameter pack et le réutiliser même si le type change car en c++ moderne il est impossible d'affecter une variable de type différent à un type.

    Par exemple ceci :

    template<typename... T> list = append<args...[i], list>::type 

    ne compilera pas.

    Par contre CPPSS pourrait générer la liste de types du style append<int, list> va donner list<int>.

    Un exemple de code sera plus parlant sûrement :

    /*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;
    } } 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; }; Ce qui transforme un fichier de plus de 13 000 lignes de codes en un fichier de seulement quelques lignes de codes pour écrire ceci : using late_params_t = typename LateParams<sort<LessPlaceholder, unique<copy_if<is_placeholder, std::remove_cv<Args>...>::type>::type>::type>::type> Un autre exemple, pour les Variant et les Visitor. (Le fichier fait plus de 700 lignes de code) https://github.com/LaurentDuroisin7601/ODFAEG/blob/master/ODFAEG/include/odfaeg/Core/variant.h Alors que avec CPPSS il ne ferait que quelques ligne de code en écrivant ceci : /*Un variant possède plusieurs type mais un seul est valide, une union me semble être appropriée, on pourrait utiliser std::optional pour rechercher le type valide.*/ template <typename... Args> union Variant { template <typename T> Variant (T&& t) { args<T> = std::forward<T>(t); } template <typename T> T get() { return constexpr { for (unsigned int i = 0; i < sizeof...(Args); i++) { /*Parameter pack déclaré en variable membre, on peut accédé à l'élément i du parameter pack comme ceci : */ if (args...[i].hasValue()) { return args...[i].value; } } } } std::optional<Args>... args; }; /*On recherche les types valide de tout les variants puis on les passe au visiteur.*/ template <typename R, typename Visitor, typename... Variants, typename... Args> apply (Visitor visitor, Variants... variants) { return visitor (variants.get()..., args...); } J'ai oublié mais je pense qu'il faudra que je mette une directive spéciale pour encadrer le code qui sera du code CPPSS à transformer en code C++ du style CPPSS {};



    Je recherche :

    Un (ou plusieurs) développeur(s) c++ ayant une connaissance du langage c++ et des templates pour la génération de code pour les templates variadiques.

    Par exemple, Args... vaut <int, placeholder<1, double>, float, placeholder<0, std::string>, placeholder<0, std::string>>  ceci devra être généré : using late_params_t = LateParams<placeholder<0, std::string>, placeholder<1, double>>; 

    • Partager sur Facebook
    • Partager sur Twitter
      8 juin 2021 à 23:37:35

      Salut! Encore un exemple qui montre que le c++ n'est pas pratique du tout quand il s'agit de modifier des typelist et de les passer à une autre classe.

      Voici un code qui ne compile pas, ou je modifie un parameter pack (juste pour tester) et le passer à une autre typelist.

      template<class T, template <class> class R>
      struct make_unique {
          template <typename A, class... xs>
          //requires std::derived_from<Pred<A>, std::true_type>
          static constexpr auto get() -> decltype(push_front<R,A, xs...>::type()){
              return push_front<R,A, xs...>::type();
          }
          /*template <typename A, class... xs>
          requires std::derived_from<Pred<A>, std::false_type>
          static constexpr auto get() -> decltype(std::tuple<xs...>()) {
              return std::tuple<A, xs...>();
          }*/
          template <size_t I=0, size_t... Ints>
          requires (I == std::tuple_size<T>())
          static constexpr auto func(std::index_sequence<Ints...>) -> decltype(get<decltype(std::get<Ints+I-1>(T())())...>()) {
              return get<decltype(std::get<Ints+I-1>(T())())...>();
      
          }
          template <size_t I=0, size_t... Ints>
          requires (I > 0 && I != std::tuple_size<T>())
          static constexpr auto const func(std::index_sequence<Ints...>) -> decltype(get<decltype(std::get<Ints+I-1>(T())())...>()) {
              return get<decltype(std::get<Ints+I-1>(T())())...>();
          }
          template <size_t I=0, size_t... Ints>
          requires (I == 0)
          static constexpr auto func(std::index_sequence<Ints...>) -> decltype(func<I+1/*, decltype(get<decltype(std::get<Ints>(T())())...>)*/>(std::make_index_sequence<std::tuple_size<T>()-I>())) {
              return func<I+1/*, decltype(get<decltype(std::get<Ints>(T())())...>)*/>(std::make_index_sequence<std::tuple_size<T>()-I>());
          }
      };
      template<class L, template <class> class R>
      struct unique {
          using type = typename L::type;
          using f = decltype(make_unique<type, R>::func(std::make_index_sequence<std::tuple_size<type>()-0>()));
      };

      Le compilateur n'arrive même pas à déduire les types que j'extrais du tuple avec get.

      ||=== Build: Debug in ODFAEGCREATOR (compiler: GNU GCC Compiler) ===|
      c:\program files (x86)\odfaeg\include\odfaeg\core\fastDelegate.h|12|warning: "EXPERIMENTAL_IMPLEMENTATION" redefined|
      ||note: this is the location of the previous definition|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\entity.h|373|warning: "/*" within comment [-Wcomment]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\entity.h|373|warning: "/*" within comment [-Wcomment]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\entity.h|373|warning: "/*" within comment [-Wcomment]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\entity.h|373|warning: "/*" within comment [-Wcomment]|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|2|warning: extra tokens at end of #include directive|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|137|warning: "/*" within comment [-Wcomment]|
      c:\program files (x86)\odfaeg\include\odfaeg\core\fastDelegate.h||In member function 'int odfaeg::core::FastDelegate<R>::bind(Args&& ...)':|
      c:\program files (x86)\odfaeg\include\odfaeg\core\fastDelegate.h|572|warning: no return statement in function returning non-void [-Wreturn-type]|
      c:\program files (x86)\odfaeg\include\odfaeg\core\fastDelegate.h||In member function 'int odfaeg::core::FastDelegate<R>::setParams(Args&& ...)':|
      c:\program files (x86)\odfaeg\include\odfaeg\core\fastDelegate.h|578|warning: no return statement in function returning non-void [-Wreturn-type]|
      c:\program files (x86)\odfaeg\include\odfaeg\math\computer.h|418|warning: suggest parentheses around '&&' within '||' [-Wparentheses]|
      c:\program files (x86)\odfaeg\include\odfaeg\math\computer.h|436|warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]|
      c:\program files (x86)\odfaeg\include\odfaeg\window\iWindow.hpp||In member function 'virtual const odfaeg::window::ContextSettings& odfaeg::window::IWindow::getSettings() const':|
      c:\program files (x86)\odfaeg\include\odfaeg\window\iWindow.hpp|193|warning: returning reference to temporary [-Wreturn-local-addr]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h||In constructor 'odfaeg::graphic::LightComponent::LightComponent(odfaeg::graphic::RenderWindow&, odfaeg::math::Vec3f, odfaeg::math::Vec3f, odfaeg::math::Vec3f, unsigned int, odfaeg::graphic::LightComponent*)':|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|180|warning: 'odfaeg::graphic::LightComponent::parent' will be initialized after [-Wreorder]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|179|warning:   'bool odfaeg::graphic::LightComponent::enableScissorTest' [-Wreorder]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|13|warning:   when initialized here [-Wreorder]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h||In member function 'virtual void odfaeg::graphic::LightComponent::recomputeSize()':|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|24|warning: unused variable 'sx' [-Wunused-variable]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|24|warning: unused variable 'sy' [-Wunused-variable]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|24|warning: variable 'ppx' set but not used [-Wunused-but-set-variable]|
      c:\program files (x86)\odfaeg\include\odfaeg\graphics\lightcomponent.h|24|warning: variable 'ppy' set but not used [-Wunused-but-set-variable]|
      c:\program files (x86)\odfaeg\include\odfaeg\network\aes.h||In member function 'void odfaeg::network::AES_ENC::Xor(char*, const char*)':|
      c:\program files (x86)\odfaeg\include\odfaeg\network\aes.h|180|warning: comparison of integer expressions of different signedness: 'int' and 'const unsigned int' [-Wsign-compare]|
      c:\program files (x86)\odfaeg\include\odfaeg\network\network.h|191|warning: the compiler can assume that the address of 'odfaeg::network::Network::cli' will never be NULL [-Waddress]|
      c:\program files (x86)\odfaeg\include\odfaeg\network\network.h|228|warning: the compiler can assume that the address of 'odfaeg::network::Network::srv' will never be NULL [-Waddress]|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp||In instantiation of 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>':|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|error: no matching function for call to 'make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func(std::make_index_sequence<4>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: constraints not satisfied|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|  required by the constraints of 'template<class T, template<class> class R> template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|98|note: the expression 'I == std::tuple_size<_Tp>() [with T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; I = 0]' evaluated to 'false'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp||In instantiation of 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>':|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I > 0 && I != std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note: constraints not satisfied|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|  required by the constraints of 'template<class T, template<class> class R> template<long long unsigned int I, long long unsigned int ...Ints>  requires  I > 0 && I != std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|104|note: the expression 'I > 0 [with I = 0]' evaluated to 'false'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp||In instantiation of 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>':|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<_Tp>() - I)>())) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|error: no matching function for call to 'make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<(0 + 1)>(std::make_index_sequence<4>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: constraints not satisfied|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|  required by the constraints of 'template<class T, template<class> class R> template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|98|note: the expression 'I == std::tuple_size<_Tp>() [with T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; I = 1]' evaluated to 'false'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I > 0 && I != std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|error: expression cannot be used as a function|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|error: no matching function for call to 'make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::<expression error>()'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|89|note: candidate: 'template<class A, class ... xs> static constexpr decltype (push_front<R, A, xs ...>::type()) make_unique<T, R>::get() [with A = A; xs = {xs ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|89|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<_Tp>() - I)>())) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|error: no matching function for call to 'make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<(1 + 1)>(std::make_index_sequence<3>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|note: constraints not satisfied|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  recursively required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|99|  required by the constraints of 'template<class T, template<class> class R> template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>)'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|98|note: the expression 'I == std::tuple_size<_Tp>() [with T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; I = 2]' evaluated to 'false'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note: candidate: 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I > 0 && I != std::tuple_size<_Tp>() static constexpr decltype (get<decltype (get<((Ints + I) - 1)>(T())())...>()) make_unique<T, R>::func(std::index_sequence<_Ind ...>) [with long long unsigned int I = I; long long unsigned int ...Ints = {Ints ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  recursively required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|110|  required by substitution of 'template<long long unsigned int I, long long unsigned int ...Ints>  requires  I == 0 static constexpr decltype (func<(I + 1)>(std::make_index_sequence<(std::tuple_size<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > >() - I)>())) make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::func<I, In|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|117|required from 'struct unique<const list<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|123|required from here|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|error: no match for call to '(std::__tuple_element_t<1, std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> > > {aka odfaeg::core::placeholder<2, int>}) ()'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|105|error: no matching function for call to 'make_unique<std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >, odfaeg::core::LateParameters>::<expression error>()'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|89|note: candidate: 'template<class A, class ... xs> static constexpr decltype (push_front<R, A, xs ...>::type()) make_unique<T, R>::get() [with A = A; xs = {xs ...}; T = std::tuple<int, odfaeg::core::placeholder<2, int>, odfaeg::core::placeholder<1, int>, odfaeg::core::placeholder<0, int> >; R = odfaeg::core::LateParameters]'|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|89|note:   template argument deduction/substitution failed:|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp||In function 'int main(int, char**)':|
      C:\Users\Laurent\Windows\Demos\ODFAEGCREATOR\main.cpp|124|error: 'late_params_t' was not declared in this scope|
      ||=== Build failed: 20 error(s), 50 warning(s) (0 minute(s), 4 second(s)) ===|
      
      

      On est obligé du coup de passer les types à la main (sinon le compilateur n'arrive pas à les déduire) ce qui n'est pas pratique surtout lorsque l'on ne les connaît pas à l'avance!

      template <class... A>
      struct list {
          using type = std::tuple<A...>;
      };
      template <template <class...> class L, class A, class... Args>
      struct push_front {
          using type = L<A, Args...>;
      };
      template<class C, template<class> class Pred, template <class...> class R>
      struct append_if {
          template <typename A, class... xs>
          requires std::derived_from<Pred<A>, std::true_type>
          static push_front<R, A, xs...>::type const get() {
      
          }
          template <typename A, class... xs>
          requires std::derived_from<Pred<A>, std::false_type>
          static R<xs...> const get() {
      
          }
          template <size_t I, size_t S, class A, class... xs>
          requires (I == 0)
          static auto func() -> decltype(get<A, xs...>()) {
              //std::cout<<"I = 0 : "<<I<<std::endl;
      
          }
          template <size_t I, size_t S, class A, class... xs>
          requires (I != S-1 && I > 0)
          static constexpr auto const func() -> decltype(get<A, xs...>()) {
              //std::cout<<"I != S-1 : "<<I<<std::endl;
              //return func<I-1, S, decltype(get<A, seq>()), xs...>();
          }
          template <size_t I, size_t S, class A, class... xs>
          requires (I == S-1)
          static constexpr auto func() -> decltype(func<I-1, S, decltype(get<A, xs...>()), xs...>()) {
              //std::cout<<"I = S-1 : "<<I<<std::endl;
              //return func<I-1, S, decltype(get<A, list<>>()), xs...>();
          }
      };
      template<template <class> class Pred, typename C, template <class> class R>
      struct copy_if {
          template <class... xs>
          using f = decltype(append_if<C, Pred, R>::template func<sizeof...(xs)-1, sizeof...(xs), xs...>());
      };





      -
      Edité par OmbreNoire 8 juin 2021 à 23:38:01

      • Partager sur Facebook
      • Partager sur Twitter
        9 juin 2021 à 7:44:04

        Hello

        Bon déjà on vas commencer par pointer du doigt la mauvaise foi vis a vis du C++ moderne:

        • Ceci est une librairie complète (qui fait certes 13000 lignes). Sont but est de fournir des outils que divers dev pourront utiliser, pas de résoudre ton problème en particulier.
        • Ceci N'est pas du C++ moderne. le C++ moderne aurait simplement utilise le header &lt;variant&gt;

        Maintenant qu'on repart sur de bonnes bases, quelques questions. Tu en es ou de ce projet en ce moment? Comme tu l'as dit c'est un sacre travail... Tu comptes le mener en même temps que ton Moteur de Jeu et ton MMO? C'est pas bien sérieux tout ca...

        A titre personnel, je pense que tu met ton incompréhension du langage sur le dos du compilateur et que tu cherches une solution a un problème qui n'existe pas. (Quand tu n'arriveras pas a faire ta tambouille avec CPPSS ça sera la faute a qui cette fois?)</variant>

        • Partager sur Facebook
        • Partager sur Twitter
          9 juin 2021 à 9:03:01

          Elried a écrit:

          Hello

          Bon déjà on vas commencer par pointer du doigt la mauvaise foi vis a vis du C++ moderne:

          • Ceci est une librairie complète (qui fait certes 13000 lignes). Sont but est de fournir des outils que divers dev pourront utiliser, pas de résoudre ton problème en particulier.
          • Ceci N'est pas du C++ moderne. le C++ moderne aurait simplement utilise le header &lt;variant&gt;

          Maintenant qu'on repart sur de bonnes bases, quelques questions. Tu en es ou de ce projet en ce moment? Comme tu l'as dit c'est un sacre travail... Tu comptes le mener en même temps que ton Moteur de Jeu et ton MMO? C'est pas bien sérieux tout ca...

          A titre personnel, je pense que tu met ton incompréhension du langage sur le dos du compilateur et que tu cherches une solution a un problème qui n'existe pas. (Quand tu n'arriveras pas a faire ta tambouille avec CPPSS ça sera la faute a qui cette fois?)</variant>


          Je ne vais pas faire ce projet finalement avec le moteur de jeux (et le jeux) ça va être de trop je vais plutôt attendre la sortie du c++23 qui je l'espère permettra de faire ce genre de choses et manipuler des types plus facilement. (Parque lorsqu'il faut : modifier une typelist ou la passer à une autre classe c'est trop compliqué à cause des restrictions du c++ moderne)
          • Partager sur Facebook
          • Partager sur Twitter

          [CPPSS] (CPP Syntax Simplifier) recrute!

          × 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