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

    +12

    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
    60. 60
    61. 61
    62. 62
    63. 63
    #include <iostream>
    
    namespace dynamic {
    
    template <class T> class scope;
    template <class T> class variable {
    public:
        variable() : initial(0), current(&initial) {}
        variable(const T &val) : initial(val, 0), current(&initial) {}
        operator T() { return current->val; }
        const T & operator = (const T & new_val) {
            return current->val = new_val;
        }
    private:
        struct node {
            node(node *prev) : val(), prev(prev) {}
            node(const T &val, node *prev) : val(val), prev(prev) {}
            T val;
            node *prev;
        };
        node initial;
        node *current;
        friend class scope<T>;
    };
    
    template <class T> class scope {
    public:
        scope(variable<T> &var) : var(var), node(var.current) {
            var.current = &node;
        }
        scope(variable<T> &var, const T &val) : var(var), node(val, var.current) {
            var.current = &node;
        }
        ~scope() {
            var.current = node.prev;
        }
    private:
        variable<T> &var;
        typename variable<T>::node node;
    };
    
    }
    
    
    dynamic::variable<int> x(100500);
    
    void foo() {
        std::cout << x << std::endl;
    }
    
    void bar() {
        dynamic::scope<int> x_(x, 42);
        foo();
        x = 265;
        foo();
    }
    
    int main() {
        foo();
        bar();
        foo();
        return 0;
    }

    Навеяно http://govnokod.ru/12993.

    https://ideone.com/7AA33Q

    Запостил: bormand, 14 Мая 2013

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

    • какая::жуть<однако>()
      Ответить
      • да::ничего::особенного<дело::привычки>()
        Ответить
        • А я уж подумал ты dynamic ограниченный из сишарпа пытаешься реализовать.
          Ответить
    • Неплохо. Правда, я бы назвал по-другому, у меня слово dynamic совсем с другим ассоциируется:
      dynamically_scoped::var
      dynamically_scoped::let
      Ответить
      • Вот были бы еще анонимные переменные... ;)

        А так придется let делать макросом для удобства...
        #define I_HATE_MACRO2(x, y) x ## y
        #define I_HATE_MACRO(x, y) I_HATE_MACRO2(x, y)
        #define let(var, val) dynamic::scope<decltype(var)::type>\
            I_HATE_MACRO(dyn_ ## var, __LINE__) (var, val)
        Ответить
    • Да, эта лучше. При оптимизации не вылетает:))
      Ответить
      • Да и работать должно пошустрее, чем перекапывание мегабайта в поисках строки.
        Ответить
    • поздравляю, вы изобрели стек.
      Ответить
      • Ну да, стек поверх стека ;)

        Но фишка тут в динамической области видимости - изменения переменной в функции bar видно в вызываемой из нее функции foo, но не видно после возврата из bar.
        Ответить
    • У-у-у. Экий крестозлодей.
      Ответить

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