From a16e1b6c0066c2ecda4ec31ea9b7e434a4aff2ad Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Mon, 16 Apr 2018 12:58:05 -0400 Subject: SkPDF: use std::aligned_storage for typed union Change-Id: I38e063cf7557aab1cffbaa126aea4dc7142d914c Reviewed-on: https://skia-review.googlesource.com/121583 Commit-Queue: Hal Canary Reviewed-by: Ben Wagner --- src/pdf/SkPDFTypes.cpp | 18 ++++++------------ src/pdf/SkPDFTypes.h | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/pdf') diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp index c1505ea413..3a8120995c 100644 --- a/src/pdf/SkPDFTypes.cpp +++ b/src/pdf/SkPDFTypes.cpp @@ -15,18 +15,13 @@ //////////////////////////////////////////////////////////////////////////////// -SkString* pun(char* x) { return reinterpret_cast(x); } -const SkString* pun(const char* x) { - return reinterpret_cast(x); -} - SkPDFUnion::SkPDFUnion(Type t) : fType(t) {} SkPDFUnion::~SkPDFUnion() { switch (fType) { case Type::kNameSkS: case Type::kStringSkS: - pun(fSkString)->~SkString(); + fSkString.destroy(); return; case Type::kObjRef: case Type::kObject: @@ -59,7 +54,7 @@ SkPDFUnion SkPDFUnion::copy() const { switch (fType) { case Type::kNameSkS: case Type::kStringSkS: - new (pun(u.fSkString)) SkString(*pun(fSkString)); + u.fSkString.init(fSkString.get()); return u; case Type::kObjRef: case Type::kObject: @@ -140,11 +135,10 @@ void SkPDFUnion::emitObject(SkWStream* stream, return; case Type::kNameSkS: stream->writeText("/"); - write_name_escaped(stream, pun(fSkString)->c_str()); + write_name_escaped(stream, fSkString.get().c_str()); return; case Type::kStringSkS: - SkPDFUtils::WriteString(stream, pun(fSkString)->c_str(), - pun(fSkString)->size()); + SkPDFUtils::WriteString(stream, fSkString.get().c_str(), fSkString.get().size()); return; case Type::kObjRef: stream->writeDecAsText(objNumMap.getObjectNumber(fObject)); @@ -221,13 +215,13 @@ SkPDFUnion SkPDFUnion::String(const char* value) { SkPDFUnion SkPDFUnion::Name(const SkString& s) { SkPDFUnion u(Type::kNameSkS); - new (pun(u.fSkString)) SkString(s); + u.fSkString.init(s); return u; } SkPDFUnion SkPDFUnion::String(const SkString& s) { SkPDFUnion u(Type::kStringSkS); - new (pun(u.fSkString)) SkString(s); + u.fSkString.init(s); return u; } diff --git a/src/pdf/SkPDFTypes.h b/src/pdf/SkPDFTypes.h index c393376abb..10fe125aa6 100644 --- a/src/pdf/SkPDFTypes.h +++ b/src/pdf/SkPDFTypes.h @@ -5,10 +5,11 @@ * found in the LICENSE file. */ - #ifndef SkPDFTypes_DEFINED #define SkPDFTypes_DEFINED +#include + #include "SkRefCnt.h" #include "SkScalar.h" #include "SkTHash.h" @@ -63,6 +64,20 @@ private: //////////////////////////////////////////////////////////////////////////////// +template +class SkStorageFor { +public: + const T& get() const { return *reinterpret_cast(&fStore); } + T& get() { return *reinterpret_cast(&fStore); } + // Up to caller to keep track of status. + template void init(Args&&... args) { + new (&this->get()) T(std::forward(args)...); + } + void destroy() { this->get().~T(); } +private: + typename std::aligned_storage::type fStore; +}; + /** A SkPDFUnion is a non-virtualized implementation of the non-compound, non-specialized PDF Object types: Name, String, @@ -129,7 +144,7 @@ private: bool fBoolValue; SkScalar fScalarValue; const char* fStaticString; - char fSkString[sizeof(SkString)]; + SkStorageFor fSkString; SkPDFObject* fObject; }; enum class Type : char { -- cgit v1.2.3