diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 7179c6ec2..e9b831f4e 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -1460,7 +1460,7 @@ void CHillFortWindow::updateGarrisons() for(int i=0; i + class ResourceSet { + private: + std::array container; public: // read resources set from json. Format example: { "gold": 500, "wood":5 } DLL_LINKAGE ResourceSet(const JsonNode & node); @@ -45,8 +47,8 @@ namespace Res #define scalarOperator(OPSIGN) \ ResourceSet& operator OPSIGN ## =(const TResource &rhs) \ { \ - for(auto i = 0; i < size(); i++) \ - at(i) OPSIGN ## = rhs; \ + for(auto i = 0; i < container.size(); i++) \ + container.at(i) OPSIGN ## = rhs; \ \ return *this; \ } @@ -54,8 +56,8 @@ namespace Res #define vectorOperator(OPSIGN) \ ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs) \ { \ - for(int i = 0; i < (int)size(); i++) \ - at(i) OPSIGN ## = rhs[i]; \ + for(auto i = 0; i < container.size(); i++) \ + container.at(i) OPSIGN ## = rhs[i]; \ \ return *this; \ } @@ -85,21 +87,82 @@ namespace Res #undef vectorOperator #undef twoOperands + using const_reference = decltype(container)::const_reference; + using value_type = decltype(container)::value_type; + using const_iterator = decltype(container)::const_iterator; + using iterator = decltype(container)::iterator; + + // Array-like interface + TResource & operator[](Res::ERes index) + { + return operator[](static_cast(index)); + } + + const TResource & operator[](Res::ERes index) const + { + return operator[](static_cast(index)); + } + + TResource & operator[](size_t index) + { + return container[index]; + } + + const TResource & operator[](size_t index) const + { + return container[index]; + } + + bool empty () const + { + for(const auto & res : *this) + if(res) + return false; + + return true; + } + + // C++ range-based for support + auto begin () -> decltype (container.begin()) + { + return container.begin(); + } + + auto end () -> decltype (container.end()) + { + return container.end(); + } + + auto begin () const -> decltype (container.cbegin()) + { + return container.cbegin(); + } + + auto end () const -> decltype (container.cend()) + { + return container.cend(); + } + + auto size () const -> decltype (container.size()) + { + return container.size(); + } + //to be used for calculations of type "how many units of sth can I afford?" int operator/(const ResourceSet &rhs) { int ret = INT_MAX; - for(int i = 0; i < (int)size(); i++) + for(int i = 0; i < container.size(); i++) if(rhs[i]) - vstd::amin(ret, at(i) / rhs[i]); + vstd::amin(ret, container.at(i) / rhs[i]); return ret; } ResourceSet & operator=(const TResource &rhs) { - for(int i = 0; i < (int)size(); i++) - at(i) = rhs; + for(int i = 0; i < container.size(); i++) + container.at(i) = rhs; return *this; } @@ -107,11 +170,16 @@ namespace Res ResourceSet operator-() const { ResourceSet ret; - for(int i = 0; i < (int)size(); i++) - ret[i] = -at(i); + for(int i = 0; i < container.size(); i++) + ret[i] = -container.at(i); return ret; } + bool operator==(const ResourceSet &rhs) const + { + return this->container == rhs.container; + } + // WARNING: comparison operators are used for "can afford" relation: a <= b means that foreach i a[i] <= b[i] // that doesn't work the other way: a > b doesn't mean that a cannot be afforded with b, it's still b can afford a // bool operator<(const ResourceSet &rhs) @@ -125,7 +193,7 @@ namespace Res template void serialize(Handler &h, const int version) { - h & static_cast&>(*this); + h & container; } DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);