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

    +13

    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
    56. 56
    57. 57
    58. 58
    59. 59
    struct read_access_tag {};
    struct write_access_tag {};
    struct read_write_access_tag : read_access_tag, write_access_tag {};
    
    template <
        typename ByteOrder,
        typename ValueType
    >
    std::size_t get_from(const uint8_t *src, ValueType &dst, const read_access_tag&) {
        ByteOrder::decode(src, dst);
        return sizeof(dst);
    }
    
    template <
        typename ByteOrder,
        typename ValueType
    >
    std::size_t put_into(ValueType src, uint8_t *dst, const write_access_tag&) {
        ByteOrder::encode(src, dst);
        return sizeof(src);
    }
    
    // ...
    
    template <
        typename ByteOrder = default_byte_order,
        typename AccessTag = read_write_access_tag
        >
    class basic_buffer {
    public:
        typedef ByteOrder byte_order;
        typedef AccessTag access_tag;
        typedef typename access_traits<access_tag>::value_type value_type;
        typedef typename access_traits<access_tag>::strict_type strict_type;
        typedef typename access_traits<access_tag>::iterator iterator;
        typedef typename access_traits<access_tag>::const_iterator const_iterator;
    
        basic_buffer(iterator begin, iterator end)
            : begin_(begin)
            , end_(end)
            , pos_(begin)
        {}
    
        // ...
    
        template <typename T>
        basic_buffer & put(T value) {
            if (bytes_left() < sizeof(value)) throw Overflow;
            pos_ += put_into<byte_order>(value, pos_, access_tag());
            return *this;
        }
    
        template <typename T>
        basic_buffer & get(T &value) {
            if (bytes_left() < sizeof(value)) throw Overflow;
            pos_ += get_from<byte_order>(pos_, value, access_tag());
            return *this;
        }
    }

    Развитие идей из

    http://govnokod.ru/12465
    Изобретаем права доступа в compile time, чтобы можно было запретить писать в readonly-буфер и читать из writeonly-буфера без дупликации кода. put_into по сути не нужен (запись в readonly_buffer у меня и без этого не скомпилится), существует из соображений симметрии. Полный код здесь
    https://github.com/roman-kashitsyn/encoding-binary

    Запостил: roman-kashitsyn, 28 Апреля 2013

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

    • Рано или поздно каждому хорошему программисту хочется проверять требования во время компиляции.
      Ответить
    • putin_to<byte_order>

      оставайтесь на месте, за вами уже выехали
      Ответить
      • putin<vv>() ? get_out_from<here>() : ! joking();
        Ответить
        • > по сути не нужен
          ---------------------------------------------
          Радиостанция ЭХО МОСКВЫ - ‎27 мин. назад
          Полиция задержала члена координационного совета оппозиции, антифашиста Романа Кашицына. Его обвиняют в участии в массовых беспорядках и применение насилия в отношении представителей власти.
          Читать далее
          Ответить
    • Для вас в C++14 Constraints запилили:
      http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3580.pdf
      Ответить
      • Они бы здесь, конечно, помогли (в частности, выдавать более вменяемые ошибки компиляции, а также помогли бы иде сформировать корректный список методов при дополнении кода), но суть в целом осталась бы довольно близкой.
        Ответить
    • красивый код
      Ответить
    • C++ ставит передо мной новые нетривиальные задачи: как написать тест, убеждающийся, что некоторый код не компилируется? Пока приходит в голову только вызов скрипта в CTest, но это жуткое извращение.
      Ответить
      • if (std::system("g++ -c ...")) ?
        Ответить
        • ещё можно слинковаться с компилятором и пропарсить исходник
          Ответить
      • Не компилируется потому что кривой или потому что до него не достает?
        Ответить

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