Analoge Literaren - guter Stil?



  • Ich finde, das ist eine sehr gute Möglichkeit den semantischen Wert einer Variable deutlicher lesbar darzustellen:

    #include "analogliterals.hpp"
    #include <cassert>
    
    int main ()
    {
      using namespace analog_literals::symbols;
    
      unsigned int a = 4;
    
      unsigned int b = I---------I;
    
      assert( a == b );
    
      assert( I-I == 0 );
      assert( I---I == 1 );
      assert( I-----I == 2 );
      assert( I-------I == 3 );
    
      unsigned int c = ( o-----o
                         |     !
                         !     !
                         !     !
                         o-----o ).area;
    
      assert( c == (I-----I) * (I-------I) );
    
      assert( ( o-----o
                |     !
                !     !
                !     !
                !     !
                o-----o ).area == ( o---------o
                                    |         !
                                    !         !
                                    o---------o ).area );
    
      assert( ( o-------------o
                |L             \
                | L             \
                |  L             \
                |   o-------------o
                |   !             !
                !   !             !
                o   |             !
                 L  |             !
                  L |             !
                   L|             !
                    o-------------o ).volume == ( o-------------o
                                                  |             !
                                                  !             !
                                                  !             !
                                                  o-------------o ).area * int(I-------------I) );
    
      assert( top( o-------o
                   |L       \
                   | L       \
                   |  o-------o
                   |  !       !
                   !  !       !
                   o  |       !
                    L |       !
                     L|       !
                      o-------o ) == ( o-------o
                                       |       !
                                       !       !
                                       o-------o ) );
    
      analog_literals::rectangle<4, 2> r = o---------o
                                           |         !
                                           !         !
                                           o---------o;
    
    }
    

    und analog_literals.hpp:

    #ifndef ANALOGLITERALS_HPP
    #define ANALOGLITERALS_HPP
    
    namespace analog_literals {
    
    typedef unsigned int uint;
    
      enum line_end { o, I };
      enum Lsymbol { L };
    
      struct eLsymbol {};
      eLsymbol operator! (Lsymbol) { return eLsymbol(); }
    
      struct gen { template <typename T> operator T () const { return T(); } };
    
      template <typename T, uint n> struct excls { excls<T, n + 1> operator! () const { return gen(); } };
    
      template <typename T, uint n> struct dashes: excls<dashes<T, n>, 0>
      { dashes<T, n + 1> operator-- (int) const { return gen(); } };
    
      template <typename, uint> struct L_symbols {}; 
      template <typename T, uint n> L_symbols<T, n + 1> operator| (L_symbols<T, n>, Lsymbol) { return gen(); }
    
      template <typename, uint> struct eL_symbols {}; 
      template <typename T, uint n> eL_symbols<T, n + 1> operator| (eL_symbols<T, n>, eLsymbol) { return gen(); }
    
      dashes<line_end, 1> operator-- (line_end, int) { return gen(); }
      excls<line_end, 1> operator! (line_end) { return gen(); }
    
      template <uint len> struct line: L_symbols<line<len>, 0>
      { static uint const length; operator uint () const { return len; } };
      template <uint x, uint y> struct rectangle { static uint const width, height, area; };
      template <uint x, uint y, uint z> struct cuboid { static uint const width, height, depth, volume; };
    
      template <uint len> uint const line<len>::length = len;
    
      template <uint x, uint y> uint const rectangle<x, y>::width = x;
      template <uint x, uint y> uint const rectangle<x, y>::height = y;
      template <uint x, uint y> uint const rectangle<x, y>::area = x * y;
    
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::width = x;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::height = y;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::depth = z;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::volume = x * y * z;
    
      template <uint x, uint y, uint z> rectangle<x, y> front (cuboid<x, y, z>) { return gen(); }
      template <uint x, uint y, uint z> rectangle<z, y> side (cuboid<x, y, z>) { return gen(); }
      template <uint x, uint y, uint z> rectangle<x, z> top (cuboid<x, y, z>) { return gen(); }
    
      template <uint ax, uint bx> bool operator== (line<ax>, line<bx>) { return ax == bx; }
    
      template <uint ax, uint ay, uint bx, uint by> bool operator== (rectangle<ax, ay>, rectangle<bx, by>)
      { return ax == bx && ay == by; }
    
      template <uint ax, uint ay, uint az, uint bx, uint by, uint bz>
      bool operator== (cuboid<ax, ay, az>, cuboid<bx, by, bz>) { return ax == bx && ay == by && az == bz; }
    
      line<0> operator- (line_end, line_end) { return gen(); }
      template <uint x> line<x> operator- (dashes<line_end, x>, line_end) { return gen(); }
    
      template <uint x, uint y> struct lower_rectangle {}; 
    
      template <uint excl_marks, uint x>
      lower_rectangle<x, (excl_marks + 1) / 2> operator- (excls<dashes<line_end, x>, excl_marks>, line_end)
      { return gen(); }
    
      template <uint x, uint y> rectangle<x, y> operator| (line<x>, lower_rectangle<x, y>) { return gen(); }
    
      template <uint x, uint y, uint z> struct cuboid_top {};
      template <uint x, uint y, uint z> struct half_cuboid {};
    
      template <uint x, uint n>
      cuboid_top<x, n + 1, n> operator| (L_symbols<line<x>, n>, line<x>) { return gen(); }
    
      template <uint x, uint y, uint z, uint n>
      eL_symbols<half_cuboid<x, y + (n + 1) / 3, z>, 0> 
        operator| (cuboid_top<x, y, z>, excls<line_end, n>) { return gen(); }
    
      template <uint x, uint y, uint z>
      cuboid<x, y, z> operator| (eL_symbols<half_cuboid<x, y, z>, z>, lower_rectangle<x, 1>) { return gen(); }
    
      namespace symbols
      {
        using analog_literals::o;
        using analog_literals::I;
        using analog_literals::L;
      }
    
      namespace shapes
      {
        using analog_literals::line;
        using analog_literals::rectangle;
        using analog_literals::cuboid;
      }
    
    }
    

    Was haltet ihr davon?



  • 👍



  • 😃 👍


  • Mod

    Interessante Idee. Schade dass gcc noch keine nutzerdefinierten Literale hat, dann könnte man daraus möglicherweise etwas nützliches bauen. In der jetzigen Form sind das ja keine Konstanten.





  • Jeremey Friesner schrieb:

    Copy paste ?

    http://hostilefork.com/2009/08/29/tweakinganalog-literals-humor/

    Nein, der Quelltext ist natürlich alleine von mir verfasst - wir sind wohl zufällig auf die gleiche Lösung des gleichen Problems gekommen. Ist auch nicht großartig außergewöhnlich - für ein bestimmtes Problem gibt es eben zwar viele Lösungen, aber nur wenige gute, und diese haben wir eben beide gefunden.



  • Sehr krank! Aber genial. 😮



  • camper schrieb:

    Schade dass gcc noch keine nutzerdefinierten Literale hat, dann könnte man daraus möglicherweise etwas nützliches bauen. In der jetzigen Form sind das ja keine Konstanten.

    Müsste sich doch auch mit constexpr hinbekommen lassen dass das "echte" Konstanten werden. Oder übersehe ich da jetzt was?
    Abgesehen davon dass ich es für total plem halte. Lustig, aber plem. 🤡



  • analog_literals schrieb:

    für ein bestimmtes Problem gibt es eben zwar viele Lösungen, aber nur wenige gute, und diese haben wir eben beide gefunden.

    Na wenn du das sagst 🙄 Ich bin mir nur noch nicht sicher, welches Problem du damit überhaupt lösen wolltest.



  • 😮 😮 😮 😮 😮 😮 😮 😮



  • Finde ich schwach 👎.

    Hier ist natürlich auf den ersten Blick ersichtlich, welcher Quader welches Volumen hat. Ist ja super intuitiv im Vergleich zu "42". Aber was ist, wenn ich den Code an jemanden schicke, der keinen monospaced font eingestellt hat? soll der dann etwas Zeichen zählen, um zu sehen, dass ich das richtige Volumen eingegeben hab?

    assert( ( o-------------o
    |L \
    | L \
    | L \
    | o-------------o
    | ! !
    ! ! !
    o | !
    L | !
    L | !
    L| !
    o-------------o ).volume == ( o-------------o
    | !
    ! !
    ! !
    o-------------o ).area * int(I-------------I) );

    seht ihr? klappt gar nicht! 🤡



  • analog_literals schrieb:

    Nein, der Quelltext ist natürlich alleine von mir verfasst - wir sind wohl zufällig auf die gleiche Lösung des gleichen Problems gekommen. Ist auch nicht großartig außergewöhnlich - für ein bestimmtes Problem gibt es eben zwar viele Lösungen, aber nur wenige gute, und diese haben wir eben beide gefunden.

    Da kommt's her: http://weegen.home.xs4all.nl/eelis/analogliterals.xhtml

    Der Code ist 1:1 der Gleiche, die Eigenleistung des OP scheint darin zu bestehen, dem Namen des Headers einen Unterstrich hinzugefügt zu haben.

    Warum er meint, diesen Kram guttenbergisieren zu müssen, ist mir allerdings schleierhaft. Das ging vor ein paar Jahren schon einmal um, und es musste damit gerechnet werden dass 1. sich jemand daran erinnert und 2. es im Google-Zeitalter leicht gefunden werden kann, zumal 3. nicht viel Ruhm damit zu haben ist. Ganz ernst gemeint kann das Ganze ja nicht sein.



  • Ich find das jetzt auch so mäßig hilfreich. Rechtecke und Quader kann ich mir auch selbst noch vorstellen. Für komplexere Objekte, die meine Vorstellungskraft überschreiben, reicht Editor-Code aber bestimmt nicht aus. Nicht zu sprechen von der Tipparbeit, die man dabei hat. Wenn ich Rechteck(10, 5) schreibe, halte ich das für einfacher... Die LOC bläht man natürlich schön auf.

    Übrigens ist es völlig egal, ob OP Urheber ist oder nicht, da er sowieso ein Unreg ist. Wenn jemand anonym postet, ist mir das ziemlich egal... (nichts für ungut, seldon)



  • Leute, ihr nehmt das wohl ein bisschen zu ernst.

    seldon schrieb:

    Warum er meint, diesen Kram guttenbergisieren zu müssen, ist mir allerdings schleierhaft.

    Ich habe analog_literals' zweiten Post jedenfalls ironisch verstanden.

    Eisflamme schrieb:

    Ich find das jetzt auch so mäßig hilfreich.

    🤡



  • Ich und irgendwas ernst nehmen? Pah. 😃

    Ne, hast wohl Recht, ist ne ganz witzige Spielerei.



  • hustbaer schrieb:

    camper schrieb:

    Schade dass gcc noch keine nutzerdefinierten Literale hat, dann könnte man daraus möglicherweise etwas nützliches bauen. In der jetzigen Form sind das ja keine Konstanten.

    Müsste sich doch auch mit constexpr hinbekommen lassen dass das "echte" Konstanten werden. Oder übersehe ich da jetzt was?

    Ich denke, ähnlich Boost Binary müsste das sogar in C (und damit auch jedem C++) als echte Makro-Konstante gehen. Die Syntax wäre dann halt eher

    XXXXX XXXXX XXX
    

    und

    ooooo ooooo ooo
    I             I
    I             I
    I             I
    I             I
    ooooo ooooo ooo
    

    und

    IHHHH HHH HHHH
    IL            L
    I L            L
    I  L            L
    I   LHHHH HHHHH HL
     L  I            I
      L I            I
       LI            I
        LHHHH HHHHH HH
    

    Nicht so schön zum Lösen, dafür aber als Makro gelöst. Wer hat Lust, das zu schreiben?



  • Da kommt's her: http://weegen.home.xs4all.nl/eelis/analogliterals.xhtml

    Oh oh oh was ist da los 😃 😃 😃
    Würd ich sagen , ziemlich erbärmlich 🙄


Anmelden zum Antworten