TmplDebugging.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class TypeDisplayer
6 
7 #pragma once
8 
9 #include "Utilities/TMPL.hpp"
10 
11 /*!
12  * \ingroup UtilitiesGroup TypeTraits
13  * \brief Get compiler error with type of template parameter
14  *
15  * The compiler error generated when using an object of type
16  * `TypeDisplayer<...>` contains the types of the template parameters. This
17  * effectively provides printf-debugging for metaprogramming. For example,
18  * \code
19  * TypeDisplayer<std::vector<double>> some_random_name;
20  * \endcode
21  * will produce a compiler error that contains the type `std::vector<double,
22  * std::allocator...>`. TypeDisplayer is extremely useful when debugging
23  * template metaprograms.
24  *
25  * \note The TypeDisplayer header should only be included during testing
26  * and debugging.
27  *
28  * \see make_list
29  */
30 template <typename...>
32 
33 /*!
34  * \ingroup UtilitiesGroup
35  * \brief Metafunction to turn a parameter pack into a typelist
36  *
37  * This metafunction is really only useful for debugging metaprograms. For
38  * example, the desired algorithm might be:
39  *
40  * \code
41  * using variables_tags_from_single_tags = tmpl::filter<
42  * extracted_from_variables,
43  * tmpl::bind<tmpl::found, tmpl::pin<mutated_tags_list>,
44  * tmpl::bind<std::is_same, tmpl::_1, tmpl::parent<tmpl::_1>>>>;
45  * \endcode
46  *
47  * However, getting the `tmpl::pin`, `tmpl::parent`, and `tmpl::bind` calls
48  * right can be extremely frustrating with little help as to what is going on.
49  * Let's introduce an error by pinning `tmpl::_1`:
50  *
51  * \code
52  * using variables_tags_from_single_tags = tmpl::filter<
53  * extracted_from_variables,
54  * tmpl::bind<tmpl::found, tmpl::pin<mutated_tags_list>,
55  * tmpl::bind<std::is_same, tmpl::pin<tmpl::_1>,
56  * tmpl::parent<tmpl::_1>>>>;
57  * \endcode
58  *
59  * The result is comparing all values in `extracted_from_variables` to
60  * themselves. To find this out, replace `tmpl::filter` and `tmpl::found` with
61  * `tmpl::transform`, and the metafunction `std::is_same` to `make_list`.
62  * You will then get back a "backtrace" of what the algorithm did, which is
63  * invaluable for getting the `tmpl::pin` and `tmpl::parent` right. That is,
64  *
65  * \code
66  * using variables_tags_from_single_tags2 = tmpl::transform<
67  * extracted_from_variables,
68  * tmpl::bind<tmpl::transform, tmpl::pin<mutated_tags_list>,
69  * tmpl::bind<make_list, tmpl::_1, tmpl::parent<tmpl::_1>>>>;
70  *
71  * TypeDisplayer<variables_tags_from_single_tags2> aeou;
72  * \endcode
73  *
74  * You will get an output along the lines of:
75  *
76  * \code
77  * src/DataStructures/DataBox.hpp:1181:40: error: implicit instantiation of
78  * undefined template
79  * 'TypeDisplayer<brigand::list<brigand::list<
80  * brigand::list<test_databox_tags::ScalarTag,
81  * test_databox_tags::Tag0>, brigand::list<test_databox_tags::ScalarTag,
82  * Tags::Variables<brigand::list<test_databox_tags::ScalarTag,
83  * test_databox_tags::VectorTag> > > >,
84  * brigand::list<brigand::list<test_databox_tags::VectorTag,
85  * test_databox_tags::Tag0>,
86  * brigand::list<test_databox_tags::VectorTag,
87  * Tags::Variables<
88  * brigand::list<test_databox_tags::ScalarTag,
89  * test_databox_tags::VectorTag> > > > > >'
90  * \endcode
91  *
92  * \see TypeDisplayer
93  */
94 template <class... Ts>
95 struct make_list {
96  using type = tmpl::list<Ts...>;
97 };
Metafunction to turn a parameter pack into a typelist.
Definition: TmplDebugging.hpp:95
Get compiler error with type of template parameter.
Definition: TmplDebugging.hpp:31
Wraps the template metaprogramming library used (brigand)