Няшная / Говнокод #25202 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
enum crap
{
    shit = 0,
    fuck,
    dick,
    ass,
    turd,
    fart,
};

static char *crap_to_str(int crap)
{
    switch (crap)
    {
        case shit:
        {
            return "shit";
        }
        case fuck:
        {
            return "fuck";
        }
        case dick:
        {
            return "dick";
        }
        case ass:
        {
            return "ass";
        }
        case turd:
        {
            return "turd";
        }
        case fart:
        {
            return "fart";
        }
        default:
        {
            return "!!!UNKNOWN CRAP!!!";
        }
    }
}

Есть ли возможность через какую-нибудь плюсовую метушню с шаблонами, констэспрами и препроцессором нагенерировать подобную хрень из готового определения структуры?

Запостил: j123123 j123123, (Updated )

Комментарии (45) RSS

  • https://stackoverflow.com/questions/240353/ - для сишного препроцессора такая хрень есть, из которой через какую-то там препроцессорную жопу можно и структуры и функцию со switch нагенерить, но мы исходим из предположения, что у нас уже определены готовые структуры, и переделывать это в понос из сишного препроцессора мы не хотим
    Ответить
      • Ещё можно занеймспейсить, но будет та же фигня:
        #include <iostream>
        #include <typeinfo>
        
        enum class crap
        {
            shit = 0,
            fuck,
            dick,
            ass,
            turd,
            fart,
        };
        
        int main() {
            crap x = crap::dick;
            std::cout << typeid(x).name() << std::endl;
            return 0;
        }
        Ответить
  • Поэтому я за Javascript
    const crap = Object.freeze(
    {
        shit: 0,
        fuck: 1,
        dick: 2,
        ass: 3,
        turd: 4,
        fart: 5
    });
    
    const obj_to_str = obj => val => {
      const arr = Object.entries(obj).find(([key, value]) => value === val)
      return arr? arr.shift(): '!!!UNKNOWN CRAP!!!'}
    
    const crap_to_str = obj_to_str(crap)
    
    console.log(crap_to_str(crap.fuck)) // 'fuck'
    console.log(crap_to_str(crap.faggot)) // '!!!UNKNOWN CRAP!!!'
    Ответить
    • Если определить метод toString(), тогда можно будет просто console.log(crap.fuck).
      Ответить
      • Если я правильно понял автора, он хочет выводить коды произвольного enum'a.
        Если я правильно понял тебя, то toString() придется определять для всех enum'ов.
        Ответить
    • Идея такая:
      1. Есть заголовочный файл с енумами.
      2. Инклюдишь его в какой-нибудь файл.
      3. Компилируешь этот файл с отладочной информацией.
      4. Пропускаешь объектный файл через постпроцессор, который вытаскивает отладочные записи для енумов, и генерирует из них функцию или базу данных, переводящую числа в наименования значений.
      5. ?????
      6. Выгода.
      Ответить
  • Тут вполне предостаточно сишного препроцессора:
    #include <stdio.h>
    
    #define CAT_(a, ...) a ## __VA_ARGS__
    #define CAT(...) CAT_(__VA_ARGS__)
    
    #define EAT(...)
    #define EXPAND(...) __VA_ARGS__
    #define IIF(c) CAT(IIF_, c)
    #define IIF_1(...) __VA_ARGS__ EAT
    #define IIF_0(...) EXPAND
    
    #define COMPL(x) CAT(COMPL_, x)
    #define COMPL_1 0
    #define COMPL_0 1
    
    #define CHECK_N(x, n, ...) n
    #define CHECK(...) CHECK_(__VA_ARGS__)
    #define CHECK_(...) CHECK_N(__VA_ARGS__, 0)
    #define PROBE(x) x, 1
    
    #define IS_EMPTY(x) BOOL(CHECK(CAT(IS_EMPTY_, x)()))
    #define IS_EMPTY_()   PROBE(~)
    
    #define NOT(x) CHECK(CAT(NOT_, x))
    #define NOT_0 PROBE(~)
    #define BOOL(x) COMPL(NOT(x))
    
    #define IF(c) IIF(BOOL(c))
    #define UNLESS(c) IF(c)()
    
    #define EMPTY()
    #define DEFER(id) id EMPTY()
    #define OBSTRUCT(id) id DEFER(EMPTY)()
    
    #define  EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
    #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
    #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
    #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
    #define EVAL4(...) EVAL5(EVAL5(EVAL5(EVAL5(__VA_ARGS__))))
    #define EVAL5(...) __VA_ARGS__
    
    #define FOREACH(macro, x, ...) \
      UNLESS(IS_EMPTY(x))( \
        macro(x) \
        OBSTRUCT(FOREACH_INDIRECT)()(macro, __VA_ARGS__) \
      )
    
    #define FOREACH_INDIRECT(...) FOREACH
    
    #define QUOTE(...) QUOTE_(__VA_ARGS__)
    #define QUOTE_(...) #__VA_ARGS__
    
    #define ENUM_ARR_ELEM(x) , QUOTE(x)
    #define ENUM(tag, first, ...) \
        enum tag {first, __VA_ARGS__}; \
        char *CAT(tag, _names)[] = {QUOTE(first)EVAL(FOREACH(ENUM_ARR_ELEM, __VA_ARGS__))}; \
        static char *CAT(tag, _to_str) (int x) \
        { \
            return x > sizeof(CAT(tag, _names)) / sizeof(char*) ? QUOTE(!!!UNKNOWN tag!!!) : CAT(tag, _names)[x]; \
        }
    
    ENUM(crap,
        shit,
        fuck,
        dick,
        ass,
        turd,
        fart
    )
    
    int main()
    {
        puts(crap_to_str(shit));
        puts(crap_to_str(666));
        return 0;
    }
    https://ideone.com/3Ehv01
    Ответить
    • Красиво. Но ведь бывают перечисления с дырками:
      enum crap
      {
          shit = 0,
          fuck,
          dick = 42,
          ass,
          turd = 265,
          fart,
      };

      Как с такими поступать?
      Ответить
  • Насколько я знаю, из готового определения структуры — только какой-нибудь еблей с парсингом определений и генерацией исходников прямо во время конпелирования. Интроспекцию-то не завезли.
    Ответить
    • Можно джава-стайл енумы запилить (указатель на статик вместо числа).
      Ответить
      • Надо их еще суметь сгенерировать из обычных готовых сишных энумов, а это ни в плюсах ни в сишке никак не сделать по-нормальному. Только писать код который читает и парсит код с этими самыми структурами и генерирует функции на основе него. И это при всем том количестве всевозможной хуйни, которую в последнем крестопарашном стандарте добавили стандартизаторы.
        Ответить
  • в джаве и котлине самые охуенные энамы. все остальное поебень на постном масле.
    Ответить
    • В котлине есть sealed классы
      Это такие енумы у которых сосут все остальные енумы
      Ответить
    • В нормальных языках есть алгебраические типы данных. Всё остальное — «поебень на постном масле».
      Ответить
      • В нормальных языках есть абстрактные инструменты(term rewriting system), которыми ты можешь построить любые типы данных. Всё остальное — «поебень на постном масле».

        Abstract reduction system, (abbreviated ARS) is the most general (unidimensional) notion about specifying a set of objects and rules that can be applied to transform them.
        Ответить
  • Как правильно сказал роман это может делать протобуфный тул

    Доречи еще всякие тулы из схем wsdl генерят прокси классы
    Ответить
  • DSL себе напиши, ты же всем это рекомендуешь.
    Желательно описывать всё в Axiom, чтобы гомоиконы и котогенерация.
    Ответить
  • Вот завезут рефлексию -- можно будет. А сейчас -- не нужно!
    Ответить
  • Как вариант:
    namespace detail::crap {
      constexpr auto shitstore = "shit\0fuck\0dick\0ass\0turd\0fart";
    }
    
    enum class crap : std::ptrdiff_t {
      shit = 0,
      fuck = shit + 5,
      dick = fuck + 5,
      ass = dick + 5,
      turd = ass + 4,
      fart = turd + 5,
    };
    
    constexpr auto crap_to_str(crap c) { return &detail::crap::shitstore[static_cast<std::underlying_type_t<crap>>(c)]; }


    https://wandbox.org/permlink/QGryioh963FK4n3c
    Ответить
    • shit = 0,
        fuck = shit + 5,
        dick = fuck + 5,
        ass = dick + 5,
        turd = ass + 4,
        fart = turd + 5,


      О даааа, считать буковки, как настоящие вконтактовские олимпиадные программисты https://govnokod.ru/24447
      Ответить
    • #include <iostream>
      #include <string_view>
      #include <cstdint>
      
      namespace detail::crap {
        constexpr auto shitstore = "shit\0fuck\0dick\0ass\0turd\0fart";
      }
      
      
      std::ptrdiff_t constexpr length(const char* str)
      {
          return *str ? 1 + length(str + 1) : 0;
      }
      
      enum class crap : std::ptrdiff_t {
        shit = 0,
        fuck = shit + length(detail::crap::shitstore + shit) + 1,
        dick = fuck + length(detail::crap::shitstore + fuck) + 1,
        ass = dick + length(detail::crap::shitstore + dick) + 1,
        turd = ass + length(detail::crap::shitstore + ass) + 1,
        fart = turd + length(detail::crap::shitstore + turd) + 1,
      };
      
      constexpr auto crap_to_str(crap c) { return &detail::crap::shitstore[static_cast<std::underlying_type_t<crap>>(c)]; }
      
      int main() {
        const auto c = crap::turd;
        std::cout << "today's crap is: " << crap_to_str(c) << '\n'; 
      }


      Пописал на плюсах - как говна поел. https://wandbox.org/permlink/WnrOCbjzOqYmsyxm
      Ответить
      • Проверим:
        ☑ Неймс-пейсы.
        ☑ Слово «class».
        ☑ Перегруженные опера-торы.
        ☑ Констэкспры.
        ☑ Крестошоблоны.
        ☑ Крестокасты.
        ☑ Вывод типов.

        И всё-таки остаётся ощущение, что чего-то не хватает. Может быть, онанимных замыканий?
        Ответить
        • Приправим немного препроцессором
          #include <iostream>
          #include <string_view>
          
          #define GAY(x) ((x) + length(detail::crap::shitstore + (x)) + 1)
          
          namespace detail::crap {
            constexpr auto shitstore = "shit\0fuck\0dick\0ass\0turd\0fart";
          }
          
          std::ptrdiff_t constexpr length(const char* str)
          {
              return *str ? 1 + length(str + 1) : 0;
          }
          
          enum class crap : std::ptrdiff_t {
            shit = 0,
            fuck = GAY(shit),
            dick = GAY(fuck),
            ass = GAY(dick),
            turd = GAY(ass),
            fart = GAY(turd),
          };
          
          constexpr auto crap_to_str(crap c) { return &detail::crap::shitstore[static_cast<std::underlying_type_t<crap>>(c)]; }
          
          int main() {
            const auto c = crap::turd;
            std::cout << "today's crap is: " << crap_to_str(c) << '\n'; 
          }
          Ответить
  • RTTI:
    {$mode objfpc}
    {$apptype console}
    {$M+}
    
    type
        TRoosters = (GoldenRooster, Junglefowl, FightingCock, Fjalarr, Gullinkambi, GallicRooster, You);
    
    Var
        s: string;
    
    begin
       WriteStr(s, FightingCock);
       Writeln(s)
    end.


    https://ideone.com/wH1KrY

    Именно поэтому я за Фрипаскаль.
    Ответить
    • Пытался реализовать самостоятельно, не применяя вызов WriteStr. Оказывается, RTTI сохраняется только для свойств классов, для скалярных переменных RTTI не записывается. Поэтому для получения массива названий енумов нужно оборачивать свойство в класс:
      {$mode objfpc}
      {$M+}
      
      uses typinfo;
      
      type
          TRoosters = (GoldenRooster, Junglefowl, FightingCock, Fjalarr, Gullinkambi, GallicRooster, You);
      
          TTestPituh = class(TObject)
          private  
              TestField: TRoosters;
          published
              property TestProp: TRoosters read TestField write TestField;
          end;
      
      function GetRoosterName(x: TRoosters): string;
          Var
              O : TTestPituh;
          begin
              O  := TTestPituh.Create;
              GetRoosterName := GetEnumName(GetPropInfo(O,'TestProp')^.PropType, Ord(x));
              O.Destroy
          end;
      
      begin
          Writeln(GetRoosterName(FightingCock))
      end.


      https://ideone.com/FJa8z4
      Ответить
      • Оказывается, инстанс не нужен. И можно даже так:
        {$mode objfpc}
        {$modeswitch typehelpers} 
        {$M+}
        
        uses typinfo;
        
        type
            TRoosters = (GoldenRooster, Junglefowl, FightingCock, Fjalarr, Gullinkambi, GallicRooster, You);
        
            TTestPituh = class(TObject)
            private  
                TestField: TRoosters;
            published
                property TestProp: TRoosters read TestField write TestField;
            end;
        
            TRoostersHelper = type helper for TRoosters
            public
                function GetRoosterName: string;
            end;
         
        function TRoostersHelper.GetRoosterName: string;
            begin
                GetRoosterName := GetEnumName(GetPropInfo(TTestPituh,'TestProp')^.PropType, LongInt(self))
            end;
        
        begin
            Writeln(FightingCock.GetRoosterName)
        end.


        https://ideone.com/irFUNw
        Ответить
        • JS-Style:
          {$mode objfpc}
          {$modeswitch typehelpers} 
          
          type
              TRoosters = (GoldenRooster, Junglefowl, FightingCock, Fjalarr, Gullinkambi, GallicRooster, You);
          
              TRoostersHelper = type helper for TRoosters
              public
                  function toString: string;
              end;
           
          function TRoostersHelper.toString: string;
              begin
                  WriteStr(Result, self)
              end;
          
          begin
              Writeln(FightingCock.toString)
          end.


          https://ideone.com/5Gb8L6
          Ответить
  • * g o a t s e x * g o a t s e x * g o a t s e x *  
     g                                               g  
     o /     \             \            /    \       o  
     a|       |             \          |      |      a  
     t|       `.             |         |       :     t  
     s`        |             |        \|       |     s  
     e \       | /       /  \\\   --__ \\       :    e  
     x  \      \/   _--~~          ~--__| \     |    x  
     *   \      \_-~                    ~-_\    |    *  
     g    \_     \        _.--------.______\|   |    g  
     o      \     \______// _ ___ _ (_(__>  \   |    o  
     a       \   .  C ___)  ______ (_(____>  |  /    a  
     t       /\ |   C ____)/      \ (_____>  |_/     t  
     s      / /\|   C_____)       |  (___>   /  \    s  
     e     |   (   _C_____)\______/  // _/ /     \   e  
     x     |    \  |__   \\_________// (__/       |  x  
     *    | \    \____)   `----   --'             |  *  
     g    |  \_          ___\       /_          _/ | g  
     o   |              /    |     |  \            | o  
     a   |             |    /       \  \           | a  
     t   |          / /    |         |  \           |t  
     s   |         / /      \__/\___/    |          |s  
     e  |         / /        |    |       |         |e  
     x  |          |         |    |       |         |x  
     * g o a t s e x * g o a t s e x * g o a t s e x *
    Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8