diff options
Diffstat (limited to 'src/record/SkRecord.h')
-rw-r--r-- | src/record/SkRecord.h | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/record/SkRecord.h b/src/record/SkRecord.h index 068155e47f..6c5177eefb 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: |