finished refactoring properties

This commit is contained in:
Dominik Tomičević 2016-02-20 17:53:09 +01:00
parent c40758363c
commit 99a0fcd8e3
18 changed files with 194 additions and 124 deletions

49
examples/proptest.cpp Normal file
View File

@ -0,0 +1,49 @@
#include <iostream>
#include "storage/model/properties/properties.hpp"
#include "storage/model/properties/property.hpp"
#include "storage/model/properties/traversers/jsonwriter.hpp"
using std::endl;
using std::cout;
int main(void)
{
Properties props;
props.set<Bool>("awesome", true);
props.set<Bool>("lame", false);
props.set<Int32>("age", 32);
// integral
Int32 a = 12;
Int32 b = 24;
Int32 c = b;
Property& d = b;
cout << "a = " << a << "; b = " << b << endl;
cout << (a > b) << (a < b) << (a == b) << (a != b) << endl;
cout << "b == d" << " -> " << (b == d) << endl;
Float x = 3.14;
Float y = 6.28;
Float z = x * 3.28 / y + a * b + 3;
cout << x << endl;
cout << z << endl;
props.set<Float>("pi", z);
StringBuffer buffer;
JsonWriter<StringBuffer> writer(buffer);
props.accept(writer);
cout << buffer.str() << endl;
return 0;
}

View File

@ -1,28 +0,0 @@
#include <iostream>
#include "storage/model/properties/properties.hpp"
#include "storage/model/properties/property.hpp"
int main(void)
{
StringBuffer buffer;
auto handler = JsonWriter<StringBuffer>(buffer);
Properties props;
props.emplace<Null>("sadness");
props.emplace<Bool>("awesome", true);
props.emplace<Bool>("lame", false);
props.emplace<Int32>("age", 32);
props.emplace<Int64>("money", 12345678910111213);
props.emplace<String>("name", "caca");
props.emplace<Float>("pi", 3.14159265358979323846264338327950288419716939937510582097);
props.emplace<Double>("pi2", 3.141592653589793238462643383279502884197169399375105820);
props.accept(handler);
handler.finish();
std::cout.precision(25);
std::cout << buffer.str() << std::endl;
return 0;
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "property.hpp"
#include "null.hpp"
#include "bool.hpp"
#include "string.hpp"
#include "int32.hpp"
#include "int64.hpp"
#include "float.hpp"
#include "double.hpp"
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;
}
}

View File

@ -43,5 +43,15 @@ public:
{
return value() == v;
}
std::ostream& print(std::ostream& stream) const override
{
return operator<<(stream, *this);
}
friend std::ostream& operator<<(std::ostream& stream, const Bool& prop)
{
return stream << prop.value();
}
};

View File

@ -0,0 +1,13 @@
#pragma once
#include "floating.hpp"
struct Double : public Floating<Double>
{
static constexpr Flags type = Flags::Double;
Double(double value) : Floating(Flags::Double), value(value) {}
double value;
};

View File

@ -1,12 +1,19 @@
#pragma once
#include "floating.hpp"
#include "double.hpp"
class Float : public Floating<Float>
{
public:
static constexpr Flags type = Flags::Float;
Float(float value) : Floating(Flags::Float), value(value) {}
operator Double() const
{
return Double(value);
}
float value;
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "integral.hpp"
#include "int64.hpp"
class Int32 : public Integral<Int32>
{
@ -9,35 +10,10 @@ public:
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; */
/* } */
operator Int64() const
{
return Int64(value);
}
int32_t value;
};

View File

@ -0,0 +1,14 @@
#pragma once
#include "integral.hpp"
class Int64 : public Integral<Int64>
{
public:
static constexpr Flags type = Flags::Int64;
Int64(int64_t value) : Integral(Flags::Int64), value(value) {}
int64_t value;
};

View File

@ -1,9 +1,18 @@
#pragma once
#include "number.hpp"
#include "floating.hpp"
#include "utils/modulo.hpp"
template <class Derived>
struct Integral : public Number<Derived>
struct Integral : public Number<Derived>, public Modulo<Derived>
{
using Number<Derived>::Number;
template <class T, typename = std::enable_if_t<
std::is_base_of<Floating<T>, T>::value>>
operator T() const
{
return T(this->derived().value);
}
};

View File

@ -29,6 +29,16 @@ public:
return false;
}
friend std::ostream& operator<<(std::ostream& stream, const Null&)
{
return stream << "NULL";
}
std::ostream& print(std::ostream& stream) const override
{
return operator<<(stream, *this);
}
private:
// the constructor for null is private, it can be constructed only as a
// value inside the Property class, Property::Null

