diff options
| -rw-r--r-- | include/tag.h | 10 | ||||
| -rw-r--r-- | src/tag.cpp | 48 | ||||
| -rw-r--r-- | src/value.cpp | 19 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | test/test_value.cpp | 38 | ||||
| -rw-r--r-- | test/test_value.h | 36 |
6 files changed, 96 insertions, 58 deletions
diff --git a/include/tag.h b/include/tag.h index 0cb3c82c95..ac3b49fa3a 100644 --- a/include/tag.h +++ b/include/tag.h @@ -123,6 +123,16 @@ public: * @throw std::invalid_argument if the type is not valid (e.g. End or Null) */ static std::unique_ptr<tag> create(tag_type type); + /** + * @brief Constructs a numeric tag of the given type and value + * @throw std::invalid_argument if the type is not numeric + */ + static std::unique_ptr<tag> create(tag_type type, int8_t val); + static std::unique_ptr<tag> create(tag_type type, int16_t val); + static std::unique_ptr<tag> create(tag_type type, int32_t val); + static std::unique_ptr<tag> create(tag_type type, int64_t val); + static std::unique_ptr<tag> create(tag_type type, float val); + static std::unique_ptr<tag> create(tag_type type, double val); friend NBT_EXPORT bool operator==(const tag& lhs, const tag& rhs); friend NBT_EXPORT bool operator!=(const tag& lhs, const tag& rhs); diff --git a/src/tag.cpp b/src/tag.cpp index 0bff2c6440..6175a36293 100644 --- a/src/tag.cpp +++ b/src/tag.cpp @@ -45,6 +45,24 @@ std::unique_ptr<tag> tag::clone() && return std::move(*this).move_clone(); } +namespace +{ + template<typename T> + std::unique_ptr<tag> create_numeric_tag(tag_type type, T val) + { + switch(type) + { + case tag_type::Byte: return make_unique<tag_byte>(static_cast<int8_t>(val)); + case tag_type::Short: return make_unique<tag_short>(static_cast<int16_t>(val)); + case tag_type::Int: return make_unique<tag_int>(static_cast<int32_t>(val)); + case tag_type::Long: return make_unique<tag_long>(static_cast<int64_t>(val)); + case tag_type::Float: return make_unique<tag_float>(static_cast<float>(val)); + case tag_type::Double: return make_unique<tag_double>(static_cast<double>(val)); + default: throw std::invalid_argument("Invalid numeric tag type"); + } + } +} + std::unique_ptr<tag> tag::create(tag_type type) { switch(type) @@ -66,6 +84,36 @@ std::unique_ptr<tag> tag::create(tag_type type) } } +std::unique_ptr<tag> tag::create(tag_type type, int8_t val) +{ + return create_numeric_tag(type, val); +} + +std::unique_ptr<tag> tag::create(tag_type type, int16_t val) +{ + return create_numeric_tag(type, val); +} + +std::unique_ptr<tag> tag::create(tag_type type, int32_t val) +{ + return create_numeric_tag(type, val); +} + +std::unique_ptr<tag> tag::create(tag_type type, int64_t val) +{ + return create_numeric_tag(type, val); +} + +std::unique_ptr<tag> tag::create(tag_type type, float val) +{ + return create_numeric_tag(type, val); +} + +std::unique_ptr<tag> tag::create(tag_type type, double val) +{ + return create_numeric_tag(type, val); +} + bool operator==(const tag& lhs, const tag& rhs) { if(typeid(lhs) != typeid(rhs)) diff --git a/src/value.cpp b/src/value.cpp index f07e28d82c..bf0ffcad78 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -67,30 +67,13 @@ void value::set(tag&& t) namespace // helper functions local to this translation unit { template<typename T> - std::unique_ptr<tag> make_numeric_tag(tag_type type, T val) - { - switch(type) - { - case tag_type::Byte: return std::unique_ptr<tag>(new tag_byte(val)); - case tag_type::Short: return std::unique_ptr<tag>(new tag_short(val)); - case tag_type::Int: return std::unique_ptr<tag>(new tag_int(val)); - case tag_type::Long: return std::unique_ptr<tag>(new tag_long(val)); - case tag_type::Float: return std::unique_ptr<tag>(new tag_float(val)); - case tag_type::Double: return std::unique_ptr<tag>(new tag_double(val)); - default: return nullptr; - } - } - - template<typename T> void assign_numeric_impl(std::unique_ptr<tag>& tag_ptr, T val, tag_type default_type) { using nbt::tag_type; if(!tag_ptr) { - tag_ptr = make_numeric_tag(default_type, val); - if(!tag_ptr) - throw std::invalid_argument("Invalid default_type"); + tag_ptr = tag::create(default_type, val); return; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 500b939d51..fab1f58c00 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -112,8 +112,7 @@ stop_warnings(format_test) # Optional local test executable to verify value assignments (developer helper) option(NBT_BUILD_LOCAL_TEST "Build a small local test executable for value assignments" ON) if(NBT_BUILD_LOCAL_TEST) - add_executable(test_value test_value.cpp) + CXXTEST_ADD_TEST(test_value test_value.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_value.h) target_link_libraries(test_value ${NBT_NAME}) - add_test(test_value test_value) stop_warnings(test_value) endif() diff --git a/test/test_value.cpp b/test/test_value.cpp deleted file mode 100644 index 6b4729ea59..0000000000 --- a/test/test_value.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include <iostream> -#include "nbt_tags.h" -#include "value.h" - -using namespace nbt; - -int main() -{ - try { - value v; - - v = int8_t(-5); - std::cout << "assigned int8_t(-5): as int32=" << int32_t(v) << ", as double=" << double(v) << "\n"; - - v = value(); - v = int16_t(12345); - std::cout << "assigned int16_t(12345): as int32=" << int32_t(v) << ", as double=" << double(v) << "\n"; - - v = value(); - v = int32_t(100000); - std::cout << "assigned int32_t(100000): as int64=" << int64_t(v) << ", as double=" << double(v) << "\n"; - - v = value(); - v = float(3.14f); - std::cout << "assigned float(3.14): as double=" << double(v) << "\n"; - - v = value(); - v = double(2.718281828); - std::cout << "assigned double(2.71828): as double=" << double(v) << "\n"; - - std::cout << "Test finished OK\n"; - } - catch(const std::exception& e) { - std::cerr << "Exception: " << e.what() << "\n"; - return 1; - } - return 0; -} diff --git a/test/test_value.h b/test/test_value.h new file mode 100644 index 0000000000..db93ffdf7a --- /dev/null +++ b/test/test_value.h @@ -0,0 +1,36 @@ +#include <cxxtest/TestSuite.h> +#include <cstdint> +#include "value.h" + +using namespace nbt; + +class value_assignment_test : public CxxTest::TestSuite +{ +public: + void test_numeric_assignments() + { + value v; + + v = int8_t(-5); + TS_ASSERT_EQUALS(int32_t(v), int32_t(-5)); + TS_ASSERT_EQUALS(double(v), static_cast<double>(int8_t(-5))); + + v = value(); + v = int16_t(12345); + TS_ASSERT_EQUALS(int32_t(v), int32_t(12345)); + TS_ASSERT_EQUALS(double(v), static_cast<double>(int16_t(12345))); + + v = value(); + v = int32_t(100000); + TS_ASSERT_EQUALS(int64_t(v), int64_t(100000)); + TS_ASSERT_EQUALS(double(v), static_cast<double>(int32_t(100000))); + + v = value(); + v = float(3.14f); + TS_ASSERT_EQUALS(double(v), static_cast<double>(3.14f)); + + v = value(); + v = double(2.718281828); + TS_ASSERT_EQUALS(double(v), 2.718281828); + } +}; |
