diff options
| -rw-r--r-- | include/tag_compound.h | 31 | ||||
| -rw-r--r-- | include/value.h | 29 | ||||
| -rw-r--r-- | src/tag_compound.cpp | 15 |
3 files changed, 58 insertions, 17 deletions
diff --git a/include/tag_compound.h b/include/tag_compound.h index 3750e8a557..8d627fca67 100644 --- a/include/tag_compound.h +++ b/include/tag_compound.h @@ -58,12 +58,33 @@ public: /** * @brief Accesses a tag by key * - * If the key exists, returns a value to the corresponding tag. - * Else, a new uninitalized entry is created under this key. + * Returns a value to the tag with the specified key, or throws an + * exception if it does not exist. + * @throw std::out_of_range if given key does not exist + * @todo Make it create a new entry rather than throwing an exception */ value& operator[](const std::string& key); /** + * @brief Inserts or assigns a tag + * + * If the given key already exists, assigns the tag to it. + * Otherwise, it is inserted under the given key. + * @return true if the key did not exist + */ + bool put(const std::string& key, std::unique_ptr<tag>&& t); + + /** + * @brief Constructs and assigns or inserts a tag into the compound + * + * Constructs a new tag of type @c T with the given args and inserts + * or assigns it to the given key. + * @return true if the key did not exist + */ + template<class T, class... Args> + bool emplace(const std::string& key, Args&&... args); + + /** * @brief Erases a tag from the compound * @return true if a tag was erased */ @@ -94,6 +115,12 @@ private: bool equals(const tag& rhs) const override; }; +template<class T, class... Args> +bool tag_compound::emplace(const std::string& key, Args&&... args) +{ + return put(key, new T(std::forward<Args>(args)...)); +} + } #endif // TAG_COMPOUND_H_INCLUDED diff --git a/include/value.h b/include/value.h index d55acf3c80..21e945625a 100644 --- a/include/value.h +++ b/include/value.h @@ -34,15 +34,15 @@ class tag_list; /** * @brief Contains an NBT value of fixed type * - * A wrapper class that can contain a tag of an arbitrary but fixed type. - * Casting or assigning incompatible types will throw an exception. - * It can also refer to an uninitialized value (e.g. when using tag_compound::operator[] - * with a non-existant key). + * A wrapper class that contains a dynamically allocated tag of a fixed type. + * Casting or assigning incompatible types will throw a exceptions. */ class value { public: explicit value() {} + explicit value(std::unique_ptr<tag>&& t); + explicit value(tag&& t); //Movable but not (implicitly) copyable value(const value&) = delete; @@ -50,9 +50,10 @@ public: value& operator=(const value&) = delete; value& operator=(value&&) = default; - //value& operator=(std::unique_ptr<tag>&& ptr); + value& operator=(std::unique_ptr<tag>&& t); + value& operator=(tag&& t); - //Assignment + //Assignment of primitives and string /** * @brief Assigns the given value to the tag if the type matches * @throw std::bad_cast if the value is not convertible to the tag type @@ -65,8 +66,6 @@ public: value& operator=(float val); value& operator=(double val); value& operator=(const std::string& str); - value& operator=(tag_compound&& comp); - value& operator=(tag_list&& list); //Conversion to tag operator tag&(); @@ -78,13 +77,13 @@ public: * @throw std::bad_cast if the tag type is not convertible to the desired * type via a widening conversion */ - explicit operator int8_t() const; - explicit operator int16_t() const; - explicit operator int32_t() const; - explicit operator int64_t() const; - explicit operator float() const; - explicit operator double() const; - explicit operator const std::string&() const; + operator int8_t() const; + operator int16_t() const; + operator int32_t() const; + operator int64_t() const; + operator float() const; + operator double() const; + operator const std::string&() const; /** * @brief In case of a tag_compound, accesses a tag by key with bounds checking diff --git a/src/tag_compound.cpp b/src/tag_compound.cpp index af0d685826..5e9d81aaf7 100644 --- a/src/tag_compound.cpp +++ b/src/tag_compound.cpp @@ -37,6 +37,21 @@ value& tag_compound::operator[](const std::string& key) return tags[key]; } +bool tag_compound::put(const std::string& key, std::unique_ptr<tag>&& t) +{ + auto it = tags.find(key); + if(it != tags.end()) + { + it->second = std::move(t); + return false; + } + else + { + tags.emplace(key, value(std::move(t))); + return true; + } +} + bool tag_compound::erase(const std::string& key) { return tags.erase(key) != 0; |
