Repository: microsoft/terminal
File: src/inc/til/winrt.h (C/C++)

Code before:
        void operator()(const winrt::event_token& token) { _handlers.remove(token); }
        template<typename... Arg>
        void raise(Arg const&... args)
        {
            _handlers(args...);
        }
        winrt::event<winrt::Windows::Foundation::TypedEventHandler<SenderT, ArgsT>> _handlers;
    };

    template<typename SenderT, typename ArgsT>
    struct forwarded_typed_event
    {
        forwarded_typed_event<SenderT, ArgsT>() = delete;
        forwarded_typed_event<SenderT, ArgsT>(typed_event<SenderT, ArgsT>& other) :
            _origin{ other } {}
        forwarded_typed_event<SenderT, ArgsT>(forwarded_typed_event<SenderT, ArgsT>& other) :
            _origin{ other._origin } {}

        winrt::event_token operator()(const winrt::Windows::Foundation::TypedEventHandler<SenderT, ArgsT>& handler) { return _origin(handler); }
        void operator()(const winrt::event_token& token) { _origin(token); }
        template<typename... Arg>
        void raise(Arg const&... args)
        {
            _origin.raise(args...);
        }
        typed_event<SenderT, ArgsT>& _origin;
    };
#endif
#ifdef WINRT_Windows_UI_Xaml_DataH

    using property_changed_event = event<winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler>;

    // This  unfortunately doesn't seem feasible. It's gonna just result in more
    // macros, which no one wants.
    //
    // Explanation can be found in the operator() below.
    /*
        template<typename T>
        struct observable_property
        {
            observable_property<T>(property_changed_event e) :
                _event{ e } {};
            observable_property<T>(property_changed_event e, T defaultValue) :
                _event{ e },
                _value{ defaultValue } {}

            T operator()()
            {
                return _value;
            }
            void operator()(const T& value)

Review comment (suggestion):
Since this will make `forwarded_event` unmoveable, but also not very safe (since references are identical to plain pointers), I'm not sure whether this class can be used as is. `FORWARDED_TYPED_EVENT` doesn't have this problem, since it has no additional storage requirements and uses safe wrapped pointers. I think we should just replace `FORWARDED_TYPED_EVENT` with an X macro, since it's only used in a single place anyways. It can also be vastly simplified now, by using `const auto&` for all parameters, instead of specifying them one by one manually.

(Same for `forward_event`.)

Code after:
        {
            _handlers(std::forward<decltype(args)>(args)...);
        }
        winrt::event<winrt::Windows::Foundation::TypedEventHandler<SenderT, ArgsT>> _handlers;
    };
#endif
#ifdef WINRT_Windows_UI_Xaml_DataH

    using property_changed_event = event<winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler>;

    // Making a til::observable_property unfortunately doesn't seem feasible.
    // It's gonna just result in more macros, which no one wants.
    //
    // 1. We don't know who the sender is, or would require `this` to always be
    //    the first parameter to one of these observable_property's.
    //
    // 2. We don't know what our own name is. We need to actually raise an event
    //    with the name of the variable as the parameter. Only way to do that is
    //    with something  like
    //
    //        til::observable<int> Foo(this, L"Foo", 42)
    //
    //    which then kinda implies the creation of:
    //
    //        #define OBSERVABLE(type, name, ...) til::observable_property<type> name{ this, L## #name, this.PropertyChanged, __VA_ARGS__ };
    //
    //     Which is just silly

#endif
}