| Index: src/record/SkRecord.h
|
| diff --git a/src/record/SkRecord.h b/src/record/SkRecord.h
|
| index 068155e47fa439d0905f01bb10317adc95a98b02..6c5177eefb6c4464b27c111c42dd4b605a40442d 100644
|
| --- a/src/record/SkRecord.h
|
| +++ b/src/record/SkRecord.h
|
| @@ -33,7 +33,7 @@ public:
|
| ~SkRecord() {
|
| Destroyer destroyer;
|
| for (unsigned i = 0; i < this->count(); i++) {
|
| - this->mutate(i, destroyer);
|
| + this->mutate<void>(i, destroyer);
|
| }
|
| }
|
|
|
| @@ -42,23 +42,24 @@ public:
|
|
|
| // Visit the i-th canvas command with a functor matching this interface:
|
| // template <typename T>
|
| - // void operator()(const T& record) { ... }
|
| + // R operator()(const T& record) { ... }
|
| // This operator() must be defined for at least all SkRecords::*.
|
| - template <typename F>
|
| - void visit(unsigned i, F& f) const {
|
| + template <typename R, typename F>
|
| + R visit(unsigned i, F& f) const {
|
| SkASSERT(i < this->count());
|
| - fRecords[i].visit(fTypes[i], f);
|
| + return fRecords[i].visit<R>(fTypes[i], f);
|
| }
|
|
|
| // Mutate the i-th canvas command with a functor matching this interface:
|
| // template <typename T>
|
| - // void operator()(T* record) { ... }
|
| + // R operator()(T* record) { ... }
|
| // This operator() must be defined for at least all SkRecords::*.
|
| - template <typename F>
|
| - void mutate(unsigned i, F& f) {
|
| + template <typename R, typename F>
|
| + R mutate(unsigned i, F& f) {
|
| SkASSERT(i < this->count());
|
| - fRecords[i].mutate(fTypes[i], f);
|
| + return fRecords[i].mutate<R>(fTypes[i], f);
|
| }
|
| + // TODO: It'd be nice to infer R from F for visit and mutate if we ever get std::result_of.
|
|
|
| // Allocate contiguous space for count Ts, to be freed when the SkRecord is destroyed.
|
| // Here T can be any class, not just those from SkRecords. Throws on failure.
|
| @@ -89,7 +90,7 @@ public:
|
| SkASSERT(i < this->count());
|
|
|
| Destroyer destroyer;
|
| - this->mutate(i, destroyer);
|
| + this->mutate<void>(i, destroyer);
|
|
|
| fTypes[i] = T::kType;
|
| return fRecords[i].set(this->allocCommand<T>());
|
| @@ -191,20 +192,24 @@ private:
|
|
|
| // Visit this record with functor F (see public API above) assuming the record we're
|
| // pointing to has this type.
|
| - template <typename F>
|
| - void visit(Type8 type, F& f) const {
|
| + template <typename R, typename F>
|
| + R visit(Type8 type, F& f) const {
|
| #define CASE(T) case SkRecords::T##_Type: return f(*this->ptr<SkRecords::T>());
|
| switch(type) { SK_RECORD_TYPES(CASE) }
|
| #undef CASE
|
| + SkDEBUGFAIL("Unreachable");
|
| + return R();
|
| }
|
|
|
| // Mutate this record with functor F (see public API above) assuming the record we're
|
| // pointing to has this type.
|
| - template <typename F>
|
| - void mutate(Type8 type, F& f) {
|
| + template <typename R, typename F>
|
| + R mutate(Type8 type, F& f) {
|
| #define CASE(T) case SkRecords::T##_Type: return f(this->ptr<SkRecords::T>());
|
| switch(type) { SK_RECORD_TYPES(CASE) }
|
| #undef CASE
|
| + SkDEBUGFAIL("Unreachable");
|
| + return R();
|
| }
|
|
|
| private:
|
|
|