aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-05-15 17:23:13 +0200
committerAdrian Kummerländer2014-05-15 17:23:13 +0200
commitec6abad74348e9b577e1dd63b41d65263bb0334a (patch)
tree95d35491c723b12687e067ee2a480b37daf19da2
parent5fbca0993146982ab1dbb0d352c1e15e40b3de22 (diff)
downloadInputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar.gz
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar.bz2
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar.lz
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar.xz
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.tar.zst
InputXSLT-ec6abad74348e9b577e1dd63b41d65263bb0334a.zip
Adapted FunctionBase template to accept multiple argument types
* FunctionBase::argument_tuple is a std::tuple specialization type specialized on the argument types passed inside the variadic template argument of FunctionBase * added tuple Mapper and XObjectValue helper namespaces containing recursive tuple construction and XObjectPtr value extraction logic * changed all external function implementations accordingly * this change was implemented to uniformly support different external function argument types than std::string
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/function/base.h40
-rw-r--r--src/function/read_directory.cc4
-rw-r--r--src/function/read_directory.h7
-rw-r--r--src/function/read_file.cc4
-rw-r--r--src/function/read_file.h7
-rw-r--r--src/function/read_xml_file.cc6
-rw-r--r--src/function/read_xml_file.h7
-rw-r--r--src/function/transform.cc6
-rw-r--r--src/function/transform.h8
-rw-r--r--src/support/tuple/mapper.h62
-rw-r--r--src/support/tuple/xobject_value.cc18
-rw-r--r--src/support/tuple/xobject_value.h17
13 files changed, 144 insertions, 43 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73443c6..8ffcb49 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ set(
src/support/filesystem_context.cc
src/support/stylesheet_parameter_guard.cc
src/support/xalan_string.cc
+ src/support/tuple/xobject_value.cc
src/support/dom/document_cache.cc
src/support/dom/document_cache_item.cc
)
diff --git a/src/function/base.h b/src/function/base.h
index 7fbd818..b74a7d8 100644
--- a/src/function/base.h
+++ b/src/function/base.h
@@ -1,29 +1,28 @@
#ifndef INPUTXSLT_SRC_FUNCTION_BASE_H_
#define INPUTXSLT_SRC_FUNCTION_BASE_H_
-#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include <xalanc/XPath/XObjectFactory.hpp>
#include <xalanc/XPath/Function.hpp>
#include <xalanc/XPath/XObject.hpp>
#include <memory>
-#include <algorithm>
-#include <array>
+#include <tuple>
#include "common.h"
#include "support/xalan_string.h"
+#include "support/tuple/mapper.h"
#include "support/dom/document_cache.h"
#include "support/filesystem_context.h"
namespace InputXSLT {
template <
- class Implementation,
- std::size_t ArgumentCount
+ typename Implementation,
+ typename... Types
>
class FunctionBase : public xalan::Function {
public:
- typedef std::array<std::string, ArgumentCount> argument_array;
+ typedef std::tuple<Types...> argument_tuple;
FunctionBase():
document_cache_(std::make_shared<DomDocumentCache>()) { }
@@ -31,34 +30,23 @@ class FunctionBase : public xalan::Function {
virtual xalan::XObjectPtr execute(
xalan::XPathExecutionContext& executionContext,
xalan::XalanNode* context,
- const XObjectArgVectorType& rawArguments,
+ const XObjectArgVectorType& arguments,
const xalan::Locator* locator
) const {
this->validateArguments(
- rawArguments,
+ arguments,
executionContext,
context,
locator
);
- argument_array pathArguments;
-
- std::transform(
- rawArguments.begin(),
- rawArguments.end(),
- pathArguments.begin(),
- [](const xalan::XObjectPtr& ptr) -> std::string {
- return toString(ptr->str());
- }
- );
-
xalan::XalanDocument* const domDocument(
this->document_cache_->create(
static_cast<Implementation*>(
const_cast<FunctionBase*>(this)
)->constructDocument(
FilesystemContext(locator),
- pathArguments
+ Mapper::template construct<argument_tuple>(arguments)
)
)
);
@@ -91,8 +79,8 @@ class FunctionBase : public xalan::Function {
const xalan::XalanDOMString& getError(
xalan::XalanDOMString& result) const {
result.assign(std::string(
- "The function expects " +
- std::to_string(ArgumentCount) +
+ "The function expects " +
+ std::to_string(std::tuple_size<argument_tuple>::value) +
" argument(s) of type string."
).data());
@@ -100,20 +88,20 @@ class FunctionBase : public xalan::Function {
}
inline void validateArguments(
- const XObjectArgVectorType& rawArguments,
+ const XObjectArgVectorType& arguments,
xalan::XPathExecutionContext& executionContext,
xalan::XalanNode* context,
const xalan::Locator* locator
) const {
const bool anyNull = std::any_of(
- rawArguments.begin(),
- rawArguments.end(),
+ arguments.begin(),
+ arguments.end(),
[](const xalan::XObjectPtr& ptr) -> bool {
return ptr.null();
}
);
- if ( rawArguments.size() != ArgumentCount || anyNull ) {
+ if ( arguments.size() != std::tuple_size<argument_tuple>::value || anyNull ) {
xalan::XPathExecutionContext::GetAndReleaseCachedString guard(
executionContext
);
diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc
index 54d3d0d..4060523 100644
--- a/src/function/read_directory.cc
+++ b/src/function/read_directory.cc
@@ -11,10 +11,10 @@ namespace InputXSLT {
xercesc::DOMDocument* FunctionReadDirectory::constructDocument(
const InputXSLT::FilesystemContext& fsContext,
- const FunctionBase::argument_array& arguments
+ const FunctionBase::argument_tuple& arguments
) {
const boost::filesystem::path directoryPath(
- fsContext.resolve(arguments[0])
+ fsContext.resolve(std::get<0>(arguments))
);
xercesc::DOMDocument* const domDocument(
diff --git a/src/function/read_directory.h b/src/function/read_directory.h
index 9dc3869..562e191 100644
--- a/src/function/read_directory.h
+++ b/src/function/read_directory.h
@@ -5,7 +5,10 @@
namespace InputXSLT {
-class FunctionReadDirectory : public FunctionBase<FunctionReadDirectory, 1> {
+class FunctionReadDirectory : public FunctionBase<
+ FunctionReadDirectory,
+ std::string
+> {
public:
using FunctionBase::FunctionBase;
@@ -14,7 +17,7 @@ class FunctionReadDirectory : public FunctionBase<FunctionReadDirectory, 1> {
xercesc::DOMDocument* constructDocument(
const FilesystemContext&,
- const FunctionBase::argument_array&
+ const FunctionBase::argument_tuple&
);
};
diff --git a/src/function/read_file.cc b/src/function/read_file.cc
index 19ca296..8e14f41 100644
--- a/src/function/read_file.cc
+++ b/src/function/read_file.cc
@@ -26,10 +26,10 @@ namespace InputXSLT {
xercesc::DOMDocument* FunctionReadFile::constructDocument(
const FilesystemContext& fsContext,
- const FunctionBase::argument_array& arguments
+ const FunctionBase::argument_tuple& arguments
) {
const boost::filesystem::path filePath(
- fsContext.resolve(arguments[0])
+ fsContext.resolve(std::get<0>(arguments))
);
xercesc::DOMDocument* const domDocument(
diff --git a/src/function/read_file.h b/src/function/read_file.h
index e7b746c..7b17583 100644
--- a/src/function/read_file.h
+++ b/src/function/read_file.h
@@ -5,7 +5,10 @@
namespace InputXSLT {
-class FunctionReadFile : public FunctionBase<FunctionReadFile, 1> {
+class FunctionReadFile : public FunctionBase<
+ FunctionReadFile,
+ std::string
+> {
public:
using FunctionBase::FunctionBase;
@@ -14,7 +17,7 @@ class FunctionReadFile : public FunctionBase<FunctionReadFile, 1> {
xercesc::DOMDocument* constructDocument(
const FilesystemContext&,
- const FunctionBase::argument_array&
+ const FunctionBase::argument_tuple&
);
};
diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc
index cf2cadd..6e89701 100644
--- a/src/function/read_xml_file.cc
+++ b/src/function/read_xml_file.cc
@@ -1,5 +1,7 @@
#include "read_xml_file.h"
+#include <xalanc/XSLT/XSLTInputSource.hpp>
+
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMElement.hpp>
@@ -34,10 +36,10 @@ namespace InputXSLT {
xercesc::DOMDocument* FunctionReadXmlFile::constructDocument(
const FilesystemContext& fsContext,
- const FunctionBase::argument_array& arguments
+ const FunctionBase::argument_tuple& arguments
) {
const boost::filesystem::path filePath(
- fsContext.resolve(arguments[0])
+ fsContext.resolve(std::get<0>(arguments))
);
xercesc::DOMDocument* const domDocument(
diff --git a/src/function/read_xml_file.h b/src/function/read_xml_file.h
index 423f0a2..5355449 100644
--- a/src/function/read_xml_file.h
+++ b/src/function/read_xml_file.h
@@ -5,7 +5,10 @@
namespace InputXSLT {
-class FunctionReadXmlFile : public FunctionBase<FunctionReadXmlFile, 1> {
+class FunctionReadXmlFile : public FunctionBase<
+ FunctionReadXmlFile,
+ std::string
+> {
public:
using FunctionBase::FunctionBase;
@@ -14,7 +17,7 @@ class FunctionReadXmlFile : public FunctionBase<FunctionReadXmlFile, 1> {
xercesc::DOMDocument* constructDocument(
const FilesystemContext&,
- const FunctionBase::argument_array&
+ const FunctionBase::argument_tuple&
);
};
diff --git a/src/function/transform.cc b/src/function/transform.cc
index 5c53044..be06037 100644
--- a/src/function/transform.cc
+++ b/src/function/transform.cc
@@ -11,14 +11,14 @@ namespace InputXSLT {
xercesc::DOMDocument* FunctionTransform::constructDocument(
const InputXSLT::FilesystemContext& fsContext,
- const FunctionBase::argument_array& arguments
+ const FunctionBase::argument_tuple& arguments
) {
const boost::filesystem::path transformationPath(
- fsContext.resolve(arguments[0])
+ fsContext.resolve(std::get<0>(arguments))
);
const boost::filesystem::path targetPath(
- fsContext.resolve(arguments[1])
+ fsContext.resolve(std::get<1>(arguments))
);
xercesc::DOMDocument* const domDocument(
diff --git a/src/function/transform.h b/src/function/transform.h
index fc735f0..2be8925 100644
--- a/src/function/transform.h
+++ b/src/function/transform.h
@@ -5,7 +5,11 @@
namespace InputXSLT {
-class FunctionTransform : public FunctionBase<FunctionTransform, 2> {
+class FunctionTransform : public FunctionBase<
+ FunctionTransform,
+ std::string,
+ std::string
+> {
public:
using FunctionBase::FunctionBase;
@@ -14,7 +18,7 @@ class FunctionTransform : public FunctionBase<FunctionTransform, 2> {
xercesc::DOMDocument* constructDocument(
const FilesystemContext&,
- const FunctionBase::argument_array&
+ const FunctionBase::argument_tuple&
);
};
diff --git a/src/support/tuple/mapper.h b/src/support/tuple/mapper.h
new file mode 100644
index 0000000..c95365e
--- /dev/null
+++ b/src/support/tuple/mapper.h
@@ -0,0 +1,62 @@
+#ifndef INPUTXSLT_SRC_SUPPORT_TUPLE_MAPPER_H_
+#define INPUTXSLT_SRC_SUPPORT_TUPLE_MAPPER_H_
+
+#include <xalanc/XPath/XObject.hpp>
+
+#include <tuple>
+#include <type_traits>
+
+#include "common.h"
+#include "xobject_value.h"
+
+namespace InputXSLT {
+
+template <bool Condition>
+using enable_if = typename std::enable_if<Condition, std::size_t>::type;
+
+namespace Mapper {
+ template <
+ typename Target,
+ std::size_t Index = 0,
+ typename Current = std::tuple<>,
+ enable_if<Index == std::tuple_size<Target>::value> = 0
+ >
+ inline Target construct(
+ const xalan::XPathExecutionContext::XObjectArgVectorType&,
+ Current&& current
+ ) {
+ return current;
+ }
+
+ template <
+ typename Target,
+ std::size_t Index = 0,
+ typename Current = std::tuple<>,
+ enable_if<Index < std::tuple_size<Target>::value> = 0
+ >
+ inline Target construct(
+ const xalan::XPathExecutionContext::XObjectArgVectorType& source,
+ Current&& current = std::tuple<>()
+ ) {
+ return construct<
+ Target,
+ Index + 1
+ >(
+ source,
+ std::tuple_cat(
+ current,
+ std::make_tuple(
+ XObjectValue::get<
+ typename std::tuple_element<Index, Target>::type
+ >(
+ source[Index]
+ )
+ )
+ )
+ );
+ }
+};
+
+}
+
+#endif // INPUTXSLT_SRC_SUPPORT_TUPLE_MAPPER_H_
diff --git a/src/support/tuple/xobject_value.cc b/src/support/tuple/xobject_value.cc
new file mode 100644
index 0000000..3883436
--- /dev/null
+++ b/src/support/tuple/xobject_value.cc
@@ -0,0 +1,18 @@
+#include "xobject_value.h"
+
+#include <string>
+
+#include "support/xalan_string.h"
+
+namespace InputXSLT {
+
+namespace XObjectValue {
+
+template <>
+std::string get<std::string>(const xalan::XObjectPtr& ptr) {
+ return toString(ptr->str());
+}
+
+}
+
+}
diff --git a/src/support/tuple/xobject_value.h b/src/support/tuple/xobject_value.h
new file mode 100644
index 0000000..bb602a4
--- /dev/null
+++ b/src/support/tuple/xobject_value.h
@@ -0,0 +1,17 @@
+#ifndef INPUTXSLT_SRC_SUPPORT_TUPLE_XOBJECT_VALUE_H_
+#define INPUTXSLT_SRC_SUPPORT_TUPLE_XOBJECT_VALUE_H_
+
+#include <xalanc/XPath/XObject.hpp>
+
+#include "common.h"
+
+namespace InputXSLT {
+
+namespace XObjectValue {
+ template <typename Type>
+ Type get(const xalan::XObjectPtr&);
+}
+
+}
+
+#endif // INPUTXSLT_SRC_SUPPORT_TUPLE_XOBJECT_VALUE_H_