aboutsummaryrefslogtreecommitdiff
path: root/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-08-10 13:09:42 +0200
committerAdrian Kummerlaender2014-08-10 13:09:42 +0200
commitf4043ec1e9f02efc7f653274b9e4e22ef2782a51 (patch)
tree7094d038dd30eef441b6895a2ac99daf5720e7d4 /articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
parent8d7f2c536f3c48d17b1de244fe6713f4d4499fd5 (diff)
downloadblog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.gz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.bz2
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.lz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.xz
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.tar.zst
blog_content-f4043ec1e9f02efc7f653274b9e4e22ef2782a51.zip
Switched content formatter to kramdown
* implemented language selection for automatic syntax highlighting ** language selection requires the language to be used to be passed as a class of the code element ** kramdown enables easy definition of this class attribute * kramdown offers more functionality such as table and class attribute support * updated all articles accordingly
Diffstat (limited to 'articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md')
-rw-r--r--articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md84
1 files changed, 45 insertions, 39 deletions
diff --git a/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md b/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
index ae46d92..db55e00 100644
--- a/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
+++ b/articles/2014-07-11_mapping_arrays_using_tuples_in_cpp11.md
@@ -6,51 +6,57 @@ While it is possible to unpack a `std::tuple` instance into individual predefine
Extracting array elements obviously requires some way of defining the appropriate indexes and mapping the elements using a tuple blueprint additionally requires this way to be statically resolvable as one can not pass a dynamic index value to `std::tuple_element`. So the first step to fullfilling the defined requirements involved the implementation of a template based index or sequence type.
- template <std::size_t...>
- struct Sequence {
- typedef Sequence type;
- };
-
- template <
- std::size_t Size,
- std::size_t Index = 0,
- std::size_t... Current
- >
- struct IndexSequence {
- typedef typename std::conditional<
- Index < Size,
- IndexSequence<Size, Index + 1, Current..., Index>,
- Sequence<Current...>
- >::type::type type;
- };
+~~~
+template <std::size_t...>
+struct Sequence {
+ typedef Sequence type;
+};
+
+template <
+ std::size_t Size,
+ std::size_t Index = 0,
+ std::size_t... Current
+>
+struct IndexSequence {
+ typedef typename std::conditional<
+ Index < Size,
+ IndexSequence<Size, Index + 1, Current..., Index>,
+ Sequence<Current...>
+ >::type::type type;
+};
+~~~
+{: .language-cpp}
This is achieved by the [`IndexSequence` template](https://github.com/KnairdA/InputXSLT/blob/master/src/support/type/sequence.h) above by recursively specializing the `Sequence` template using static recursion controlled by the standard libraries template metaprogramming utility template `std::conditional`. This means that e.g. the type `Sequence<0, 1, 2, 3>` can also be defined as `IndexSequence<4>::type`.
Now all that is required to accomplish the goal is instantiating the sequence type and passing it to a variadic member template as [follows](https://github.com/KnairdA/InputXSLT/blob/master/src/function/base.h):
+~~~
+[...]
+this->callConstructDocument(
+ parameters,
+ locator,
+ typename IndexSequence<parameter_count>::type()
+)
+[...]
+template <std::size_t... Index>
+inline xalan::XalanDocument* callConstructDocument(
+ const XObjectArgVectorType& parameters,
+ const xalan::Locator* locator,
+ Sequence<Index...>
+) const {
[...]
- this->callConstructDocument(
- parameters,
- locator,
- typename IndexSequence<parameter_count>::type()
- )
- [...]
- template <std::size_t... Index>
- inline xalan::XalanDocument* callConstructDocument(
- const XObjectArgVectorType& parameters,
- const xalan::Locator* locator,
- Sequence<Index...>
- ) const {
- [...]
- return this->document_cache_->create(
- static_cast<const Implementation*>(this)->constructDocument(
- valueGetter.get<typename std::tuple_element<
- Index,
- std::tuple<Types...>
- >::type>(parameters[Index])...
- )
- );
- }
+ return this->document_cache_->create(
+ static_cast<const Implementation*>(this)->constructDocument(
+ valueGetter.get<typename std::tuple_element<
+ Index,
+ std::tuple<Types...>
+ >::type>(parameters[Index])...
+ )
+ );
+}
+~~~
+{: .language-cpp}
As we can see a `IndexSequence` template specialization instance is passed to the variadic `callConstructDocument` method to expose the actual sequence values as `Index`. This method then resolves the `Index` parameter pack as both the array and `std::tuple` index inside the calls to the `valueGetter.get` template method which is called for every sequence element because of this. What this means is that we are now able to implement non-template `constructDocument` methods inside XSLT external function implementations such as [FunctionTransform](https://github.com/KnairdA/InputXSLT/blob/master/src/function/transform.h). The values passed to these methods are automatically extracted from the argument array and converted into their respective types as required.