IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

[Succ()] retour au debut de l'enum


Sujet :

Delphi

  1. #1
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut [Succ()] retour au debut de l'enum
    Salut tout le monde,
    une petite question toute bete mais qui me serait d'une grande utilité (sinon tant pis, je le ferai moi meme) : Existe-t'il une fonction comme Succ mais qui retourne au début de l'enum automatiquement?
    Du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    type TMonEnum = (me1, me2, me3);
     
    SuccEx(me1) = me2
    SuccEx(me3) = me1
    qui pourrait s'implementer comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    function SuccEx(x: Enum): Enum;
    begin
      if x = High(Enum) then
        x := Low(Enum)
      else
        x := Succ(x);
    end;

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    tu peux noter que Succ n'est pas une véritable fonction mais une sorte de macro, non typé !!! ce n'est qu'un Inc !

    Selon la directive de compilation RANGECHECKS, il me semble, si tu fais Succ si ce n'est pas actif, tu te retrouves avec une valeur farfelue, sinon, cela provoque une ERangeError ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    tu peux noter que Succ n'est pas une véritable fonction mais une sorte de macro, non typé !!!
    je sais pas d'où tu note ca, mais la fonction n'est pas implémentée dans System.pas

    Donc est il possible (avec les RTTI par exemple) de faire une fonction (non typée je suppose) qui puisse savoir si une variable est arrivée aux bornes des limites() de son type?

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Disons que c'est un ensemble d'indice :

    - le prototype n'est pas syntaxiquement correct
    - pas d'implémentation dans System (pas de Succ ni _Succ, ...)
    - le codé généré par Enum := Succ(Enum) ne donne pas un "Call Succ" mais un simple "INC Registre" en assembleur ...

    le terme macro étant un abus de langage, en fait succ pourrait presque être comparé à un opérateur comme + ou and ...

    Sinon, pour les fonctions non typés, j'avoue que je ne sais pas trop comment cela fonctionne ... à par ma fonction RealAssigned qui utilise un param non typé, je n'ai jamais tenté de faire une fonction non typé (d'ailleurs, ça serait quoi la syntaxe ???)

    Ensuite pour le RTTI, ben, les bornes avec RANGECHECKS c'est généré en dur dans l'assembleur pour ce qui concerne les Enum ... il faudrait passer en paramètre de la fonction le typeinfo, car j'ai l'impression, que le compilateur mets aussi en dur le typeinfo pour les fonctions genre Length ou CopyRecord, ... puis il avec le type, il va chercher dans les RTTI, ... mais il a au moins un point d'entrée typé connu !

    tient, le sujet "Enregistrement de record non finalisé" pourrait t'intéresser, les liens de SJRD en particulier ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Donc est il possible (avec les RTTI par exemple) de faire une fonction (non typée je suppose) qui puisse savoir si une variable est arrivée aux bornes des limites() de son type?
    Tu es en Delphi.NET ? Si c'est le cas, effectivement tu peux connaitre les valeurs possibles d'un enum via Reflexion.

    Sinon en Delphi peut-être que les fonction high et low fonctionnent sur un enum, je n'en sais rien.
    Par contre les RTTI ce sont des informations supplémentaires qui permettent d'accéder aux membres Published d'une classe non ? Je doute qu'il soit possible d'interroger un enum de cette façon.

    Le compilateur travaille avec sa table des symboles pour générer les contrôles des limites "en dur", pas avec les RTTI.

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    La Reflexion .NET se base sur les RTTI, et cela ne concerne pas que les propriétés publiés des objets en M+ mais aussi les type record, tableau, ... pour pouvoir les finaliser et aussi allouer leur mémoire tout simplement ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Le compilateur travaille avec sa table des symboles pour générer les contrôles des limites "en dur", pas avec les RTTI.
    Oui, c'est ce que j'ai dit ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Par contre les RTTI ce sont des informations supplémentaires qui permettent d'accéder aux membres Published d'une classe non ? Je doute qu'il soit possible d'interroger un enum de cette façon.
    C'est en effet ce que pensent les pauvres mortels .......

    Non en fait les RTTI c'est beaucoup plus que tu ne crois. Et il est effectivement possible d'obtenir des informations sur un enum avec les RTTI. Voici une fonction avec paramètres non typés et RTTI qui fait ce que tu veux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    uses
      TypInfo;
     
    procedure IncLoop(var Value; TypeInfo: PTypeInfo);
    var
      TypeData: PTypeData;
      HighValue: Integer;
    begin
      Assert(TypeInfo.Kind = tkEnumeration);
      TypeData := GetTypeData(TypeInfo);
     
      if TypeData.OrdType = otUByte then
      begin
        // Enum stocké sur 1 octet
        if Byte(Value) = TypeData.MaxValue then
          Byte(Value) := 0
        else
          Inc(Byte(Value));
      end else
      begin
        // Enum stocké sur 2 octets
        if Word(Value) = TypeData.MaxValue then
          Word(Value) := 0
        else
          Inc(Word(Value));
      end;
    end;
    Bon c'est pas testé mais ça devrait très bien fonctionner. Ca s'utilise comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      MonEnum: TMonEnum;
    begin
      IncLoop(MonEnum, TypeInfo(TMonEnum));
    end;
    En réfléchissant un peu, tu pourras même écrire la fonction inverse (DecLoop) assez facilement.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  8. #8
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    merci beaucoup sjrd.
    Ce code n'est il pas un peu trop lourd comparé un un simple test directement dans le code?

    Dommage qu'il n'y ai pas de #define en delphi

    je teste ca des demain

  9. #9
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par guillemouze Voir le message
    Ce code n'est il pas un peu trop lourd comparé un un simple test directement dans le code?
    Si, sans aucun doute. Je ne prétendais pas fournir de solution légère, mais générique. Tu peux simplifier pas mal si tu sais que ton enum est stocké sur un seul octet (il a 256 valeurs maximum) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure IncLoop(var Value; TypeInfo: PTypeInfo);
    var
      TypeData: PTypeData;
    begin
      Assert(TypeInfo.Kind = tkEnumeration);
      TypeData := GetTypeData(TypeInfo);
     
      if Byte(Value) = TypeData.MaxValue then
        Byte(Value) := 0
      else
        Inc(Byte(Value));
    end;
    Voire peut-être ceci, à voir si ça passe au niveau de l'appel sur le const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure IncLoop(var Value; const HighValue); inline;
    begin
      if Byte(Value) = Byte(HighValue) then
        Byte(Value) := 0
      else
        Inc(Byte(Value));
    end;
    A utiliser alors comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IncLoop(MonEnum, High(TMonEnum));
    Grâce à l'inlining, il y a des chances que celui-là produise son code à l'endroit de l'appel, mais il faut avoir Delphi 2006 minimum.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

Discussions similaires

  1. retour au debut de boucle
    Par awatefawatef dans le forum VHDL
    Réponses: 1
    Dernier message: 09/08/2013, 14h18
  2. affichage alert et retour au debut (js)
    Par asus02 dans le forum jQuery
    Réponses: 0
    Dernier message: 06/11/2011, 17h53
  3. [C#] [debutant] Valeur de retour d'une fenetre
    Par fremsoi dans le forum Windows Forms
    Réponses: 14
    Dernier message: 28/07/2006, 11h28
  4. Réponses: 8
    Dernier message: 13/09/2005, 17h32
  5. [Debutant(e)] Code de retour de mon programme
    Par benji999 dans le forum Général Java
    Réponses: 2
    Dernier message: 10/12/2004, 13h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo