2015-12-08 04:51:55 +08:00
|
|
|
#pragma once
|
2015-08-30 07:12:46 +08:00
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2016-02-14 00:59:48 +08:00
|
|
|
#include <cassert>
|
2015-08-30 07:12:46 +08:00
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
#include "utils/underlying_cast.hpp"
|
2015-08-31 03:23:48 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
class Null;
|
|
|
|
|
|
|
|
class Property
|
2015-08-30 07:12:46 +08:00
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
public:
|
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
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
// Type | Mask
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
// Null | 0000 0000 0000 0000 0000 0000 0000 0000
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
// Bool | 0000 0000 0000 0000 0000 0000 0000 0001
|
|
|
|
// + True | 0000 0000 0000 0000 0000 0000 0000 0011
|
|
|
|
// + False | 0000 0000 0000 0000 0000 0000 0000 0101
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
// String | 0000 0000 0000 0000 0000 0000 0000 1000
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
// Number | 0000 0000 0000 0000 0000 0000 0001 0000
|
|
|
|
// + Integral | 0000 0000 0000 0000 0000 0000 0011 0000
|
|
|
|
// + Int32 | 0000 0000 0000 0000 0000 0000 0111 0000
|
|
|
|
// + Int64 | 0000 0000 0000 0000 0000 0000 1011 0000
|
|
|
|
// + Floating | 0000 0000 0000 0000 0000 0001 0001 0000
|
|
|
|
// + Float | 0000 0000 0000 0000 0000 0011 0001 0000
|
|
|
|
// + Double | 0000 0000 0000 0000 0000 0101 0001 0000
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
// Array | 0000 0000 0000 0000 0001 0000 0000 0000
|
|
|
|
// -----------+----------------------------------------
|
|
|
|
|
|
|
|
Null = 0x0,
|
|
|
|
Bool = 0x1,
|
|
|
|
True = 0x2 | Bool,
|
|
|
|
False = 0x4 | Bool,
|
|
|
|
|
|
|
|
String = 0x8,
|
|
|
|
|
|
|
|
Number = 0x10,
|
|
|
|
Integral = 0x20 | Number,
|
|
|
|
Int32 = 0x40 | Integral,
|
|
|
|
Int64 = 0x80 | Integral,
|
|
|
|
|
|
|
|
Floating = 0x100 | Number,
|
|
|
|
Float = 0x200 | Floating,
|
|
|
|
Double = 0x400 | Floating,
|
2015-10-14 02:17:45 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
static const Null Null;
|
|
|
|
|
2015-10-14 02:17:45 +08:00
|
|
|
Property(Flags flags) : flags(flags) {}
|
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
// this is giving problems with default constructors in derived classes
|
|
|
|
// Property(const Property&) = delete;
|
|
|
|
// Property(Property&&) = delete;
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
virtual bool operator==(const Property& other) const = 0;
|
|
|
|
|
|
|
|
bool operator!=(const Property& other) const
|
2015-10-14 02:17:45 +08:00
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
return !operator==(other);
|
2015-10-14 02:17:45 +08:00
|
|
|
}
|
2015-08-31 03:23:48 +08:00
|
|
|
|
|
|
|
template <class T>
|
2016-02-14 00:59:48 +08:00
|
|
|
bool is() const
|
2015-08-31 03:23:48 +08:00
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
return underlying_cast(flags) & underlying_cast(T::type);
|
2015-08-31 03:23:48 +08:00
|
|
|
}
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
template <class T>
|
|
|
|
T& as()
|
2015-10-14 02:17:45 +08:00
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
assert(this->is<T>());
|
|
|
|
return *static_cast<T*>(this);
|
2015-10-14 02:17:45 +08:00
|
|
|
}
|
2015-08-30 07:12:46 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
template <class T>
|
|
|
|
const T& as() const
|
|
|
|
{
|
|
|
|
assert(this->is<T>());
|
|
|
|
return *static_cast<const T*>(this);
|
|
|
|
}
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
template <class Handler>
|
|
|
|
void accept(Handler& handler);
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
const Flags flags;
|
2015-10-14 02:17:45 +08:00
|
|
|
};
|
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* struct Int64 : public Property */
|
|
|
|
/* { */
|
|
|
|
/* static constexpr Flags type = Flags::Int64; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* Int64(int64_t value) */
|
|
|
|
/* : Property(Flags::Int64), value(value) {} */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* int64_t value; */
|
|
|
|
/* }; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* struct Float : public Property */
|
|
|
|
/* { */
|
|
|
|
/* static constexpr Flags type = Flags::Float; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* Float(float value) */
|
|
|
|
/* : Property(Flags::Float), value(value) {} */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* float value; */
|
|
|
|
/* }; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* struct Double : public Property */
|
|
|
|
/* { */
|
|
|
|
/* static constexpr Flags type = Flags::Double; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* Double(double value) */
|
|
|
|
/* : Property(Flags::Double), value(value) {} */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
2016-02-14 00:59:48 +08:00
|
|
|
/* double value; */
|
|
|
|
/* }; */
|
2015-10-14 02:17:45 +08:00
|
|
|
|
|
|
|
template <class Handler>
|
|
|
|
void Property::accept(Handler& h)
|
|
|
|
{
|
2016-02-14 00:59:48 +08:00
|
|
|
/* 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
|
|
|
}
|