diff --git a/src/Value.cpp b/src/Value.cpp index df2ec25476..e20be7a27e 100644 --- a/src/Value.cpp +++ b/src/Value.cpp @@ -9,19 +9,40 @@ using namespace ntimpl; -Value::Value() : m_type(NT_UNASSIGNED) {} +Value::Value() { m_val.type = NT_UNASSIGNED; } -Value::Value(NT_Type type, const private_init&) : m_type(type) {} +Value::Value(NT_Type type, const private_init&) { + m_val.type = type; + if (m_val.type == NT_BOOLEAN_ARRAY) + m_val.data.arr_boolean.arr = nullptr; + else if (m_val.type == NT_DOUBLE_ARRAY) + m_val.data.arr_double.arr = nullptr; + else if (m_val.type == NT_STRING_ARRAY) + m_val.data.arr_string.arr = nullptr; +} + +Value::~Value() { + if (m_val.type == NT_BOOLEAN_ARRAY) + delete[] m_val.data.arr_boolean.arr; + else if (m_val.type == NT_DOUBLE_ARRAY) + delete[] m_val.data.arr_double.arr; + else if (m_val.type == NT_STRING_ARRAY) + delete[] m_val.data.arr_string.arr; +} std::shared_ptr Value::MakeBooleanArray(llvm::ArrayRef value) { auto val = std::make_shared(NT_BOOLEAN_ARRAY, private_init()); - val->m_boolean_array = value; + val->m_val.data.arr_boolean.arr = new int[value.size()]; + val->m_val.data.arr_boolean.size = value.size(); + std::copy(value.begin(), value.end(), val->m_val.data.arr_boolean.arr); return val; } std::shared_ptr Value::MakeDoubleArray(llvm::ArrayRef value) { auto val = std::make_shared(NT_DOUBLE_ARRAY, private_init()); - val->m_double_array = value; + val->m_val.data.arr_double.arr = new double[value.size()]; + val->m_val.data.arr_double.size = value.size(); + std::copy(value.begin(), value.end(), val->m_val.data.arr_double.arr); return val; } @@ -29,20 +50,12 @@ std::shared_ptr Value::MakeStringArray( llvm::ArrayRef value) { auto val = std::make_shared(NT_STRING_ARRAY, private_init()); val->m_string_array = value; - return val; -} - -std::shared_ptr Value::MakeBooleanArray(std::vector&& value) { - auto val = std::make_shared(NT_BOOLEAN_ARRAY, private_init()); - val->m_boolean_array = std::move(value); - value.clear(); - return val; -} - -std::shared_ptr Value::MakeDoubleArray(std::vector&& value) { - auto val = std::make_shared(NT_DOUBLE_ARRAY, private_init()); - val->m_double_array = std::move(value); - value.clear(); + // point NT_Value to the contents in the vector. + val->m_val.data.arr_string.arr = new NT_String[value.size()]; + for (std::size_t i=0; im_val.data.arr_string.arr[i].str = const_cast(value[i].c_str()); + val->m_val.data.arr_string.arr[i].len = value[i].size(); + } return val; } @@ -51,6 +64,13 @@ std::shared_ptr Value::MakeStringArray( auto val = std::make_shared(NT_STRING_ARRAY, private_init()); val->m_string_array = std::move(value); value.clear(); + // point NT_Value to the contents in the vector. + val->m_val.data.arr_string.arr = new NT_String[val->m_string_array.size()]; + for (std::size_t i=0; im_string_array.size(); ++i) { + val->m_val.data.arr_string.arr[i].str = + const_cast(val->m_string_array[i].c_str()); + val->m_val.data.arr_string.arr[i].len = val->m_string_array[i].size(); + } return val; } @@ -158,17 +178,27 @@ bool ntimpl::operator==(const Value& lhs, const Value& rhs) { case NT_UNASSIGNED: return true; // XXX: is this better being false instead? case NT_BOOLEAN: - return lhs.m_boolean == rhs.m_boolean; + return lhs.m_val.data.v_boolean == rhs.m_val.data.v_boolean; case NT_DOUBLE: - return lhs.m_double == rhs.m_double; + return lhs.m_val.data.v_double == rhs.m_val.data.v_double; case NT_STRING: case NT_RAW: case NT_RPC: return lhs.m_string == rhs.m_string; case NT_BOOLEAN_ARRAY: - return lhs.m_boolean_array == rhs.m_boolean_array; + if (lhs.m_val.data.arr_boolean.size != rhs.m_val.data.arr_boolean.size) + return false; + return std::memcmp(lhs.m_val.data.arr_boolean.arr, + rhs.m_val.data.arr_boolean.arr, + lhs.m_val.data.arr_boolean.size * + sizeof(lhs.m_val.data.arr_boolean.arr[0])) == 0; case NT_DOUBLE_ARRAY: - return lhs.m_double_array == rhs.m_double_array; + if (lhs.m_val.data.arr_double.size != rhs.m_val.data.arr_double.size) + return false; + return std::memcmp(lhs.m_val.data.arr_double.arr, + rhs.m_val.data.arr_double.arr, + lhs.m_val.data.arr_double.size * + sizeof(lhs.m_val.data.arr_double.arr[0])) == 0; case NT_STRING_ARRAY: return lhs.m_string_array == rhs.m_string_array; default: diff --git a/src/Value.h b/src/Value.h index 3751bce33f..e2625264d7 100644 --- a/src/Value.h +++ b/src/Value.h @@ -26,83 +26,99 @@ class Value { public: Value(); Value(NT_Type type, const private_init&); + ~Value(); - NT_Type type() const { return m_type; } + NT_Type type() const { return m_val.type; } + const NT_Value& value() const { return m_val; } /* * Type-Safe Getters */ bool GetBoolean() const { - assert(m_type == NT_BOOLEAN); - return m_boolean; + assert(m_val.type == NT_BOOLEAN); + return m_val.data.v_boolean != 0; } double GetDouble() const { - assert(m_type == NT_DOUBLE); - return m_double; + assert(m_val.type == NT_DOUBLE); + return m_val.data.v_double; } llvm::StringRef GetString() const { - assert(m_type == NT_STRING); + assert(m_val.type == NT_STRING); return m_string; } llvm::StringRef GetRaw() const { - assert(m_type == NT_RAW); + assert(m_val.type == NT_RAW); return m_string; } llvm::StringRef GetRpc() const { - assert(m_type == NT_RPC); + assert(m_val.type == NT_RPC); return m_string; } llvm::ArrayRef GetBooleanArray() const { - assert(m_type == NT_BOOLEAN_ARRAY); - return m_boolean_array; + assert(m_val.type == NT_BOOLEAN_ARRAY); + return llvm::ArrayRef(m_val.data.arr_boolean.arr, + m_val.data.arr_boolean.size); } llvm::ArrayRef GetDoubleArray() const { - assert(m_type == NT_DOUBLE_ARRAY); - return m_double_array; + assert(m_val.type == NT_DOUBLE_ARRAY); + return llvm::ArrayRef(m_val.data.arr_double.arr, + m_val.data.arr_double.size); } llvm::ArrayRef GetStringArray() const { - assert(m_type == NT_STRING_ARRAY); + assert(m_val.type == NT_STRING_ARRAY); return m_string_array; } static std::shared_ptr MakeBoolean(bool value) { auto val = std::make_shared(NT_BOOLEAN, private_init()); - val->m_boolean = value; + val->m_val.data.v_boolean = value; return val; } static std::shared_ptr MakeDouble(double value) { auto val = std::make_shared(NT_DOUBLE, private_init()); - val->m_double = value; + val->m_val.data.v_double = value; return val; } static std::shared_ptr MakeString(llvm::StringRef value) { auto val = std::make_shared(NT_STRING, private_init()); val->m_string = value; + val->m_val.data.v_string.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_string.len = val->m_string.size(); return val; } static std::shared_ptr MakeString(std::string&& value) { auto val = std::make_shared(NT_STRING, private_init()); val->m_string = std::move(value); + val->m_val.data.v_string.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_string.len = val->m_string.size(); return val; } static std::shared_ptr MakeRaw(llvm::StringRef value) { auto val = std::make_shared(NT_RAW, private_init()); val->m_string = value; + val->m_val.data.v_raw.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_raw.len = val->m_string.size(); return val; } static std::shared_ptr MakeRaw(std::string&& value) { auto val = std::make_shared(NT_RAW, private_init()); val->m_string = std::move(value); + val->m_val.data.v_raw.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_raw.len = val->m_string.size(); return val; } static std::shared_ptr MakeRpc(llvm::StringRef value) { auto val = std::make_shared(NT_RPC, private_init()); val->m_string = value; + val->m_val.data.v_raw.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_raw.len = val->m_string.size(); return val; } static std::shared_ptr MakeRpc(std::string&& value) { auto val = std::make_shared(NT_RPC, private_init()); val->m_string = std::move(value); + val->m_val.data.v_raw.str = const_cast(val->m_string.c_str()); + val->m_val.data.v_raw.len = val->m_string.size(); return val; } @@ -111,9 +127,7 @@ class Value { static std::shared_ptr MakeStringArray( llvm::ArrayRef value); - // Note: These functions move the values out of the vector. - static std::shared_ptr MakeBooleanArray(std::vector&& value); - static std::shared_ptr MakeDoubleArray(std::vector&& value); + // Note: This function moves the values out of the vector. static std::shared_ptr MakeStringArray( std::vector&& value); @@ -122,12 +136,8 @@ class Value { friend bool operator==(const Value& lhs, const Value& rhs); private: - NT_Type m_type; - bool m_boolean; - double m_double; + NT_Value m_val; std::string m_string; - std::vector m_boolean_array; - std::vector m_double_array; std::vector m_string_array; };