Adds ValueReferencePair, ValueList and tests.

Change-Id: I58bdb808fb7a62bb601589c31d9602daeb9b343a
Signed-off-by: Johannes Wendel <johannes.wendel@iese.fraunhofer.de>
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
new file mode 100644
index 0000000..884f9ed
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/api_v2/dataspecification/IValueList.h
@@ -0,0 +1,25 @@
+#ifndef BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IVALUELIST_H
+#define BASYX_SUBMODEL_API_V2_DATASPECIFICATION_IVALUELIST_H
+
+#include <BaSyx/submodel/simple/dataspecification/ValueReferencePair.h>
+
+namespace basyx {
+namespace submodel {
+namespace api {
+
+class IValueList
+{
+public:
+	virtual ~IValueList() = 0;
+
+	virtual void addValueReferencePair(const simple::ValueReferencePair & valueRefPair) = 0;
+	virtual std::vector<simple::ValueReferencePair> getValueReferencePairs() = 0;
+};
+
+inline IValueList::~IValueList() = default;
+
+}
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
new file mode 100644
index 0000000..b4dbb6b
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/dataspecification/ValueList.h
@@ -0,0 +1,27 @@
+#ifndef BASYX_C_SDK_VALUELIST_H
+#define BASYX_C_SDK_VALUELIST_H
+
+#include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
+#include <BaSyx/vab/ElementMap.h>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+class ValueList
+  : public api::IValueList
+  , public vab::ElementMap
+{
+public:
+  ValueList();
+  explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
+
+  void addValueReferencePair(const simple::ValueReferencePair & valueRefPair) override;
+  std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
+};
+
+}
+}
+}
+
+#endif //BASYX_C_SDK_VALUELIST_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
index 01091df..091bd13 100644
--- a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/map_v2/reference/Reference.h
@@ -26,6 +26,7 @@
 	Reference(const api::IReference & other);
 	Reference(const Reference & other) = default;
 	Reference(Reference && other) noexcept = default;
+  Reference(basyx::object & object);
 
 	Reference & operator=(const api::IReference & other);
 	Reference & operator=(const Reference & other) = default;
@@ -42,6 +43,10 @@
 	virtual bool empty() const override;
 public:
 //	static Reference FromIdentifiable(const std::string & keyElementType, bool local, const IIdentifiable & identifiable);
