1. C++ / Говнокод #11377

    +16

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    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
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    template<typename T1, typename T2, size_t OFFSET = 8>
    struct EnumMult
    {
        template<T1 t1, T2 t2>
        struct Static
        {
            static const size_t V = (t1 << OFFSET) | t2;
        };
    
        static size_t Dynamic(T1 t1, T2 t2)
        {
            return (t1 << OFFSET) | t2;
        }
    };
    
    // example
    #include <iostream>
    
    enum Suit
    {
        SPADES,
        CLUBS,
        DIAMONDS,
        HEARTS
    };
    
    enum Value
    {
        SEVEN,
        EIGHT,
        NINE,
        TEN,
        JACK,
        QUEEN,
        KING,
        ACE
    };
    
    int main()
    {
        typedef EnumMult<Suit, Value> CardMult;
        switch (CardMult::Dynamic(CLUBS, SEVEN))
        {
        case CardMult::Static<SPADES, ACE>::V:
            std::cout << "ACE OF SPADES";
            break;
        case CardMult::Static<CLUBS, SEVEN>::V:
            std::cout << "HOOK";
            break;
        default:
            std::cout << "NOTHING SPECIAL";
        }
        std::cout << std::endl;
        return 0;
    }

    Понадобилось обработать два enum'а конструкцией switch-case, подумал, что было бы круто сделать квадратный свитч-кейс, но пришла и другая идиотская идея: шаблон для декартова умножения двух енумов. Заранее извините, если паттерн известный.

    Запостил: vercetti, 07 Июля 2012

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

    • Умно и красиво, но лучше класс карты сделать.
      Ответить
    • > квадратный свитч-кейс

      switch-case-table
      Ответить
    • 32 варианта? мда
      Ответить
    • > struct Static
      > static size_t Dynamic(T1 t1, T2 t2)

      Ну вы поняли, на какой недостаток крестошаблонов я намекаю и на какой язык, в котором этого недостатка нет.
      Ответить
    • По делу: битор и сдвиг считаются компилятором на ура, и в свичи их пихать можно без шаблона.
      Ответить
    • Кстати в c++11 можно поступить вот так:
      class Card
      {
      public:
          constexpr Card(Suit suit, Value value) : m_suit(suit), m_value(value) {}
          constexpr operator int() const { return m_suit << 8 | m_value; }
          constexpr Suit suit() const { return m_suit; }
          constexpr Value value() const { return m_value; }
          /* еще какие-нибудь методы */
      private:
          Suit m_suit;
          Value m_value;
      };
      
      Card card(CLUBS, SEVEN);
      switch (card)
      {
          case Card(SPADES, ACE):
              std::cout << "ACE OF SPADES";
              break;
          case Card(CLUBS, SEVEN):
              std::cout << "HOOK";
              break;    
          default:
              std::cout << "NOTHING SPECIAL";
          }
      }
      Ответить
      • почти сопоставление с образцом )
        Ответить
        • только написать в 10 раз больше и только для целых воркает, ну и кен нот инто плейсхолдер _
          Ответить
      • Ещё один аргумент в защиту нового стандарта. Спасибо.
        Ответить
      • у нас просто какие-то проблемы с внедрением GCC с поддержкой C++11, поэтому пока без auto и прочих прелестей :)
        Ответить
        • >поэтому пока без auto и прочих прелестей
          qt? ide от qt can not into auto и и прочие прелести
          Ответить
          • > ide от qt can not into auto и и прочие прелести
            Qt Creator 2.5.0: "Improved support of C++11 (nullptr, constexpr, static_assert, noexcept, inline namespaces, auto, lambdas)". А auto, к слову, уже давно подсвечивал.
            Ответить
            • >Improved support of C++11
              >auto
              Научился в вывод типа переменной? Раньше типы для авто переменных не мог подсвечивать.
              А на лямбды ругался, мол непонятная хренотень.
              Ответить
              • > Научился в вывод типа переменной?
                Частично - выводит простые, нешаблонные типы. В шаблонных теряется.

                > А на лямбды ругался, мол непонятная хренотень.
                Как на говно на лямбды уже не смотрит, но аргументы внутри тела подсказать пока не осиливает.
                Ответить
                • Новому стандарту не хватает ортогональности.
                  Есть форич for(:) и одновременно std::for_each. При этом в последнем приходится указывать тип аргумента лямбды, а в первом автовывод. А тот же std::find_if, который используется чуть ли не чаще - лишен своей конструкции с автовыводом.
                  Ответить
                  • батенька, зачем вам такой частый линейный поиск?
                    в любом случае, вместо
                    for (some_long_namespace::some_long_class_name::const_iterator i = some_obj.begin(); i != some_obj.end(); ++i)
                    наконец-то можно будет
                    for (auto i: some_obj)
                    да и в тех случаях, когда нет готовой уже функции, покрывающей тело цикла, любой серьезный for предпочтительней, чем for_each с громоздкой лямбдой внутри
                    ну а в find_if разве нужна какая то дополнительная конструкция?
                    Ответить
                    • >батенька, зачем вам такой частый линейный поиск?
                      Как высокоуровневая замена (HOF) циклу в частых частных случаях.
                      Ответить
                      • я проакцентировал именно на "частом"
                        грешно это
                        Ответить
                        • >грешно это
                          для гарантированно маленьких n - нет
                          грешно втыкать хеш_мап там, где линейный поиск быстрее и эффективнее по памяти
                          Ответить
      • Оверинженеринг?
        http://liveworkspace.org/code/1350bbf8fb613c930e617021901f1850


        constexpr size_t Card(size_t t1, size_t t2, size_t OFFSET = 8)
        {
           return (t1 << OFFSET) | t2;
        }
        ...
        switch (Card(CLUBS, SEVEN))
            {
            case Card(SPADES, ACE):
                std::cout << "ACE OF SPADES";
                break;
            case Card(CLUBS, SEVEN):
                std::cout << "HOOK";
                break;
            default:
                std::cout << "NOTHING SPECIAL";
            }
        Ответить
        • Ну почему сразу оверинжиниринг... Класс Card же не только для свича, но еще и для хранения карт, и для использования в других частях программы (методы suit() и value()).
          Ответить
    • Это не круто :) Круто было бы, если бы ты сделал нумерацию, которой заранее не нужно знать, сколько там будет вариантов по каждому измерению. Т.е. избавился бы от необходимости знать 'OFFSET'.

      Например, реализуй-ка нумерацию типа той, которая используется для доказательства счетности множества рациональных чисел :)
      Ответить
      • Как-то так?
        http://ideone.com/fX4cC
        Ответить
        • Как формулу выводили?
          Ответить
          • Да там ничего сложного. Для начала выписал первые несколько чисел:

            0 2 5 9
            1 4 8
            3 7
            6


            Затем записал формулу для чисел в первой строке - (x*x+3*x)/2. Заметим, что по вертикали к числам первой строки прибавляются x+1, x+2, x+3 и т.п. Поэтому, воспользовавшись формулой для суммы арифметической прогрессии, число, стоящее в ячейке (x, y) можно записать как
            (2*(x+1)+y-1)*y/2 + (x*x+3*x)/2. Что после упрощения превратится в ((x+y)^2+y+3*x)/2 или (x+y)*(x+y+1)/2 + x.
            Ответить
        • Не пойму, в чем суть этой штуки?
          Очень похоже на jpeg zigzag. Но речь же шла о другом.
          Ответить
          • > Не пойму, в чем суть этой штуки?
            "Круто было бы, если бы ты сделал нумерацию, которой заранее не нужно знать, сколько там будет вариантов по каждому измерению ... skipped ... Например, реализуй-ка нумерацию типа той, которая используется для доказательства счетности множества рациональных чисел"
            Разве это не реализация подобной нумерации?
            Ответить
            • >используется для доказательства счетности множества рациональных чисел
              Честно говоря мне непонятен именно пост TheCalligrapher.
              Вопрос: этот зигзаг - основное требование или просто интересный побочный эффект.
              Ответить
              • Зигзаг - первый попавшийся способ нумерации всех целочисленных точек в квадранте, который пришел в мою дурную голову ;) А так - можно было и по спирали обходить и ромбиками...

                Вот только практической пользы тут не так и много. Числа в машинном представлении ограничены ;(
                Ответить
                • Всё равно не пойму. Заполнение непоследовательное - числа в нижнем правом углу квадрата идут с промежутками (есть 180 а 17х - нету).
                  Спираль наверное лучший вариант.
                  Вот еще. Jpeg-зигзаг идет змейкой и потому там гораздо трудней его перемешать правильно, ибо нет такой формулы.
                  Ответить
                  • > Заполнение непоследовательное
                    Заполнение то последовательное, но т.к. мы используем квадрат или прямоугольник (тема началась с того, как занумеровать декартово произведение двух енумов), некоторые числа, не попавшие в него, просто не будут использоваться.

                    > Спираль наверное лучший вариант.
                    Согласен.

                    > Jpeg-зигзаг идет змейкой
                    Да-да... Я его для случая 8х8 то еле-еле реализовал, когда писал велосидекодер jpeg.
                    Ответить
                  • Так 17x просто не попали в область 10x10. Была бы 20x20, они бы попали
                    Ответить
                • > Jpeg-зигзаг идет непрерывной змейкой
                  http://upload.wikimedia.org/wikipedia/commons/thumb/4/43/JPEG_ZigZag.svg/220px-JPEG_ZigZag.svg.png
                  Ответить
      • Или, если немного упростить формулу:
        http://ideone.com/oCPgk
        Ответить
        • Можно соптимизировать и на двойку умножить
          Ответить
          • > Можно соптимизировать и на двойку умножить
            Но тогда метод будет выдавать только четные числа. Или я не так понял вашу идею?
            Ответить
            • Да, только четные. Но я глупость сказал, просто на автомате увидел деление и захотел избавиться, не подумав, что там деление на два, которое считается быстро.
              Ответить
      • И, наконец, с поддержкой знаковых чисел:
        http://ideone.com/0IOHl
        Ответить
        • Вот интересно, если в этом варианте вывести на экран только простые числа, получится как-нибудь интересная геометрия?
          Ответить
        • Вот
          http://ideone.com/5CbfA
          Ответить
          • Назовем это облаком guest'а.
            Ответить
            • Простые числа строятся вдоль линий.
              По аналогии со спиралью улама.
              Ответить
    • Ноги сами пошли к нему, и когда я прилёг рядом, Пашка, словно котёнок, потянулся, повернулся в мою сторону и ткнулся носом мне в грудь. И сразу так захотелось его обнять! Он был такой нежный, такой хорошенький, что не верилось, что тот наглый хам и этот пушистик - один и тот же человек. Вот он открывает глазки и мило улыбается.
      Ответить

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