blob: 827de462491b802b86d032410d04af07cc4edcfd [file] [log] [blame]
Igor Murashkinaaebaa02015-01-26 10:55:53 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "variant_map.h"
18#include "gtest/gtest.h"
19
20#define EXPECT_NULL(expected) EXPECT_EQ(reinterpret_cast<const void*>(expected), \
21 reinterpret_cast<void*>(NULL));
22
23namespace art {
24
25namespace {
26 template <typename TValue>
27 struct FruitMapKey : VariantMapKey<TValue> {
28 FruitMapKey() {}
29 };
30
31 struct FruitMap : VariantMap<FruitMap, FruitMapKey> {
32 // This 'using' line is necessary to inherit the variadic constructor.
33 using VariantMap<FruitMap, FruitMapKey>::VariantMap;
34
35 // Make the next '4' usages of Key slightly shorter to type.
36 template <typename TValue>
37 using Key = FruitMapKey<TValue>;
38
39 static const Key<int> Apple;
40 static const Key<double> Orange;
41 };
42
43 const FruitMap::Key<int> FruitMap::Apple;
44 const FruitMap::Key<double> FruitMap::Orange;
45} // namespace
46
47TEST(VariantMaps, BasicReadWrite) {
48 FruitMap fm;
49
50 EXPECT_NULL(fm.Get(FruitMap::Apple));
51 EXPECT_FALSE(fm.Exists(FruitMap::Apple));
52 EXPECT_NULL(fm.Get(FruitMap::Orange));
53 EXPECT_FALSE(fm.Exists(FruitMap::Orange));
54
55 fm.Set(FruitMap::Apple, 1);
56 EXPECT_NULL(fm.Get(FruitMap::Orange));
57 EXPECT_EQ(1, *fm.Get(FruitMap::Apple));
58 EXPECT_TRUE(fm.Exists(FruitMap::Apple));
59
60 fm.Set(FruitMap::Apple, 5);
61 EXPECT_NULL(fm.Get(FruitMap::Orange));
62 EXPECT_EQ(5, *fm.Get(FruitMap::Apple));
63 EXPECT_TRUE(fm.Exists(FruitMap::Apple));
64
65 fm.Set(FruitMap::Orange, 555.0);
66 EXPECT_EQ(5, *fm.Get(FruitMap::Apple));
67 EXPECT_DOUBLE_EQ(555.0, *fm.Get(FruitMap::Orange));
68 EXPECT_EQ(size_t(2), fm.Size());
69
70 fm.Remove(FruitMap::Apple);
71 EXPECT_FALSE(fm.Exists(FruitMap::Apple));
72
73 fm.Clear();
74 EXPECT_EQ(size_t(0), fm.Size());
75 EXPECT_FALSE(fm.Exists(FruitMap::Orange));
76}
77
78TEST(VariantMaps, RuleOfFive) {
79 // Test empty constructor
80 FruitMap fmEmpty;
81 EXPECT_EQ(size_t(0), fmEmpty.Size());
82
83 // Test empty constructor
84 FruitMap fmFilled;
85 fmFilled.Set(FruitMap::Apple, 1);
86 fmFilled.Set(FruitMap::Orange, 555.0);
87 EXPECT_EQ(size_t(2), fmFilled.Size());
88
89 // Test copy constructor
90 FruitMap fmEmptyCopy(fmEmpty);
91 EXPECT_EQ(size_t(0), fmEmptyCopy.Size());
92
93 // Test copy constructor
94 FruitMap fmFilledCopy(fmFilled);
95 EXPECT_EQ(size_t(2), fmFilledCopy.Size());
96 EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy.Get(FruitMap::Apple));
97 EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy.Get(FruitMap::Orange));
98
99 // Test operator=
100 FruitMap fmFilledCopy2;
101 fmFilledCopy2 = fmFilled;
102 EXPECT_EQ(size_t(2), fmFilledCopy2.Size());
103 EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy2.Get(FruitMap::Apple));
104 EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy2.Get(FruitMap::Orange));
105
106 // Test move constructor
107 FruitMap fmMoved(std::move(fmFilledCopy));
108 EXPECT_EQ(size_t(0), fmFilledCopy.Size());
109 EXPECT_EQ(size_t(2), fmMoved.Size());
110 EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved.Get(FruitMap::Apple));
111 EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved.Get(FruitMap::Orange));
112
113 // Test operator= move
114 FruitMap fmMoved2;
115 fmMoved2.Set(FruitMap::Apple, 12345); // This value will be clobbered after the move
116
117 fmMoved2 = std::move(fmFilledCopy2);
118 EXPECT_EQ(size_t(0), fmFilledCopy2.Size());
119 EXPECT_EQ(size_t(2), fmMoved2.Size());
120 EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved2.Get(FruitMap::Apple));
121 EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved2.Get(FruitMap::Orange));
122}
123
124TEST(VariantMaps, VariadicConstructors) {
125 // Variadic constructor, 1 kv/pair
126 FruitMap fmApple(FruitMap::Apple, 12345);
127 EXPECT_EQ(size_t(1), fmApple.Size());
128 EXPECT_EQ(12345, *fmApple.Get(FruitMap::Apple));
129
130 // Variadic constructor, 2 kv/pair
131 FruitMap fmAppleAndOrange(FruitMap::Apple, 12345,
132 FruitMap::Orange, 100.0);
133 EXPECT_EQ(size_t(2), fmAppleAndOrange.Size());
134 EXPECT_EQ(12345, *fmAppleAndOrange.Get(FruitMap::Apple));
135 EXPECT_DOUBLE_EQ(100.0, *fmAppleAndOrange.Get(FruitMap::Orange));
136}
137
138TEST(VariantMaps, ReleaseOrDefault) {
139 FruitMap fmAppleAndOrange(FruitMap::Apple, 12345,
140 FruitMap::Orange, 100.0);
141
142 int apple = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple);
143 EXPECT_EQ(12345, apple);
144
145 // Releasing will also remove the Apple key.
146 EXPECT_EQ(size_t(1), fmAppleAndOrange.Size());
147
148 // Releasing again yields a default value.
149 int apple2 = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple);
150 EXPECT_EQ(0, apple2);
151}
152
153TEST(VariantMaps, GetOrDefault) {
154 FruitMap fm(FruitMap::Apple, 12345);
155
156 // Apple gives the expected value we set.
157 int apple = fm.GetOrDefault(FruitMap::Apple);
158 EXPECT_EQ(12345, apple);
159
160 // Map is still 1.
161 EXPECT_EQ(size_t(1), fm.Size());
162
163 // Orange gives back a default value, since it's not in the map.
164 double orange = fm.GetOrDefault(FruitMap::Orange);
165 EXPECT_DOUBLE_EQ(0.0, orange);
166}
167
168} // namespace art