1aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin/* 2aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Copyright (C) 2015 The Android Open Source Project 3aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 4aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 5aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * you may not use this file except in compliance with the License. 6aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * You may obtain a copy of the License at 7aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 8aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 9aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 10aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Unless required by applicable law or agreed to in writing, software 11aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 12aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * See the License for the specific language governing permissions and 14aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * limitations under the License. 15aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin */ 16aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 17aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "variant_map.h" 18aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "gtest/gtest.h" 19aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 20aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#define EXPECT_NULL(expected) EXPECT_EQ(reinterpret_cast<const void*>(expected), \ 212cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier static_cast<void*>(nullptr)); 22aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 23aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinnamespace art { 24aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 25aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinnamespace { 26aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin template <typename TValue> 27aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin struct FruitMapKey : VariantMapKey<TValue> { 28aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMapKey() {} 29aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin }; 30aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 31aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin struct FruitMap : VariantMap<FruitMap, FruitMapKey> { 32aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // This 'using' line is necessary to inherit the variadic constructor. 33aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using VariantMap<FruitMap, FruitMapKey>::VariantMap; 34aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 35aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Make the next '4' usages of Key slightly shorter to type. 36aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin template <typename TValue> 37aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using Key = FruitMapKey<TValue>; 38aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 39aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const Key<int> Apple; 40aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const Key<double> Orange; 412798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin static const Key<std::string> Label; 42aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin }; 43aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 44aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin const FruitMap::Key<int> FruitMap::Apple; 45aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin const FruitMap::Key<double> FruitMap::Orange; 462798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin const FruitMap::Key<std::string> FruitMap::Label; 47aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} // namespace 48aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 49aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor MurashkinTEST(VariantMaps, BasicReadWrite) { 50aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fm; 51aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 52aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_NULL(fm.Get(FruitMap::Apple)); 53aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_FALSE(fm.Exists(FruitMap::Apple)); 54aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_NULL(fm.Get(FruitMap::Orange)); 55aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_FALSE(fm.Exists(FruitMap::Orange)); 56aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 57aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fm.Set(FruitMap::Apple, 1); 58aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_NULL(fm.Get(FruitMap::Orange)); 59aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(1, *fm.Get(FruitMap::Apple)); 60aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_TRUE(fm.Exists(FruitMap::Apple)); 61aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 62aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fm.Set(FruitMap::Apple, 5); 63aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_NULL(fm.Get(FruitMap::Orange)); 64aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(5, *fm.Get(FruitMap::Apple)); 65aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_TRUE(fm.Exists(FruitMap::Apple)); 66aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 67aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fm.Set(FruitMap::Orange, 555.0); 68aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(5, *fm.Get(FruitMap::Apple)); 69aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(555.0, *fm.Get(FruitMap::Orange)); 70aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fm.Size()); 71aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 722798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin // Simple remove 73aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fm.Remove(FruitMap::Apple); 74aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_FALSE(fm.Exists(FruitMap::Apple)); 75aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 76aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fm.Clear(); 77aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(0), fm.Size()); 78aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_FALSE(fm.Exists(FruitMap::Orange)); 79aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 80aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 812798da180524dde1f923b4ee964877546bd6bb44Igor MurashkinTEST(VariantMaps, SetPreviousValue) { 822798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin FruitMap fm; 832798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin 842798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin // Indirect remove by setting yourself again 852798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin fm.Set(FruitMap::Label, std::string("hello_world")); 862798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin auto* ptr = fm.Get(FruitMap::Label); 872798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin ASSERT_TRUE(ptr != nullptr); 882798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin *ptr = "foobar"; 892798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin 902798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin // Set the value to the same exact pointer which we got out of the map. 912798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin // This should cleanly 'just work' and not try to delete the value too early. 922798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin fm.Set(FruitMap::Label, *ptr); 932798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin 942798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin auto* new_ptr = fm.Get(FruitMap::Label); 952798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin ASSERT_TRUE(ptr != nullptr); 962798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin EXPECT_EQ(std::string("foobar"), *new_ptr); 972798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin} 982798da180524dde1f923b4ee964877546bd6bb44Igor Murashkin 99aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor MurashkinTEST(VariantMaps, RuleOfFive) { 100aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test empty constructor 101aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmEmpty; 102aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(0), fmEmpty.Size()); 103aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 104aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test empty constructor 105aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmFilled; 106aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fmFilled.Set(FruitMap::Apple, 1); 107aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fmFilled.Set(FruitMap::Orange, 555.0); 108aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmFilled.Size()); 109aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 110aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test copy constructor 111aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmEmptyCopy(fmEmpty); 112aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(0), fmEmptyCopy.Size()); 113aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 114aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test copy constructor 115aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmFilledCopy(fmFilled); 116aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmFilledCopy.Size()); 117aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy.Get(FruitMap::Apple)); 118aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy.Get(FruitMap::Orange)); 119aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 120aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test operator= 121aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmFilledCopy2; 122aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fmFilledCopy2 = fmFilled; 123aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmFilledCopy2.Size()); 124aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy2.Get(FruitMap::Apple)); 125aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy2.Get(FruitMap::Orange)); 126aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 127aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test move constructor 128aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmMoved(std::move(fmFilledCopy)); 129aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(0), fmFilledCopy.Size()); 130aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmMoved.Size()); 131aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved.Get(FruitMap::Apple)); 132aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved.Get(FruitMap::Orange)); 133aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 134aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Test operator= move 135aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmMoved2; 136aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fmMoved2.Set(FruitMap::Apple, 12345); // This value will be clobbered after the move 137aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 138aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin fmMoved2 = std::move(fmFilledCopy2); 139aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(0), fmFilledCopy2.Size()); 140aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmMoved2.Size()); 141aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved2.Get(FruitMap::Apple)); 142aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved2.Get(FruitMap::Orange)); 143aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 144aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 145aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor MurashkinTEST(VariantMaps, VariadicConstructors) { 146aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Variadic constructor, 1 kv/pair 147aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmApple(FruitMap::Apple, 12345); 148aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(1), fmApple.Size()); 149aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(12345, *fmApple.Get(FruitMap::Apple)); 150aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 151aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Variadic constructor, 2 kv/pair 152aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmAppleAndOrange(FruitMap::Apple, 12345, 153aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap::Orange, 100.0); 154aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(2), fmAppleAndOrange.Size()); 155aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(12345, *fmAppleAndOrange.Get(FruitMap::Apple)); 156aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(100.0, *fmAppleAndOrange.Get(FruitMap::Orange)); 157aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 158aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 159aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor MurashkinTEST(VariantMaps, ReleaseOrDefault) { 160aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fmAppleAndOrange(FruitMap::Apple, 12345, 161aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap::Orange, 100.0); 162aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 163aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin int apple = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple); 164aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(12345, apple); 165aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 166aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Releasing will also remove the Apple key. 167aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(1), fmAppleAndOrange.Size()); 168aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 169aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Releasing again yields a default value. 170aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin int apple2 = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple); 171aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(0, apple2); 172aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 173aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 174aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor MurashkinTEST(VariantMaps, GetOrDefault) { 175aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin FruitMap fm(FruitMap::Apple, 12345); 176aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 177aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Apple gives the expected value we set. 178aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin int apple = fm.GetOrDefault(FruitMap::Apple); 179aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(12345, apple); 180aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 181aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Map is still 1. 182aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_EQ(size_t(1), fm.Size()); 183aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 184aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Orange gives back a default value, since it's not in the map. 185aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin double orange = fm.GetOrDefault(FruitMap::Orange); 186aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin EXPECT_DOUBLE_EQ(0.0, orange); 187aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 188aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 189aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} // namespace art 190