summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tag.h10
-rw-r--r--src/tag.cpp48
-rw-r--r--src/value.cpp19
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/test_value.cpp38
-rw-r--r--test/test_value.h36
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);
+ }
+};