On 7/30/2013 1:17 PM, Boris Zbarsky wrote:
On 7/30/13 11:13 AM, Dave Townsend wrote:
The JS promise implementation came out of a desire to use promises in
add-ons and devtools amongst others. I believe the C++ implementation came
out of the DOM spec. I'm not sure why we need both.

OK. Given that there is also a desire to be able to use the DOM Promises in b2g (see bug 897913), how do people feel about enabling the Promise API in at least chrome globals (and via Xrays), and setting up Promise in things like JS component globals as well? This shouldn't be too difficult to do... Then anyone who wants to use Promises in Chrome code can use the DOM ones.

For what it's worth, I've pondered what it would take to give a "C++-ish" API to promises. It turns out to not be extremely difficult, except for the fact that there are a bajillion ways to represent functions in C++, so the approach really requires std::function to work properly, and even then, template argument deduction fails (this could probably be remedied with more function overloading to get what you need in common cases, or people can suck it up and manually specify the return type for Then). An example implementation, tested with both libstdc++ 4.8 [I'm told std::function exists as far back as 4.5, and it looks like stlport even has it] and MSVC10, is as follows:
#include <functional>
#include <memory>
#include <vector>

/// Returns a promise to return something of type T
template <typename T>
class Promise {
public:
  Promise() : mResolvers(new std::vector<std::function<void(T)>>()) {}
  void Resolve(T aValue) {
    for (auto it = mResolvers->begin(); it != mResolvers->end(); ++it) {
      (*it)(aValue);
    }
  }

  template <typename U>
  Promise<U> Then(const std::function<U(T)> &resolve) {
    Reinvoker<U> x(resolve);
    mResolvers->push_back(x);
    return *x.getPromise();
  }

  template <typename U> class Reinvoker {
    std::shared_ptr<Promise<U>> mResult;
    std::function<U(T)> mCallee;
  public:
    Reinvoker(const std::function<U(T)> callee) :
      mResult(new Promise<U>()),
      mCallee(callee) {}

    std::shared_ptr<Promise<U>> getPromise() { return mResult; }
    void operator()(T x) { mResult->Resolve(mCallee(x)); }
  };
private:
std::shared_ptr<std::vector<std::function<void(T)>>> mResolvers;
};

Given that this kind of thing works, I wonder if it would make sense to use this sort of thing in C++ as well...

--
Joshua Cranmer
Thunderbird and DXR developer
Source code archæologist

_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to