SpECTRE Documentation Coverage Report
Current view: top level - Utilities - PrettyType.hpp Hit Total Coverage
Commit: 817e13c5144619b701c7cd870655d8dbf94ab8ce Lines: 12 12 100.0 %
Date: 2024-07-19 22:17:05
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 1.14