+
+private:
+  static simple::Key keyMap_to_key(basyx::object &keyMap);
+  static std::vector<simple::Key> keyMapList_to_keyList(basyx::object::object_list_t &keyMapList);
 };
 
 }
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
new file mode 100644
index 0000000..df22b8c
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueList.h
@@ -0,0 +1,28 @@
+#ifndef BASYX_C_SDK_SIMPLE_VALUELIST_H
+#define BASYX_C_SDK_SIMPLE_VALUELIST_H
+
+#include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class ValueList
+    : public api::IValueList
+{
+public:
+  ValueList() = default;
+  explicit ValueList(const std::vector<simple::ValueReferencePair> & list);
+
+  void addValueReferencePair(const simple::ValueReferencePair & valueRefPair) override;
+  std::vector<simple::ValueReferencePair> getValueReferencePairs() override;
+
+private:
+  std::vector<simple::ValueReferencePair> list;
+};
+
+}
+}
+}
+
+#endif //BASYX_C_SDK_VALUELIST_H
diff --git a/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
new file mode 100644
index 0000000..6e9a484
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/include/BaSyx/submodel/simple/dataspecification/ValueReferencePair.h
@@ -0,0 +1,43 @@
+#ifndef BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUEREFERENCEPAIR_H
+#define BASYX_SUBMODEL_SIMPLE_DATASPECIFICATION_VALUEREFERENCEPAIR_H
+
+#include <BaSyx/submodel/simple/reference/Reference.h>
+#include <BaSyx/shared/object/object_type.h>
+#include <BaSyx/shared/object.h>
+
+#include <string>
+#include <BaSyx/submodel/map_v2/reference/Reference.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+class ValueReferencePair
+{
+private:
+	std::string value;
+	Reference valueId;
+
+public:
+	ValueReferencePair() = default;
+	ValueReferencePair(const ValueReferencePair & other) = default;
+	ValueReferencePair(ValueReferencePair && other) noexcept = default;
+
+	ValueReferencePair & operator=(const ValueReferencePair & other) = default;
+	ValueReferencePair & operator=(ValueReferencePair && other) noexcept = default;
+
+	ValueReferencePair(const std::string & value, const api::IReference & valueId)
+		: value(value), valueId(valueId)
+	{};
+
+	~ValueReferencePair() = default;
+public:
+	const std::string & getValue() const { return this->value; };
+	const api::IReference & getValueId() const { return this->valueId; };
+};
+
+}
+}
+}
+
+#endif 
\ No newline at end of file
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
index 091d19b..6a8bdc1 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/src/submodel/CMakeLists.txt
@@ -49,6 +49,7 @@
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/submodelelement/SubmodelElementCollection.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/dataspecification/DataSpecification.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/dataspecification/DataSpecificationIEC61360.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/map_v2/dataspecification/ValueList.cpp
 
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/AssetAdministrationShell.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/aas/Asset.cpp
@@ -58,6 +59,7 @@
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/DataSpecificationContent.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/DataSpecification.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/DataSpecificationIEC61360.cpp
+		${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/dataspecification/ValueList.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/identifier/Identifier.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/parts/ConceptDescription.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/submodel/simple/qualifier/AdministrativeInformation.cpp
@@ -95,6 +97,7 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/dataspecification/IDataSpecificationContent.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/dataspecification/IDataSpecification.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/dataspecification/IDataSpecificationIEC61360.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/dataspecification/IValueList.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/identifier/Identifier.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/constraint/IConstraint.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/api_v2/constraint/IFormula.h
@@ -130,6 +133,10 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ElementFactory.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/LangStringSet.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/common/ModelType.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/dataspecification/DataSpecificationContent.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/dataspecification/DataSpecificationIEC61360.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/dataspecification/DataSpecification.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/dataspecification/ValueList.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Formula.h
 		${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/constraint/Qualifier.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/map_v2/qualifier/HasDataSpecification.h
@@ -157,6 +164,8 @@
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/DataSpecificationContent.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/DataSpecification.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/DataSpecificationIEC61360.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/ValueReferencePair.h
+		${BASYX_SUBMODEL_INCLUDE_DIR}/simple/dataspecification/ValueList.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/identifier/Identifier.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/parts/ConceptDescription.h
         ${BASYX_SUBMODEL_INCLUDE_DIR}/simple/qualifier/AdministrativeInformation.h
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
new file mode 100644
index 0000000..6ac067d
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/dataspecification/ValueList.cpp
@@ -0,0 +1,38 @@
+#include <BaSyx/submodel/map_v2/dataspecification/ValueList.h>
+
+namespace basyx {
+namespace submodel {
+namespace map {
+
+ValueList::ValueList()
+  : vab::ElementMap(basyx::object::make_object_list())
+{}
+
+ValueList::ValueList(const std::vector<simple::ValueReferencePair> &list)
+    : vab::ElementMap()
+{}
+
+void ValueList::addValueReferencePair(const simple::ValueReferencePair & valueRefPair)
+{
+  object obj = object::make_map();
+  obj.insertKey("value", valueRefPair.getValue());
+  obj.insertKey("valueId", map::Reference(valueRefPair.getValueId()).getMap());
+  this->map.insert(obj);
+}
+
+std::vector<simple::ValueReferencePair> ValueList::getValueReferencePairs()
+{
+  std::vector<simple::ValueReferencePair> list;
+  for (auto & pair_obj : this->map.Get<object::object_list_t&>())
+  {
+    std::string value = pair_obj.getProperty("value").GetStringContent();
+    auto reference = simple::Reference(map::Reference(pair_obj.getProperty("valueId")));
+    simple::ValueReferencePair pair(value, reference);
+    list.push_back(pair);
+  }
+  return list;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
index 2938898..12d439d 100644
--- a/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/map_v2/reference/Reference.cpp
@@ -42,26 +42,17 @@
 
 Reference::Reference(const IReference & other)
 	: Reference{other.getKeys()}
-{
-};
+{};
+
+
+Reference::Reference(basyx::object &object)
+  : Reference(keyMapList_to_keyList(object.getProperty("keys").Get<object::object_list_t&>()))
+{}
 
 
 std::vector<simple::Key> Reference::getKeys() const
 {
-	std::vector<simple::Key> keys;
-
-	auto keyList = this->map.getProperty("keys").Get<basyx::object::object_list_t&>();
-	for (auto & keyMap : keyList)
-	{
-		keys.emplace_back(
-			  KeyElementsUtil::fromString(keyMap.getProperty(KeyPath::Type).Get<std::string&>()),
-			  keyMap.getProperty(KeyPath::Local).Get<bool>(),
-			  KeyTypeUtil::fromString(keyMap.getProperty(KeyPath::IdType).Get<std::string&>()),
-			  keyMap.getProperty(KeyPath::Value).Get<std::string&>()
-		);
-	};
-
-	return keys;
+	return this->keyMapList_to_keyList(this->map.getProperty("keys").Get<basyx::object::object_list_t&>());
 };
 
 
@@ -90,3 +81,27 @@
 {
 	return this->map.getProperty("keys").empty();
 }
+
+simple::Key Reference::keyMap_to_key(basyx::object &keyMap)
+{
+  return simple::Key
+  (
+    KeyElementsUtil::fromString(keyMap.getProperty(KeyPath::Type).Get<std::string&>()),
+    keyMap.getProperty(KeyPath::Local).Get<bool>(),
+    KeyTypeUtil::fromString(keyMap.getProperty(KeyPath::IdType).Get<std::string&>()),
+    keyMap.getProperty(KeyPath::Value).Get<std::string&>()
+  );
+}
+
+std::vector<simple::Key> Reference::keyMapList_to_keyList(basyx::object::object_list_t &keyMapList)
+{
+  std::vector<simple::Key> keys;
+
+  for (auto & keyMap : keyMapList)
+  {
+    keys.emplace_back(keyMap_to_key(keyMap));
+  };
+
+  return keys;
+}
+
diff --git a/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/ValueList.cpp b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/ValueList.cpp
new file mode 100644
index 0000000..2164ba2
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/submodel/submodel/simple/dataspecification/ValueList.cpp
@@ -0,0 +1,23 @@
+#include <BaSyx/submodel/simple/dataspecification/ValueList.h>
+
+namespace basyx {
+namespace submodel {
+namespace simple {
+
+ValueList::ValueList(const std::vector<simple::ValueReferencePair> &list)
+  : list(list)
+{}
+
+void ValueList::addValueReferencePair(const simple::ValueReferencePair &valueRefPair)
+{
+  this->list.push_back(valueRefPair);
+}
+
+std::vector<simple::ValueReferencePair> ValueList::getValueReferencePairs()
+{
+  return this->list;
+}
+
+}
+}
+}
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
index 4637453..8885f8d 100644
--- a/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/CMakeLists.txt
@@ -17,6 +17,7 @@
 	api/qualifier/test_Qualifiable.cpp
 	api/qualifier/test_Referable.cpp
 	api/reference/test_Reference.cpp
+	api/dataspecification/test_ValueList.cpp
 	map/common/test_ElementContainer.cpp
 	api/common/test_LangStringSet.cpp
 	map_v2/dataspecification/test_DataSpecification.cpp
diff --git a/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/dataspecification/test_ValueList.cpp b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/dataspecification/test_ValueList.cpp
new file mode 100644
index 0000000..c095507
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/tests/regression/submodel/api/dataspecification/test_ValueList.cpp
@@ -0,0 +1,69 @@
+#include <gtest/gtest.h>
+
+#include <BaSyx/submodel/api_v2/dataspecification/IValueList.h>
+#include <BaSyx/submodel/simple/dataspecification/ValueList.h>
+#include <BaSyx/submodel/map_v2/dataspecification/ValueList.h>
+
+using namespace basyx::submodel;
+
+// Implementations to run tests for
+using ImplTypes = ::testing::Types<
+    simple::ValueList,
+    map::ValueList
+>;
+
+template<class Impl>
+class ValueListTest :public ::testing::Test {
+protected:
+  using impl_t = Impl;
+protected:
+  std::unique_ptr<api::IValueList> valueList;
+protected:
+  void SetUp() override
+  {
+    this->valueList = util::make_unique<Impl>();
+  }
+
+  void TearDown() override
+  {
+  }
+};
+
+TYPED_TEST_CASE(ValueListTest, ImplTypes);
+
+TYPED_TEST(ValueListTest, TestConstructor)
+{
+  auto list = this->valueList->getValueReferencePairs();
+  ASSERT_EQ(list.size(), 0);
+}
+
+TYPED_TEST(ValueListTest, TestAddSingleValueRefPair)
+{
+  simple::ValueReferencePair referencePair("pair", simple::Reference());
+
+  this->valueList->addValueReferencePair(referencePair);
+
+  auto list = this->valueList->getValueReferencePairs();
+
+  ASSERT_EQ(list.size(), 1);
+  ASSERT_EQ(list[0].getValue(), referencePair.getValue());
+}
+
+TYPED_TEST(ValueListTest, TestAddMultipleValueRefPair)
+{
+  simple::ValueReferencePair referencePair0("pair0", simple::Reference());
+  simple::ValueReferencePair referencePair1("pair1", simple::Reference());
+  simple::ValueReferencePair referencePair2("pair2", simple::Reference());
+
+  this->valueList->addValueReferencePair(referencePair0);
+  this->valueList->addValueReferencePair(referencePair1);
+  this->valueList->addValueReferencePair(referencePair2);
+
+  auto list = this->valueList->getValueReferencePairs();
+
+  ASSERT_EQ(list.size(), 3);
+  ASSERT_EQ(list[0].getValue(), referencePair0.getValue());
+  ASSERT_EQ(list[1].getValue(), referencePair1.getValue());
+  ASSERT_EQ(list[2].getValue(), referencePair2.getValue());
+}
+