Partially added comparators and math operations to numerical properties
This commit is contained in:
parent
694d3363d6
commit
c40758363c
47
storage/model/properties/bool.hpp
Normal file
47
storage/model/properties/bool.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "property.hpp"
|
||||
|
||||
class Bool : public Property
|
||||
{
|
||||
public:
|
||||
static constexpr Flags type = Flags::Bool;
|
||||
|
||||
Bool(bool value) : Property(value ? Flags::True : Flags::False) {}
|
||||
|
||||
Bool(const Bool& other) = default;
|
||||
|
||||
bool value() const
|
||||
{
|
||||
// true when the subtraction of True from flags is equal to zero
|
||||
|
||||
// True 0000 0000 0000 0000 0000 0000 0000 0011
|
||||
// False 0000 0000 0000 0000 0000 0000 0000 0101
|
||||
//
|
||||
// True - True = 0
|
||||
// False - True != 0
|
||||
|
||||
return (underlying_cast(flags) - underlying_cast(Flags::True)) == 0;
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
|
||||
bool operator==(const Property& other) const override
|
||||
{
|
||||
return other.is<Bool>() && operator==(other.as<Bool>());
|
||||
}
|
||||
|
||||
bool operator==(const Bool& other) const
|
||||
{
|
||||
return other.flags == flags;
|
||||
}
|
||||
|
||||
bool operator==(bool v) const
|
||||
{
|
||||
return value() == v;
|
||||
}
|
||||
};
|
||||
|
12
storage/model/properties/float.hpp
Normal file
12
storage/model/properties/float.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "floating.hpp"
|
||||
|
||||
class Float : public Floating<Float>
|
||||
{
|
||||
static constexpr Flags type = Flags::Float;
|
||||
|
||||
Float(float value) : Floating(Flags::Float), value(value) {}
|
||||
|
||||
float value;
|
||||
};
|
9
storage/model/properties/floating.hpp
Normal file
9
storage/model/properties/floating.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "number.hpp"
|
||||
|
||||
template <class Derived>
|
||||
struct Floating : public Number<Derived>
|
||||
{
|
||||
using Number<Derived>::Number;
|
||||
};
|
44
storage/model/properties/int32.hpp
Normal file
44
storage/model/properties/int32.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "integral.hpp"
|
||||
|
||||
class Int32 : public Integral<Int32>
|
||||
{
|
||||
public:
|
||||
static constexpr Flags type = Flags::Int32;
|
||||
|
||||
Int32(int32_t value) : Integral(Flags::Int32), value(value) {}
|
||||
|
||||
/* friend constexpr bool operator==(const Int32& lhs, const Int32& rhs) */
|
||||
/* { */
|
||||
/* return lhs.value == rhs.value; */
|
||||
/* } */
|
||||
|
||||
/* friend constexpr bool operator<(const Int32& lhs, const Int32& rhs) */
|
||||
/* { */
|
||||
/* return lhs.value < rhs.value; */
|
||||
/* } */
|
||||
|
||||
/* friend constexpr bool operator==(const Int32& lhs, int32_t rhs) */
|
||||
/* { */
|
||||
/* return lhs.value == rhs; */
|
||||
/* } */
|
||||
|
||||
/* friend constexpr bool operator<(const Int32& lhs, int32_t rhs) */
|
||||
/* { */
|
||||
/* return lhs.value < rhs; */
|
||||
/* } */
|
||||
|
||||
/* friend constexpr bool operator==(int32_t lhs, const Int32& rhs) */
|
||||
/* { */
|
||||
/* return lhs == rhs.value; */
|
||||
/* } */
|
||||
|
||||
/* friend constexpr bool operator<(int32_t lhs, const Int32& rhs) */
|
||||
/* { */
|
||||
/* return lhs < rhs.value; */
|
||||
/* } */
|
||||
|
||||
int32_t value;
|
||||
};
|
||||
|
9
storage/model/properties/integral.hpp
Normal file
9
storage/model/properties/integral.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "number.hpp"
|
||||
|
||||
template <class Derived>
|
||||
struct Integral : public Number<Derived>
|
||||
{
|
||||
using Number<Derived>::Number;
|
||||
};
|
41
storage/model/properties/null.hpp
Normal file
41
storage/model/properties/null.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "property.hpp"
|
||||
|
||||
class Null : public Property
|
||||
{
|
||||
public:
|
||||
friend class Property;
|
||||
|
||||
static constexpr Flags type = Flags::Null;
|
||||
|
||||
Null(const Null&) = delete;
|
||||
Null(Null&&) = delete;
|
||||
|
||||
Null operator=(const Null&) = delete;
|
||||
|
||||
bool operator==(const Property& other) const override
|
||||
{
|
||||
return other.is<Null>();
|
||||
}
|
||||
|
||||
bool operator==(const Null&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
explicit operator bool()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// the constructor for null is private, it can be constructed only as a
|
||||
// value inside the Property class, Property::Null
|
||||
Null() : Property(Flags::Null) {}
|
||||
};
|
||||
|
||||
// Null is a const singleton declared in class Property
|
||||
// it can be used as a type by using Null or as a value by using Property::Null
|
||||
const Null Property::Null;
|
||||
|
38
storage/model/properties/number.hpp
Normal file
38
storage/model/properties/number.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "property.hpp"
|
||||
#include "utils/crtp.hpp"
|
||||
#include "utils/total_ordering.hpp"
|
||||
#include "utils/unary_negation.hpp"
|
||||
#include "utils/math_operations.hpp"
|
||||
|
||||
template <class Derived>
|
||||
class Number : public Property,
|
||||
public Crtp<Derived>,
|
||||
public TotalOrdering<Derived>,
|
||||
public MathOperations<Derived>,
|
||||
public UnaryNegation<Derived>
|
||||
{
|
||||
public:
|
||||
using Property::Property;
|
||||
|
||||
bool operator==(const Property& other) const override
|
||||
{
|
||||
return other.is<Derived>() && *this == other.as<Derived>();
|
||||
}
|
||||
|
||||
friend bool operator==(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
friend bool operator<(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const Derived& number)
|
||||
{
|
||||
return s << number.value;
|
||||
}
|
||||
};
|
@ -3,16 +3,24 @@
|
||||
#include <map>
|
||||
|
||||
#include "property.hpp"
|
||||
#include "null.hpp"
|
||||
#include "bool.hpp"
|
||||
#include "string.hpp"
|
||||
#include "int32.hpp"
|
||||
|
||||
class Properties
|
||||
{
|
||||
using props_t = std::map<std::string, Property::sptr>;
|
||||
|
||||
public:
|
||||
const Property* at(const std::string& key) const
|
||||
const Property& at(const std::string& key) const
|
||||
{
|
||||
auto it = props.find(key);
|
||||
return it == props.end() ? nullptr : it->second.get();
|
||||
|
||||
if(it == props.end())
|
||||
return Property::Null;
|
||||
|
||||
return *it->second.get();
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
@ -59,3 +67,10 @@ public:
|
||||
private:
|
||||
props_t props;
|
||||
};
|
||||
|
||||
template<>
|
||||
void Properties::set<Null>(const std::string& key)
|
||||
{
|
||||
clear(key);
|
||||
}
|
||||
|
||||
|
@ -2,140 +2,144 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "utils/underlying_cast.hpp"
|
||||
|
||||
struct Property
|
||||
class Null;
|
||||
|
||||
class Property
|
||||
{
|
||||
public:
|
||||
using sptr = std::shared_ptr<Property>;
|
||||
|
||||
enum class Flags : unsigned
|
||||
{
|
||||
Bool = 0x2,
|
||||
True = 0x4 | Bool,
|
||||
False = 0x8 | Bool,
|
||||
// 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
|
||||
// -----------+----------------------------------------
|
||||
|
||||
String = 0x10,
|
||||
Null = 0x0,
|
||||
Bool = 0x1,
|
||||
True = 0x2 | Bool,
|
||||
False = 0x4 | Bool,
|
||||
|
||||
Number = 0x20,
|
||||
Integral = 0x40 | Number,
|
||||
Int32 = 0x80 | Integral,
|
||||
Int64 = 0x100 | Integral,
|
||||
String = 0x8,
|
||||
|
||||
Floating = 0x200 | Number,
|
||||
Float = 0x400 | Floating,
|
||||
Double = 0x800 | Floating,
|
||||
Number = 0x10,
|
||||
Integral = 0x20 | Number,
|
||||
Int32 = 0x40 | Integral,
|
||||
Int64 = 0x80 | Integral,
|
||||
|
||||
Floating = 0x100 | Number,
|
||||
Float = 0x200 | Floating,
|
||||
Double = 0x400 | Floating,
|
||||
|
||||
Array = 0x1000,
|
||||
|
||||
type_mask = 0xFFF
|
||||
};
|
||||
|
||||
static const Null Null;
|
||||
|
||||
Property(Flags flags) : flags(flags) {}
|
||||
|
||||
Property(const Property&) = default;
|
||||
// this is giving problems with default constructors in derived classes
|
||||
// Property(const Property&) = delete;
|
||||
// Property(Property&&) = delete;
|
||||
|
||||
template <class T>
|
||||
T* is()
|
||||
virtual bool operator==(const Property& other) const = 0;
|
||||
|
||||
bool operator!=(const Property& other) const
|
||||
{
|
||||
return underlying_cast(flags) & T::type;
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* as()
|
||||
bool is() const
|
||||
{
|
||||
if(this->is<T>())
|
||||
return static_cast<T*>(this);
|
||||
return underlying_cast(flags) & underlying_cast(T::type);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
template <class T>
|
||||
T& as()
|
||||
{
|
||||
assert(this->is<T>());
|
||||
return *static_cast<T*>(this);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& as() const
|
||||
{
|
||||
assert(this->is<T>());
|
||||
return *static_cast<const T*>(this);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
void accept(Handler& handler);
|
||||
|
||||
Flags flags;
|
||||
const Flags flags;
|
||||
};
|
||||
|
||||
struct Bool : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::Bool;
|
||||
/* struct Int64 : public Property */
|
||||
/* { */
|
||||
/* static constexpr Flags type = Flags::Int64; */
|
||||
|
||||
Bool(bool value) : Property(value ? Flags::True : Flags::False) {}
|
||||
/* Int64(int64_t value) */
|
||||
/* : Property(Flags::Int64), value(value) {} */
|
||||
|
||||
bool value()
|
||||
{
|
||||
unsigned flags = underlying_cast(this->flags);
|
||||
unsigned true_t = underlying_cast(Flags::True);
|
||||
/* int64_t value; */
|
||||
/* }; */
|
||||
|
||||
return (flags - true_t) == 0;
|
||||
}
|
||||
};
|
||||
/* struct Float : public Property */
|
||||
/* { */
|
||||
/* static constexpr Flags type = Flags::Float; */
|
||||
|
||||
struct String : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::String;
|
||||
/* Float(float value) */
|
||||
/* : Property(Flags::Float), value(value) {} */
|
||||
|
||||
String(const std::string& value)
|
||||
: Property(Flags::String), value(value) {}
|
||||
/* float value; */
|
||||
/* }; */
|
||||
|
||||
String(std::string&& value)
|
||||
: Property(Flags::String), value(value) {}
|
||||
/* struct Double : public Property */
|
||||
/* { */
|
||||
/* static constexpr Flags type = Flags::Double; */
|
||||
|
||||
std::string value;
|
||||
};
|
||||
/* Double(double value) */
|
||||
/* : Property(Flags::Double), value(value) {} */
|
||||
|
||||
struct Int32 : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::Int32;
|
||||
|
||||
Int32(int32_t value)
|
||||
: Property(Flags::Int32), value(value) {}
|
||||
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
struct Int64 : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::Int64;
|
||||
|
||||
Int64(int64_t value)
|
||||
: Property(Flags::Int64), value(value) {}
|
||||
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
struct Float : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::Float;
|
||||
|
||||
Float(float value)
|
||||
: Property(Flags::Float), value(value) {}
|
||||
|
||||
float value;
|
||||
};
|
||||
|
||||
struct Double : public Property
|
||||
{
|
||||
static constexpr Flags type = Flags::Double;
|
||||
|
||||
Double(double value)
|
||||
: Property(Flags::Double), value(value) {}
|
||||
|
||||
double 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;
|
||||
}
|
||||
/* 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; */
|
||||
/* } */
|
||||
}
|
||||
|
38
storage/model/properties/string.hpp
Normal file
38
storage/model/properties/string.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "property.hpp"
|
||||
|
||||
class String : public Property
|
||||
{
|
||||
public:
|
||||
static constexpr Flags type = Flags::String;
|
||||
|
||||
String(const std::string& value) : Property(Flags::String), value(value) {}
|
||||
|
||||
String(std::string&& value) : Property(Flags::String), value(value) {}
|
||||
|
||||
String(const String&) = default;
|
||||
String(String&&) = default;
|
||||
|
||||
operator const std::string&() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
bool operator==(const Property& other) const override
|
||||
{
|
||||
return other.is<String>() && operator==(other.as<String>());
|
||||
}
|
||||
|
||||
bool operator==(const String& other) const
|
||||
{
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
bool operator==(const std::string& other) const
|
||||
{
|
||||
return value == other;
|
||||
}
|
||||
|
||||
std::string value;
|
||||
};
|
25
storage/model/properties/utils/math_operations.hpp
Normal file
25
storage/model/properties/utils/math_operations.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
template <class Derived>
|
||||
struct MathOperations
|
||||
{
|
||||
friend Derived operator+(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return Derived(lhs.value + rhs.value);
|
||||
}
|
||||
|
||||
friend Derived operator-(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return Derived(lhs.value - rhs.value);
|
||||
}
|
||||
|
||||
friend Derived operator*(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return Derived(lhs.value * rhs.value);
|
||||
}
|
||||
|
||||
friend Derived operator/(const Derived& lhs, const Derived& rhs)
|
||||
{
|
||||
return Derived(lhs.value / rhs.value);
|
||||
}
|
||||
};
|
12
storage/model/properties/utils/unary_negation.hpp
Normal file
12
storage/model/properties/utils/unary_negation.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/crtp.hpp"
|
||||
|
||||
template <class Derived>
|
||||
struct UnaryNegation : Crtp<Derived>
|
||||
{
|
||||
Derived operator-() const
|
||||
{
|
||||
return Derived(-this->derived().value);
|
||||
}
|
||||
};
|
45
utils/total_ordering_with.hpp
Normal file
45
utils/total_ordering_with.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
template <class Derived, class T>
|
||||
struct TotalOrderingWith
|
||||
{
|
||||
friend constexpr bool operator!=(const Derived& a, const T& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const Derived& a, const T& b)
|
||||
{
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const Derived& a, const T& b)
|
||||
{
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const Derived& a, const T& b)
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator!=(const T& a, const Derived& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator<=(const T& a, const Derived& b)
|
||||
{
|
||||
return a < b || a == b;
|
||||
}
|
||||
|
||||
friend constexpr bool operator>(const T& a, const Derived& b)
|
||||
{
|
||||
return !(a <= b);
|
||||
}
|
||||
|
||||
friend constexpr bool operator>=(const T& a, const Derived& b)
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user