From 99a0fcd8e3bd39a82df84e779719d058276148e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Tomic=CC=8Cevic=CC=81?= <dominik.tomicevic@gmail.com> Date: Sat, 20 Feb 2016 17:53:09 +0100 Subject: [PATCH] finished refactoring properties --- examples/proptest.cpp | 49 ++++++++++++++++ proptest.cpp | 28 --------- storage/model/properties/all.hpp | 27 +++++++++ storage/model/properties/bool.hpp | 10 ++++ storage/model/properties/double.hpp | 13 +++++ storage/model/properties/float.hpp | 7 +++ storage/model/properties/int32.hpp | 34 ++--------- storage/model/properties/int64.hpp | 14 +++++ storage/model/properties/integral.hpp | 11 +++- storage/model/properties/null.hpp | 10 ++++ storage/model/properties/number.hpp | 9 ++- storage/model/properties/properties.hpp | 13 +---- storage/model/properties/property.hpp | 57 +++---------------- storage/model/properties/string.hpp | 10 ++++ .../{ => traversers}/jsonwriter.hpp | 9 ++- storage/model/properties/utils/modulo.hpp | 10 ++++ .../model/properties/utils/unary_negation.hpp | 2 +- utils/crtp.hpp | 5 ++ 18 files changed, 194 insertions(+), 124 deletions(-) create mode 100644 examples/proptest.cpp delete mode 100644 proptest.cpp create mode 100644 storage/model/properties/all.hpp create mode 100644 storage/model/properties/double.hpp create mode 100644 storage/model/properties/int64.hpp rename storage/model/properties/{ => traversers}/jsonwriter.hpp (88%) create mode 100644 storage/model/properties/utils/modulo.hpp diff --git a/examples/proptest.cpp b/examples/proptest.cpp new file mode 100644 index 000000000..a4b531677 --- /dev/null +++ b/examples/proptest.cpp @@ -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; +} + + + diff --git a/proptest.cpp b/proptest.cpp deleted file mode 100644 index 9b1db673a..000000000 --- a/proptest.cpp +++ /dev/null @@ -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; -} diff --git a/storage/model/properties/all.hpp b/storage/model/properties/all.hpp new file mode 100644 index 000000000..9a9eaebdd --- /dev/null +++ b/storage/model/properties/all.hpp @@ -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; + } +} diff --git a/storage/model/properties/bool.hpp b/storage/model/properties/bool.hpp index f27e19ab4..69d68287b 100644 --- a/storage/model/properties/bool.hpp +++ b/storage/model/properties/bool.hpp @@ -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(); + } }; diff --git a/storage/model/properties/double.hpp b/storage/model/properties/double.hpp new file mode 100644 index 000000000..780c2cba0 --- /dev/null +++ b/storage/model/properties/double.hpp @@ -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; +}; + diff --git a/storage/model/properties/float.hpp b/storage/model/properties/float.hpp index 177f92187..64496ba0d 100644 --- a/storage/model/properties/float.hpp +++ b/storage/model/properties/float.hpp @@ -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; }; diff --git a/storage/model/properties/int32.hpp b/storage/model/properties/int32.hpp index 2415e9ccb..ed588b4fd 100644 --- a/storage/model/properties/int32.hpp +++ b/storage/model/properties/int32.hpp @@ -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; }; diff --git a/storage/model/properties/int64.hpp b/storage/model/properties/int64.hpp new file mode 100644 index 000000000..eb699ce06 --- /dev/null +++ b/storage/model/properties/int64.hpp @@ -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; +}; + diff --git a/storage/model/properties/integral.hpp b/storage/model/properties/integral.hpp index dcffa541b..e94bed313 100644 --- a/storage/model/properties/integral.hpp +++ b/storage/model/properties/integral.hpp @@ -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); + } }; diff --git a/storage/model/properties/null.hpp b/storage/model/properties/null.hpp index 7a867a089..c09171ba6 100644 --- a/storage/model/properties/null.hpp +++ b/storage/model/properties/null.hpp @@ -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 diff --git a/storage/model/properties/number.hpp b/storage/model/properties/number.hpp index d4c278b42..41a710487 100644 --- a/storage/model/properties/number.hpp +++ b/storage/model/properties/number.hpp @@ -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()); + } }; diff --git a/storage/model/properties/properties.hpp b/storage/model/properties/properties.hpp index 26d16a282..4452804c9 100644 --- a/storage/model/properties/properties.hpp +++ b/storage/model/properties/properties.hpp @@ -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(); } diff --git a/storage/model/properties/property.hpp b/storage/model/properties/property.hpp index a03e04565..50b5fb6e6 100644 --- a/storage/model/properties/property.hpp +++ b/storage/model/properties/property.hpp @@ -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; */ - /* } */ -} diff --git a/storage/model/properties/string.hpp b/storage/model/properties/string.hpp index 028d10d5e..38e2699b7 100644 --- a/storage/model/properties/string.hpp +++ b/storage/model/properties/string.hpp @@ -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; }; diff --git a/storage/model/properties/jsonwriter.hpp b/storage/model/properties/traversers/jsonwriter.hpp similarity index 88% rename from storage/model/properties/jsonwriter.hpp rename to storage/model/properties/traversers/jsonwriter.hpp index 179b64bf1..b4d03ec23 100644 --- a/storage/model/properties/jsonwriter.hpp +++ b/storage/model/properties/traversers/jsonwriter.hpp @@ -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; }; diff --git a/storage/model/properties/utils/modulo.hpp b/storage/model/properties/utils/modulo.hpp new file mode 100644 index 000000000..6d43d50b1 --- /dev/null +++ b/storage/model/properties/utils/modulo.hpp @@ -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); + } +}; diff --git a/storage/model/properties/utils/unary_negation.hpp b/storage/model/properties/utils/unary_negation.hpp index c324a9cd4..511c1d55a 100644 --- a/storage/model/properties/utils/unary_negation.hpp +++ b/storage/model/properties/utils/unary_negation.hpp @@ -3,7 +3,7 @@ #include "utils/crtp.hpp" template <class Derived> -struct UnaryNegation : Crtp<Derived> +struct UnaryNegation : public Crtp<Derived> { Derived operator-() const { diff --git a/utils/crtp.hpp b/utils/crtp.hpp index 08dda592f..e07ed7426 100644 --- a/utils/crtp.hpp +++ b/utils/crtp.hpp @@ -10,4 +10,9 @@ struct Crtp { return *static_cast<Derived*>(this); } + + const Derived& derived() const + { + return *static_cast<const Derived*>(this); + } };