Project
Loading...
Searching...
No Matches
mpl_tools.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12//-*- Mode: C++ -*-
13
14#ifndef MPL_TOOLS_H
15#define MPL_TOOLS_H
16//****************************************************************************
17//* This file is free software: you can redistribute it and/or modify *
18//* it under the terms of the GNU General Public License as published by *
19//* the Free Software Foundation, either version 3 of the License, or *
20//* (at your option) any later version. *
21//* *
22//* Primary Authors: Matthias Richter <richterm@scieq.net> *
23//* *
24//* The authors make no claims about the suitability of this software for *
25//* any purpose. It is provided "as is" without express or implied warranty. *
26//****************************************************************************
27
28// @file mpl_tools.h
29// @author Matthias Richter
30// @since 2016-09-09
31// @brief Tools for using the boost MPL
32
33#include <boost/mpl/vector.hpp>
34#include <boost/mpl/fold.hpp>
35#include <boost/mpl/set.hpp>
36#include <boost/mpl/placeholders.hpp>
37#include <boost/mpl/bind.hpp>
38
39using boost::mpl::placeholders::_;
40using boost::mpl::placeholders::_1;
41using boost::mpl::placeholders::_2;
42
43namespace o2
44{
45namespace mpl
46{
47
56template <typename T>
58{
59 private:
60 // the default implementaton of this trait expects the type T to be an
61 // mpl sequence with a begin meta function.
62 template <typename U, typename _Iter>
63 struct VectorTraits {
64 enum { result = true };
65 using type = typename U::type;
66 };
67 // specialization for non sequences, for any data type which has no
68 // begin meta function defined, the iterator is void type and this
69 // specialization kicks in. The specialization wraps the type into
70 // a sequence with one entry
71 template <typename U>
72 struct VectorTraits<U, boost::mpl::void_> {
73 enum { result = false };
74 using type = typename boost::mpl::fold<boost::mpl::vector<>, //
75 boost::mpl::set<U>, //
76 boost::mpl::insert<boost::mpl::_1, U> //
77 >::type; //
78 };
79
80 public:
82 enum { isSequence = VectorTraits<T, typename boost::mpl::begin<T>::type>::result };
84 using type = typename VectorTraits<T, typename boost::mpl::begin<T>::type>::type;
85};
86
87/******************************************************************************
88 * @brief Meta program to create a vector of wrapped types from a sequencs
89 * of types. A new mpl vector containing Wrapper<Type> for every
90 * element of the original sequence is created
91 * mpl::fold recursivly applies the elements of the list to the previous result
92 * placeholder _2 refers to the element, placeholder _1 to the previous result
93 * or initial condition for the first element
94 */
95template <typename Seq, typename Wrapper>
97 using type = typename boost::mpl::fold< //
98 Seq, //
99 boost::mpl::vector<>, //
100 boost::mpl::push_back<_1, boost::mpl::bind1<Wrapper, _2>> //
101 >::type;
102};
103
104/******************************************************************************
105 * @brief apply functor to element at mpl sequence position
106 * This meta function recurses through the list while incrementing the index
107 * and calls the functor at the required position
108 *
109 * @note this is a helper macro to the apply_at function
110 */
111template <typename _IndexT, // data type of position index
112 typename _Iterator, // current iterator position
113 typename _End, // end iterator position
114 typename _ReturnT, // type of the return value
115 _IndexT _Index, // current index
116 typename F // functor
117 >
119 static _ReturnT apply(_IndexT position, F f)
120 {
121 if (position == _Index) {
122 // this is the queried position, execute function and
123 // terminate loop by forwarding _End as _Iterator and thus
124 // calling the specialization
125 // TODO: check the performance penalty of the element instantiation
126 typename boost::mpl::deref<_Iterator>::type element;
127 return f(element);
128 } else {
129 // go to next element
131 _IndexT, //
132 typename boost::mpl::next<_Iterator>::type, //
133 _End, //
134 _ReturnT, //
135 _Index + 1, //
136 F //
137 >::apply(position, f);
138 }
139 }
140};
141// specialization: end of recursive loop, kicks in if _Iterator matches
142// _End.
143// here we end up if the position parameter is out of bounds
144template <typename _IndexT, typename _End, typename _ReturnT, _IndexT _Index, typename F>
145struct apply_at_sequence_position<_IndexT, _End, _End, _ReturnT, _Index, F> {
146 static _ReturnT apply(_IndexT position, F f)
147 {
148 // TODO: this is probably the place to through an exeption because
149 // we are out of bound
150 return _ReturnT(0);
151 }
152};
153
154/******************************************************************************
155 * @brief A default functor with void return type and no operation
156 */
159 template <typename T>
161 {
162 }
163};
164
165/******************************************************************************
166 * @brief Apply a functor to an element of a compile time sequence
167 * This meta function is a bridge to the runtime environment to apply a functor
168 * to an element of a compile time list of types.
169 * Required template parameter: sequence - typename defining the list of types
170 *
171 * @arg position position of element in the list
172 * @arg f functor
173 */
174template <typename _Sequence, typename _IndexT = int, typename F = defaultFunctor>
175typename F::return_type apply_at(_IndexT position, F f)
176{
178 typename boost::mpl::end<_Sequence>::type, typename F::return_type, 0,
179 F>::apply(position, f);
180}
181
182} // namespace mpl
183} // namespace o2
184#endif
type trait to transparently use sequences of types This type trait simply forwards to the given type ...
Definition mpl_tools.h:58
typename VectorTraits< T, typename boost::mpl::begin< T >::type >::type type
the tarits type, always a sequence
Definition mpl_tools.h:84
GLuint64EXT * result
Definition glcorearb.h:5662
GLdouble f
Definition glcorearb.h:310
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
F::return_type apply_at(_IndexT position, F f)
Definition mpl_tools.h:175
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static _ReturnT apply(_IndexT position, F f)
Definition mpl_tools.h:119
return_type operator()(T)
Definition mpl_tools.h:160
typename boost::mpl::fold< Seq, boost::mpl::vector<>, boost::mpl::push_back< _1, boost::mpl::bind1< Wrapper, _2 > > >::type type
Definition mpl_tools.h:101