SpECTRE Documentation Coverage Report
Current view: top level - Utilities - PrettyType.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 12 12
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Contains a pretty_type library to write types in a "pretty" format
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <boost/core/demangle.hpp>
      10              : #include <deque>
      11              : #include <forward_list>
      12              : #include <list>
      13              : #include <map>
      14              : #include <memory>
      15              : #include <queue>
      16              : #include <set>
      17              : #include <sstream>
      18              : #include <stack>
      19              : #include <string>
      20              : #include <type_traits>
      21              : #include <typeinfo>
      22              : #include <unordered_map>
      23              : #include <unordered_set>
      24              : #include <vector>
      25              : 
      26              : #include "Utilities/Requires.hpp"
      27              : #include "Utilities/TMPL.hpp"
      28              : #include "Utilities/TypeTraits/ArraySize.hpp"
      29              : #include "Utilities/TypeTraits/IsA.hpp"
      30              : #include "Utilities/TypeTraits/IsStdArray.hpp"
      31              : 
      32              : /// \cond
      33              : #define PRETTY_TYPE_USE_BOOST
      34              : /// \endcond
      35              : 
      36              : /*!
      37              :  * \ingroup PrettyTypeGroup
      38              :  * \brief Contains all functions that are part of PrettyType, used for printing
      39              :  * types in a pretty manner.
      40              :  */
      41            1 : namespace pretty_type {
      42              : namespace detail {
      43              : using str_const = const char* const;
      44              : 
      45              : template <typename T>
      46              : struct Type;
      47              : 
      48              : template <>
      49              : struct Type<char> {
      50              :   using type = char;
      51              :   static constexpr str_const type_name = {"char"};
      52              : };
      53              : 
      54              : template <>
      55              : struct Type<signed char> {
      56              :   using type = signed char;
      57              :   static constexpr str_const type_name = {"signed char"};
      58              : };
      59              : 
      60              : template <>
      61              : struct Type<unsigned char> {
      62              :   using type = unsigned char;
      63              :   static constexpr str_const type_name = {"unsigned char"};
      64              : };
      65              : 
      66              : template <>
      67              : struct Type<wchar_t> {
      68              :   using type = wchar_t;
      69              :   static constexpr str_const type_name = {"wchar_t"};
      70              : };
      71              : 
      72              : template <>
      73              : struct Type<char16_t> {
      74              :   using type = char16_t;
      75              :   static constexpr str_const type_name = {"char16_t"};
      76              : };
      77              : 
      78              : template <>
      79              : struct Type<char32_t> {
      80              :   using type = char32_t;
      81              :   static constexpr str_const type_name = {"char32_t"};
      82              : };
      83              : 
      84              : template <>
      85              : struct Type<int> {
      86              :   using type = int;
      87              :   static constexpr str_const type_name = {"int"};
      88              : };
      89              : 
      90              : template <>
      91              : struct Type<unsigned int> {
      92              :   using type = unsigned int;
      93              :   static constexpr str_const type_name = {"unsigned int"};
      94              : };
      95              : 
      96              : template <>
      97              : struct Type<long> {
      98              :   using type = long;
      99              :   static constexpr str_const type_name = {"long"};
     100              : };
     101              : 
     102              : template <>
     103              : struct Type<unsigned long> {
     104              :   using type = unsigned long;
     105              :   static constexpr str_const type_name = {"unsigned long"};
     106              : };
     107              : 
     108              : template <>
     109              : struct Type<long long> {
     110              :   using type = long long;
     111              :   static constexpr str_const type_name = {"long long"};
     112              : };
     113              : 
     114              : template <>
     115              : struct Type<unsigned long long> {
     116              :   using type = unsigned long long;
     117              :   static constexpr str_const type_name = {"unsigned long long"};
     118              : };
     119              : 
     120              : template <>
     121              : struct Type<short> {
     122              :   using type = short;
     123              :   static constexpr str_const type_name = {"short"};
     124              : };
     125              : 
     126              : template <>
     127              : struct Type<unsigned short> {
     128              :   using type = unsigned short;
     129              :   static constexpr str_const type_name = {"unsigned short"};
     130              : };
     131              : 
     132              : template <>
     133              : struct Type<float> {
     134              :   using type = float;
     135              :   static constexpr str_const type_name = {"float"};
     136              : };
     137              : 
     138              : template <>
     139              : struct Type<double> {
     140              :   using type = double;
     141              :   static constexpr str_const type_name = {"double"};
     142              : };
     143              : 
     144              : template <>
     145              : struct Type<long double> {
     146              :   using type = long double;
     147              :   static constexpr str_const type_name = {"long double"};
     148              : };
     149              : 
     150              : template <>
     151              : struct Type<bool> {
     152              :   using type = bool;
     153              :   static constexpr str_const type_name = {"bool"};
     154              : };
     155              : 
     156              : template <>
     157              : struct Type<void> {
     158              :   using type = void;
     159              :   static constexpr str_const type_name = {"void"};
     160              : };
     161              : 
     162              : template <>
     163              : struct Type<std::string> {
     164              :   using type = std::string;
     165              :   static constexpr str_const type_name = {"std::string"};
     166              : };
     167              : 
     168              : template <typename... T>
     169              : using TemplateMap_t = tmpl::map<tmpl::pair<T, Type<T>>...>;
     170              : 
     171              : template <typename T>
     172              : std::string add_qualifiers() {
     173              :   std::stringstream ss;
     174              :   if (std::is_pointer<T>::value) {
     175              :     if (std::is_const<std::remove_pointer_t<T>>::value) {
     176              :       ss << " const";
     177              :     }
     178              :     if (std::is_volatile<std::remove_pointer_t<T>>::value) {
     179              :       ss << " volatile";
     180              :     }
     181              :     ss << "*";
     182              :   }
     183              :   if (std::is_const<std::remove_reference_t<T>>::value) {
     184              :     ss << " const";
     185              :   }
     186              :   if (std::is_volatile<std::remove_reference_t<T>>::value) {
     187              :     ss << " volatile";
     188              :   }
     189              :   if (std::is_reference<T>::value) {
     190              :     ss << "&";
     191              :   }
     192              :   return ss.str();
     193              : }
     194              : 
     195              : /*!
     196              :  * \ingroup PrettyTypeGroup
     197              :  * Used to construct the name of a container
     198              :  *
     199              :  * \tparam T the type whose name to print
     200              :  * \tparam M the map of the basic types to print
     201              :  * \tparam KT the struct holding the template alias template_list which is a
     202              :  * list of known specializations of construct_name for those containers
     203              :  */
     204              : template <typename T, typename M, typename KT, typename = std::nullptr_t>
     205              : struct construct_name;
     206              : template <typename T, typename M, typename KT>
     207              : struct construct_name<
     208              :     T, M, KT,
     209              :     Requires<tmpl::has_key<M, std::decay_t<std::remove_pointer_t<T>>>::value ==
     210              :              1>> {
     211              :   static std::string get() {
     212              :     constexpr str_const t =
     213              :         tmpl::at<M, std::decay_t<std::remove_pointer_t<T>>>::type_name;
     214              :     std::stringstream ss;
     215              :     ss << t << add_qualifiers<T>();
     216              :     return ss.str();
     217              :   }
     218              : };
     219              : 
     220              : template <typename T, typename M, typename KT>
     221              : struct construct_name<
     222              :     T, M, KT,
     223              :     Requires<
     224              :         tmpl::has_key<M, std::decay_t<std::remove_reference_t<
     225              :                              std::remove_pointer_t<T>>>>::value == 0 and
     226              :         std::is_same<
     227              :             tmpl::list<>,
     228              :             tmpl::find<typename KT::template template_list<std::decay_t<
     229              :                            std::remove_reference_t<std::remove_pointer_t<T>>>>,
     230              :                        std::is_base_of<std::true_type, tmpl::_1>>>::value>> {
     231              :   static std::string get() {
     232              :     std::stringstream ss;
     233              : #if defined(PRETTY_TYPE_USE_BOOST)
     234              :     ss << boost::core::demangle(typeid(T).name());
     235              : #else
     236              :     ss << typeid(T).name();
     237              : #endif
     238              :     return ss.str();
     239              :   }
     240              : };
     241              : 
     242              : // STL Sequences
     243              : template <typename T, typename M, typename KT>
     244              : struct construct_name<
     245              :     T, M, KT,
     246              :     Requires<tt::is_a_v<std::vector, std::decay_t<std::remove_reference_t<
     247              :                                          std::remove_pointer_t<T>>>>>> {
     248              :   using type = std::decay_t<std::remove_pointer_t<T>>;
     249              :   static std::string get() {
     250              :     std::stringstream ss;
     251              :     ss << "std::vector<"
     252              :        << construct_name<
     253              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     254              :               KT>::get();
     255              :     ss << add_qualifiers<typename type::value_type>() << ">";
     256              :     ss << add_qualifiers<T>();
     257              :     return ss.str();
     258              :   }
     259              : };
     260              : 
     261              : template <typename T, typename M, typename KT>
     262              : struct construct_name<
     263              :     T, M, KT,
     264              :     Requires<tt::is_std_array_v<
     265              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     266              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     267              :   static std::string get() {
     268              :     std::stringstream ss;
     269              :     ss << "std::array<"
     270              :        << construct_name<
     271              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     272              :               KT>::get();
     273              :     ss << add_qualifiers<typename type::value_type>();
     274              :     ss << ", " << tt::array_size<type>::value << ">";
     275              :     ss << add_qualifiers<T>();
     276              :     return ss.str();
     277              :   }
     278              : };
     279              : 
     280              : template <typename T, typename M, typename KT>
     281              : struct construct_name<
     282              :     T, M, KT,
     283              :     Requires<tt::is_a_v<std::deque, std::decay_t<std::remove_reference_t<
     284              :                                         std::remove_pointer_t<T>>>>>> {
     285              :   using type = std::decay_t<std::remove_pointer_t<T>>;
     286              :   static std::string get() {
     287              :     std::stringstream ss;
     288              :     ss << "std::deque<"
     289              :        << construct_name<
     290              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     291              :               KT>::get();
     292              :     ss << add_qualifiers<typename type::value_type>() << ">";
     293              :     ss << add_qualifiers<T>();
     294              :     return ss.str();
     295              :   }
     296              : };
     297              : 
     298              : template <typename T, typename M, typename KT>
     299              : struct construct_name<
     300              :     T, M, KT,
     301              :     Requires<tt::is_a_v<std::forward_list, std::decay_t<std::remove_reference_t<
     302              :                                                std::remove_pointer_t<T>>>>>> {
     303              :   using type = std::decay_t<std::remove_pointer_t<T>>;
     304              :   static std::string get() {
     305              :     std::stringstream ss;
     306              :     ss << "std::forward_list<"
     307              :        << construct_name<
     308              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     309              :               KT>::get();
     310              :     ss << add_qualifiers<typename type::value_type>() << ">";
     311              :     ss << add_qualifiers<T>();
     312              :     return ss.str();
     313              :   }
     314              : };
     315              : 
     316              : template <typename T, typename M, typename KT>
     317              : struct construct_name<
     318              :     T, M, KT,
     319              :     Requires<tt::is_a_v<std::list, std::decay_t<std::remove_reference_t<
     320              :                                        std::remove_pointer_t<T>>>>>> {
     321              :   using type = std::decay_t<std::remove_pointer_t<T>>;
     322              :   static std::string get() {
     323              :     std::stringstream ss;
     324              :     ss << "std::list<"
     325              :        << construct_name<
     326              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     327              :               KT>::get();
     328              :     ss << add_qualifiers<typename type::value_type>() << ">";
     329              :     ss << add_qualifiers<T>();
     330              :     return ss.str();
     331              :   }
     332              : };
     333              : 
     334              : // STL Associative containers
     335              : template <typename T, typename M, typename KT>
     336              : struct construct_name<
     337              :     T, M, KT,
     338              :     Requires<tt::is_a_v<std::map, std::decay_t<std::remove_reference_t<
     339              :                                       std::remove_pointer_t<T>>>>>> {
     340              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     341              :   static std::string get() {
     342              :     std::stringstream ss;
     343              :     ss << "std::map<"
     344              :        << construct_name<
     345              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     346              :               KT>::get()
     347              :        << add_qualifiers<typename type::key_type>() << ", "
     348              :        << construct_name<
     349              :               std::decay_t<std::remove_pointer_t<typename type::mapped_type>>,
     350              :               M, KT>::get()
     351              :        << add_qualifiers<typename type::mapped_type>() << ">";
     352              :     ss << add_qualifiers<T>();
     353              :     return ss.str();
     354              :   }
     355              : };
     356              : 
     357              : template <typename T, typename M, typename KT>
     358              : struct construct_name<
     359              :     T, M, KT,
     360              :     Requires<tt::is_a_v<std::multimap, std::decay_t<std::remove_reference_t<
     361              :                                            std::remove_pointer_t<T>>>>>> {
     362              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     363              :   static std::string get() {
     364              :     std::stringstream ss;
     365              :     ss << "std::multimap<"
     366              :        << construct_name<
     367              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     368              :               KT>::get()
     369              :        << add_qualifiers<typename type::key_type>() << ", "
     370              :        << construct_name<
     371              :               std::decay_t<std::remove_pointer_t<typename type::mapped_type>>,
     372              :               M, KT>::get()
     373              :        << add_qualifiers<typename type::mapped_type>() << ">";
     374              :     ss << add_qualifiers<T>();
     375              :     return ss.str();
     376              :   }
     377              : };
     378              : 
     379              : template <typename T, typename M, typename KT>
     380              : struct construct_name<
     381              :     T, M, KT,
     382              :     Requires<tt::is_a_v<std::multiset, std::decay_t<std::remove_reference_t<
     383              :                                            std::remove_pointer_t<T>>>>>> {
     384              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     385              :   static std::string get() {
     386              :     std::stringstream ss;
     387              :     ss << "std::multiset<"
     388              :        << construct_name<
     389              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     390              :               KT>::get()
     391              :        << add_qualifiers<typename type::key_type>() << ">";
     392              :     ss << add_qualifiers<T>();
     393              :     return ss.str();
     394              :   }
     395              : };
     396              : 
     397              : template <typename T, typename M, typename KT>
     398              : struct construct_name<
     399              :     T, M, KT,
     400              :     Requires<tt::is_a_v<std::set, std::decay_t<std::remove_reference_t<
     401              :                                       std::remove_pointer_t<T>>>>>> {
     402              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     403              :   static std::string get() {
     404              :     std::stringstream ss;
     405              :     ss << "std::set<"
     406              :        << construct_name<
     407              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     408              :               KT>::get()
     409              :        << add_qualifiers<typename type::key_type>() << ">";
     410              :     ss << add_qualifiers<T>();
     411              :     return ss.str();
     412              :   }
     413              : };
     414              : 
     415              : // STL Unordered associative containers
     416              : 
     417              : template <typename T, typename M, typename KT>
     418              : struct construct_name<
     419              :     T, M, KT,
     420              :     Requires<tt::is_a_v<
     421              :         std::unordered_map,
     422              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     423              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     424              :   static std::string get() {
     425              :     std::stringstream ss;
     426              :     ss << "std::unordered_map<"
     427              :        << construct_name<
     428              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     429              :               KT>::get()
     430              :        << add_qualifiers<typename type::key_type>() << ", "
     431              :        << construct_name<
     432              :               std::decay_t<std::remove_pointer_t<typename type::mapped_type>>,
     433              :               M, KT>::get()
     434              :        << add_qualifiers<typename type::mapped_type>() << ">";
     435              :     ss << add_qualifiers<T>();
     436              :     return ss.str();
     437              :   }
     438              : };
     439              : 
     440              : template <typename T, typename M, typename KT>
     441              : struct construct_name<
     442              :     T, M, KT,
     443              :     Requires<tt::is_a_v<
     444              :         std::unordered_multimap,
     445              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     446              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     447              :   static std::string get() {
     448              :     std::stringstream ss;
     449              :     ss << "std::unordered_multimap<"
     450              :        << construct_name<
     451              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     452              :               KT>::get()
     453              :        << add_qualifiers<typename type::key_type>() << ", "
     454              :        << construct_name<
     455              :               std::decay_t<std::remove_pointer_t<typename type::mapped_type>>,
     456              :               M, KT>::get()
     457              :        << add_qualifiers<typename type::mapped_type>() << ">";
     458              :     ss << add_qualifiers<T>();
     459              :     return ss.str();
     460              :   }
     461              : };
     462              : 
     463              : template <typename T, typename M, typename KT>
     464              : struct construct_name<
     465              :     T, M, KT,
     466              :     Requires<tt::is_a_v<
     467              :         std::unordered_multiset,
     468              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     469              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     470              :   static std::string get() {
     471              :     std::stringstream ss;
     472              :     ss << "std::unordered_multiset<"
     473              :        << construct_name<
     474              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     475              :               KT>::get()
     476              :        << add_qualifiers<typename type::key_type>() << ">";
     477              :     ss << add_qualifiers<T>();
     478              :     return ss.str();
     479              :   }
     480              : };
     481              : 
     482              : template <typename T, typename M, typename KT>
     483              : struct construct_name<
     484              :     T, M, KT,
     485              :     Requires<tt::is_a_v<
     486              :         std::unordered_set,
     487              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     488              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     489              :   static std::string get() {
     490              :     std::stringstream ss;
     491              :     ss << "std::unordered_set<"
     492              :        << construct_name<
     493              :               std::decay_t<std::remove_pointer_t<typename type::key_type>>, M,
     494              :               KT>::get()
     495              :        << add_qualifiers<typename type::key_type>() << ">";
     496              :     ss << add_qualifiers<T>();
     497              :     return ss.str();
     498              :   }
     499              : };
     500              : 
     501              : // STL Container adaptors
     502              : template <typename T, typename M, typename KT>
     503              : struct construct_name<
     504              :     T, M, KT,
     505              :     Requires<tt::is_a_v<
     506              :         std::priority_queue,
     507              :         std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>>>> {
     508              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     509              :   static std::string get() {
     510              :     std::stringstream ss;
     511              :     ss << "std::priority_queue<"
     512              :        << construct_name<
     513              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     514              :               KT>::get()
     515              :        << add_qualifiers<typename type::value_type>() << ", "
     516              :        << construct_name<std::decay_t<std::remove_pointer_t<
     517              :                              typename type::container_type>>,
     518              :                          M, KT>::get()
     519              :        << add_qualifiers<typename type::container_type>() << ">";
     520              :     ss << add_qualifiers<T>();
     521              :     return ss.str();
     522              :   }
     523              : };
     524              : 
     525              : template <typename T, typename M, typename KT>
     526              : struct construct_name<
     527              :     T, M, KT,
     528              :     Requires<tt::is_a_v<std::queue, std::decay_t<std::remove_reference_t<
     529              :                                         std::remove_pointer_t<T>>>>>> {
     530              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     531              :   static std::string get() {
     532              :     std::stringstream ss;
     533              :     ss << "std::queue<"
     534              :        << construct_name<
     535              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     536              :               KT>::get()
     537              :        << add_qualifiers<typename type::value_type>() << ", "
     538              :        << construct_name<std::decay_t<std::remove_pointer_t<
     539              :                              typename type::container_type>>,
     540              :                          M, KT>::get()
     541              :        << add_qualifiers<typename type::container_type>() << ">";
     542              :     ss << add_qualifiers<T>();
     543              :     return ss.str();
     544              :   }
     545              : };
     546              : 
     547              : template <typename T, typename M, typename KT>
     548              : struct construct_name<
     549              :     T, M, KT,
     550              :     Requires<tt::is_a_v<std::stack, std::decay_t<std::remove_reference_t<
     551              :                                         std::remove_pointer_t<T>>>>>> {
     552              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     553              :   static std::string get() {
     554              :     std::stringstream ss;
     555              :     ss << "std::stack<"
     556              :        << construct_name<
     557              :               std::decay_t<std::remove_pointer_t<typename type::value_type>>, M,
     558              :               KT>::get()
     559              :        << add_qualifiers<typename type::value_type>() << ", "
     560              :        << construct_name<std::decay_t<std::remove_pointer_t<
     561              :                              typename type::container_type>>,
     562              :                          M, KT>::get()
     563              :        << add_qualifiers<typename type::container_type>() << ">";
     564              :     ss << add_qualifiers<T>();
     565              :     return ss.str();
     566              :   }
     567              : };
     568              : 
     569              : // STL Smart pointers
     570              : template <typename T, typename M, typename KT>
     571              : struct construct_name<
     572              :     T, M, KT,
     573              :     Requires<tt::is_a_v<std::unique_ptr, std::decay_t<std::remove_reference_t<
     574              :                                              std::remove_pointer_t<T>>>>>> {
     575              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     576              :   static std::string get() {
     577              :     std::stringstream ss;
     578              :     ss << "std::unique_ptr<"
     579              :        << construct_name<std::decay_t<std::remove_pointer_t<decltype(
     580              :                              *std::declval<type>())>>,
     581              :                          M, KT>::get()
     582              :        << add_qualifiers<
     583              :               std::remove_reference_t<decltype(*std::declval<type>())>>()
     584              :        << ">";
     585              :     ss << add_qualifiers<T>();
     586              :     return ss.str();
     587              :   }
     588              : };
     589              : 
     590              : template <typename T, typename M, typename KT>
     591              : struct construct_name<
     592              :     T, M, KT,
     593              :     Requires<tt::is_a_v<std::shared_ptr, std::decay_t<std::remove_reference_t<
     594              :                                              std::remove_pointer_t<T>>>>>> {
     595              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     596              :   static std::string get() {
     597              :     std::stringstream ss;
     598              :     ss << "std::shared_ptr<"
     599              :        << construct_name<std::decay_t<std::remove_pointer_t<decltype(
     600              :                              *std::declval<type>())>>,
     601              :                          M, KT>::get()
     602              :        << add_qualifiers<
     603              :               std::remove_reference_t<decltype(*std::declval<type>())>>()
     604              :        << ">";
     605              :     ss << add_qualifiers<T>();
     606              :     return ss.str();
     607              :   }
     608              : };
     609              : 
     610              : template <typename T, typename M, typename KT>
     611              : struct construct_name<
     612              :     T, M, KT,
     613              :     Requires<tt::is_a_v<std::weak_ptr, std::decay_t<std::remove_reference_t<
     614              :                                            std::remove_pointer_t<T>>>>>> {
     615              :   using type = std::decay_t<std::remove_reference_t<std::remove_pointer_t<T>>>;
     616              :   using element_type = typename type::element_type;
     617              :   static std::string get() {
     618              :     std::stringstream ss;
     619              :     ss << "std::weak_ptr<"
     620              :        << construct_name<std::decay_t<std::remove_pointer_t<element_type>>, M,
     621              :                          KT>::get()
     622              :        << add_qualifiers<element_type>() << ">";
     623              :     ss << add_qualifiers<T>();
     624              :     return ss.str();
     625              :   }
     626              : };
     627              : }  // namespace detail
     628              : 
     629              : /*!
     630              :  * \ingroup PrettyTypeGroup
     631              :  * \brief typelist of basic types that can be pretty printed
     632              :  *
     633              :  * These are specializations of tt::Type<T>
     634              :  */
     635            1 : using basics_map =
     636              :     detail::TemplateMap_t<char, signed char, unsigned char, wchar_t, char16_t,
     637              :                           char32_t, int, unsigned int, long, unsigned long,
     638              :                           long long, unsigned long long, short, unsigned short,
     639              :                           float, double, long double, bool, std::string>;
     640              : 
     641              : /*!
     642              :  * \ingroup PrettyTypeGroup
     643              :  * \brief A list of type traits to check if something is an STL member
     644              :  *
     645              :  * Contains a template alias with the name template_list of type traits that
     646              :  * identify STL containers that can be pretty printed
     647              :  */
     648            1 : struct stl_templates {
     649              :   /// List of known STL classes that can be pretty printed
     650              :   template <typename X>
     651            1 :   using template_list = tmpl::list<
     652              :       tt::is_a<std::vector, X>, tt::is_std_array<X>, tt::is_a<std::deque, X>,
     653              :       tt::is_a<std::forward_list, X>, tt::is_a<std::list, X>,
     654              :       tt::is_a<std::map, X>, tt::is_a<std::set, X>, tt::is_a<std::multiset, X>,
     655              :       tt::is_a<std::multimap, X>, tt::is_a<std::unordered_map, X>,
     656              :       tt::is_a<std::unordered_multimap, X>,
     657              :       tt::is_a<std::unordered_multiset, X>, tt::is_a<std::unordered_set, X>,
     658              :       tt::is_a<std::priority_queue, X>, tt::is_a<std::queue, X>,
     659              :       tt::is_a<std::stack, X>, tt::is_a<std::unique_ptr, X>,
     660              :       tt::is_a<std::shared_ptr, X>, tt::is_a<std::weak_ptr, X>>;
     661              : };
     662              : 
     663              : /*!
     664              :  * \ingroup PrettyTypeGroup
     665              :  *  \brief Returns a string with the prettiest typename known for the type T.
     666              :  *
     667              :  *  Example usage: auto name = get_name<T>();
     668              :  *
     669              :  *  \tparam T the type to print
     670              :  *  \tparam Map a tmpl::map of basic types (non-containers) and their Type<T>
     671              :  *  specializations that determine how to print the type name in a pretty form
     672              :  *  \tparam KnownTemplates struct hold template alias tmpl::list of is_... that
     673              :  *  are known how to be printed pretty
     674              :  *  \return std::string containing the typename
     675              :  */
     676              : template <typename T, typename Map = basics_map,
     677              :           typename KnownTemplates = stl_templates>
     678            1 : std::string get_name() {
     679              :   return detail::construct_name<T, Map, KnownTemplates>::get();
     680              : }
     681              : 
     682              : /*!
     683              :  * \ingroup PrettyTypeGroup
     684              :  * \brief Returns a string with the prettiest typename known for the runtime
     685              :  * type of x.
     686              :  *
     687              :  * The result will generally not be as pretty as the result of
     688              :  * get_name, but this function will report the derived type of a class
     689              :  * when only given a base class reference, which get_type cannot do.
     690              :  */
     691              : template <typename T>
     692            1 : std::string get_runtime_type_name(const T& x) {
     693              :   return boost::core::demangle(typeid(x).name());
     694              : }
     695              : 
     696              : namespace detail {
     697              : std::string extract_short_name(const std::string& name);
     698              : }  // namespace detail
     699              : 
     700              : /*!
     701              :  * \ingroup PrettyTypeGroup
     702              :  * \brief Return the "short name" of a class, that is, the name
     703              :  * without template parameters or scopes.
     704              :  */
     705              : template <typename T>
     706            1 : std::string short_name() {
     707              :   return detail::extract_short_name(typeid(T).name());
     708              : }
     709              : 
     710              : namespace detail {
     711              : template <typename T, typename = std::void_t<>>
     712              : struct name_helper {
     713              :   static std::string name() { return pretty_type::short_name<T>(); }
     714              : };
     715              : 
     716              : template <typename T>
     717              : struct name_helper<T, std::void_t<decltype(T::name())>> {
     718              :   static std::string name() { return T::name(); }
     719              : };
     720              : }  // namespace detail
     721              : 
     722              : /// @{
     723              : /*!
     724              :  * \ingroup PrettyTypeGroup
     725              :  * \brief Return the result of the `name()` member of a class. If a class
     726              :  * doesn't have a `name()` member, call `pretty_type::short_name<T>()` instead.
     727              :  *
     728              :  * \warning Do not use this inside the `name()` member of struct. This
     729              :  * can lead to recursion as `pretty_type::name<Tag>()` will call the `name()`
     730              :  * member of the struct.
     731              :  */
     732              : template <typename T>
     733            1 : std::string name() {
     734              :   return detail::name_helper<T>::name();
     735              : }
     736              : 
     737              : template <typename T>
     738            1 : std::string name(const T& /*unused*/) {
     739              :   return name<T>();
     740              : }
     741              : /// @}
     742              : 
     743              : /*!
     744              :  * \ingroup PrettyTypeGroup
     745              :  * \brief Return a comma separated list of the `pretty_type::name` of every type
     746              :  * in a `tmpl::list`.
     747              :  *
     748              :  * \note The `tmpl::list` must be flattened.
     749              :  */
     750              : template <typename List>
     751            1 : std::string list_of_names() {
     752              :   static_assert(tt::is_a_v<tmpl::list, List>);
     753              :   std::stringstream ss{};
     754              :   bool first_element = true;
     755              :   tmpl::for_each<List>([&first_element, &ss](auto v) {
     756              :     using type = tmpl::type_from<decltype(v)>;
     757              :     static_assert(not tt::is_a_v<tmpl::list, type>,
     758              :                   "The tmpl::list provided to pretty_type::list_of_names must "
     759              :                   "be flattened.");
     760              :     if (not first_element) {
     761              :       ss << ", ";
     762              :     } else {
     763              :       first_element = false;
     764              :     }
     765              : 
     766              :     ss << pretty_type::name<type>();
     767              :   });
     768              : 
     769              :   return ss.str();
     770              : }
     771              : 
     772              : /*!
     773              :  * \ingroup PrettyTypeGroup
     774              :  * \brief Return a vector of the `pretty_type::get_name` of every type
     775              :  * in a `tmpl::list`.
     776              :  */
     777              : template <typename... Types>
     778            1 : std::vector<std::string> vector_of_get_names(tmpl::list<Types...> /*meta*/) {
     779              :   return {pretty_type::get_name<Types>()...};
     780              : }
     781              : }  // namespace pretty_type
        

Generated by: LCOV version 2.0-1