// SPDX-License-Identifier: MIT
#pragma once
#include <memory>
namespace fedem
{
namespace fson
{
class Null;
class Boolean;
class Number;
class String;
class Array;
class Object;
// ─────────────────────────────────────────────────────────────────────
// Value
//
// Abstract base of every FSON value (docs/notation/00030-value.rrd):
// string | number | object | array | true | false | null
//
// Polymorphic class hierarchy; instances are owned through
// std::unique_ptr< Value > and duplicated with clone().
// The as<T>() helpers return nullptr when the dynamic type differs,
// so callers can branch without dynamic_cast.
// ─────────────────────────────────────────────────────────────────────
class Value
{
public:
enum class Type
{
Null,
Boolean,
Number,
String,
Array,
Object
};
virtual ~Value( );
virtual Type getType( ) const noexcept = 0;
// Deep copy including all attached comments.
virtual std::unique_ptr< Value > clone( ) const = 0;
bool isNull ( ) const noexcept;
bool isBoolean( ) const noexcept;
bool isNumber ( ) const noexcept;
bool isString ( ) const noexcept;
bool isArray ( ) const noexcept;
bool isObject ( ) const noexcept;
virtual Null* asNull ( ) noexcept;
virtual Null const* asNull ( ) const noexcept;
virtual Boolean* asBoolean( ) noexcept;
virtual Boolean const* asBoolean( ) const noexcept;
virtual Number* asNumber ( ) noexcept;
virtual Number const* asNumber ( ) const noexcept;
virtual String* asString ( ) noexcept;
virtual String const* asString ( ) const noexcept;
virtual Array* asArray ( ) noexcept;
virtual Array const* asArray ( ) const noexcept;
virtual Object* asObject ( ) noexcept;
virtual Object const* asObject ( ) const noexcept;
protected:
Value( ) = default;
private:
Value( Value const& ) = delete;
Value( Value&& ) = delete;
Value& operator=( Value const& ) = delete;
Value& operator=( Value&& ) = delete;
};
inline bool Value::isNull( ) const noexcept
{
return getType( ) == Type::Null;
}
inline bool Value::isBoolean( ) const noexcept
{
return getType( ) == Type::Boolean;
}
inline bool Value::isNumber( ) const noexcept
{
return getType( ) == Type::Number;
}
inline bool Value::isString( ) const noexcept
{
return getType( ) == Type::String;
}
inline bool Value::isArray( ) const noexcept
{
return getType( ) == Type::Array;
}
inline bool Value::isObject( ) const noexcept
{
return getType( ) == Type::Object;
}
} // end namespace fson
} // end namespace fedem