GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — AliceO2/Algorithm/include/Algorithm/mpl_tools.h at dev · daneecool/AliceO2 Expand file tree/ Copy pathmpl_tools.hMore file actions 184 lines (171 loc) · 7.32 KB / Copy pathmpl_tools.hFile metadata and controls184 lines (171 loc) · 7.32 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 // Copyright 2019-2020 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. // // This software is distributed under the terms of the GNU General Public // License v3 (GPL Version 3), copied verbatim in the file "COPYING". // // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. //-*- Mode: C++ -*- #ifndef MPL_TOOLS_H #define MPL_TOOLS_H //**************************************************************************** //* This file is free software: you can redistribute it and/or modify * //* it under the terms of the GNU General Public License as published by * //* the Free Software Foundation, either version 3 of the License, or * //* (at your option) any later version. * //* * //* Primary Authors: Matthias Richter <[email protected]> * //* * //* The authors make no claims about the suitability of this software for * //* any purpose. It is provided "as is" without express or implied warranty. * //**************************************************************************** // @file mpl_tools.h // @author Matthias Richter // @since 2016-09-09 // @brief Tools for using the boost MPL #include <boost/mpl/vector.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/set.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/mpl/bind.hpp> using boost::mpl::placeholders::_; using boost::mpl::placeholders::_1; using boost::mpl::placeholders::_2; namespace o2 { namespace mpl { /** * @brief type trait to transparently use sequences of types * This type trait simply forwards to the given type if it is already a * sequence but wraps any non-sequence type into an mpl vector with one entry. * * Usage: make_mpl_vector<T>::type * make_mpl_vector<T>::isSequence */ template <typename T> class make_mpl_vector { private: // the default implementaton of this trait expects the type T to be an // mpl sequence with a begin meta function. template <typename U, typename _Iter> struct VectorTraits { enum { result = true }; using type = typename U::type; }; // specialization for non sequences, for any data type which has no // begin meta function defined, the iterator is void type and this // specialization kicks in. The specialization wraps the type into // a sequence with one entry template <typename U> struct VectorTraits<U, boost::mpl::void_> { enum { result = false }; using type = typename boost::mpl::fold<boost::mpl::vector<>, // boost::mpl::set<U>, // boost::mpl::insert<boost::mpl::_1, U> // >::type; // }; public: /// iSequence tells if the original type is a sequence enum { isSequence = VectorTraits<T, typename boost::mpl::begin<T>::type>::result }; /// the tarits type, always a sequence using type = typename VectorTraits<T, typename boost::mpl::begin<T>::type>::type; }; /****************************************************************************** * @brief Meta program to create a vector of wrapped types from a sequencs * of types. A new mpl vector containing Wrapper<Type> for every * element of the original sequence is created * mpl::fold recursivly applies the elements of the list to the previous result * placeholder _2 refers to the element, placeholder _1 to the previous result * or initial condition for the first element */ template <typename Seq, typename Wrapper> struct do_typewrap { using type = typename boost::mpl::fold< // Seq, // boost::mpl::vector<>, // boost::mpl::push_back<_1, boost::mpl::bind1<Wrapper, _2>> // >::type; }; /****************************************************************************** * @brief apply functor to element at mpl sequence position * This meta function recurses through the list while incrementing the index * and calls the functor at the required position * * @note this is a helper macro to the apply_at function */ template <typename _IndexT, // data type of position index typename _Iterator, // current iterator position typename _End, // end iterator position typename _ReturnT, // type of the return value _IndexT _Index, // current index typename F // functor > struct apply_at_sequence_position { static _ReturnT apply(_IndexT position, F f) { if (position == _Index) { // this is the queried position, execute function and // terminate loop by forwarding _End as _Iterator and thus // calling the specialization // TODO: check the performance penalty of the element instantiation typename boost::mpl::deref<_Iterator>::type element; return f(element); } else { // go to next element return apply_at_sequence_position< // _IndexT, // typename boost::mpl::next<_Iterator>::type, // _End, // _ReturnT, // _Index + 1, // F // >::apply(position, f); } } }; // specialization: end of recursive loop, kicks in if _Iterator matches // _End. // here we end up if the position parameter is out of bounds template <typename _IndexT, typename _End, typename _ReturnT, _IndexT _Index, typename F> struct apply_at_sequence_position<_IndexT, _End, _End, _ReturnT, _Index, F> { static _ReturnT apply(_IndexT position, F f) { // TODO: this is probably the place to through an exeption because // we are out of bound return _ReturnT(0); } }; /****************************************************************************** * @brief A default functor with void return type and no operation */ struct defaultFunctor { using return_type = void; template <typename T> return_type operator()(T) { } }; /****************************************************************************** * @brief Apply a functor to an element of a compile time sequence * This meta function is a bridge to the runtime environment to apply a functor * to an element of a compile time list of types. * Required template parameter: sequence - typename defining the list of types * * @arg position position of element in the list * @arg f functor */ template <typename _Sequence, typename _IndexT = int, typename F = defaultFunctor> typename F::return_type apply_at(_IndexT position, F f) { return apply_at_sequence_position<_IndexT, typename boost::mpl::begin<_Sequence>::type, typename boost::mpl::end<_Sequence>::type, typename F::return_type, 0, F>::apply(position, f); } } // namespace mpl } // namespace o2 #endif |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |