51#ifdef P4C_GTEST_ENABLED 
   52    FRIEND_TEST(Util, Json);
 
   56    enum Kind { String, Number, True, False, Null };
 
   58    JsonValue(
bool b) : tag(b ? Kind::True : Kind::False) {}     
 
   59    JsonValue(big_int v) : tag(Kind::Number), value(v) {}        
 
   60    JsonValue(
int v) : tag(Kind::Number), value(v) {}            
 
   61    JsonValue(
long v) : tag(Kind::Number), value(v) {}           
 
   63    JsonValue(
unsigned v) : tag(Kind::Number), value(v) {}       
 
   64    JsonValue(
unsigned long v) : tag(Kind::Number), value(v) {}  
 
   66    JsonValue(
double v) : tag(Kind::Number), value(v) {}         
 
   67    JsonValue(
float v) : tag(Kind::Number), value(v) {}          
 
   71    JsonValue(
const char *s) : tag(Kind::String), str(s) {}         
 
   72    JsonValue(
const std::string &s) : tag(Kind::String), str(s) {}  
 
   73    void serialize(std::ostream &out) 
const override;
 
   75    bool operator==(
const big_int &v) 
const;
 
   77    template <
typename T, 
typename std::enable_if_t<std::is_
integral_v<T>, 
int> = 0>
 
   78    bool operator==(
const T &v)
 const {
 
   79        return (tag == Kind::Number) && (v == value);
 
   81    bool operator==(
const double &v) 
const;
 
   82    bool operator==(
const float &v) 
const;
 
   83    bool operator==(
const cstring &s) 
const;
 
   86    bool operator==(
const char *s) 
const;
 
   87    bool operator==(
const std::string &s) 
const;
 
   88    bool operator==(
const JsonValue &other) 
const;
 
   90    bool isNumber()
 const { 
return tag == Kind::Number; }
 
   91    bool isBool()
 const { 
return tag == Kind::True || tag == Kind::False; }
 
   92    bool isString()
 const { 
return tag == Kind::String; }
 
   93    bool isNull()
 const { 
return tag == Kind::Null; }
 
   97    big_int getValue() 
const;
 
  104        if (kind == Kind::String || kind == Kind::Number)
 
  105            throw std::logic_error(
"Incorrect constructor called");
 
  109    const big_int value = 0;
 
  110    const cstring str = cstring::empty;