View File

@ -1,14 +1,12 @@
#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>
@ -18,7 +16,7 @@ public:
bool operator==(const Property& other) const override
{
return other.is<Derived>() && *this == other.as<Derived>();
return other.is<Derived>() && this->derived() == other.as<Derived>();
}
friend bool operator==(const Derived& lhs, const Derived& rhs)
@ -35,4 +33,9 @@ public:
{
return s << number.value;
}
std::ostream& print(std::ostream& stream) const override
{
return operator<<(stream, this->derived());
}
};

View File

@ -3,10 +3,7 @@
#include <map>
#include "property.hpp"
#include "null.hpp"
#include "bool.hpp"
#include "string.hpp"
#include "int32.hpp"
#include "all.hpp"
class Properties
{
@ -52,15 +49,9 @@ public:
template <class Handler>
void accept(Handler& handler) const
{
bool first = true;
for(auto& kv : props)
{
handler.handle(kv.first, *kv.second, first);
handler.handle(kv.first, *kv.second);
if(first)
first = false;
}
handler.finish();
}

View File

@ -3,6 +3,7 @@
#include <memory>
#include <string>
#include <cassert>
#include <ostream>
#include "utils/underlying_cast.hpp"
@ -61,10 +62,6 @@ public:
Property(Flags flags) : flags(flags) {}
// this is giving problems with default constructors in derived classes
// Property(const Property&) = delete;
// Property(Property&&) = delete;
virtual bool operator==(const Property& other) const = 0;
bool operator!=(const Property& other) const
@ -92,54 +89,16 @@ public:
return *static_cast<const T*>(this);
}
virtual std::ostream& print(std::ostream& stream) const = 0;
friend std::ostream& operator<<(std::ostream& stream, const Property& prop)
{
return prop.print(stream);
}
template <class Handler>
void accept(Handler& handler);
const Flags flags;
};
/* 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; */
/* }; */
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; */
/* } */
}

View File

@ -34,5 +34,15 @@ public:
return value == other;
}
friend std::ostream& operator<<(std::ostream& stream, const String& prop)
{
return stream << prop.value;
}
std::ostream& print(std::ostream& stream) const override
{
return operator<<(stream, *this);
}
std::string value;
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "properties.hpp"
#include "../properties.hpp"
#include "../all.hpp"
template <class Buffer>
struct JsonWriter
@ -11,11 +12,14 @@ public:
buffer << '{';
};
void handle(const std::string& key, Property& value, bool first)
void handle(const std::string& key, Property& value)
{
if(!first)
buffer << ',';
if(first)
first = false;
buffer << '"' << key << "\":";
value.accept(*this);
}
@ -56,6 +60,7 @@ public:
}
private:
bool first {true};
Buffer& buffer;
};

View File

@ -0,0 +1,10 @@
#pragma once
template <class Derived>
struct Modulo
{
friend Derived operator%(const Derived& lhs, const Derived& rhs)
{
return Derived(lhs.value % rhs.value);
}
};

View File

@ -3,7 +3,7 @@
#include "utils/crtp.hpp"
template <class Derived>
struct UnaryNegation : Crtp<Derived>
struct UnaryNegation : public Crtp<Derived>
{
Derived operator-() const
{

View File

@ -10,4 +10,9 @@ struct Crtp
{
return *static_cast<Derived*>(this);
}
const Derived& derived() const
{
return *static_cast<const Derived*>(this);
}
};