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