// 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. // @file test_mpl_tools.cxx // @author Matthias Richter // @since 2017-06-22 // @brief Test program for MPL tools #define BOOST_TEST_MODULE Utility test #define BOOST_TEST_MAIN #define BOOST_TEST_DYN_LINK #include #include "../include/Algorithm/mpl_tools.h" #include #include #include #include #include #include #include #include #include #include // see note below #include #include #include #include // FIXME: mpl/string.hpp required to be included to avoid compilation error // error: no matching function for call to ‘assertion_failed ...' in the mpl::for_each // implementation (BOOST_MPL_ASSERT check). Not fully understood as simply including // mpl/assert.hpp does not help. Maybe it's an inconssitency in the do_typewrap meta // program namespace bmpl = boost::mpl; // defining a list of known data types using knowntypes = bmpl::vector; // get the index of an element in a type sequence template struct type_index { using type = typename bmpl::if_::type, bmpl::int_, // typename type_index::type, End, // typename bmpl::deref::type, // T, // Count + 1 // >::type>::type; // static const int value = type::value; }; // termination condition template struct type_index { using type = typename bmpl::if_::type, // bmpl::int_, // bmpl::int_>::type; // static const int value = type::value; }; // Initializer for the inner type wrapper, use the index in the // list of known types template struct Initializer { static const int value = type_index::type, // typename bmpl::end::type, // bmpl::void_, // T>::value; // }; // the inner class for the fold // the data member is initialized with the index in the list // of known data types which can be wrapped by the class template class Model { public: using value_type = T; Model() : mData(Initializer::value) {} ~Model() = default; friend std::ostream& operator<<(std::ostream& stream, const Model& rhs) { stream << "Model "; stream << rhs.mData; return stream; } private: T mData; }; // the outer class for the fold template class Codec { public: using value_type = T; using wrapped_type = typename T::value_type; Codec() = default; ~Codec() = default; friend std::ostream& operator<<(std::ostream& stream, const Codec& rhs) { stream << "Codec "; stream << rhs.mData; return stream; } private: T mData; }; // simple functor for printing class/type info struct checktype { template void operator()(const T& v) { std::cout << v << std::endl; std::cout << "is integral: " << std::is_integral::value << std::endl; } }; BOOST_AUTO_TEST_CASE(test_mpl_fold) { using types = bmpl::vector; std::cout << std::endl << "checking types:" << std::endl; bmpl::for_each(checktype()); // bmpl::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 // in this particular example, the initial condition is a data type for in 0, // which is incremented with bmpl::next if the type of the element is float using number_of_floats = bmpl::fold, bmpl::if_, bmpl::next<_1>, _1>>::type; // using the meta program, this can be a static_assert static_assert(number_of_floats::value == 4, "inconsistent number of float values in the type definition"); // wrapping all elements into the Model class std::cout << std::endl << "checking first fold:" << std::endl; using models = o2::mpl::do_typewrap>::type>::type; bmpl::for_each(checktype()); // wrapping all elements into the Codec class std::cout << std::endl << "checking second fold:" << std::endl; using codecs = o2::mpl::do_typewrap>::type>::type; bmpl::for_each(checktype()); }