From 18d0b898586985b8b0d0a4a8a752ce85c3363084 Mon Sep 17 00:00:00 2001
From: "m.marn" <m.marn@gsi.de>
Date: Mon, 27 Mar 2023 08:54:39 +0000
Subject: [PATCH] Remove all dependencies to boost

Fixes #83

See merge request silecs/opensilecs!32
---
 .../src/silecs-cli-client/main.cpp            | 21 ++---
 .../interface/core/SilecsService.cpp          | 13 ++-
 .../interface/equipment/PLCBlock.cpp          |  6 +-
 .../interface/equipment/PLCBlock.h            |  6 +-
 .../interface/equipment/PLCRegister.cpp       | 12 +--
 .../interface/equipment/PLCRegister.h         | 12 +--
 .../interface/equipment/SilecsBlock.cpp       |  5 +-
 .../interface/equipment/SilecsBlock.h         |  4 +-
 .../interface/equipment/SilecsDevice.cpp      | 20 ++---
 .../interface/equipment/SilecsDevice.h        |  9 +-
 .../interface/equipment/SilecsPLC.cpp         | 21 ++---
 .../interface/equipment/SilecsRegister.cpp    | 39 ++++----
 .../interface/equipment/SilecsRegister.h      |  3 +-
 .../interface/utility/XMLParser.cpp           | 88 ++++++++++++-------
 .../interface/utility/XMLParser.h             | 66 ++++++--------
 .../diagnostictoolmainview.cpp                |  7 +-
 .../src/silecs-diagnostic/silecsmodule.cpp    | 12 ++-
 17 files changed, 170 insertions(+), 174 deletions(-)

diff --git a/silecs-cli-client/src/silecs-cli-client/main.cpp b/silecs-cli-client/src/silecs-cli-client/main.cpp
index f9e8eb2..ee2c3f2 100755
--- a/silecs-cli-client/src/silecs-cli-client/main.cpp
+++ b/silecs-cli-client/src/silecs-cli-client/main.cpp
@@ -28,8 +28,6 @@
 #include <silecs-communication/interface/equipment/SilecsDevice.h>
 #include <silecs-communication/interface/equipment/SilecsRegister.h>
 
-#include <boost/assign/list_of.hpp> // init vector of strings
-
 const std::string startbold = "\e[1m";
 const std::string endbold = "\e[0m";
 
