• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #ifndef LIBTEXTCLASSIFIER_UTILS_VARIANT_H_
18 #define LIBTEXTCLASSIFIER_UTILS_VARIANT_H_
19 
20 #include <map>
21 #include <string>
22 #include <vector>
23 
24 #include "utils/base/integral_types.h"
25 #include "utils/base/logging.h"
26 #include "utils/strings/stringpiece.h"
27 
28 namespace libtextclassifier3 {
29 
30 // Represents a type-tagged union of different basic types.
31 class Variant {
32  public:
33   enum Type {
34     TYPE_EMPTY = 0,
35     TYPE_INT8_VALUE = 1,
36     TYPE_UINT8_VALUE = 2,
37     TYPE_INT_VALUE = 3,
38     TYPE_UINT_VALUE = 4,
39     TYPE_INT64_VALUE = 5,
40     TYPE_UINT64_VALUE = 6,
41     TYPE_FLOAT_VALUE = 7,
42     TYPE_DOUBLE_VALUE = 8,
43     TYPE_BOOL_VALUE = 9,
44     TYPE_STRING_VALUE = 10,
45     TYPE_STRING_VECTOR_VALUE = 11,
46     TYPE_FLOAT_VECTOR_VALUE = 12,
47     TYPE_INT_VECTOR_VALUE = 13,
48     TYPE_STRING_VARIANT_MAP_VALUE = 14,
49   };
50 
Variant()51   Variant() : type_(TYPE_EMPTY) {}
Variant(const int8_t value)52   explicit Variant(const int8_t value)
53       : type_(TYPE_INT8_VALUE), int8_value_(value) {}
Variant(const uint8_t value)54   explicit Variant(const uint8_t value)
55       : type_(TYPE_UINT8_VALUE), uint8_value_(value) {}
Variant(const int value)56   explicit Variant(const int value)
57       : type_(TYPE_INT_VALUE), int_value_(value) {}
Variant(const uint value)58   explicit Variant(const uint value)
59       : type_(TYPE_UINT_VALUE), uint_value_(value) {}
Variant(const int64 value)60   explicit Variant(const int64 value)
61       : type_(TYPE_INT64_VALUE), long_value_(value) {}
Variant(const uint64 value)62   explicit Variant(const uint64 value)
63       : type_(TYPE_UINT64_VALUE), ulong_value_(value) {}
Variant(const float value)64   explicit Variant(const float value)
65       : type_(TYPE_FLOAT_VALUE), float_value_(value) {}
Variant(const double value)66   explicit Variant(const double value)
67       : type_(TYPE_DOUBLE_VALUE), double_value_(value) {}
Variant(const StringPiece value)68   explicit Variant(const StringPiece value)
69       : type_(TYPE_STRING_VALUE), string_value_(value.ToString()) {}
Variant(const std::string value)70   explicit Variant(const std::string value)
71       : type_(TYPE_STRING_VALUE), string_value_(value) {}
Variant(const char * value)72   explicit Variant(const char* value)
73       : type_(TYPE_STRING_VALUE), string_value_(value) {}
Variant(const bool value)74   explicit Variant(const bool value)
75       : type_(TYPE_BOOL_VALUE), bool_value_(value) {}
Variant(const std::vector<std::string> & value)76   explicit Variant(const std::vector<std::string>& value)
77       : type_(TYPE_STRING_VECTOR_VALUE), string_vector_value_(value) {}
Variant(const std::vector<float> & value)78   explicit Variant(const std::vector<float>& value)
79       : type_(TYPE_FLOAT_VECTOR_VALUE), float_vector_value_(value) {}
Variant(const std::vector<int> & value)80   explicit Variant(const std::vector<int>& value)
81       : type_(TYPE_INT_VECTOR_VALUE), int_vector_value_(value) {}
Variant(const std::map<std::string,Variant> & value)82   explicit Variant(const std::map<std::string, Variant>& value)
83       : type_(TYPE_STRING_VARIANT_MAP_VALUE),
84         string_variant_map_value_(value) {}
85 
86   Variant& operator=(const Variant&) = default;
87 
88   template <class T>
89   struct dependent_false : std::false_type {};
90 
91   template <typename T>
Value()92   T Value() const {
93     static_assert(dependent_false<T>::value, "Not supported.");
94   }
95 
96   template <>
Value()97   int8 Value() const {
98     TC3_CHECK(Has<int8>());
99     return int8_value_;
100   }
101 
102   template <>
Value()103   uint8 Value() const {
104     TC3_CHECK(Has<uint8>());
105     return uint8_value_;
106   }
107 
108   template <>
Value()109   int Value() const {
110     TC3_CHECK(Has<int>());
111     return int_value_;
112   }
113 
114   template <>
Value()115   uint Value() const {
116     TC3_CHECK(Has<uint>());
117     return uint_value_;
118   }
119 
120   template <>
Value()121   int64 Value() const {
122     TC3_CHECK(Has<int64>());
123     return long_value_;
124   }
125 
126   template <>
Value()127   uint64 Value() const {
128     TC3_CHECK(Has<uint64>());
129     return ulong_value_;
130   }
131 
132   template <>
Value()133   float Value() const {
134     TC3_CHECK(Has<float>());
135     return float_value_;
136   }
137 
138   template <>
Value()139   double Value() const {
140     TC3_CHECK(Has<double>());
141     return double_value_;
142   }
143 
144   template <>
Value()145   bool Value() const {
146     TC3_CHECK(Has<bool>());
147     return bool_value_;
148   }
149 
150   template <typename T>
151   const T& ConstRefValue() const;
152 
153   template <>
ConstRefValue()154   const std::string& ConstRefValue() const {
155     TC3_CHECK(Has<std::string>());
156     return string_value_;
157   }
158 
159   template <>
ConstRefValue()160   const std::vector<std::string>& ConstRefValue() const {
161     TC3_CHECK(Has<std::vector<std::string>>());
162     return string_vector_value_;
163   }
164 
165   template <>
ConstRefValue()166   const std::vector<float>& ConstRefValue() const {
167     TC3_CHECK(Has<std::vector<float>>());
168     return float_vector_value_;
169   }
170 
171   template <>
ConstRefValue()172   const std::vector<int>& ConstRefValue() const {
173     TC3_CHECK(Has<std::vector<int>>());
174     return int_vector_value_;
175   }
176 
177   template <>
ConstRefValue()178   const std::map<std::string, Variant>& ConstRefValue() const {
179     TC3_CHECK((Has<std::map<std::string, Variant>>()));
180     return string_variant_map_value_;
181   }
182 
183   template <typename T>
184   bool Has() const;
185 
186   template <>
187   bool Has<int8>() const {
188     return type_ == TYPE_INT8_VALUE;
189   }
190 
191   template <>
192   bool Has<uint8>() const {
193     return type_ == TYPE_UINT8_VALUE;
194   }
195 
196   template <>
197   bool Has<int>() const {
198     return type_ == TYPE_INT_VALUE;
199   }
200 
201   template <>
202   bool Has<uint>() const {
203     return type_ == TYPE_UINT_VALUE;
204   }
205 
206   template <>
207   bool Has<int64>() const {
208     return type_ == TYPE_INT64_VALUE;
209   }
210 
211   template <>
212   bool Has<uint64>() const {
213     return type_ == TYPE_UINT64_VALUE;
214   }
215 
216   template <>
217   bool Has<float>() const {
218     return type_ == TYPE_FLOAT_VALUE;
219   }
220 
221   template <>
222   bool Has<double>() const {
223     return type_ == TYPE_DOUBLE_VALUE;
224   }
225 
226   template <>
227   bool Has<bool>() const {
228     return type_ == TYPE_BOOL_VALUE;
229   }
230 
231   template <>
232   bool Has<std::string>() const {
233     return type_ == TYPE_STRING_VALUE;
234   }
235 
236   template <>
237   bool Has<std::vector<std::string>>() const {
238     return type_ == TYPE_STRING_VECTOR_VALUE;
239   }
240 
241   template <>
242   bool Has<std::vector<float>>() const {
243     return type_ == TYPE_FLOAT_VECTOR_VALUE;
244   }
245 
246   template <>
247   bool Has<std::vector<int>>() const {
248     return type_ == TYPE_INT_VECTOR_VALUE;
249   }
250 
251   template <>
252   bool Has<std::map<std::string, Variant>>() const {
253     return type_ == TYPE_STRING_VARIANT_MAP_VALUE;
254   }
255 
256   // Converts the value of this variant to its string representation, regardless
257   // of the type of the actual value.
258   std::string ToString() const;
259 
GetType()260   Type GetType() const { return type_; }
261 
HasValue()262   bool HasValue() const { return type_ != TYPE_EMPTY; }
263 
264  private:
265   Type type_;
266   union {
267     int8_t int8_value_;
268     uint8_t uint8_value_;
269     int int_value_;
270     uint uint_value_;
271     int64 long_value_;
272     uint64 ulong_value_;
273     float float_value_;
274     double double_value_;
275     bool bool_value_;
276   };
277   std::string string_value_;
278   std::vector<std::string> string_vector_value_;
279   std::vector<float> float_vector_value_;
280   std::vector<int> int_vector_value_;
281   std::map<std::string, Variant> string_variant_map_value_;
282 };
283 
284 // Pretty-printing function for Variant.
285 logging::LoggingStringStream& operator<<(logging::LoggingStringStream& stream,
286                                          const Variant& value);
287 
288 }  // namespace libtextclassifier3
289 
290 #endif  // LIBTEXTCLASSIFIER_UTILS_VARIANT_H_
291