2015-12-08 04:51:55 +08:00
|
|
|
#pragma once
|
2015-08-30 07:12:46 +08:00
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
#include "utils/underlying_cast.hpp"
|
2015-08-31 03:23:48 +08:00
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
struct Property
|
2015-08-30 07:12:46 +08:00
|
|
|
{
|
|
|
|
using sptr = std::shared_ptr<Property>;
|
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
enum class Flags : unsigned
|
2015-10-12 02:59:27 +08:00
|
|
|
{
|
2015-10-14 02:17:45 +08:00
|
|
|
Bool = 0x2,
|
|
|
|
True = 0x4 | Bool,
|
|
|
|
False = 0x8 | Bool,
|
|
|
|
|
|
|
|
String = 0x10,
|
|
|
|
|
|
|
|
Number = 0x20,
|
|
|
|
Integral = 0x40 | Number,
|
|
|
|
Int32 = 0x80 | Integral,
|
|
|
|
Int64 = 0x100 | Integral,
|
|
|
|
|
|
|
|
Floating = 0x200 | Number,
|
|
|
|
Float = 0x400 | Floating,
|
|
|
|
Double = 0x800 | Floating,
|
|
|
|
|
|
|
|
Array = 0x1000,
|
2015-10-12 02:59:27 +08:00
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
type_mask = 0xFFF
|
|
|
|
};
|
2015-10-12 02:59:27 +08:00
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
Property(Flags flags) : flags(flags) {}
|
|
|
|
|
|
|
|
Property(const Property&) = default;
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
T* is()
|
|
|
|
{
|
|
|
|
return underlying_cast(flags) & T::type;
|
|
|
|
}
|
2015-08-31 03:23:48 +08:00
|
|
|
|
|
|
|
template <class T>
|
|
|
|
T* as()
|
|
|
|
{
|
2015-10-14 02:17:45 +08:00
|
|
|
if(this->is<T>())
|
2015-08-31 03:23:48 +08:00
|
|
|
return static_cast<T*>(this);
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-10-14 02:17:45 +08:00
|
|
|
|
|
|
|
template <class Handler>
|
|
|
|
void accept(Handler& handler);
|
|
|
|
|
|
|
|
Flags flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Bool : public Property
|
2015-08-30 07:12:46 +08:00
|
|
|
{
|
2015-10-14 02:17:45 +08:00
|
|
|
static constexpr Flags type = Flags::Bool;
|
|
|
|
|
|
|
|
Bool(bool value) : Property(value ? Flags::True : Flags::False) {}
|
|
|
|
|
|
|
|
bool value()
|
|
|
|
{
|
|
|
|
unsigned flags = underlying_cast(this->flags);
|
|
|
|
unsigned true_t = underlying_cast(Flags::True);
|
|
|
|
|
|
|
|
return (flags - true_t) == 0;
|
|
|
|
}
|
2015-08-30 07:12:46 +08:00
|
|
|
};
|
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
struct String : public Property
|
|
|
|
{
|
|
|
|
static constexpr Flags type = Flags::String;
|
|
|
|
|
2015-12-14 16:30:32 +08:00
|
|
|
String(const std::string& value)
|
2015-10-14 02:17:45 +08:00
|
|
|
: Property(Flags::String), value(value) {}
|
|
|
|
|
|
|
|
String(std::string&& value)
|
|
|
|
: Property(Flags::String), value(value) {}
|
|
|
|
|
|
|
|
std::string value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Int32 : public Property
|
|
|
|
{
|
|
|
|
static constexpr Flags type = Flags::Int32;
|
|
|
|
|
2015-12-14 16:30:32 +08:00
|
|
|
Int32(int32_t value)
|
2015-10-14 02:17:45 +08:00
|
|
|
: Property(Flags::Int32), value(value) {}
|
|
|
|
|
|
|
|
int32_t value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Int64 : public Property
|
|
|
|
{
|
|
|
|
static constexpr Flags type = Flags::Int64;
|
|
|
|
|
2015-12-14 16:30:32 +08:00
|
|
|
Int64(int64_t value)
|
2015-10-14 02:17:45 +08:00
|
|
|
: Property(Flags::Int64), value(value) {}
|
|
|
|
|
|
|
|
int64_t value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Float : public Property
|
|
|
|
{
|
|
|
|
static constexpr Flags type = Flags::Float;
|
|
|
|
|
2015-12-14 16:30:32 +08:00
|
|
|
Float(float value)
|
2015-10-14 02:17:45 +08:00
|
|
|
: Property(Flags::Float), value(value) {}
|
|
|
|
|
|
|
|
float value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Double : public Property
|
|
|
|
{
|
|
|
|
static constexpr Flags type = Flags::Double;
|
|
|
|
|
2015-12-14 16:30:32 +08:00
|
|
|
Double(double value)
|
2015-10-14 02:17:45 +08:00
|
|
|
: Property(Flags::Double), value(value) {}
|
|
|
|
|
|
|
|
double value;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class Handler>
|
|
|
|
void Property::accept(Handler& h)
|
|
|
|
{
|
|
|
|
switch(flags)
|
|
|
|
{
|
|
|
|
case Flags::True: return h.handle(static_cast<Bool&>(*this));
|
|
|
|
case Flags::False: return h.handle(static_cast<Bool&>(*this));
|
|
|
|
case Flags::String: return h.handle(static_cast<String&>(*this));
|
|
|
|
case Flags::Int32: return h.handle(static_cast<Int32&>(*this));
|
|
|
|
case Flags::Int64: return h.handle(static_cast<Int64&>(*this));
|
|
|
|
case Flags::Float: return h.handle(static_cast<Float&>(*this));
|
|
|
|
case Flags::Double: return h.handle(static_cast<Double&>(*this));
|
|
|
|
default: return;
|
|
|
|
}
|
2015-08-31 03:23:48 +08:00
|
|
|
}
|