From f6ff54c492df81018cf48da039ee681508f88e46 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sat, 16 Aug 2014 23:30:36 +0200 Subject: Implemented primitive optional parameter support for external functions * renamed FunctionExternalTextFormatter into FunctionExternalCommand ** the goal is to provide a general interface to a variety of external commands *** e.g. not just text formatters but system utilities for file management and so on ** this requires the stdin parameter to be optional as not all external commands require stdin input * implemented "filter_derived" helper template to determine amount of optional parameters ** optional parameters are defined as "boost::optional" specializations *** they in turn can be detected by checking if "boost::optional_detail::optional_tag" is a base class * "callConstructDocument" member method of "FunctionBase" performs additional bounds checking of parameter vector * "boost::optional" specific member overload was added to "XObjectValue" helper class ** we will have to provide full specializations for all optional types as C++ prohibits partial member function template specialization * renamed the external function in "PlattformGuard" * changed README.md and test cases accordingly --- src/function/base.h | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'src/function/base.h') diff --git a/src/function/base.h b/src/function/base.h index 2d1e4c4..a8f93b9 100644 --- a/src/function/base.h +++ b/src/function/base.h @@ -5,6 +5,8 @@ #include #include +#include + #include #include @@ -14,6 +16,7 @@ #include "support/include_entity_resolver.h" #include "support/dom/document_cache.h" #include "support/type/sequence.h" +#include "support/type/filter.h" #include "support/type/xobject_value.h" namespace InputXSLT { @@ -23,7 +26,13 @@ template < typename... Types > class FunctionBase : public xalan::Function { - static const std::size_t parameter_count = sizeof...(Types); + static const std::size_t parameter_count = sizeof...(Types); + static const std::size_t optional_parameter_count = std::tuple_size< + typename filter_derived< + boost::optional_detail::optional_tag, + Types... + >::type + >::value; public: FunctionBase(IncludeEntityResolver* resolver): @@ -108,16 +117,20 @@ class FunctionBase : public xalan::Function { valueGetter.get - >::type>(parameters[Index])... + >::type>( + Index < parameters.size() + ? parameters[Index] + : xalan::XObjectPtr() + )... ) ); } inline void validateParameters( - const XObjectArgVectorType& parameters, + const XObjectArgVectorType& parameters, xalan::XPathExecutionContext& executionContext, - xalan::XalanNode* context, - const xalan::Locator* locator + xalan::XalanNode* context, + const xalan::Locator* locator ) const { const bool anyNull = std::any_of( parameters.begin(), @@ -127,7 +140,9 @@ class FunctionBase : public xalan::Function { } ); - if ( parameters.size() != parameter_count || anyNull ) { + if ( parameters.size() > parameter_count || + parameters.size() < optional_parameter_count || + anyNull ) { xalan::XPathExecutionContext::GetAndReleaseCachedString guard( executionContext ); -- cgit v1.2.3