From 49ce5a019c5f8e4d862432734a42bc7aa2a18387 Mon Sep 17 00:00:00 2001 From: ljfa-ag Date: Tue, 30 Jun 2015 17:45:50 +0200 Subject: Change interfaces of tag_compound and value once again --- include/tag_compound.h | 31 +++++++++++++++++++++++++++++-- include/value.h | 29 ++++++++++++++--------------- 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,11 +58,32 @@ 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&& 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 + 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 +bool tag_compound::emplace(const std::string& key, Args&&... args) +{ + return put(key, new T(std::forward(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&& 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&& ptr); + value& operator=(std::unique_ptr&& 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&& 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; -- cgit 0.0.5-2-1-g0f52