aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pdf
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2018-04-16 12:58:05 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 18:19:10 +0000
commita16e1b6c0066c2ecda4ec31ea9b7e434a4aff2ad (patch)
treef90903642eb4184f493c153f61a91d855c438e71 /src/pdf
parenta19381d211cba5d02b023f8f0930255ef8df3534 (diff)
SkPDF: use std::aligned_storage for typed union
Change-Id: I38e063cf7557aab1cffbaa126aea4dc7142d914c Reviewed-on: https://skia-review.googlesource.com/121583 Commit-Queue: Hal Canary <halcanary@google.com> Reviewed-by: Ben Wagner <bungeman@google.com>
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/SkPDFTypes.cpp18
-rw-r--r--src/pdf/SkPDFTypes.h19
2 files changed, 23 insertions, 14 deletions
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<SkString*>(x); }
-const SkString* pun(const char* x) {
- return reinterpret_cast<const SkString*>(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 <type_traits>
+
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkTHash.h"
@@ -63,6 +64,20 @@ private:
////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class SkStorageFor {
+public:
+ const T& get() const { return *reinterpret_cast<const T*>(&fStore); }
+ T& get() { return *reinterpret_cast<T*>(&fStore); }
+ // Up to caller to keep track of status.
+ template<class... Args> void init(Args&&... args) {
+ new (&this->get()) T(std::forward<Args>(args)...);
+ }
+ void destroy() { this->get().~T(); }
+private:
+ typename std::aligned_storage<sizeof(T), alignof(T)>::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<SkString> fSkString;
SkPDFObject* fObject;
};
enum class Type : char {