Put empty path checking to a function

Instead of checking for .empty() everywhere I'm pushing path fragments,
do it once in a new function called pushFragment, which resolves nodeup_
fragments.

Change-Id: I2528f814991eed5218d8272ea386bd732a7448a5
diff --git a/src/ast_path.cpp b/src/ast_path.cpp
index 0079962..318aada 100644
--- a/src/ast_path.cpp
+++ b/src/ast_path.cpp
@@ -258,3 +258,27 @@
 
     return res;
 }
+
+namespace {
+template <typename NodeType>
+void impl_pushFragment(std::vector<NodeType>& where, const NodeType& what)
+{
+    if (std::holds_alternative<nodeup_>(what.m_suffix)) {
+        if (!where.empty()) { // Allow going up, when already at root
+            where.pop_back();
+        }
+    } else {
+        where.push_back(what);
+    }
+}
+}
+
+void schemaPath_::pushFragment(const schemaNode_& fragment)
+{
+    impl_pushFragment(m_nodes, fragment);
+}
+
+void dataPath_::pushFragment(const dataNode_& fragment)
+{
+    impl_pushFragment(m_nodes, fragment);
+}
diff --git a/src/ast_path.hpp b/src/ast_path.hpp
index da99a26..91268e6 100644
--- a/src/ast_path.hpp
+++ b/src/ast_path.hpp
@@ -117,6 +117,8 @@
     Scope m_scope = Scope::Relative;
     std::vector<schemaNode_> m_nodes;
     TrailingSlash m_trailingSlash = TrailingSlash::NonPresent;
+    // @brief Pushes a new fragment. Pops a fragment if it's nodeup_
+    void pushFragment(const schemaNode_& fragment);
 };
 
 struct dataPath_ {
@@ -124,6 +126,9 @@
     Scope m_scope = Scope::Relative;
     std::vector<dataNode_> m_nodes;
     TrailingSlash m_trailingSlash = TrailingSlash::NonPresent;
+
+    // @brief Pushes a new fragment. Pops a fragment if it's nodeup_
+    void pushFragment(const dataNode_& fragment);
 };
 
 std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node);
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 43fc329..3543e93 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -279,13 +279,7 @@
         }
 
         for (const auto& fragment : suffix.m_nodes) {
-            if (std::holds_alternative<nodeup_>(fragment.m_suffix)) {
-                if (!res.m_nodes.empty()) { // Allow going up, when already at root
-                    res.m_nodes.pop_back();
-                }
-            } else {
-                res.m_nodes.push_back(fragment);
-            }
+            res.pushFragment(fragment);
         }
 
         return res;
diff --git a/src/parser.cpp b/src/parser.cpp
index 4911fac..bf00a7e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -86,13 +86,7 @@
         m_curDir = name;
     } else {
         for (const auto& it : name.m_nodes) {
-            if (std::holds_alternative<nodeup_>(it.m_suffix)) {
-                if (!m_curDir.m_nodes.empty()) { // Allow going up, when already at root
-                    m_curDir.m_nodes.pop_back();
-                }
-            } else {
-                m_curDir.m_nodes.push_back(it);
-            }
+            m_curDir.pushFragment(it);
         }
     }
 }
diff --git a/src/parser_context.cpp b/src/parser_context.cpp
index d1ebe06..17f6604 100644
--- a/src/parser_context.cpp
+++ b/src/parser_context.cpp
@@ -39,20 +39,10 @@
 
 void ParserContext::pushPathFragment(const dataNode_& node)
 {
-    auto pushNode = [] (auto& where, const auto& what) {
-        if (std::holds_alternative<nodeup_>(what.m_suffix)) {
-            if (!where.m_nodes.empty()) { // Allow going up, when already at root
-                where.m_nodes.pop_back();
-            }
-        } else {
-            where.m_nodes.push_back(what);
-        }
-    };
-
     if (m_curPath.type() == typeid(dataPath_)) {
-        pushNode(boost::get<dataPath_>(m_curPath), node);
+        boost::get<dataPath_>(m_curPath).pushFragment(node);
     } else {
-        pushNode(boost::get<schemaPath_>(m_curPath), dataNodeToSchemaNode(node));
+        boost::get<schemaPath_>(m_curPath).pushFragment(dataNodeToSchemaNode(node));
     }
 }