• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DNKpp / mimicpp / 18388726968

09 Oct 2025 08:46PM UTC coverage: 92.629% (-5.5%) from 98.112%
18388726968

Pull #138

github

web-flow
Merge b67d4c028 into 798c20ab0
Pull Request #138: CI: Use latest gcovr

1797 of 2079 branches covered (86.44%)

Branch coverage included in aggregate %.

2413 of 2466 relevant lines covered (97.85%)

7268.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.41
/include/mimic++/printing/type/Templated.hpp
1
//          Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2
// Distributed under the Boost Software License, Version 1.0.
3
//    (See accompanying file LICENSE_1_0.txt or copy at
4
//          https://www.boost.org/LICENSE_1_0.txt)
5

6
#ifndef MIMICPP_PRINTING_TYPE_TEMPLATED_HPP
7
#define MIMICPP_PRINTING_TYPE_TEMPLATED_HPP
8

9
#pragma once
10

11
#include "mimic++/Fwd.hpp"
12
#include "mimic++/config/Config.hpp"
13
#include "mimic++/printing/Format.hpp"
14
#include "mimic++/printing/Fwd.hpp"
15
#include "mimic++/printing/type/PrintType.hpp"
16
#include "mimic++/utilities/TypeList.hpp"
17

18
#ifndef MIMICPP_DETAIL_IS_MODULE
19
    #include <algorithm>
20
    #include <concepts>
21
    #include <functional>
22
    #include <memory>
23
    #include <memory_resource>
24
    #include <type_traits>
25
    #include <utility>
26
#endif
27

