diff options
author | Adrian Kummerländer | 2014-05-15 17:23:13 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-05-15 17:23:13 +0200 |
commit | ec6abad74348e9b577e1dd63b41d65263bb0334a (patch) | |
tree | 95d35491c723b12687e067ee2a480b37daf19da2 | |
parent | 5fbca0993146982ab1dbb0d352c1e15e40b3de22 (diff) | |
download | InputXSLT-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.txt | 1 | ||||
-rw-r--r-- | src/function/base.h | 40 | ||||
-rw-r--r-- | src/function/read_directory.cc | 4 | ||||
-rw-r--r-- | src/function/read_directory.h | 7 | ||||
-rw-r--r-- | src/function/read_file.cc | 4 | ||||
-rw-r--r-- | src/function/read_file.h | 7 | ||||
-rw-r--r-- | src/function/read_xml_file.cc | 6 | ||||
-rw-r--r-- | src/function/read_xml_file.h | 7 | ||||
-rw-r--r-- | src/function/transform.cc | 6 | ||||
-rw-r--r-- | src/function/transform.h | 8 | ||||
-rw-r--r-- | src/support/tuple/mapper.h | 62 | ||||
-rw-r--r-- | src/support/tuple/xobject_value.cc | 18 | ||||
-rw-r--r-- | src/support/tuple/xobject_value.h | 17 |
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_ |