1a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie//===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===// 2a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// 3a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// The LLVM Compiler Infrastructure 4a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// 5a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// This file is distributed under the University of Illinois Open Source 6a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// License. See LICENSE.TXT for details. 7a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// 8a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie//===----------------------------------------------------------------------===// 9a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 10a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie#include "gtest/gtest.h" 11a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie#include "llvm/ADT/Optional.h" 12a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikieusing namespace llvm; 13a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 14a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikienamespace { 15a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 16a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikiestruct NonDefaultConstructible { 17a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie static unsigned CopyConstructions; 18a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie static unsigned Destructions; 19a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie static unsigned CopyAssignments; 20a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie explicit NonDefaultConstructible(int) { 21a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 22a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible(const NonDefaultConstructible&) { 23a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie ++CopyConstructions; 24a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 25a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible &operator=(const NonDefaultConstructible&) { 26a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie ++CopyAssignments; 27a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie return *this; 28a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 29a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie ~NonDefaultConstructible() { 30a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie ++Destructions; 31a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 32a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie static void ResetCounts() { 33a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie CopyConstructions = 0; 34a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Destructions = 0; 35a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie CopyAssignments = 0; 36a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 37a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie}; 38a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 39a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikieunsigned NonDefaultConstructible::CopyConstructions = 0; 40a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikieunsigned NonDefaultConstructible::Destructions = 0; 41a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikieunsigned NonDefaultConstructible::CopyAssignments = 0; 42a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 43a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie// Test fixture 44a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikieclass OptionalTest : public testing::Test { 45a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie}; 46a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 47a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, NonDefaultConstructibleTest) { 48a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> O; 49a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_FALSE(O); 50a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 51a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 52a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, ResetTest) { 53a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 54a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> O(NonDefaultConstructible(3)); 55a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 56a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 57a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 58a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 594318fc5e1e44f355ae117dcac385f1718d971e90David Blaikie O.reset(); 60a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 61a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 62a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 63a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 64a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 65a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, InitializationLeakTest) { 66a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 67a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible>(NonDefaultConstructible(3)); 68a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 69a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 70a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::Destructions); 71a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 72a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 73a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, CopyConstructionTest) { 74a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 75a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie { 76a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); 77a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 78a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 79a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 80a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 81a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> B(A); 82a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 83a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 84a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 85a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 86a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 87a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 88a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 89a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::Destructions); 90a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 91a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 92a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, ConstructingCopyAssignmentTest) { 93a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 94a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie { 95a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); 96a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> B; 97a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 98a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 99a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 100a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 101a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie B = A; 102a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 103a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 104a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 105a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 106a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 107a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 108a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 109a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::Destructions); 110a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 111a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 112a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, CopyingCopyAssignmentTest) { 113a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 114a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie { 115a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); 116a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> B(NonDefaultConstructible(4)); 117a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions); 118a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 119a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::Destructions); 120a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 121a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie B = A; 122a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 123a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments); 124a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 125a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 126a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 127a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 128a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 129a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(2u, NonDefaultConstructible::Destructions); 130a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 131a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 132a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, DeletingCopyAssignmentTest) { 133a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 134a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie { 135a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> A; 136a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> B(NonDefaultConstructible(3)); 137a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); 138a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 139a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 140a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 141a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie B = A; 142a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 143a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 144a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(1u, NonDefaultConstructible::Destructions); 145a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 146a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 147a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 148a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 149a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 150a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 151a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 152a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David BlaikieTEST_F(OptionalTest, NullCopyConstructionTest) { 153a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 154a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie { 155a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> A; 156a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie Optional<NonDefaultConstructible> B; 157a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 158a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 159a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 160a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 161a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie B = A; 162a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 163a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 164a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 165a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie NonDefaultConstructible::ResetCounts(); 166a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie } 167a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); 168a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); 169a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie EXPECT_EQ(0u, NonDefaultConstructible::Destructions); 170a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} 171a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTEST_F(OptionalTest, GetValueOr) { 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Optional<int> A; 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(42, A.getValueOr(42)); 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines A = 5; 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(5, A.getValueOr(42)); 17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct MultiArgConstructor { 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int x, y; 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MultiArgConstructor(int x, int y) : x(x), y(y) {} 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines explicit MultiArgConstructor(int x, bool positive) 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : x(x), y(positive ? x : -x) {} 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 186ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MultiArgConstructor(const MultiArgConstructor &) = delete; 187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MultiArgConstructor(MultiArgConstructor &&) = delete; 188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MultiArgConstructor &operator=(const MultiArgConstructor &) = delete; 189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MultiArgConstructor &operator=(MultiArgConstructor &&) = delete; 19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static unsigned Destructions; 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ~MultiArgConstructor() { 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Destructions; 19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static void ResetCounts() { 19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Destructions = 0; 19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesunsigned MultiArgConstructor::Destructions = 0; 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTEST_F(OptionalTest, Emplace) { 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MultiArgConstructor::ResetCounts(); 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Optional<MultiArgConstructor> A; 20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines A.emplace(1, 2); 20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_TRUE(A.hasValue()); 20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(1, A->x); 20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(2, A->y); 20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(0u, MultiArgConstructor::Destructions); 21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines A.emplace(5, false); 21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_TRUE(A.hasValue()); 21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(5, A->x); 21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(-5, A->y); 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(1u, MultiArgConstructor::Destructions); 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 218485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikiestruct MoveOnly { 219485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie static unsigned MoveConstructions; 220485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie static unsigned Destructions; 221485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie static unsigned MoveAssignments; 222485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie int val; 223485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie explicit MoveOnly(int val) : val(val) { 224485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie } 225485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie MoveOnly(MoveOnly&& other) { 226485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie val = other.val; 227485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie ++MoveConstructions; 228485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie } 229485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie MoveOnly &operator=(MoveOnly&& other) { 230485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie val = other.val; 231485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie ++MoveAssignments; 232485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie return *this; 233485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie } 234485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie ~MoveOnly() { 235485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie ++Destructions; 236485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie } 237485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie static void ResetCounts() { 238485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie MoveConstructions = 0; 239485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie Destructions = 0; 240485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie MoveAssignments = 0; 241485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie } 242485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie}; 243485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie 244485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikieunsigned MoveOnly::MoveConstructions = 0; 245485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikieunsigned MoveOnly::Destructions = 0; 246485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikieunsigned MoveOnly::MoveAssignments = 0; 247485740205bcaa9c348c1675f81e8d1673b7694aaDavid Blaikie 248ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyNull) { 249ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 250ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> O; 251ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveConstructions); 252ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 253ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::Destructions); 254ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 255ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 256ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyConstruction) { 257ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 258ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> O(MoveOnly(3)); 259ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_TRUE((bool)O); 260ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(3, O->val); 261ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::MoveConstructions); 262ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 263ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 264ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 265ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 266ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyMoveConstruction) { 267ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> A(MoveOnly(3)); 268ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 269ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> B(std::move(A)); 270ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_FALSE((bool)A); 271ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_TRUE((bool)B); 272ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(3, B->val); 273ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::MoveConstructions); 274ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 275ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 276ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 277ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 278ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyAssignment) { 279ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 280ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> O; 281ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie O = MoveOnly(3); 282ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_TRUE((bool)O); 283ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(3, O->val); 284ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::MoveConstructions); 285ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 286ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 287ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 288ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 289ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyInitializingAssignment) { 290ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> A(MoveOnly(3)); 291ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> B; 292ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 293ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie B = std::move(A); 294ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_FALSE((bool)A); 295ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_TRUE((bool)B); 296ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(3, B->val); 297ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::MoveConstructions); 298ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 299ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 300ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 301ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 302ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyNullingAssignment) { 303ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> A; 304ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> B(MoveOnly(3)); 305ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 306ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie B = std::move(A); 307ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_FALSE((bool)A); 308ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_FALSE((bool)B); 309ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveConstructions); 310ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveAssignments); 311ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 312ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 313ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 314ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid BlaikieTEST_F(OptionalTest, MoveOnlyAssigningAssignment) { 315ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> A(MoveOnly(3)); 316ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie Optional<MoveOnly> B(MoveOnly(4)); 317ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie MoveOnly::ResetCounts(); 318ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie B = std::move(A); 319ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_FALSE((bool)A); 320ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_TRUE((bool)B); 321ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(3, B->val); 322ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(0u, MoveOnly::MoveConstructions); 323ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::MoveAssignments); 324ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie EXPECT_EQ(1u, MoveOnly::Destructions); 325ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie} 326ea72255f5b0e8d92d5ae9feb5e92605d123888caDavid Blaikie 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct Immovable { 32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static unsigned Constructions; 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static unsigned Destructions; 33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int val; 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines explicit Immovable(int val) : val(val) { 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Constructions; 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ~Immovable() { 33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++Destructions; 33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static void ResetCounts() { 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constructions = 0; 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Destructions = 0; 34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate: 34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // This should disable all move/copy operations. 343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Immovable(Immovable&& other) = delete; 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesunsigned Immovable::Constructions = 0; 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesunsigned Immovable::Destructions = 0; 34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTEST_F(OptionalTest, ImmovableEmplace) { 35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Optional<Immovable> A; 35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Immovable::ResetCounts(); 35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines A.emplace(4); 35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_TRUE((bool)A); 35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(4, A->val); 35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(1u, Immovable::Constructions); 35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(0u, Immovable::Destructions); 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if LLVM_HAS_RVALUE_REFERENCE_THIS 36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTEST_F(OptionalTest, MoveGetValueOr) { 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Optional<MoveOnly> A; 36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MoveOnly::ResetCounts(); 36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val); 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(1u, MoveOnly::MoveConstructions); 36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(0u, MoveOnly::MoveAssignments); 36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(2u, MoveOnly::Destructions); 36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines A = MoveOnly(5); 37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MoveOnly::ResetCounts(); 37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val); 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(1u, MoveOnly::MoveConstructions); 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(0u, MoveOnly::MoveAssignments); 37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(2u, MoveOnly::Destructions); 37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif // LLVM_HAS_RVALUE_REFERENCE_THIS 37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarTEST_F(OptionalTest, NoneComparison) { 381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Optional<int> o; 382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_EQ(o, None); 383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_EQ(None, o); 384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_FALSE(o != None); 385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_FALSE(None != o); 386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar o = 3; 387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_FALSE(o == None); 388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_FALSE(None == o); 389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_TRUE(o != None); 390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EXPECT_TRUE(None != o); 391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 393a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie} // end anonymous namespace 394a28eda7e401f37a2fe42ca9bba96b6e662b60cf0David Blaikie 395