diff options
author | Yuri Gorshenin <y@maps.me> | 2017-06-21 01:07:36 +0300 |
---|---|---|
committer | Yuri Gorshenin <mipt.vi002@gmail.com> | 2017-07-05 16:41:38 +0300 |
commit | 41800988f08780d79efe5db10ddd8e15a060929f (patch) | |
tree | ff2687c229b9eeb6de695e272383788be96302d7 /ugc/types.hpp | |
parent | 56347174828c1982b397a4671b1e9991d209a912 (diff) |
[ugc] Template and macro magic for visitors.
Diffstat (limited to 'ugc/types.hpp')
-rw-r--r-- | ugc/types.hpp | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/ugc/types.hpp b/ugc/types.hpp index 1fffe74d07..32e4e2cd64 100644 --- a/ugc/types.hpp +++ b/ugc/types.hpp @@ -4,7 +4,6 @@ #include "coding/hex.hpp" - #include <chrono> #include <cstdint> #include <memory> @@ -13,6 +12,18 @@ #include <string> #include <vector> +#define DECLARE_VISITOR(...) \ + template <typename Visitor> \ + void Visit(Visitor & visitor) \ + { \ + __VA_ARGS__; \ + } \ + template <typename Visitor> \ + void Visit(Visitor & visitor) const \ + { \ + __VA_ARGS__; \ + } + namespace ugc { using TranslationKey = std::string; @@ -33,11 +44,25 @@ inline std::string DebugPrint(Sentiment const & sentiment) } } +inline uint32_t ToDaysSinceEpoch(Time const & time) +{ + auto const hours = std::chrono::duration_cast<std::chrono::hours>(time.time_since_epoch()); + return static_cast<uint32_t>(hours.count()) / 24; +} + +inline Time FromDaysSinceEpoch(uint32_t days) +{ + auto const hours = std::chrono::hours(days * 24); + return Time(hours); +} + struct RatingRecord { RatingRecord() = default; RatingRecord(TranslationKey const & key, float const value) : m_key(key), m_value(value) {} + DECLARE_VISITOR(visitor(m_key, "key"), visitor.VisitRating(m_value, "value")) + bool operator==(RatingRecord const & rhs) const { return m_key == rhs.m_key && m_value == rhs.m_value; @@ -62,6 +87,8 @@ struct Rating { } + DECLARE_VISITOR(visitor(m_ratings, "ratings"), visitor.VisitRating(m_aggValue, "aggValue")) + bool operator==(Rating const & rhs) const { return m_ratings == rhs.m_ratings && m_aggValue == rhs.m_aggValue; @@ -70,8 +97,8 @@ struct Rating friend std::string DebugPrint(Rating const & rating) { std::ostringstream os; - os << "Rating [ ratings:" << ::DebugPrint(rating.m_ratings) << ", aggValue:" << rating.m_aggValue - << " ]"; + os << "Rating [ ratings:" << ::DebugPrint(rating.m_ratings) + << ", aggValue:" << rating.m_aggValue << " ]"; return os.str(); } @@ -86,8 +113,9 @@ struct UID std::string ToString() const { return NumToHex(m_hi) + NumToHex(m_lo); } - bool operator==(UID const & rhs) const { return m_hi == rhs.m_hi && m_lo == rhs.m_lo; } + DECLARE_VISITOR(visitor(m_hi, "hi"), visitor(m_lo, "lo")); + bool operator==(UID const & rhs) const { return m_hi == rhs.m_hi && m_lo == rhs.m_lo; } friend std::string DebugPrint(UID const & uid) { std::ostringstream os; @@ -104,8 +132,9 @@ struct Author Author() = default; Author(UID const & uid, std::string const & name) : m_uid(uid), m_name(name) {} - bool operator==(Author const & rhs) const { return m_uid == rhs.m_uid && m_name == rhs.m_name; } + DECLARE_VISITOR(visitor(m_uid, "uid"), visitor(m_name, "name")); + bool operator==(Author const & rhs) const { return m_uid == rhs.m_uid && m_name == rhs.m_name; } friend std::string DebugPrint(Author const & author) { std::ostringstream os; @@ -122,8 +151,9 @@ struct Text Text() = default; Text(std::string const & text, uint8_t const lang) : m_text(text), m_lang(lang) {} - bool operator==(Text const & rhs) const { return m_lang == rhs.m_lang && m_text == rhs.m_text; } + DECLARE_VISITOR(visitor(m_lang, "lang"), visitor(m_text, "text")); + bool operator==(Text const & rhs) const { return m_lang == rhs.m_lang && m_text == rhs.m_text; } friend std::string DebugPrint(Text const & text) { std::ostringstream os; @@ -147,24 +177,16 @@ struct Review { } + DECLARE_VISITOR(visitor(m_id, "id"), visitor(m_text, "text"), visitor(m_author, "author"), + visitor.VisitRating(m_rating, "rating"), visitor(m_sentiment, "sentiment"), + visitor(m_time, "time")) + bool operator==(Review const & rhs) const { return m_id == rhs.m_id && m_text == rhs.m_text && m_author == rhs.m_author && m_rating == rhs.m_rating && m_sentiment == rhs.m_sentiment && m_time == rhs.m_time; } - uint32_t DaysSinceEpoch() const - { - auto const hours = std::chrono::duration_cast<std::chrono::hours>(m_time.time_since_epoch()); - return static_cast<uint32_t>(hours.count()) / 24; - } - - void SetDaysSinceEpoch(uint32_t days) - { - auto const hours = std::chrono::hours(days * 24); - m_time = Time(hours); - } - friend std::string DebugPrint(Review const & review) { std::ostringstream os; @@ -174,7 +196,7 @@ struct Review os << "author:" << DebugPrint(review.m_author) << ", "; os << "rating:" << review.m_rating << ", "; os << "sentiment:" << DebugPrint(review.m_sentiment) << ", "; - os << "days since epoch:" << review.DaysSinceEpoch() << " ]"; + os << "days since epoch:" << ToDaysSinceEpoch(review.m_time) << " ]"; return os.str(); } @@ -196,6 +218,8 @@ struct Attribute { } + DECLARE_VISITOR(visitor(m_key, "key"), visitor(m_value, "value")) + bool operator==(Attribute const & rhs) const { return m_key == rhs.m_key && m_value == rhs.m_value; @@ -221,7 +245,11 @@ struct UGC { } - bool operator==(UGC const & rhs) const { + DECLARE_VISITOR(visitor(m_rating, "rating"), visitor(m_reviews, "review"), + visitor(m_attributes, "attributes")) + + bool operator==(UGC const & rhs) const + { return m_rating == rhs.m_rating && m_reviews == rhs.m_reviews && m_attributes == rhs.m_attributes; } @@ -274,3 +302,5 @@ struct UGCUpdate ReviewFeedback m_feedbacks; }; } // namespace ugc + +#undef DECLARE_VISITOR |