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