@@ -179,9 +177,8 @@ bool isRegisterInBlock(std::string registerName, std::string blockName, Silecs::
 std::vector<std::string> getDeviceNames(Silecs::XMLParser &paramParser)
 {
     std::vector < std::string > deviceNames;
-    boost::ptr_vector<Silecs::ElementXML> deviceNodes = paramParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class/Instance");
-    boost::ptr_vector<Silecs::ElementXML>::iterator deviceNode;
-    for (deviceNode = deviceNodes.begin(); deviceNode != deviceNodes.end(); deviceNode++)
+    auto deviceNodes = paramParser.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class/Instance");
+    for (auto deviceNode = deviceNodes.begin(); deviceNode != deviceNodes.end(); deviceNode++)
     {
         deviceNames.push_back(deviceNode->getAttribute("label"));
     }
@@ -193,9 +190,8 @@ std::vector<std::string> getBlockNamesFromDeviceName(std::string deviceName, Sil
     std::vector < std::string > blockNames;
     Silecs::ElementXML classNode = paramParser.getFirstElementFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[Instance/@label='" + deviceName + "']");
     std::string className = classNode.getAttribute("name");
-    boost::ptr_vector<Silecs::ElementXML> blocks = paramParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[ name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block']");
-    boost::ptr_vector<Silecs::ElementXML>::iterator block;
-    for (block = blocks.begin(); block != blocks.end(); block++)
+    auto blocks = paramParser.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[ name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block']");
+    for (auto block = blocks.begin(); block != blocks.end(); block++)
     {
         //std::cout<< block->getAttribute("name") << std::endl;
         blockNames.push_back(block->getAttribute("name"));
@@ -208,9 +204,8 @@ std::vector<std::string> getRegisterNamesFromDeviceBlockName(std::string deviceN
     std::vector < std::string > registerNames;
     Silecs::ElementXML classNode = paramParser.getFirstElementFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[Instance/@label='" + deviceName + "']");
     std::string className = classNode.getAttribute("name");
-    boost::ptr_vector<Silecs::ElementXML> registerNodes = paramParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[@name='" + blockName + "']/*[ name()='Acquisition-Register' or name()='Setting-Register' or name()='Volatile-Register']");
-    boost::ptr_vector<Silecs::ElementXML>::iterator registerNode;
-    for (registerNode = registerNodes.begin(); registerNode != registerNodes.end(); registerNode++)
+    auto registerNodes = paramParser.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[@name='" + blockName + "']/*[ name()='Acquisition-Register' or name()='Setting-Register' or name()='Volatile-Register']");
+    for (auto registerNode = registerNodes.begin(); registerNode != registerNodes.end(); registerNode++)
     {
         //std::cout<< block->getAttribute("name") << std::endl;
         registerNames.push_back(registerNode->getAttribute("name"));
@@ -296,7 +291,9 @@ void setRegister(Silecs::Register *reg, std::string value)
 
 int connectInteractive(Silecs::Service *service, Silecs::XMLParser &paramParser)
 {
-    std::vector < std::string > mainMenu = boost::assign::list_of("connect to plc-device")("select block")("select register")("print whole device")("print block")("print register")("query plc run state")("cold-restart plc");
+    std::vector <std::string> mainMenu = {"connect to plc-device", "select block",
+        "select register", "print whole device", "print block", "print register",
+        "query plc run state", "cold-restart plc"};
     Silecs::Cluster *silecsCluster = NULL;
     Silecs::PLC *plc = NULL;
     Silecs::Device *device = NULL;
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp
index ec59fb3..b5402bf 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp
@@ -18,8 +18,7 @@ Contributors:
 #include <silecs-communication/interface/utility/StringUtilities.h>
 #include <unistd.h>
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include <libgen.h>
 
 /* **********************************************************************
  * Global data definition related to the software install and versioning
@@ -222,11 +221,11 @@ const std::string Service::getBinaryFolderPath()
     {
         throw SilecsException(__FILE__, __LINE__, "Failed to get binary folder");
     }
-    std::string path(buf, size);
-    boost::system::error_code ec;
-    boost::filesystem::path binaryPath(boost::filesystem::canonical(path, boost::filesystem::current_path(), ec));
-    boost::filesystem::path dir = binaryPath.parent_path();
-    return dir.make_preferred().string();
+    if (size == -1)
+    {
+        throw SilecsException{__FILE__, __LINE__, errno};
+    }
+    return dirname(buf);
 }
 
 const std::string Service::getParamFile(std::string controllerName)
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp
index 11a4b92..c8016b6 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp
@@ -29,7 +29,7 @@ Contributors:
 namespace Silecs
 {
 
-PLCBlock::PLCBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+PLCBlock::PLCBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType) :
                 Block(thePLC, blockNode, accessType)
 {
     // Create buffer for the block exchanges
@@ -50,7 +50,7 @@ PLCBlock::~PLCBlock()
     pBuffer_ = NULL;
 }
 
-InputBlock::InputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+InputBlock::InputBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType) :
                 PLCBlock(thePLC, blockNode, accessType)
 {
     if (DEBUG & Log::topics_)
@@ -70,7 +70,7 @@ InputBlock::~InputBlock()
 {
 }
 
-OutputBlock::OutputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+OutputBlock::OutputBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType) :
                 PLCBlock(thePLC, blockNode, accessType)
 {
     if (DEBUG & Log::topics_)
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h
index 81d3caf..0d22d92 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h
@@ -25,7 +25,7 @@ class PLCBlock : public Block
 {
 
 public:
-    PLCBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+    PLCBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType);
     ~PLCBlock();
 
     inline unsigned long& getBufferSize()
@@ -49,7 +49,7 @@ class InputBlock : public PLCBlock
 {
 
 public:
-    InputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+    InputBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType);
     virtual ~InputBlock();
 
 };
@@ -62,7 +62,7 @@ class OutputBlock : public PLCBlock
 {
 
 public:
-    OutputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+    OutputBlock(PLC* thePLC, const ElementXML& blockNode, AccessType accessType);
     virtual ~OutputBlock();
 
 };
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
index ba178e6..239522f 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
@@ -19,7 +19,7 @@ Contributors:
 namespace Silecs
 {
 
-PLCRegister::PLCRegister(Device* theDevice, ElementXML* registerNode) :
+PLCRegister::PLCRegister(Device* theDevice, const ElementXML& registerNode) :
                 Register(theDevice, registerNode)
 {
 }
@@ -27,7 +27,7 @@ PLCRegister::~PLCRegister()
 {
 }
 
-BigEndianRegister::BigEndianRegister(Device* theDevice, ElementXML* registerNode) :
+BigEndianRegister::BigEndianRegister(Device* theDevice, const ElementXML& registerNode) :
                 PLCRegister(theDevice, registerNode)
 {
 }
@@ -35,7 +35,7 @@ BigEndianRegister::~BigEndianRegister()
 {
 }
 
-LittleEndianRegister::LittleEndianRegister(Device* theDevice, ElementXML* registerNode) :
+LittleEndianRegister::LittleEndianRegister(Device* theDevice, const ElementXML& registerNode) :
                 PLCRegister(theDevice, registerNode)
 {
 }
@@ -43,7 +43,7 @@ LittleEndianRegister::~LittleEndianRegister()
 {
 }
 
-S7Register::S7Register(Device* theDevice, ElementXML* registerNode) :
+S7Register::S7Register(Device* theDevice, const ElementXML& registerNode) :
                 BigEndianRegister(theDevice, registerNode)
 {
 }
@@ -51,7 +51,7 @@ S7Register::~S7Register()
 {
 }
 
-UnityRegister::UnityRegister(Device* theDevice, ElementXML* registerNode) :
+UnityRegister::UnityRegister(Device* theDevice, const ElementXML& registerNode) :
                 LittleEndianRegister(theDevice, registerNode)
 {
 }
@@ -59,7 +59,7 @@ UnityRegister::~UnityRegister()
 {
 }
 
-TwinCATRegister::TwinCATRegister(Device* theDevice, ElementXML* registerNode) :
+TwinCATRegister::TwinCATRegister(Device* theDevice, const ElementXML& registerNode) :
                 UnityRegister(theDevice, registerNode)
 {
 }
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h
index 33bb8df..c7c7200 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h
@@ -35,7 +35,7 @@ class PLCRegister : public Register
 private:
 
 protected:
-    PLCRegister(Device* theDevice, ElementXML* registerNode);
+    PLCRegister(Device* theDevice, const ElementXML& registerNode);
     virtual ~PLCRegister();
 
     // export register extraction methods
@@ -86,7 +86,7 @@ class BigEndianRegister : public PLCRegister
 {
 
 public:
-    BigEndianRegister(Silecs::Device* theDevice, ElementXML* registerNode);
+    BigEndianRegister(Silecs::Device* theDevice, const ElementXML& registerNode);
     virtual ~BigEndianRegister();
 
 protected:
@@ -103,7 +103,7 @@ class LittleEndianRegister : public PLCRegister
 {
 
 public:
-    LittleEndianRegister(Silecs::Device* theDevice, ElementXML* registerNode);
+    LittleEndianRegister(Silecs::Device* theDevice, const ElementXML& registerNode);
     virtual ~LittleEndianRegister();
 
 protected:
@@ -119,7 +119,7 @@ protected:
 class S7Register : public BigEndianRegister
 {
 public:
-    S7Register(Silecs::Device* theDevice, ElementXML* registerNode);
+    S7Register(Silecs::Device* theDevice, const ElementXML& registerNode);
     virtual ~S7Register();
 
 private:
@@ -147,7 +147,7 @@ private:
 class UnityRegister : public LittleEndianRegister
 {
 public:
-    UnityRegister(Silecs::Device* theDevice, ElementXML* registerNode);
+    UnityRegister(Silecs::Device* theDevice, const ElementXML& registerNode);
     virtual ~UnityRegister();
 
 private:
@@ -177,7 +177,7 @@ private:
 class TwinCATRegister : public UnityRegister
 {
 public:
-    TwinCATRegister(Silecs::Device* theDevice, ElementXML* registerNode);
+    TwinCATRegister(Silecs::Device* theDevice, const ElementXML& registerNode);
     virtual ~TwinCATRegister();
 
 protected:
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp
index 0a9c462..fcdb48d 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp
@@ -26,13 +26,12 @@ Contributors:
 namespace Silecs
 {
 
-Block::Block(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+Block::Block(PLC* thePLC, const ElementXML& blockNode, AccessType accessType) :
                 thePLC_(thePLC), configuration_(false)
 {
     std::string designName = blockNode.getAttribute("name");
 
-
-    if(blockNode.name_ == "Configuration-Block")
+    if(blockNode.getName() == "Configuration-Block")
         configuration_ = true;
 
     name_ = designName;
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h
index 201a7d0..075ab8b 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h
@@ -17,8 +17,6 @@ Contributors:
 #include <silecs-communication/interface/core/SilecsService.h>
 #include <silecs-communication/interface/utility/Thread.h>
 
-#include <boost/shared_ptr.hpp>
-
 namespace Silecs
 {
 class Action;
@@ -37,7 +35,7 @@ class Block
 {
 
 public:
-    Block(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+    Block(PLC* thePLC, const ElementXML& blockNode, AccessType accessType);
     virtual ~Block();
 
     /*!
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
index 844cf94..c9bda1f 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
@@ -31,7 +31,7 @@ Contributors:
 
 namespace Silecs
 {
-Device::Device(PLC* thePLC, const ElementXML& deviceNode, boost::ptr_vector<ElementXML>& blockNodes) :
+Device::Device(PLC* thePLC, const ElementXML& deviceNode, const std::vector<ElementXML>& blockNodes) :
                 thePLC_(thePLC)
 {
     // Update Device ElementXML attributes
@@ -55,16 +55,15 @@ Device::Device(PLC* thePLC, const ElementXML& deviceNode, boost::ptr_vector<Elem
 
     LOG(ALLOC) << "Creating SilecsDevice: " << label_;
 
-    boost::ptr_vector<ElementXML>::const_iterator blockIter;
-    for (blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
+    for (auto blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
     {
         std::string blockName = blockIter->getAttribute("name");
         LOG(ALLOC) << "Adding Block to Device: " << blockName;
-        AccessType accessType = Block::whichAccessType(blockIter->name_);
+        AccessType accessType = Block::whichAccessType(blockIter->getName());
         AccessArea accessArea = AccessArea::Memory;
         if (blockIter->hasAttribute("ioType")) // only IO-Blocks have this attribute
             accessArea = Block::whichAccessArea(blockIter->getAttribute("ioType"));
-        std::vector<boost::shared_ptr<ElementXML> > registerNodes = blockIter->childList_;
+        auto& registerNodes = blockIter->getChildNodes();
         instantiateRegisters(blockName, accessType, accessArea, registerNodes);
     }
 }
@@ -156,7 +155,7 @@ std::string Device::getRegisterList()
     return registerList;
 }
 
-Register* Device::instantiateRegister(ElementXML* registerNode)
+Register* Device::instantiateRegister(const ElementXML& registerNode)
 {
     switch (getPLC()->getBrandID())
     {
@@ -188,17 +187,16 @@ Register* Device::instantiateRegister(ElementXML* registerNode)
     } //switch
 }
 
-void Device::instantiateRegisters(std::string blockName, AccessType accessType, AccessArea accessArea, std::vector<boost::shared_ptr<ElementXML> >& registerNodes)
+void Device::instantiateRegisters(std::string blockName, AccessType accessType, AccessArea accessArea, const std::vector<ElementXML>& registerNodes)
 {
     std::vector<Register*> registerCol;
 
     //LOG(SETUP) << "Ordering registers for block: " <<  blockName << " on Device: " << getLabel();
 
-    std::vector<boost::shared_ptr<ElementXML> >::const_iterator registerIter;
-    for (registerIter = registerNodes.begin(); registerIter != registerNodes.end(); registerIter++)
+    for (auto registerIter = registerNodes.begin(); registerIter != registerNodes.end(); registerIter++)
     {
-        std::string registerName = (*registerIter)->getAttribute("name");
-        Register* pReg = instantiateRegister(registerIter->get());
+        std::string registerName = registerIter->getAttribute("name");
+        Register* pReg = instantiateRegister(*registerIter);
         pReg->setAccessArea(accessArea);
         pReg->setAccessType(accessType);
         pReg->setBlockName(blockName);
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
index 9254145..dcc685d 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
@@ -20,9 +20,6 @@ Contributors:
 #include <vector>
 #include <map>
 
-#include <boost/shared_ptr.hpp>
-#include <boost/ptr_container/ptr_vector.hpp>
-
 namespace Silecs
 {
 class PLC;
@@ -122,7 +119,7 @@ private:
     friend class CNVSendBlockMode;
     friend class CNVSendDeviceMode;
 
-    Device(PLC* thePLC, const ElementXML& deviceNode, boost::ptr_vector<ElementXML>& blockNodes);
+    Device(PLC* thePLC, const ElementXML& deviceNode, const std::vector<ElementXML>& blockNodes);
     virtual ~Device();
 
     inline long& getInputAddress(AccessArea area)
@@ -143,9 +140,9 @@ private:
         return address_;
     }
 
-    Register* instantiateRegister(ElementXML* registerNode);
+    Register* instantiateRegister(const ElementXML& registerNode);
 
-    void instantiateRegisters(std::string blockName, AccessType accessType, AccessArea accessArea, std::vector<boost::shared_ptr<ElementXML> >& registerNodes);
+    void instantiateRegisters(std::string blockName, AccessType accessType, AccessArea accessArea, const std::vector<ElementXML>& registerNodes);
 
     /*!
      * \fn getBlock
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
index 9bbf216..01e0f6c 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
@@ -499,17 +499,14 @@ void PLC::extractDatabase()
             break;
     };
 
-    std::vector<boost::shared_ptr<ElementXML> > classNodes = mappingNode.childList_;
-    std::vector<boost::shared_ptr<ElementXML> >::const_iterator classIter;
-    for (classIter = classNodes.begin(); classIter != classNodes.end(); classIter++)
+    const std::vector<ElementXML>& classNodes = mappingNode.getChildNodes();
+    for (auto& classNode : classNodes)
     {
-        std::string className = (*classIter)->getAttribute("name");
-        boost::ptr_vector<ElementXML> blockNodes = xmlParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[ name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block' or name()='Configuration-Block' or name()='Setting-IO-Block' or name()='Acquisition-IO-Block' or name()='Command-IO-Block']");
-        boost::ptr_vector<ElementXML>::const_iterator blockIter;
+        std::string className = classNode.getAttribute("name");
+        std::vector<ElementXML> blockNodes = xmlParser.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/*[ name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block' or name()='Configuration-Block' or name()='Setting-IO-Block' or name()='Acquisition-IO-Block' or name()='Command-IO-Block']");
 
-        boost::ptr_vector<ElementXML> instanceNodes = xmlParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/Instance");
-        boost::ptr_vector<ElementXML>::const_iterator instanceIter;
-        for (instanceIter = instanceNodes.begin(); instanceIter != instanceNodes.end(); instanceIter++)
+        std::vector<ElementXML> instanceNodes = xmlParser.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/Instance");
+        for (auto instanceIter = instanceNodes.begin(); instanceIter != instanceNodes.end(); instanceIter++)
         {
             Device* pDevice = new Device(this, *instanceIter, blockNodes);
             deviceCol_.push_back(std::make_pair(pDevice->getLabel(), pDevice));
@@ -517,11 +514,11 @@ void PLC::extractDatabase()
                 theHeader_ = pDevice;
         }
 
-        for (blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
+        for (auto blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
         {
             std::string blockName = (*blockIter).getAttribute("name");
-            AccessType accessType = Block::whichAccessType( (*blockIter).name_);
-            LOG((DIAG)) << "The block '" << blockName << " of type '" << (*blockIter).name_ << "' will be created.";
+            AccessType accessType = Block::whichAccessType( (*blockIter).getName());
+            LOG((DIAG)) << "The block '" << blockName << " of type '" << (*blockIter).getName() << "' will be created.";
 
             Block* pBlock = 0;
             // Instantiate Input blocks ------------------------------------------------------
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
index d704aaa..4c66a67 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
@@ -27,36 +27,35 @@ Contributors:
 namespace Silecs
 {
 
-Register::Register(Device* theDevice, ElementXML* registerNode) :
+Register::Register(Device* theDevice, const ElementXML& registerNode) :
                 theDevice_(theDevice), isConfiguration_(false)
 {
-    name_ = registerNode->getAttribute("name");
+    name_ = registerNode.getAttribute("name");
     length_ = 1;
     dimension1_ = 1;
     dimension2_ = 1;
-    std::vector<boost::shared_ptr<ElementXML> > childNodes = registerNode->childList_;
-    std::vector<boost::shared_ptr<ElementXML> >::const_iterator childIter;
-    for (childIter = childNodes.begin(); childIter != childNodes.end(); childIter++)
+    const std::vector<ElementXML>& childNodes = registerNode.getChildNodes();
+    for (auto childIter = childNodes.begin(); childIter != childNodes.end(); childIter++)
     {
         // We have to loop, since there is as well the description-element
-        format_ = whichFormatType( (*childIter)->getAttribute("format"));
-        if ( (*childIter)->hasAttribute("dim"))
-            StringUtilities::fromString(dimension1_, (*childIter)->getAttribute("dim")); // dim is used for 1d-arrays
-        if ( (*childIter)->hasAttribute("dim1"))
-            StringUtilities::fromString(dimension1_, (*childIter)->getAttribute("dim1"));
-        if ( (*childIter)->hasAttribute("dim2"))
-            StringUtilities::fromString(dimension2_, (*childIter)->getAttribute("dim2"));
-        if ( (*childIter)->hasAttribute("string-length"))
-            StringUtilities::fromString(length_, (*childIter)->getAttribute("string-length"));
+        format_ = whichFormatType(childIter->getAttribute("format"));
+        if (childIter->hasAttribute("dim"))
+            StringUtilities::fromString(dimension1_, childIter->getAttribute("dim")); // dim is used for 1d-arrays
+        if (childIter->hasAttribute("dim1"))
+            StringUtilities::fromString(dimension1_, childIter->getAttribute("dim1"));
+        if (childIter->hasAttribute("dim2"))
+            StringUtilities::fromString(dimension2_, childIter->getAttribute("dim2"));
+        if (childIter->hasAttribute("string-length"))
+            StringUtilities::fromString(length_, childIter->getAttribute("string-length"));
     }
-    StringUtilities::fromString(size_, registerNode->getAttribute("size"));
-    StringUtilities::fromString(memSize_, registerNode->getAttribute("mem-size"));
-    StringUtilities::fromString(address_, registerNode->getAttribute("address"));
-    if ( registerNode->hasAttribute("bit-number"))
-        StringUtilities::fromString(bitNumber_, registerNode->getAttribute("bit-number"));
+    StringUtilities::fromString(size_, registerNode.getAttribute("size"));
+    StringUtilities::fromString(memSize_, registerNode.getAttribute("mem-size"));
+    StringUtilities::fromString(address_, registerNode.getAttribute("address"));
+    if (registerNode.hasAttribute("bit-number"))
+        StringUtilities::fromString(bitNumber_, registerNode.getAttribute("bit-number"));
 
 
-    if(registerNode->name_ == "Configuration-Register")
+    if(registerNode.getName() == "Configuration-Register")
         isConfiguration_ = true;
 
     isInitialized_ = false; //register not initialized yet (used for output registers)
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
index 2c8e3dd..7e0a6c0 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
@@ -15,7 +15,6 @@ Contributors:
 #define _SILECS_REGISTER_H_
 
 #include <stdint.h>
-#include <boost/shared_ptr.hpp>
 #include <string>
 
 namespace Silecs
@@ -1653,7 +1652,7 @@ public:
 
     /// @cond
 protected:
-    Register(Device* theDevice, ElementXML* registerNode);
+    Register(Device* theDevice, const ElementXML& registerNode);
     virtual ~Register();
 
     // export register extraction methods
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp
index 5c0cd06..4f74f2e 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp
@@ -25,6 +25,42 @@ bool isInitialized_ = false;
 namespace Silecs
 {
 
+bool ElementXML::hasAttribute(const std::string& attributeName) const
+{
+    for (auto attributeIter = attributeList_.begin(); attributeIter != attributeList_.end(); ++attributeIter)
+    {
+        if (attributeIter->name_ == attributeName)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+std::string ElementXML::getAttribute(const std::string& attributeName) const
+{
+    for (auto attributeIter = attributeList_.begin(); attributeIter != attributeList_.end(); ++attributeIter)
+    {
+        if (attributeIter->name_ == attributeName)
+        {
+            return attributeIter->value_;
+        }
+    }
+    std::ostringstream message;
+    message << "The XML Attribute '" << attributeName << "' was not found";
+    throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+}
+
+const std::vector<ElementXML>& ElementXML::getChildNodes() const
+{
+    return childList_;
+}
+
+const std::string& ElementXML::getName() const
+{
+    return name_;
+}
+
 XMLParser::XMLParser(const std::string& fileName, bool validateFile) :
                 fileName_(fileName)
 {
@@ -88,10 +124,10 @@ void XMLParser::fillElement(xmlNodePtr node, ElementXML& element) const
         xmlAttrPtr curAttr;
         for (curAttr = node->properties; curAttr != NULL; curAttr = curAttr->next)
         {
-            boost::shared_ptr<AttributeXML> attribute(new AttributeXML());
-            attribute->name_ = reinterpret_cast<const char*>(curAttr->name);
-            value = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attribute->name_.c_str()));
-            attribute->value_ = reinterpret_cast<const char*>(value);
+            AttributeXML attribute;
+            attribute.name_ = reinterpret_cast<const char*>(curAttr->name);
+            value = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attribute.name_.c_str()));
+            attribute.value_ = reinterpret_cast<const char*>(value);
             xmlFree(value);
             value = NULL;
             element.attributeList_.push_back(attribute);
@@ -105,17 +141,17 @@ void XMLParser::fillElement(xmlNodePtr node, ElementXML& element) const
         {
             if ( (curNode->type == XML_ELEMENT_NODE))
             {
-                boost::shared_ptr<ElementXML> child(new ElementXML());
-                fillElement(curNode, *child);
-                element.childList_.push_back(child);
+                ElementXML child;
+                fillElement(curNode, child);
+                element.childList_.push_back(std::move(child));
             }
         }
     }
 }
 
-boost::optional<boost::ptr_vector<ElementXML> > XMLParser::getElementsFromXPath(const std::string& xpathExpression) const
+std::vector<ElementXML> XMLParser::getElementsFromXPathInner(const std::string& xpathExpression) const
 {
-    boost::optional<boost::ptr_vector<ElementXML> > elements;
+    std::vector<ElementXML> elements;
     // Load the XML document
     const xmlDocPtr document = xmlParseFile(fileName_.c_str());
     if (document == NULL)
@@ -144,13 +180,9 @@ boost::optional<boost::ptr_vector<ElementXML> > XMLParser::getElementsFromXPath(
     {
         for (int i = 0; i < xpathObject->nodesetval->nodeNr; ++i)
         {
-            std::unique_ptr<ElementXML> element(new ElementXML());
-            fillElement(xpathObject->nodesetval->nodeTab[i], *element);
-            if (!elements)
-            {
-                elements = boost::ptr_vector<ElementXML>();
-            }
-            elements->push_back(element.release());
+            ElementXML element;
+            fillElement(xpathObject->nodesetval->nodeTab[i], element);
+            elements.push_back(std::move(element));
         }
     }
     // Cleanup
@@ -160,40 +192,34 @@ boost::optional<boost::ptr_vector<ElementXML> > XMLParser::getElementsFromXPath(
     return elements;
 }
 
-boost::ptr_vector<ElementXML> XMLParser::getElementsFromXPath_throwIfEmpty(const std::string& xpathExpression) const
+std::vector<ElementXML> XMLParser::getElementsFromXPath(const std::string& xpathExpression) const
 {
-    boost::optional<boost::ptr_vector<ElementXML> > result = getElementsFromXPath(xpathExpression);
-    if (!result)
-    {
-        std::ostringstream message;
-        message << "The xpathExpression: '" << xpathExpression << "' did not find a match";
-        throw SilecsException(__FILE__, __LINE__, message.str().c_str());
-    }
-    if (result.get().size() == 0)
+    auto result = getElementsFromXPathInner(xpathExpression);
+    if (result.empty())
     {
         std::ostringstream message;
         message << "The xpathExpression: '" << xpathExpression << "' returned an empty collection of xml-Elements";
         throw SilecsException(__FILE__, __LINE__, message.str().c_str());
     }
-    return result.get();
+    return result;
 }
 
 ElementXML XMLParser::getFirstElementFromXPath(const std::string& xpathExpression) const
 {
-    boost::optional<boost::ptr_vector<ElementXML> > result = getElementsFromXPath_throwIfEmpty(xpathExpression);
-    return result.get()[0];
+    auto result = getElementsFromXPath(xpathExpression);
+    return std::move(result.front());
 }
 
 ElementXML XMLParser::getSingleElementFromXPath(const std::string& xpathExpression) const
 {
-    boost::optional<boost::ptr_vector<ElementXML> > result = getElementsFromXPath_throwIfEmpty(xpathExpression);
-    if (result.get().size() > 1)
+    auto result = getElementsFromXPath(xpathExpression);
+    if (result.size() > 1)
     {
         std::ostringstream message;
         message << "The xpathExpression: '" << xpathExpression << "' returns more than one XML-Elements";
         throw SilecsException(__FILE__, __LINE__, message.str().c_str());
     }
-    return result.get()[0];
+    return std::move(result.front());
 }
 
 xmlChar* XMLParser::ConvertInput(const char *in, const char *encoding)
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h
index 39ff3e5..5adaabd 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h
@@ -14,9 +14,6 @@ Contributors:
 #ifndef _XMLPARSER_HPP_
 #define _XMLPARSER_HPP_
 
-#include <boost/optional.hpp>
-#include <boost/ptr_container/ptr_vector.hpp>
-#include <boost/shared_ptr.hpp>
 #include <string>
 #include <vector>
 #include <iostream>
@@ -61,7 +58,16 @@ public:
  */
 class ElementXML
 {
+friend class XMLParser;
 public:
+    bool hasAttribute(const std::string& attributeName) const;
+
+    std::string getAttribute(const std::string& attributeName) const;
+
+    const std::vector<ElementXML>& getChildNodes() const;
+
+    const std::string& getName() const;
+private:
     /*!
      * \brief name of the xml-node
      */
@@ -75,40 +81,12 @@ public:
     /*!
      * \brief list of attributes of the element
      */
-    std::vector<boost::shared_ptr<AttributeXML> > attributeList_;
+    std::vector<AttributeXML> attributeList_;
 
     /*!
      * \brief list of children of the element
      */
-    std::vector<boost::shared_ptr<ElementXML> > childList_;
-
-    bool hasAttribute(const std::string& attributeName) const
-    {
-        std::vector<boost::shared_ptr<AttributeXML> >::const_iterator attributeIter;
-        for (attributeIter = attributeList_.begin(); attributeIter != attributeList_.end(); ++attributeIter)
-        {
-            if ( (*attributeIter)->name_ == attributeName)
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    std::string getAttribute(const std::string& attributeName) const
-    {
-        std::vector<boost::shared_ptr<AttributeXML> >::const_iterator attributeIter;
-        for (attributeIter = attributeList_.begin(); attributeIter != attributeList_.end(); ++attributeIter)
-        {
-            if ( (*attributeIter)->name_ == attributeName)
-            {
-                return (*attributeIter)->value_;
-            }
-        }
-        std::ostringstream message;
-        message << "The XML Attribute '" << attributeName << "' was not found";
-        throw SilecsException(__FILE__, __LINE__, message.str().c_str());
-    }
+    std::vector<ElementXML> childList_;
 };
 
 /*!
@@ -130,19 +108,23 @@ public:
     /*!
      * \brief destructor
      */
-    virtual ~XMLParser();
+    ~XMLParser();
 
     /*!
      * \brief Retrieve the elements identified by the XPath expression from the XML file
      * \param xpathExpression The XPath expression
      */
-    virtual boost::optional<boost::ptr_vector<ElementXML> > getElementsFromXPath(const std::string& xpathExpression) const;
 
-    virtual ElementXML getSingleElementFromXPath(const std::string& xpathExpression) const;
+    ElementXML getSingleElementFromXPath(const std::string& xpathExpression) const;
 
-    virtual ElementXML getFirstElementFromXPath(const std::string& xpathExpression) const;
+    ElementXML getFirstElementFromXPath(const std::string& xpathExpression) const;
 
-    virtual boost::ptr_vector<ElementXML> getElementsFromXPath_throwIfEmpty(const std::string& xpathExpression) const;
+    /*!
+     * \brief Retrieve the elements identified by the XPath expression from the XML file. If no
+              elements are found an exception is thrown.
+     * \param xpathExpression The XPath expression
+     */
+    std::vector<ElementXML> getElementsFromXPath(const std::string& xpathExpression) const;
 
     /*!
      * \brief Has to be executed from the main-thread before this class can be used
@@ -156,6 +138,14 @@ public:
 
 private:
 
+    /*!
+     * \brief Retrieve the elements identified by the XPath expression from the XML file. If no
+              elements are found an empty vector is returned. This method is used by the public
+              facing getElementsFromXPath which throws if no elements are found.
+     * \param xpathExpression The XPath expression
+     */
+    std::vector<ElementXML> getElementsFromXPathInner(const std::string& xpathExpression) const;
+
     /*!
      * \brief removes carrier return from string
      * \param s the string to remove the carrier from
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
index e5bab31..03ae945 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
@@ -759,10 +759,10 @@ void diagnosticToolMainView::fillClassNameComboBox()
 {
     Utils::logInfo(ui->console,"Loading deploy file: " + deployFile);
     XMLParser parserDeploy(deployFile,true);
-    boost::ptr_vector<ElementXML> classNodes;
+    std::vector<ElementXML> classNodes;
     try
     {
-        classNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/SilecsDesign");
+        classNodes = parserDeploy.getElementsFromXPath("/SILECS-Deploy/SilecsDesign");
     }
     catch(const Silecs::SilecsException& ex2)
     {
@@ -771,8 +771,7 @@ void diagnosticToolMainView::fillClassNameComboBox()
     }
 
     QStringList list;
-    boost::ptr_vector<ElementXML>::const_iterator classIter;
-    for(classIter = classNodes.begin(); classIter != classNodes.end(); classIter++)
+    for(auto classIter = classNodes.begin(); classIter != classNodes.end(); classIter++)
     {
         QString className(classIter->getAttribute("silecs-design-name").c_str());
         if(!list.contains(className))
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
index 659e2b5..3ecf320 100755
--- a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
@@ -127,9 +127,8 @@ Item *silecsModule::generateTree(string className, string deployFile)
     string deployName = deployUnitNode.getAttribute("name");
     std::size_t deployFolderPos = deployFile.find(deployName);
     string deployProjectPath = deployFile.substr(0,deployFolderPos) + deployName;
-    boost::ptr_vector<ElementXML> controllerNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/Controller");
-    boost::ptr_vector<ElementXML>::const_iterator controllerIter;
-    for(controllerIter = controllerNodes.begin(); controllerIter != controllerNodes.end(); controllerIter++)
+    std::vector<ElementXML> controllerNodes = parserDeploy.getElementsFromXPath("/SILECS-Deploy/Controller");
+    for(auto controllerIter = controllerNodes.begin(); controllerIter != controllerNodes.end(); controllerIter++)
     {
         std::string plcName = controllerIter->getAttribute("host-name");
         Silecs::PLC *plc;
@@ -149,11 +148,11 @@ Item *silecsModule::generateTree(string className, string deployFile)
         // add plc on the tree
         Item *plcItem = Utils::addTreeItem(root,QString::fromStdString(plcName),"",QString::fromStdString(PLC_TYPE),plc,":/Images/PLC.png");
 
-        boost::ptr_vector<ElementXML> instances;
+        std::vector<ElementXML> instances;
         XMLParser parseParam(parameterFile,true);
         try
         {
-            instances = parseParam.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/Instance");
+            instances = parseParam.getElementsFromXPath("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='" + className + "']/Instance");
         }
         catch(const Silecs::SilecsException& ex2)
         {
@@ -161,8 +160,7 @@ Item *silecsModule::generateTree(string className, string deployFile)
             break;
         }
 
-        boost::ptr_vector<ElementXML>::iterator pInstanceIter;
-        for(pInstanceIter = instances.begin(); pInstanceIter != instances.end(); ++pInstanceIter)
+        for(auto pInstanceIter = instances.begin(); pInstanceIter != instances.end(); ++pInstanceIter)
         {
             std::string deviceName = pInstanceIter->getAttribute("label");
             Utils::logInfo(messageConsole_,"found device: '" + deviceName + "' in parameter-file");
-- 
GitLab