Skip to content

Instantly share code, notes, and snippets.

@p2004a
Last active October 17, 2025 07:28
Show Gist options
  • Select an option

  • Save p2004a/045726d70a490d12ad62 to your computer and use it in GitHub Desktop.

Select an option

Save p2004a/045726d70a490d12ad62 to your computer and use it in GitHub Desktop.

Revisions

  1. p2004a revised this gist Dec 20, 2021. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions defer.cpp
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    // SPDX-FileCopyrightText: 2015 Marek Rusinowski
    // SPDX-License-Identifier: MIT
    #include <memory>
    #include <cstdio>

  2. p2004a created this gist Aug 16, 2015.
    41 changes: 41 additions & 0 deletions defer.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    #include <memory>
    #include <cstdio>

    template<typename F>
    class defer_finalizer {
    F f;
    bool moved;
    public:
    template<typename T>
    defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { }

    defer_finalizer(const defer_finalizer &) = delete;

    defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) {
    other.moved = true;
    }

    ~defer_finalizer() {
    if (!moved) f();
    }
    };

    struct {
    template<typename F>
    defer_finalizer<F> operator<<(F && f) {
    return defer_finalizer<F>(std::forward<F>(f));
    }
    } deferrer;

    #define TOKENPASTE(x, y) x ## y
    #define TOKENPASTE2(x, y) TOKENPASTE(x, y)
    #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&]

    void f() {
    FILE *f = fopen("asdasd", "r");
    defer {
    fclose(f);
    };
    }

    // Compiler optimizes it nicely: http://goo.gl/XAGl6A