1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/no_destructor.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/logging.h"
11 #include "build/build_config.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace base {
15 
16 namespace {
17 
18 struct CheckOnDestroy {
~CheckOnDestroybase::__anon2cf3a6bd0111::CheckOnDestroy19   ~CheckOnDestroy() { CHECK(false); }
20 };
21 
TEST(NoDestructorTest,SkipsDestructors)22 TEST(NoDestructorTest, SkipsDestructors) {
23   NoDestructor<CheckOnDestroy> destructor_should_not_run;
24 }
25 
26 struct CopyOnly {
27   CopyOnly() = default;
28 
29   CopyOnly(const CopyOnly&) = default;
30   CopyOnly& operator=(const CopyOnly&) = default;
31 
32   CopyOnly(CopyOnly&&) = delete;
33   CopyOnly& operator=(CopyOnly&&) = delete;
34 };
35 
36 struct MoveOnly {
37   MoveOnly() = default;
38 
39   MoveOnly(const MoveOnly&) = delete;
40   MoveOnly& operator=(const MoveOnly&) = delete;
41 
42   MoveOnly(MoveOnly&&) = default;
43   MoveOnly& operator=(MoveOnly&&) = default;
44 };
45 
46 struct ForwardingTestStruct {
ForwardingTestStructbase::__anon2cf3a6bd0111::ForwardingTestStruct47   ForwardingTestStruct(const CopyOnly&, MoveOnly&&) {}
48 };
49 
TEST(NoDestructorTest,ForwardsArguments)50 TEST(NoDestructorTest, ForwardsArguments) {
51   CopyOnly copy_only;
52   MoveOnly move_only;
53 
54   static NoDestructor<ForwardingTestStruct> test_forwarding(
55       copy_only, std::move(move_only));
56 }
57 
TEST(NoDestructorTest,Accessors)58 TEST(NoDestructorTest, Accessors) {
59   static NoDestructor<std::string> awesome("awesome");
60 
61   EXPECT_EQ("awesome", *awesome);
62   EXPECT_EQ(0, awesome->compare("awesome"));
63   EXPECT_EQ(0, awesome.get()->compare("awesome"));
64 }
65 
66 // Passing initializer list to a NoDestructor like in this test
67 // is ambiguous in GCC.
68 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84849
69 #if !defined(COMPILER_GCC) && !defined(__clang__)
TEST(NoDestructorTest,InitializerList)70 TEST(NoDestructorTest, InitializerList) {
71   static NoDestructor<std::vector<std::string>> vector({"a", "b", "c"});
72 }
73 #endif
74 }  // namespace
75 
76 }  // namespace base
77