28
namespace mimicpp::printing::type::detail
29
{
30
#ifdef MIMICPP_CONFIG_EXPERIMENTAL_PRETTY_TYPES
31

32
    template <typename T, print_iterator OutIter>
33
    constexpr OutIter pretty_template_name(OutIter out)
34
    {
35
        StringT name = type_name<T>();
1,620✔
36
        auto const iter = std::ranges::find(name, '<');
1,620✔
37
        MIMICPP_ASSERT(iter != name.cend(), "Given name is not a template.");
38
        name.erase(iter, name.end());
3,240✔
39

40
        return type::prettify_type(std::move(out), std::move(name));
4,860✔
41
    }
1,620✔
42

43
    template <typename NameGenerator>
44
    struct basic_template_type_printer
45
    {
46
        template <print_iterator OutIter>
47
        static constexpr OutIter print(OutIter out)
48
        {
49
            return std::invoke(NameGenerator{}, std::move(out));
1,619✔
50
        }
51
    };
52

53
    template <typename Type, template <typename...> typename Template, typename LeadingArgList>
54
    struct is_default_arg_for
55
        : public std::false_type
56
    {
57
    };
58

59
    template <typename Type, template <typename...> typename Template, typename... LeadingArgs>
60
        requires requires { typename Template<LeadingArgs...>; }
61
    struct is_default_arg_for<Type, Template, util::type_list<LeadingArgs...>>
62
        : public std::is_same<
63
              Template<LeadingArgs...>,
64
              Template<LeadingArgs..., Type>>
65
    {
66
    };
67

68
    template <typename Type, template <typename...> typename Template, typename LeadingArgList>
69
    concept default_arg_for = is_default_arg_for<Type, Template, LeadingArgList>::value;
70

71
    template <typename List>
72
    struct type_list_pop_back_if_can
73
        : public util::type_list_pop_back<List>
74
    {
75
    };
76

77
    template <>
78
    struct type_list_pop_back_if_can<util::type_list<>>
79
    {
80
        using type = util::type_list<>;
81
    };
82

83
    template <
84
        typename ArgList,
85
        template <typename...> typename Template,
86
        typename PopBack = type_list_pop_back_if_can<ArgList>>
87
    struct drop_default_args_for_impl
88
    {
89
        using type = ArgList;
90
    };
91

92
    template <typename ArgList, template <typename...> typename Template, typename PopBack>
93
        requires requires { typename PopBack::popped; }
94
              && default_arg_for<typename PopBack::popped, Template, typename PopBack::type>
95
    struct drop_default_args_for_impl<ArgList, Template, PopBack>
96
        : public drop_default_args_for_impl<typename PopBack::type, Template>
97
    {
98
    };
99

100
    template <template <typename...> typename Template, typename ArgList>
101
    struct drop_default_args_for
102
        : public drop_default_args_for_impl<ArgList, Template>
103
    {
104
    };
105

106
    template <template <typename...> typename Template, typename ArgList>
107
    struct template_type_name_generator_fn
108
    {
109
        template <print_iterator OutIter>
110
        constexpr OutIter operator()(OutIter out) const
111
        {
112
            using MinimalArgList = typename drop_default_args_for<Template, ArgList>::type;
113
            using Type = util::type_list_populate_t<Template, MinimalArgList>;
114

115
            out = pretty_template_name<Type>(std::move(out));
1,606✔
116
            out = format::format_to(std::move(out), "<");
3,212✔
117
            out = print_separated(std::move(out), ", ", MinimalArgList{});
3,212✔
118
            out = format::format_to(std::move(out), ">");
3,212✔
119

120
            return out;
1,606✔
121
        }
122
    };
123

124
    template <template <typename...> typename Template, typename... Ts>
125
    struct template_type_printer<Template<Ts...>>
126
        : public basic_template_type_printer<
127
              template_type_name_generator_fn<Template, util::type_list<Ts...>>>
128
    {
129
    };
130

131
    template <typename Allocator>
132
    struct is_pmr_allocator
133
        : public std::false_type
134
    {
135
    };
136

137
    template <typename T>
138
    struct is_pmr_allocator<std::pmr::polymorphic_allocator<T>>
139
        : public std::true_type
140
    {
141
    };
142

143
    template <template <typename...> typename Template, typename... Ts>
144
    concept std_pmr_container =
145
        requires {
146
            typename Template<Ts...>::allocator_type;
147
            typename Template<Ts...>::value_type;
148
        }
149
        && is_pmr_allocator<typename Template<Ts...>::allocator_type>::value
150
        && default_arg_for<std::allocator<typename Template<Ts...>::value_type>, Template, util::type_list_pop_back_t<util::type_list<Ts...>>>;
151

152
    static constexpr StringViewT stdPrefix{"std::"};
153

154
    template <template <typename...> typename Template, typename ArgList>
155
    struct potential_pmr_container_type_name_generator_fn
156
    {
157
        template <print_iterator OutIter>
158
        OutIter operator()(OutIter out) const
159
        {
160
            StringT const name = std::invoke(
89✔
161
                [] {
×
162
                    StringStreamT stream{};
89✔
163
                    std::invoke(
89✔
164
                        template_type_name_generator_fn<
165
                            Template,
166
                            util::type_list_pop_back_t<ArgList>>{},
167
                        std::ostreambuf_iterator{stream});
178✔
168
                    return std::move(stream).str();
178✔
169
                });
89✔
170

171
            // we do not want to accidentally manipulate non-std types, so make sure the `std::`` is actually part of the type
172
            if (name.starts_with(stdPrefix))
89✔
173
            {
174
                out = format::format_to(std::move(out), "std::pmr::");
176✔
175
                out = std::ranges::copy(
88✔
176
                          name.cbegin() + stdPrefix.size(),
176✔
177
                          name.cend(),
178
                          std::move(out))
88✔
179
                          .out;
180
            }
181
            // It's not an actual `std` type, but we've removed the allocator for the name generation, thus we need
182
            // generate it again with the actual allocator.
183
            else
184
            {
185
                out = std::invoke(
1✔
186
                    template_type_name_generator_fn<Template, ArgList>{},
187
                    std::move(out));
1✔
188
            }
189

190
            return out;
89✔
191
        }
89✔
192
    };
193

194
    template <template <typename...> typename Template, typename... Ts>
195
        requires std_pmr_container<Template, Ts...>
196
    struct template_type_printer<Template<Ts...>>
197
        : public basic_template_type_printer<
198
              potential_pmr_container_type_name_generator_fn<Template, util::type_list<Ts...>>>
199
    {
200
    };
201

202
    // used for array, span and the like
203
    // should also handle c++26s inplace_vector
204
    // see: https://en.cppreference.com/w/cpp/container/inplace_vector
205
    template <template <typename, auto...> typename Template, typename T, auto n>
206
    struct template_type_printer<Template<T, n>>
207
        : public basic_template_type_printer<
208
              decltype([]<print_iterator OutIter>(OutIter out) {
209
                  out = pretty_template_name<Template<T, n>>(std::move(out));
8✔
210
                  out = format::format_to(std::move(out), "<");
16✔
211
                  out = mimicpp::print_type<T>(std::move(out));
8✔
212
                  out = format::format_to(std::move(out), ", {}>", n);
16✔
213

214
                  return out;
8✔
215
              })>
216
    {
217
    };
218

219
    template <template <typename, auto...> typename Template, typename T, auto n>
220
        requires std::same_as<Template<T>, Template<T, n>>
221
    struct template_type_printer<Template<T, n>>
222
        : public basic_template_type_printer<
223
              decltype([]<print_iterator OutIter>(OutIter out) {
224
                  out = pretty_template_name<Template<T, n>>(std::move(out));
6✔
225
                  out = format::format_to(std::move(out), "<");
12✔
226
                  out = mimicpp::print_type<T>(std::move(out));
6✔
227
                  out = format::format_to(std::move(out), ">");
12✔
228

229
                  return out;
6✔
230
              })>
231
    {
232
    };
233

234
#endif
235

236
}
237

238
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc