Project
Loading...
Searching...
No Matches
test_mpl_tools.cxx
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// @file test_mpl_tools.cxx
13// @author Matthias Richter
14// @since 2017-06-22
15// @brief Test program for MPL tools
16
17#define BOOST_TEST_MODULE Utility test
18#define BOOST_TEST_MAIN
19#define BOOST_TEST_DYN_LINK
20#include <boost/test/unit_test.hpp>
21#include "../include/Algorithm/mpl_tools.h"
22#include <boost/mpl/size.hpp>
23#include <boost/type.hpp>
24#include <boost/mpl/range_c.hpp>
25#include <boost/mpl/vector.hpp>
26#include <boost/mpl/deref.hpp>
27#include <boost/mpl/for_each.hpp>
28#include <boost/mpl/vector_c.hpp>
29#include <boost/mpl/placeholders.hpp>
30#include <boost/mpl/lambda.hpp>
31#include <boost/mpl/string.hpp> // see note below
32#include <iostream>
33#include <iomanip>
34#include <vector>
35#include <type_traits>
36
37// FIXME: mpl/string.hpp required to be included to avoid compilation error
38// error: no matching function for call to ‘assertion_failed ...' in the mpl::for_each
39// implementation (BOOST_MPL_ASSERT check). Not fully understood as simply including
40// mpl/assert.hpp does not help. Maybe it's an inconssitency in the do_typewrap meta
41// program
42namespace bmpl = boost::mpl;
43
44// defining a list of known data types
45using knowntypes = bmpl::vector<float, double, long double, short, long>;
46
47// get the index of an element in a type sequence
48template <typename Iterator, typename End, typename Element, typename T, int Count = 0>
49struct type_index {
50 using type = typename bmpl::if_<typename std::is_same<Element, T>::type, bmpl::int_<Count>, //
52 typename bmpl::deref<Iterator>::type, //
53 T, //
54 Count + 1 //
55 >::type>::type; //
56 static const int value = type::value;
57};
58// termination condition
59template <typename End, typename Element, typename T, int Count>
60struct type_index<End, End, Element, T, Count> {
61 using type = typename bmpl::if_<typename std::is_same<Element, T>::type, //
62 bmpl::int_<Count>, //
63 bmpl::int_<Count + 1>>::type; //
64
65 static const int value = type::value;
66};
67
68// Initializer for the inner type wrapper, use the index in the
69// list of known types
70template <typename T>
73 typename bmpl::end<knowntypes>::type, //
74 bmpl::void_, //
75 T>::value; //
76};
77
78// the inner class for the fold
79// the data member is initialized with the index in the list
80// of known data types which can be wrapped by the class
81template <typename T>
82class Model
83{
84 public:
85 using value_type = T;
86
88 ~Model() = default;
89
90 friend std::ostream& operator<<(std::ostream& stream, const Model& rhs)
91 {
92 stream << "Model ";
93 stream << rhs.mData;
94 return stream;
95 }
96
97 private:
98 T mData;
99};
100
101// the outer class for the fold
102template <typename T>
103class Codec
104{
105 public:
106 using value_type = T;
107 using wrapped_type = typename T::value_type;
108
109 Codec() = default;
110 ~Codec() = default;
111
112 friend std::ostream& operator<<(std::ostream& stream, const Codec& rhs)
113 {
114 stream << "Codec ";
115 stream << rhs.mData;
116 return stream;
117 }
118
119 private:
120 T mData;
121};
122
123// simple functor for printing class/type info
124struct checktype {
125 template <typename T>
126 void operator()(const T& v)
127 {
128 std::cout << v << std::endl;
129 std::cout << "is integral: " << std::is_integral<T>::value << std::endl;
130 }
131};
132
134{
135 using types = bmpl::vector<long, float, short, double, float, long, long double>;
136 std::cout << std::endl
137 << "checking types:" << std::endl;
138 bmpl::for_each<types>(checktype());
139
140 // bmpl::fold recursivly applies the elements of the list to the previous result
141 // placeholder _2 refers to the element, placeholder _1 to the previous result
142 // or initial condition for the first element
143 // in this particular example, the initial condition is a data type for in 0,
144 // which is incremented with bmpl::next if the type of the element is float
145 using number_of_floats =
146 bmpl::fold<types, bmpl::int_<0>, bmpl::if_<std::is_floating_point<_2>, bmpl::next<_1>, _1>>::type;
147 // using the meta program, this can be a static_assert
148 static_assert(number_of_floats::value == 4, "inconsistent number of float values in the type definition");
149
150 // wrapping all elements into the Model class
151 std::cout << std::endl
152 << "checking first fold:" << std::endl;
154 bmpl::for_each<models>(checktype());
155
156 // wrapping all elements into the Codec class
157 std::cout << std::endl
158 << "checking second fold:" << std::endl;
160 bmpl::for_each<codecs>(checktype());
161}
typename T::value_type wrapped_type
~Codec()=default
friend std::ostream & operator<<(std::ostream &stream, const Codec &rhs)
Codec()=default
friend std::ostream & operator<<(std::ostream &stream, const Model &rhs)
~Model()=default
const GLdouble * v
Definition glcorearb.h:832
GLsizei GLenum GLenum * types
Definition glcorearb.h:2516
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLuint stream
Definition glcorearb.h:1806
static const int value
void operator()(const T &v)
typename bmpl::if_< typename std::is_same< Element, T >::type, bmpl::int_< Count >, bmpl::int_< Count+1 > >::type type
typename bmpl::if_< typename std::is_same< Element, T >::type, bmpl::int_< Count >, typename type_index< typename bmpl::next< Iterator >::type, End, typename bmpl::deref< Iterator >::type, T, Count+1 >::type >::type type
BOOST_AUTO_TEST_CASE(test_mpl_fold)
bmpl::vector< float, double, long double, short, long > knowntypes