Line data Source code
1 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 TypeTraitsGroup 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...> 31 1 : struct TypeDisplayer; 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 1 : struct make_list { 96 0 : using type = tmpl::list<Ts...>; 97 : };