13a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary/*
23a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary * Copyright 2015 Google Inc.
33a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary *
43a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary * Use of this source code is governed by a BSD-style license that can be
53a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary * found in the LICENSE file.
63a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary */
73a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary#include "Test.h"
8a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungeman#include "SkTemplates.h"
9221524de3be1fc343ad328c5e99562f32b5cad9cbungeman#include <utility>
103a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary
113a6672ae0c95f24f873dca21424e060df9f9c3e5halcanarynamespace {
123a6672ae0c95f24f873dca21424e060df9f9c3e5halcanaryclass Moveable {
133a6672ae0c95f24f873dca21424e060df9f9c3e5halcanarypublic:
143a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary    Moveable() {}
153a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary    Moveable(Moveable&&) {}
163a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary    Moveable& operator=(Moveable&&) { return *this; }
173a6672ae0c95f24f873dca21424e060df9f9c3e5halcanaryprivate:
183a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary    Moveable(const Moveable&);
193a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary    Moveable& operator=(const Moveable&);
203a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary};
21a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungemantemplate <typename T> void deleter(T*) { }
22a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungemantemplate <typename T> struct Deleter {
23a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungeman    void operator()(T* t) { delete static_cast<const Moveable*>(t); }
24a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungeman};
253a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary} // namespace
263a6672ae0c95f24f873dca21424e060df9f9c3e5halcanary
273a6672ae0c95f24f873dca21424e060df9f9c3e5halcanaryDEF_TEST(CPlusPlusEleven_RvalueAndMove, r) {
28221524de3be1fc343ad328c5e99562f32b5cad9cbungeman    Moveable src1; Moveable dst1(std::move(src1));
29221524de3be1fc343ad328c5e99562f32b5cad9cbungeman    Moveable src2, dst2; dst2 = std::move(src2);
30a3434d83cf988f930a73aaca5ba88f6f6fa8f547bungeman}
315c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
325c05d10511610c35f7912d48ede509c7e32e0a3cmtklein#define TOO_BIG "The unique_ptr was bigger than expected."
335c05d10511610c35f7912d48ede509c7e32e0a3cmtklein#define WEIRD_SIZE "The unique_ptr was a different size than expected."
345c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
355c05d10511610c35f7912d48ede509c7e32e0a3cmtkleinDEF_TEST(CPlusPlusEleven_UniquePtr, r) {
365c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    struct SmallUniquePtr {
375c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        Moveable* p;
385c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    };
395c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    struct BigUniquePtr {
405c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        void(*d)(Moveable*);
415c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        Moveable* p;
425c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    };
435c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
445c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    static_assert(sizeof(skstd::unique_ptr<Moveable>) == sizeof(SmallUniquePtr), TOO_BIG);
455c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    static_assert(sizeof(skstd::unique_ptr<Moveable[]>) == sizeof(SmallUniquePtr), TOO_BIG);
465c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
475c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    using proc = void(*)(Moveable*);
485c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    static_assert(sizeof(skstd::unique_ptr<Moveable, proc>) == sizeof(BigUniquePtr), WEIRD_SIZE);
495c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    static_assert(sizeof(skstd::unique_ptr<Moveable[], proc>) == sizeof(BigUniquePtr), WEIRD_SIZE);
505c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
515c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
525c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<Moveable, void(*)(Moveable*)> u(nullptr, deleter<Moveable>);
535c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(BigUniquePtr), WEIRD_SIZE);
545c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
55221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
565c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(BigUniquePtr), WEIRD_SIZE);
575c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
585c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
595c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
605c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<Moveable, void(*)(Moveable*)> u(nullptr, [](Moveable* m){ deleter(m); });
615c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(BigUniquePtr), WEIRD_SIZE);
625c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
63221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
645c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(BigUniquePtr), WEIRD_SIZE);
655c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
665c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
675c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
685c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        auto d = [](Moveable* m){ deleter(m); };
695c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<Moveable, decltype(d)> u(nullptr, d);
705c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(SmallUniquePtr), TOO_BIG);
715c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
72221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
735c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(SmallUniquePtr), TOO_BIG);
745c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
755c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
765c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
775c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<Moveable, Deleter<Moveable>> u(nullptr, Deleter<Moveable>());
785c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(SmallUniquePtr), TOO_BIG);
795c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
80221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
815c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(SmallUniquePtr), TOO_BIG);
825c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
835c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
845c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
855c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<Moveable, Deleter<Moveable>> u(new Moveable(), Deleter<Moveable>());
865c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(SmallUniquePtr), TOO_BIG);
875c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
88221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
895c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(SmallUniquePtr), TOO_BIG);
905c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
915c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
925c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    {
935c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        skstd::unique_ptr<const void, Deleter<const void>> u(new Moveable(), Deleter<const void>());
945c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u) == sizeof(SmallUniquePtr), TOO_BIG);
955c05d10511610c35f7912d48ede509c7e32e0a3cmtklein
96221524de3be1fc343ad328c5e99562f32b5cad9cbungeman        auto u2 = std::move(u);
975c05d10511610c35f7912d48ede509c7e32e0a3cmtklein        static_assert(sizeof(u2) == sizeof(SmallUniquePtr), TOO_BIG);
985c05d10511610c35f7912d48ede509c7e32e0a3cmtklein    }
995c05d10511610c35f7912d48ede509c7e32e0a3cmtklein}
100